awacke1 commited on
Commit
30b2906
ยท
verified ยท
1 Parent(s): 3829aef

Create backup2.app.py

Browse files
Files changed (1) hide show
  1. backup2.app.py +381 -0
backup2.app.py ADDED
@@ -0,0 +1,381 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import re
3
+ import streamlit as st
4
+ from PIL import Image
5
+ import fitz
6
+ from reportlab.lib.pagesizes import A4
7
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
8
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
9
+ from reportlab.lib import colors
10
+ from reportlab.pdfbase import pdfmetrics
11
+ from reportlab.pdfbase.ttfonts import TTFont
12
+
13
+ st.set_page_config(layout="wide", initial_sidebar_state="collapsed")
14
+
15
+ def create_pdf_tab(default_markdown):
16
+ # Font setup
17
+ available_fonts = {
18
+ "NotoEmoji Variable": "NotoEmoji-VariableFont_wght.ttf",
19
+ "NotoEmoji Bold": "NotoEmoji-Bold.ttf",
20
+ "NotoEmoji Light": "NotoEmoji-Light.ttf",
21
+ "NotoEmoji Medium": "NotoEmoji-Medium.ttf",
22
+ "NotoEmoji Regular": "NotoEmoji-Regular.ttf",
23
+ "NotoEmoji SemiBold": "NotoEmoji-SemiBold.ttf"
24
+ }
25
+
26
+ # Sidebar configuration
27
+ with st.sidebar:
28
+ selected_font_name = st.selectbox("Select NotoEmoji Font", options=list(available_fonts.keys()))
29
+ selected_font_path = available_fonts[selected_font_name]
30
+ base_font_size = st.slider("Font Size (points)", min_value=6, max_value=16, value=9, step=1) # Default to 9
31
+ plain_text_mode = st.checkbox("Render as Plain Text (Preserve Bold Only)", value=False)
32
+ num_columns = st.selectbox("Number of Columns", options=[1, 2, 3, 4, 5, 6], index=3) # Default to 4
33
+
34
+ # Markdown editor and buttons
35
+ if 'markdown_content' not in st.session_state:
36
+ st.session_state.markdown_content = default_markdown
37
+
38
+ edited_markdown = st.text_area("Modify the markdown content below:", value=st.session_state.markdown_content, height=300)
39
+ if st.button("Update PDF"):
40
+ st.session_state.markdown_content = edited_markdown
41
+ st.rerun()
42
+
43
+ st.download_button(label="Save Markdown", data=st.session_state.markdown_content, file_name="deities_guide.md", mime="text/markdown")
44
+
45
+ # Register font
46
+ pdfmetrics.registerFont(TTFont(selected_font_name, selected_font_path))
47
+
48
+ # Emoji font application
49
+ def apply_emoji_font(text, emoji_font):
50
+ emoji_pattern = re.compile(
51
+ r"([\U0001F300-\U0001F5FF"
52
+ r"\U0001F600-\U0001F64F"
53
+ r"\U0001F680-\U0001F6FF"
54
+ r"\U0001F700-\U0001F77F"
55
+ r"\U0001F780-\U0001F7FF"
56
+ r"\U0001F800-\U0001F8FF"
57
+ r"\U0001F900-\U0001F9FF"
58
+ r"\U0001FA00-\U0001FA6F"
59
+ r"\U0001FA70-\U0001FAFF"
60
+ r"\u2600-\u26FF"
61
+ r"\u2700-\u27BF]+)"
62
+ )
63
+ def replace_emoji(match):
64
+ emoji = match.group(1)
65
+ if len(emoji) > 1:
66
+ emoji = emoji[0]
67
+ return f'<font face="{emoji_font}">{emoji}</font>'
68
+ return emoji_pattern.sub(replace_emoji, text)
69
+
70
+ # Markdown to PDF content
71
+ def markdown_to_pdf_content(markdown_text, plain_text_mode):
72
+ lines = markdown_text.strip().split('\n')
73
+ pdf_content = []
74
+
75
+ if plain_text_mode:
76
+ for line in lines:
77
+ line = line.strip()
78
+ if not line or line.startswith('# '):
79
+ continue
80
+ bold_pattern = re.compile(r'\*\*(.*?)\*\*')
81
+ line = bold_pattern.sub(r'<b>\1</b>', line)
82
+ pdf_content.append(line)
83
+ else:
84
+ for line in lines:
85
+ line = line.strip()
86
+ if not line or line.startswith('# '):
87
+ continue
88
+ if line.startswith('## ') or line.startswith('### '):
89
+ text = line.replace('## ', '').replace('### ', '').strip()
90
+ pdf_content.append(f"<b>{text}</b>")
91
+ else:
92
+ pdf_content.append(line.strip())
93
+
94
+ total_lines = len(pdf_content)
95
+ return pdf_content, total_lines
96
+
97
+ # Create PDF
98
+ def create_pdf(markdown_text, base_font_size, plain_text_mode, num_columns):
99
+ buffer = io.BytesIO()
100
+ # Double A4 page: A4 width * 2 (landscape)
101
+ page_width = A4[0] * 2
102
+ page_height = A4[1]
103
+ doc = SimpleDocTemplate(buffer, pagesize=(page_width, page_height), leftMargin=36, rightMargin=36, topMargin=36, bottomMargin=36)
104
+ styles = getSampleStyleSheet()
105
+ story = []
106
+ spacer_height = 10
107
+ section_spacer_height = 15 # Extra spacing before numbered sections
108
+ pdf_content, total_lines = markdown_to_pdf_content(markdown_text, plain_text_mode)
109
+
110
+ item_font_size = base_font_size
111
+ section_font_size = base_font_size * 1.1
112
+
113
+ section_style = ParagraphStyle(
114
+ 'SectionStyle', parent=styles['Heading2'], fontName="Helvetica-Bold",
115
+ textColor=colors.darkblue, fontSize=section_font_size, leading=section_font_size * 1.2, spaceAfter=2
116
+ )
117
+ item_style = ParagraphStyle(
118
+ 'ItemStyle', parent=styles['Normal'], fontName="Helvetica",
119
+ fontSize=item_font_size, leading=item_font_size * 1.15, spaceAfter=1
120
+ )
121
+
122
+ story.append(Spacer(1, spacer_height))
123
+ columns = [[] for _ in range(num_columns)]
124
+ lines_per_column = total_lines / num_columns if num_columns > 0 else total_lines
125
+ current_line_count = 0
126
+ current_column = 0
127
+
128
+ # Regex to detect numbered sections (e.g., "1. ", "2. ")
129
+ number_pattern = re.compile(r'^\d+\.\s')
130
+
131
+ for i, item in enumerate(pdf_content):
132
+ # Add extra spacing before numbered sections (but not the first one)
133
+ if i > 0 and number_pattern.match(item):
134
+ columns[current_column].append(Spacer(1, section_spacer_height))
135
+
136
+ if current_line_count >= lines_per_column and current_column < num_columns - 1:
137
+ current_column += 1
138
+ current_line_count = 0
139
+ columns[current_column].append(item)
140
+ current_line_count += 1
141
+
142
+ column_cells = [[] for _ in range(num_columns)]
143
+ for col_idx, column in enumerate(columns):
144
+ for item in column:
145
+ if isinstance(item, Spacer):
146
+ column_cells[col_idx].append(item)
147
+ elif isinstance(item, str) and item.startswith('<b>'):
148
+ text = item.replace('<b>', '').replace('</b>', '')
149
+ column_cells[col_idx].append(Paragraph(apply_emoji_font(text, selected_font_name), section_style))
150
+ else:
151
+ column_cells[col_idx].append(Paragraph(apply_emoji_font(item, selected_font_name), item_style))
152
+
153
+ max_cells = max(len(cells) for cells in column_cells) if column_cells else 0
154
+ for cells in column_cells:
155
+ cells.extend([Paragraph("", item_style)] * (max_cells - len(cells)))
156
+
157
+ col_width = (page_width - 72) / num_columns if num_columns > 0 else page_width - 72
158
+ table_data = list(zip(*column_cells)) if column_cells else [[]]
159
+ table = Table(table_data, colWidths=[col_width] * num_columns, hAlign='CENTER')
160
+ table.setStyle(TableStyle([
161
+ ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
162
+ ('BACKGROUND', (0, 0), (-1, -1), colors.white), ('GRID', (0, 0), (-1, -1), 0, colors.white),
163
+ ('LINEAFTER', (0, 0), (num_columns-1, -1), 0.5, colors.grey),
164
+ ('LEFTPADDING', (0, 0), (-1, -1), 2), ('RIGHTPADDING', (0, 0), (-1, -1), 2),
165
+ ('TOPPADDING', (0, 0), (-1, -1), 1), ('BOTTOMPADDING', (0, 0), (-1, -1), 1),
166
+ ]))
167
+
168
+ story.append(table)
169
+ doc.build(story)
170
+ buffer.seek(0)
171
+ return buffer.getvalue()
172
+
173
+ # PDF to image
174
+ def pdf_to_image(pdf_bytes):
175
+ try:
176
+ doc = fitz.open(stream=pdf_bytes, filetype="pdf")
177
+ images = []
178
+ for page in doc:
179
+ pix = page.get_pixmap(matrix=fitz.Matrix(2.0, 2.0))
180
+ img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
181
+ images.append(img)
182
+ doc.close()
183
+ return images
184
+ except Exception as e:
185
+ st.error(f"Failed to render PDF preview: {e}")
186
+ return None
187
+
188
+ # Main logic (PDF generation and preview only)
189
+ with st.spinner("Generating PDF..."):
190
+ pdf_bytes = create_pdf(st.session_state.markdown_content, base_font_size, plain_text_mode, num_columns)
191
+
192
+ with st.container():
193
+ pdf_images = pdf_to_image(pdf_bytes)
194
+ if pdf_images:
195
+ for img in pdf_images:
196
+ st.image(img, use_container_width=True)
197
+ else:
198
+ st.info("Download the PDF to view it locally.")
199
+
200
+ # "Download PDF" in sidebar
201
+ with st.sidebar:
202
+ st.download_button(label="Download PDF", data=pdf_bytes, file_name="deities_guide.pdf", mime="application/pdf")
203
+
204
+ default_markdown = """# Deities Guide: Mythology and Moral Lessons ๐ŸŒŸ
205
+
206
+ 1. ๐Ÿ“œ Introduction
207
+ - Purpose: Explore deities, spirits, saints, and beings with their stories and morals.
208
+ - Usage: Guide for learning and storytelling across traditions.
209
+ - Themes: Justice, faith, hubris, redemption, cosmic order.
210
+
211
+ 2. ๐Ÿ› ๏ธ Core Concepts of Divinity
212
+ - Powers: Creation, omniscience, shapeshifting across entities.
213
+ - Life Cycle: Mortality, immortality, transitions such as saints and avatars.
214
+ - Communication: Omens, visions, miracles from gods and spirits.
215
+
216
+ 3. โšก Standard Abilities
217
+ - Creation: Gods and spirits shape worlds, such as Allah and Vishnu.
218
+ - Influence: Saints and prophets intercede, for example, Muhammad and Paul.
219
+ - Transformation: Angels and avatars shift forms, like Gabriel and Krishna.
220
+ - Knowledge: Foresight or revelation, as seen with the Holy Spirit and Brahma.
221
+ - Judgment: Divine authority, exemplified by Yahweh and Yama.
222
+
223
+ 4. โณ Mortality and Immortality
224
+ - Gods: Eternal, such as Allah and Shiva.
225
+ - Spirits: Realm-bound, like jinn and devas.
226
+ - Saints/Prophets: Mortal to divine, for instance, Moses and Rama.
227
+ - Beings: Limbo states, such as cherubim and rakshasas.
228
+ - Lessons: Faith and duty define transitions.
229
+
230
+ 5. ๐ŸŒ  Ascension and Signs
231
+ - Paths: Birth, deeds, revelation, as with Jesus and Arjuna.
232
+ - Signs: Miracles and prophecies, like those in the Quran and Gita.
233
+ - Morals: Obedience and devotion shape destiny.
234
+
235
+ 6. ๐ŸŽฒ Storytelling and Games
236
+ - Portrayal: Gods, spirits, and saints in narratives or RPGs.
237
+ - Dynamics: Clerics, imams, and sadhus serve higher powers.
238
+ - Balance: Power versus personality for depth.
239
+
240
+ 7. ๐ŸŽฎ Dungeon Mastering Beings
241
+ - Gods: Epic scope, such as Allah and Vishnu.
242
+ - Spirits: Local influence, like jinn and apsaras.
243
+ - Saints: Moral anchors, for example, St. Francis and Ali.
244
+
245
+ 8. ๐Ÿ™ Devotee Relationships
246
+ - Clerics: Serve gods, such as Krishnaโ€™s priests.
247
+ - Mediums: Channel spirits, like jinn whisperers.
248
+ - Faithful: Venerate saints and prophets, for instance, Fatimaโ€™s followers.
249
+
250
+ 9. ๐Ÿฆ… American Indian Traditions
251
+ - Coyote, Raven, White Buffalo Woman: Trickster kin and wise mother.
252
+ - Relation: Siblings and guide teach balance.
253
+ - Lesson: Chaos breeds wisdom.
254
+
255
+ 10. โš”๏ธ Arthurian Legends
256
+ - Merlin, Morgan le Fay, Arthur: Mentor, rival, son.
257
+ - Relation: Family tests loyalty.
258
+ - Lesson: Honor versus betrayal.
259
+
260
+ 11. ๐Ÿ›๏ธ Babylonian Mythology
261
+ - Marduk, Tiamat, Ishtar: Son, mother, lover.
262
+ - Relation: Kinship drives order.
263
+ - Lesson: Power reshapes chaos.
264
+
265
+ 12. โœ๏ธ Christian Trinity
266
+ - God (Yahweh), Jesus, Holy Spirit: Father, Son, Spirit.
267
+ - Relation: Divine family redeems.
268
+ - Lesson: Faith restores grace.
269
+
270
+ 13. ๐Ÿ˜‡ Christian Saints & Angels
271
+ - St. Michael, Gabriel, Mary: Warrior, messenger, mother.
272
+ - Relation: Heavenly kin serve God.
273
+ - Lesson: Duty upholds divine will.
274
+
275
+ 14. ๐Ÿ€ Celtic Mythology
276
+ - Lugh, Morrigan, Cernunnos: Son, mother, father.
277
+ - Relation: Family governs cycles.
278
+ - Lesson: Courage in fate.
279
+
280
+ 15. ๐ŸŒ„ Central American Traditions
281
+ - Quetzalcoatl, Tezcatlipoca, Huitzilopochtli: Brothers and war son.
282
+ - Relation: Sibling rivalry creates.
283
+ - Lesson: Sacrifice builds worlds.
284
+
285
+ 16. ๐Ÿ‰ Chinese Mythology
286
+ - Jade Emperor, Nuwa, Sun Wukong: Father, mother, rebel son.
287
+ - Relation: Family enforces harmony.
288
+ - Lesson: Duty curbs chaos.
289
+
290
+ 17. ๐Ÿ™ Cthulhu Mythos
291
+ - Cthulhu, Nyarlathotep, Yog-Sothoth: Elder kin.
292
+ - Relation: Cosmic trio overwhelms.
293
+ - Lesson: Insignificance humbles.
294
+
295
+ 18. โ˜ฅ Egyptian Mythology
296
+ - Ra, Osiris, Isis: Father, son, mother.
297
+ - Relation: Family ensures renewal.
298
+ - Lesson: Justice prevails.
299
+
300
+ 19. โ„๏ธ Finnish Mythology
301
+ - Vรคinรคmรถinen, Louhi, Ukko: Son, mother, father.
302
+ - Relation: Kinship tests wisdom.
303
+ - Lesson: Perseverance wins.
304
+
305
+ 20. ๐Ÿ›๏ธ Greek Mythology
306
+ - Zeus, Hera, Athena: Father, mother, daughter.
307
+ - Relation: Family rules with tension.
308
+ - Lesson: Hubris meets wisdom.
309
+
310
+ 21. ๐Ÿ•‰๏ธ Hindu Trimurti
311
+ - Brahma, Vishnu, Shiva: Creator, preserver, destroyer.
312
+ - Relation: Divine trio cycles existence.
313
+ - Lesson: Balance sustains life.
314
+
315
+ 22. ๐ŸŒบ Hindu Avatars & Devis
316
+ - Krishna, Rama, Durga: Sons and fierce mother.
317
+ - Relation: Avatars and goddess protect dharma.
318
+ - Lesson: Duty defeats evil.
319
+
320
+ 23. ๐ŸŒธ Japanese Mythology
321
+ - Amaterasu, Susanoo, Tsukuyomi: Sister, brothers.
322
+ - Relation: Siblings balance cosmos.
323
+ - Lesson: Harmony versus chaos.
324
+
325
+ 24. ๐Ÿ—ก๏ธ Melnibonean Legends
326
+ - Arioch, Xiombarg, Elric: Lords and mortal son.
327
+ - Relation: Pact binds chaos.
328
+ - Lesson: Power corrupts.
329
+
330
+ 25. โ˜ช๏ธ Muslim Divine & Messengers
331
+ - Allah, Muhammad, Gabriel: God, prophet, angel.
332
+ - Relation: Messenger reveals divine will.
333
+ - Lesson: Submission brings peace.
334
+
335
+ 26. ๐Ÿ‘ป Muslim Spirits & Kin
336
+ - Jinn, Iblis, Khidr: Spirits and guide defy or aid.
337
+ - Relation: Supernatural kin test faith.
338
+ - Lesson: Obedience versus rebellion.
339
+
340
+ 27. ๐Ÿฐ Nehwon Legends
341
+ - Death, Ningauble, Sheelba: Fateful trio.
342
+ - Relation: Guides shape destiny.
343
+ - Lesson: Cunning defies fate.
344
+
345
+ 28. ๐Ÿง Nonhuman Traditions
346
+ - Corellon, Moradin, Gruumsh: Elf, dwarf, orc fathers.
347
+ - Relation: Rivals define purpose.
348
+ - Lesson: Community endures.
349
+
350
+ 29. แšฑ Norse Mythology
351
+ - Odin, Frigg, Loki: Father, mother, trickster son.
352
+ - Relation: Family faces doom.
353
+ - Lesson: Sacrifice costs.
354
+
355
+ 30. ๐Ÿ—ฟ Sumerian Mythology
356
+ - Enki, Inanna, Anu: Son, daughter, father.
357
+ - Relation: Kin wield knowledge.
358
+ - Lesson: Ambition shapes.
359
+
360
+ 31. ๐Ÿ“š Appendices
361
+ - Planes: Realms of gods, spirits, saints, such as Paradise and Svarga.
362
+ - Symbols: Rituals and artifacts of faith.
363
+ - Charts: Domains and duties for devotees.
364
+
365
+ 32. ๐ŸŒŒ Planes of Existence
366
+ - Heaven/Paradise: Christian/Muslim abode.
367
+ - Svarga: Hindu divine realm.
368
+ - Underworld: Spirits linger, for example, Sheol and Naraka.
369
+
370
+ 33. ๐Ÿ• Temple Trappings
371
+ - Cross/Crescent: Christian/Muslim faith.
372
+ - Mandalas: Hindu devotion.
373
+ - Relics: Saintsโ€™ and prophetsโ€™ legacy.
374
+
375
+ 34. ๐Ÿ“Š Clerical Chart
376
+ - Gods: Domains, such as creation and mercy.
377
+ - Spirits: Influence, like guidance and mischief.
378
+ - Saints/Prophets: Virtues, for instance, justice and prophecy.
379
+ """
380
+
381
+ create_pdf_tab(default_markdown)