Spaces:
Runtime error
Runtime error
ashhadahsan
commited on
Commit
•
c060b6c
1
Parent(s):
778230b
Upload 7 files
Browse files- Goodreads_books_with_genres.csv +0 -0
- app.py +111 -0
- constants.py +216 -0
- generator.py +34 -0
- prompts.py +46 -0
- requirements.txt +6 -0
- utils.py +54 -0
Goodreads_books_with_genres.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
app.py
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from constants import *
|
3 |
+
from stqdm import stqdm
|
4 |
+
from prompts import *
|
5 |
+
from generator import *
|
6 |
+
from utils import *
|
7 |
+
|
8 |
+
|
9 |
+
st.set_page_config(
|
10 |
+
layout="wide",
|
11 |
+
page_title="AI Book Generator",
|
12 |
+
page_icon=":book:",
|
13 |
+
)
|
14 |
+
st.title("AI Book Generator")
|
15 |
+
st.markdown("<h3>Select options </h3>", unsafe_allow_html=True)
|
16 |
+
with st.expander("Educational value *"):
|
17 |
+
age_range = st.select_slider("Age range of the reader", options=AGE_RANGE)
|
18 |
+
skill_development = st.selectbox("Skill development", options=SKILL_DEVELOPMENT)
|
19 |
+
learning_obectives = st.selectbox(
|
20 |
+
"Learning objectives", options=LEARNING_OBJECTIVES
|
21 |
+
)
|
22 |
+
with st.expander("Emotional value *"):
|
23 |
+
theme = st.selectbox("Theme", options=THEME)
|
24 |
+
mood = st.selectbox("Moood of story", options=MODD_OF_STORY)
|
25 |
+
positive_messaging = st.selectbox("Skill development", options=POSITIVE_MESSAGNG)
|
26 |
+
with st.expander("Personal *"):
|
27 |
+
theme = st.selectbox("Gender", options=GENDER)
|
28 |
+
fvrt_book = st.text_input("Favorite book")
|
29 |
+
with st.expander("Book Details * "):
|
30 |
+
chapters = st.number_input(
|
31 |
+
"How many chapters should the book have?", min_value=3, max_value=100, value=5
|
32 |
+
)
|
33 |
+
|
34 |
+
title = st.text_input("Title of the book")
|
35 |
+
genre = st.selectbox("Genre", options=GENRE)
|
36 |
+
topic = st.selectbox("Topic ", options=TOPIC)
|
37 |
+
main_name = st.text_input("Name of main character")
|
38 |
+
type_of_main_character = st.selectbox(
|
39 |
+
"Type of main character", TYPE_OF_MAIN_CHARACTER
|
40 |
+
)
|
41 |
+
antagonist_name = st.text_input("Antagonist name")
|
42 |
+
antagonsit_type = st.selectbox("Antagonist type", options=ANTAGONIST_TYPE)
|
43 |
+
suuporting_character_name = st.text_input("Supporting character name (if any)")
|
44 |
+
suporting_character_type = st.selectbox(
|
45 |
+
"Supporting character type", options=SUPPORTING_CHARACTER_TYPE
|
46 |
+
)
|
47 |
+
settings = st.selectbox("Setting ", options=SETTINGS)
|
48 |
+
resolution = st.selectbox("Resolution", options=RESOLUTION)
|
49 |
+
|
50 |
+
btn = st.button("Generate Book")
|
51 |
+
if btn:
|
52 |
+
content = []
|
53 |
+
for x in stqdm(range(chapters), desc="Generating book"):
|
54 |
+
if x == 0:
|
55 |
+
prmpt = get_initial_prompts(
|
56 |
+
genre,
|
57 |
+
type_of_main_character,
|
58 |
+
main_name,
|
59 |
+
skill_development,
|
60 |
+
learning_obectives,
|
61 |
+
theme,
|
62 |
+
topic,
|
63 |
+
)
|
64 |
+
content.append(complete_with_gpt(prmpt, 200, "gpt2", 1500, 0.7, 1.5))
|
65 |
+
if x == 1:
|
66 |
+
prmpt = story_setting_prompt(
|
67 |
+
genre,
|
68 |
+
type_of_main_character,
|
69 |
+
main_name,
|
70 |
+
skill_development,
|
71 |
+
learning_obectives,
|
72 |
+
theme,
|
73 |
+
mood,
|
74 |
+
antagonist_name,
|
75 |
+
antagonsit_type,
|
76 |
+
)
|
77 |
+
previous = " ".join(x for x in content)
|
78 |
+
prmpt = previous + " " + prmpt
|
79 |
+
content.append(complete_with_gpt(prmpt, 200, "gpt2", 1500, 0.7, 1.5))
|
80 |
+
|
81 |
+
if x % 3 == 0:
|
82 |
+
prmpt = supporting_character_inclusion(
|
83 |
+
genre,
|
84 |
+
suuporting_character_name,
|
85 |
+
suporting_character_type,
|
86 |
+
positive_messaging,
|
87 |
+
)
|
88 |
+
previous = " ".join(x for x in content)
|
89 |
+
prmpt = previous + " " + prmpt
|
90 |
+
content.append(complete_with_gpt(prmpt, 200, "gpt2", 1500, 0.7, 1.5))
|
91 |
+
if x == chapters - 1:
|
92 |
+
prmpt = ending_scene(genre, resolution, main_name, positive_messaging)
|
93 |
+
previous = " ".join(x for x in content)
|
94 |
+
prmpt = previous + " " + prmpt
|
95 |
+
content.append(complete_with_gpt(prmpt, 200, "gpt2", 1500, 0.7, 1.5))
|
96 |
+
else:
|
97 |
+
previous = " ".join(x for x in content)
|
98 |
+
prmpt = previous
|
99 |
+
content.append(complete_with_gpt(prmpt, 200, "gpt2", 1500, 0.7, 1.5))
|
100 |
+
|
101 |
+
st.write(content)
|
102 |
+
filenamee = to_pdf(convert(create_md(text=content, title=title)))
|
103 |
+
with open(filenamee, "rb") as pdf_file:
|
104 |
+
PDFbyte = pdf_file.read()
|
105 |
+
|
106 |
+
st.download_button(
|
107 |
+
label="Download Book",
|
108 |
+
data=PDFbyte,
|
109 |
+
file_name=filenamee,
|
110 |
+
mime="application/octet-stream",
|
111 |
+
)
|
constants.py
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Educational values
|
2 |
+
AGE_RANGE = [3, 4, 5]
|
3 |
+
SKILL_DEVELOPMENT = [
|
4 |
+
"Curiosity",
|
5 |
+
"Imagination",
|
6 |
+
"Communication",
|
7 |
+
"Observation",
|
8 |
+
"Adaptability",
|
9 |
+
"Persistence",
|
10 |
+
"Collaboration",
|
11 |
+
"Emotional Intelligence",
|
12 |
+
"Self-awareness",
|
13 |
+
"Memory",
|
14 |
+
]
|
15 |
+
LEARNING_OBJECTIVES = [
|
16 |
+
"Science exploration",
|
17 |
+
"Nature observation",
|
18 |
+
"History and social studies",
|
19 |
+
"Language development",
|
20 |
+
"Math concepts",
|
21 |
+
"Fine motor skills" "Gross motor skills",
|
22 |
+
]
|
23 |
+
|
24 |
+
# emotionl values
|
25 |
+
THEME = [
|
26 |
+
"Empathy",
|
27 |
+
"Kindness",
|
28 |
+
"Friendship",
|
29 |
+
"Courage",
|
30 |
+
"Diversity",
|
31 |
+
"Imagination",
|
32 |
+
"Perseverance",
|
33 |
+
"Self-confidence",
|
34 |
+
"Responsibility" "Gratitude",
|
35 |
+
]
|
36 |
+
MODD_OF_STORY = [
|
37 |
+
"Lighthearted",
|
38 |
+
"Funny",
|
39 |
+
"Adventure",
|
40 |
+
"Comforting",
|
41 |
+
"Calm",
|
42 |
+
"Educational",
|
43 |
+
"Inspiring",
|
44 |
+
]
|
45 |
+
POSITIVE_MESSAGNG = [
|
46 |
+
"Kindness and compassion",
|
47 |
+
"Friendship and cooperation",
|
48 |
+
"Respect for others and diversity",
|
49 |
+
"Self-confidence and self-esteem",
|
50 |
+
"Perseverance and resilience",
|
51 |
+
"Honesty and integrity",
|
52 |
+
"Responsibility and accountability",
|
53 |
+
"Empathy and understanding",
|
54 |
+
"Mindfulness and emotional regulation",
|
55 |
+
"Creativity and imagination",
|
56 |
+
]
|
57 |
+
|
58 |
+
# Personal
|
59 |
+
GENDER = ["Male", "Female"]
|
60 |
+
GENRE = [
|
61 |
+
"Fairy tales",
|
62 |
+
"Biography",
|
63 |
+
"Animal stories",
|
64 |
+
"Adventure stories",
|
65 |
+
"Rhyming books",
|
66 |
+
"Concept books",
|
67 |
+
"Folktales",
|
68 |
+
"Nursery rhymes",
|
69 |
+
"Science fiction",
|
70 |
+
"Humorous books",
|
71 |
+
]
|
72 |
+
TOPIC = [
|
73 |
+
"Animals (fiction and non-fiction)",
|
74 |
+
"Friendship and relationships",
|
75 |
+
"Family and home life",
|
76 |
+
"Bedtime stories",
|
77 |
+
"Colors and shapes",
|
78 |
+
"Numbers and counting",
|
79 |
+
"Alphabet and phonics",
|
80 |
+
"Fairy tales and nursery rhymes",
|
81 |
+
"Adventure and exploration",
|
82 |
+
"Imagination and creativity",
|
83 |
+
]
|
84 |
+
|
85 |
+
TYPE_OF_MAIN_CHARACTER = [
|
86 |
+
"Human",
|
87 |
+
"Monkey",
|
88 |
+
"Cat",
|
89 |
+
"Caterpillar",
|
90 |
+
"Dog",
|
91 |
+
"Teddy bear",
|
92 |
+
"Elephant",
|
93 |
+
"Lions",
|
94 |
+
"Penguins",
|
95 |
+
"Monkeys",
|
96 |
+
"Ducks",
|
97 |
+
"Frogs",
|
98 |
+
"Giraffes",
|
99 |
+
"Tigers",
|
100 |
+
"Whales",
|
101 |
+
"Zebras",
|
102 |
+
"Superhero",
|
103 |
+
"Dinosaur",
|
104 |
+
"Robot",
|
105 |
+
"Aliens",
|
106 |
+
"Dragons",
|
107 |
+
"Pirates",
|
108 |
+
"Princess",
|
109 |
+
"Fairy",
|
110 |
+
"Dragons",
|
111 |
+
"Cyclops",
|
112 |
+
"Yeti",
|
113 |
+
"Bigfoot",
|
114 |
+
"Goblins",
|
115 |
+
"Trolls",
|
116 |
+
"Ghosts",
|
117 |
+
"Fire trucks",
|
118 |
+
"Trains",
|
119 |
+
"Race cars",
|
120 |
+
"Construction vehicle",
|
121 |
+
"Airplanes",
|
122 |
+
"Helicopters",
|
123 |
+
"Boats",
|
124 |
+
"Spaceships",
|
125 |
+
"Motorcycles",
|
126 |
+
"Buses",
|
127 |
+
]
|
128 |
+
ANTAGONIST_TYPE = [
|
129 |
+
"Witch",
|
130 |
+
"Wizard",
|
131 |
+
"Evil queen",
|
132 |
+
"Evil king",
|
133 |
+
"Monster",
|
134 |
+
"Pirate",
|
135 |
+
"Giant",
|
136 |
+
"Robot",
|
137 |
+
"Evil machine",
|
138 |
+
"Human",
|
139 |
+
"Monkey",
|
140 |
+
"Cat",
|
141 |
+
"Caterpillar",
|
142 |
+
"Dog",
|
143 |
+
"Teddy bear",
|
144 |
+
"Elephant",
|
145 |
+
"Lions",
|
146 |
+
"Penguins",
|
147 |
+
"Monkeys",
|
148 |
+
"Ducks",
|
149 |
+
"Frogs",
|
150 |
+
"Giraffes",
|
151 |
+
"Tigers",
|
152 |
+
"Whales",
|
153 |
+
"Zebras",
|
154 |
+
"Superhero",
|
155 |
+
"Dinosaur",
|
156 |
+
"Robot",
|
157 |
+
"Aliens",
|
158 |
+
"Dragons",
|
159 |
+
"Pirates",
|
160 |
+
"Princess",
|
161 |
+
"Fairy",
|
162 |
+
"Dragons",
|
163 |
+
"Cyclops",
|
164 |
+
"Yeti",
|
165 |
+
"Bigfoot",
|
166 |
+
"Goblins",
|
167 |
+
"Trolls",
|
168 |
+
"Ghosts",
|
169 |
+
"Fire trucks",
|
170 |
+
"Trains",
|
171 |
+
"Race cars",
|
172 |
+
"Construction vehicle",
|
173 |
+
"Airplanes",
|
174 |
+
"Helicopters",
|
175 |
+
"Boats",
|
176 |
+
"Spaceships",
|
177 |
+
"Motorcycles",
|
178 |
+
"Buses",
|
179 |
+
]
|
180 |
+
SUPPORTING_CHARACTER_TYPE = ANTAGONIST_TYPE
|
181 |
+
SETTINGS = [
|
182 |
+
"Forests",
|
183 |
+
"Underwater",
|
184 |
+
"Imaginary world",
|
185 |
+
"Cityscapes",
|
186 |
+
"Countryside",
|
187 |
+
"Outer space",
|
188 |
+
"Castle",
|
189 |
+
"School",
|
190 |
+
"Magical kingdom",
|
191 |
+
"Enchanted forest",
|
192 |
+
"Circus",
|
193 |
+
"City",
|
194 |
+
]
|
195 |
+
RESOLUTION = [
|
196 |
+
"Apologizing and making amends",
|
197 |
+
"Learning to share and take turns",
|
198 |
+
"Standing up for oneself and others",
|
199 |
+
"Overcoming fear and facing challenges",
|
200 |
+
"Solving a problem or mystery",
|
201 |
+
"Learning a lesson or moral value",
|
202 |
+
"Forgiving and moving on",
|
203 |
+
"Accepting differences and celebrating diversity",
|
204 |
+
"Helping others and showing kindness",
|
205 |
+
"Making a new friend or finding common ground",
|
206 |
+
"Discovering a new passion or talent",
|
207 |
+
"Resolving a conflict peacefully and fairly",
|
208 |
+
"Making a sacrifice for the greater good",
|
209 |
+
"Learning from mistakes and taking responsibility",
|
210 |
+
"Understanding the consequences of one's actions",
|
211 |
+
"Finding a creative or innovative solution",
|
212 |
+
"Embracing change and adapting to new situations",
|
213 |
+
"Discovering the importance of teamwork and cooperation",
|
214 |
+
"Making a tough decision and sticking to it",
|
215 |
+
"Embracing the power of imagination and creativity",
|
216 |
+
]
|
generator.py
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import pipeline
|
2 |
+
|
3 |
+
|
4 |
+
def generate(text, the_model, max_length, temperature, repetition_penalty):
|
5 |
+
generator = pipeline("text-generation", model=the_model)
|
6 |
+
result = generator(
|
7 |
+
text,
|
8 |
+
num_return_sequences=1,
|
9 |
+
max_length=max_length,
|
10 |
+
temperature=temperature,
|
11 |
+
repetition_penalty=repetition_penalty,
|
12 |
+
no_repeat_ngram_size=2,
|
13 |
+
early_stopping=False,
|
14 |
+
)
|
15 |
+
return result[0]["generated_text"]
|
16 |
+
|
17 |
+
|
18 |
+
def complete_with_gpt(
|
19 |
+
text, context, the_model, max_length, temperature, repetition_penalty
|
20 |
+
):
|
21 |
+
# Use the last [context] characters of the text as context
|
22 |
+
max_length = max_length + context
|
23 |
+
return generate(
|
24 |
+
text[-context:], the_model, max_length, temperature, repetition_penalty
|
25 |
+
)
|
26 |
+
|
27 |
+
|
28 |
+
# complete_with_gpt("I am a language model",200,'gpt2-medium',1500,0.7,1.5)
|
29 |
+
# def generate(genre:str,topic:str,main_name:str,type_of_main_character:str,antagonist_name:str,
|
30 |
+
# antagonist_type:str,supporting_character_name:str,supporting_char_type:str,settings:str,
|
31 |
+
# resoluton:str,chapter:int
|
32 |
+
# ):
|
33 |
+
# chapter_text={}
|
34 |
+
# for x in range(chapter):0
|
prompts.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def get_initial_prompts(
|
2 |
+
key,
|
3 |
+
type_of_main_character,
|
4 |
+
main_character_name,
|
5 |
+
skill_development,
|
6 |
+
learning_objectives,
|
7 |
+
theme,
|
8 |
+
topic,
|
9 |
+
):
|
10 |
+
|
11 |
+
prompts = {
|
12 |
+
"Fairy tales": f"I am a land far far away there was a {type_of_main_character} who is famous by the name {main_character_name} . {main_character_name} always had a good{skill_development} and the story revolves around {learning_objectives} ,once can learn about {theme}. This is a famous topic consisting of {topic} for childrens "
|
13 |
+
}
|
14 |
+
|
15 |
+
return prompts.get(key)
|
16 |
+
|
17 |
+
|
18 |
+
def story_setting_prompt(
|
19 |
+
key,
|
20 |
+
type_of_main_character,
|
21 |
+
main_character_name,
|
22 |
+
skill_development,
|
23 |
+
learning_objectives,
|
24 |
+
theme,
|
25 |
+
mood_of_story,
|
26 |
+
ant_name,
|
27 |
+
ant_type,
|
28 |
+
):
|
29 |
+
prompts = {
|
30 |
+
"Fairy tales": f"{main_character_name} was always inclined towards {mood_of_story} but there was a {ant_type} famoulsy known as {ant_name} the {ant_type} who did not like {main_character_name}"
|
31 |
+
}
|
32 |
+
return prompts.get(key)
|
33 |
+
|
34 |
+
|
35 |
+
def supporting_character_inclusion(key, sup_name, sup_type, positive_messaging):
|
36 |
+
prompts = {
|
37 |
+
"Fairy tales": f"Our hero who was always a supporter of {positive_messaging} had an friend named {sup_name} who was a {sup_type}"
|
38 |
+
}
|
39 |
+
return prompts.get(key)
|
40 |
+
|
41 |
+
|
42 |
+
def ending_scene(key, resolution, main_char, positive_mess):
|
43 |
+
prompts = {
|
44 |
+
"Fairy tales": f"So this concludes that {main_char} was focused on getting {positive_mess} out for the world which resulted in {resolution}"
|
45 |
+
}
|
46 |
+
return prompts.get(key)
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
transformers
|
2 |
+
streamlit
|
3 |
+
markdown
|
4 |
+
pdfkit
|
5 |
+
pandas
|
6 |
+
stqdm
|
utils.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import random
|
3 |
+
import markdown
|
4 |
+
import pdfkit
|
5 |
+
import platform
|
6 |
+
|
7 |
+
|
8 |
+
def get_book_genre(book_name: str) -> str:
|
9 |
+
|
10 |
+
df = pd.read_csv("Goodreads_books_with_genres.csv")
|
11 |
+
genre = df[df.Title.str.contains(book_name)]["genres"].values.tolist()[0].split(";")
|
12 |
+
genre = genre[random.randint(0, len(genre))]
|
13 |
+
return genre
|
14 |
+
|
15 |
+
|
16 |
+
def create_md(text, title):
|
17 |
+
with open(f"{title}.md", "w") as f:
|
18 |
+
f.write(f"# Title: {title}")
|
19 |
+
f.write(r"\n")
|
20 |
+
for x in range(len(text)):
|
21 |
+
f.write("\n")
|
22 |
+
f.write(f"## Chapter {x+1}")
|
23 |
+
f.write("\n")
|
24 |
+
f.write(text[x])
|
25 |
+
return title
|
26 |
+
|
27 |
+
|
28 |
+
def convert(filename):
|
29 |
+
with open(f"{filename}.md", "r") as f:
|
30 |
+
text = f.read()
|
31 |
+
html = markdown.markdown(text)
|
32 |
+
|
33 |
+
with open(f"{filename}.html", "w", encoding="utf-8") as f:
|
34 |
+
f.write(html)
|
35 |
+
return f"{filename}"
|
36 |
+
|
37 |
+
|
38 |
+
def to_pdf(filename):
|
39 |
+
if platform.system() == "Windows":
|
40 |
+
path_to_wkhtmltopdf = r"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"
|
41 |
+
|
42 |
+
# Point pdfkit configuration to wkhtmltopdf.exe
|
43 |
+
config = pdfkit.configuration(wkhtmltopdf=path_to_wkhtmltopdf)
|
44 |
+
|
45 |
+
# Convert HTML file to PDF
|
46 |
+
pdfkit.from_file(
|
47 |
+
f"{filename}.html", output_path=f"{filename}.pdf", configuration=config
|
48 |
+
)
|
49 |
+
return f"{filename}.pdf"
|
50 |
+
else:
|
51 |
+
pdfkit.from_file(
|
52 |
+
f"{filename}.html", output_path=f"{filename}.pdf", configuration=config
|
53 |
+
)
|
54 |
+
return f"{filename}.pdf"
|