awacke1 commited on
Commit
f56c398
·
verified ·
1 Parent(s): 397c8b0

Create app.py.backupSunEve.py

Browse files
Files changed (1) hide show
  1. app.py.backupSunEve.py +368 -0
app.py.backupSunEve.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ For this app take current version below and add the ability to generate it not only for each page layout but also every font to paragraph lead caharcter mappings with smart mappings to process markdown bold and markdown outlines and outline characters and alignement including tables and outlines to special font and layout instructions that mimic the markdown beauty with unicode reflect with maximally the right combinations of ofontsso first read the ttf file and determine which fonts then use those dynamically and have output sample of each ready for user: import streamlit as st
2
+
3
+ from pathlib import Path
4
+
5
+ import base64
6
+
7
+ import datetime
8
+
9
+ import re
10
+
11
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
12
+
13
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
14
+
15
+ from reportlab.lib.pagesizes import letter, A4, legal, landscape
16
+
17
+ from reportlab.lib.units import inch
18
+
19
+ from reportlab.lib import colors
20
+
21
+
22
+
23
+ # --- Configuration & Setup ---
24
+
25
+
26
+
27
+ # Define layouts using reportlab's pagesizes
28
+
29
+ # The 'size' key now holds a tuple (width, height)
30
+
31
+ LAYOUTS = {
32
+
33
+     "A4 Portrait": {"size": A4, "icon": "📄"},
34
+
35
+     "A4 Landscape": {"size": landscape(A4), "icon": "📄"},
36
+
37
+     "Letter Portrait": {"size": letter, "icon": "📄"},
38
+
39
+     "Letter Landscape": {"size": landscape(letter), "icon": "📄"},
40
+
41
+     "Legal Portrait": {"size": legal, "icon": "📄"},
42
+
43
+     "Legal Landscape": {"size": landscape(legal), "icon": "📄"},
44
+
45
+ }
46
+
47
+
48
+
49
+ # Directory to save the generated PDFs
50
+
51
+ OUTPUT_DIR = Path("generated_pdfs")
52
+
53
+ OUTPUT_DIR.mkdir(exist_ok=True)
54
+
55
+
56
+
57
+ # --- ReportLab PDF Generation ---
58
+
59
+
60
+
61
+ def markdown_to_story(markdown_text: str):
62
+
63
+     """Converts a markdown string into a list of ReportLab Flowables (a 'story')."""
64
+
65
+     styles = getSampleStyleSheet()
66
+
67
+     
68
+
69
+     # Define custom styles
70
+
71
+     style_normal = styles['BodyText']
72
+
73
+     style_h1 = styles['h1']
74
+
75
+     style_h2 = styles['h2']
76
+
77
+     style_h3 = styles['h3']
78
+
79
+     style_code = styles['Code']
80
+
81
+     
82
+
83
+     # A simple regex-based parser for markdown
84
+
85
+     story = []
86
+
87
+     lines = markdown_text.split('\n')
88
+
89
+     
90
+
91
+     in_code_block = False
92
+
93
+     code_block_text = ""
94
+
95
+
96
+
97
+     for line in lines:
98
+
99
+         if line.strip().startswith("```"):
100
+
101
+             if in_code_block:
102
+
103
+                 story.append(Paragraph(code_block_text.replace('\n', '<br/>'), style_code))
104
+
105
+                 in_code_block = False
106
+
107
+                 code_block_text = ""
108
+
109
+             else:
110
+
111
+                 in_code_block = True
112
+
113
+             continue
114
+
115
+
116
+
117
+         if in_code_block:
118
+
119
+             # Escape HTML tags for code blocks
120
+
121
+             escaped_line = line.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
122
+
123
+             code_block_text += escaped_line + '\n'
124
+
125
+             continue
126
+
127
+
128
+
129
+         if line.startswith("# "):
130
+
131
+             story.append(Paragraph(line[2:], style_h1))
132
+
133
+         elif line.startswith("## "):
134
+
135
+             story.append(Paragraph(line[3:], style_h2))
136
+
137
+         elif line.startswith("### "):
138
+
139
+             story.append(Paragraph(line[4:], style_h3))
140
+
141
+         elif line.strip().startswith(("* ", "- ")):
142
+
143
+             # Handle bullet points
144
+
145
+             story.append(Paragraph(f"• {line.strip()[2:]}", style_normal, bulletText='•'))
146
+
147
+         elif re.match(r'^\d+\.\s', line.strip()):
148
+
149
+             # Handle numbered lists
150
+
151
+             story.append(Paragraph(line.strip(), style_normal))
152
+
153
+         elif line.strip() == "":
154
+
155
+             story.append(Spacer(1, 0.2 * inch))
156
+
157
+         else:
158
+
159
+             # Handle bold and italics
160
+
161
+             line = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', line)
162
+
163
+             line = re.sub(r'_(.*?)_', r'<i>\1</i>', line)
164
+
165
+             story.append(Paragraph(line, style_normal))
166
+
167
+             
168
+
169
+     return story
170
+
171
+
172
+
173
+ def create_pdf_with_reportlab(md_path: Path, layout_name: str, layout_properties: dict):
174
+
175
+     """Creates a PDF for a given markdown file and layout."""
176
+
177
+     try:
178
+
179
+         md_content = md_path.read_text(encoding="utf-8")
180
+
181
+         
182
+
183
+         date_str = datetime.datetime.now().strftime("%Y-%m-%d")
184
+
185
+         output_filename = f"{md_path.stem}_{layout_name.replace(' ', '-')}_{date_str}.pdf"
186
+
187
+         output_path = OUTPUT_DIR / output_filename
188
+
189
+
190
+
191
+         doc = SimpleDocTemplate(
192
+
193
+             str(output_path),
194
+
195
+             pagesize=layout_properties.get("size", A4),
196
+
197
+             rightMargin=inch,
198
+
199
+             leftMargin=inch,
200
+
201
+             topMargin=inch,
202
+
203
+             bottomMargin=inch
204
+
205
+         )
206
+
207
+         
208
+
209
+         story = markdown_to_story(md_content)
210
+
211
+         
212
+
213
+         doc.build(story)
214
+
215
+         
216
+
217
+     except Exception as e:
218
+
219
+       �� st.error(f"Failed to process {md_path.name} with ReportLab: {e}")
220
+
221
+
222
+
223
+
224
+
225
+ # --- Streamlit UI and File Handling (Mostly Unchanged) ---
226
+
227
+
228
+
229
+ def get_file_download_link(file_path: Path) -> str:
230
+
231
+     """Generates a base64-encoded download link for a file."""
232
+
233
+     with open(file_path, "rb") as f:
234
+
235
+         data = base64.b64encode(f.read()).decode()
236
+
237
+     return f'<a href="data:application/octet-stream;base64,{data}" download="{file_path.name}">Download</a>'
238
+
239
+
240
+
241
+ def display_file_explorer():
242
+
243
+     """Renders a simple file explorer in the Streamlit app."""
244
+
245
+     st.header("📂 File Explorer")
246
+
247
+
248
+
249
+     st.subheader("Source Markdown Files (.md)")
250
+
251
+     md_files = list(Path(".").glob("*.md"))
252
+
253
+     if not md_files:
254
+
255
+         st.info("No Markdown files found. Create a `.md` file to begin.")
256
+
257
+     else:
258
+
259
+         for md_file in md_files:
260
+
261
+             col1, col2 = st.columns([0.8, 0.2])
262
+
263
+             with col1:
264
+
265
+                 st.write(f"📝 `{md_file.name}`")
266
+
267
+             with col2:
268
+
269
+                 st.markdown(get_file_download_link(md_file), unsafe_allow_html=True)
270
+
271
+
272
+
273
+     st.subheader("Generated PDF Files")
274
+
275
+     pdf_files = sorted(list(OUTPUT_DIR.glob("*.pdf")), key=lambda p: p.stat().st_mtime, reverse=True)
276
+
277
+     if not pdf_files:
278
+
279
+         st.info("No PDFs generated yet. Click the button above.")
280
+
281
+     else:
282
+
283
+         for pdf_file in pdf_files:
284
+
285
+             col1, col2 = st.columns([0.8, 0.2])
286
+
287
+             with col1:
288
+
289
+                 st.write(f"📄 `{pdf_file.name}`")
290
+
291
+             with col2:
292
+
293
+                 st.markdown(get_file_download_link(pdf_file), unsafe_allow_html=True)
294
+
295
+
296
+
297
+
298
+
299
+ # --- Main App ---
300
+
301
+
302
+
303
+ st.set_page_config(layout="wide", page_title="PDF Generator")
304
+
305
+
306
+
307
+ st.title("📄 Markdown to PDF Generator (ReportLab Engine)")
308
+
309
+ st.markdown("This tool finds all `.md` files in this directory, converts them to PDF in various layouts, and provides download links. It uses the `ReportLab` library and requires no external dependencies.")
310
+
311
+
312
+
313
+ if not list(Path(".").glob("*.md")):
314
+
315
+     with open("sample.md", "w", encoding="utf-8") as f:
316
+
317
+         f.write("# Sample Document\n\nThis is a sample markdown file. **ReportLab** is now creating the PDF.\n\n### Features\n- Item 1\n- Item 2\n\n1. Numbered item\n2. Another one\n\n```\ndef hello():\n    print(\"Hello, PDF!\")\n```\n")
318
+
319
+     st.rerun()
320
+
321
+
322
+
323
+ if st.button("🚀 Generate PDFs from all Markdown Files", type="primary"):
324
+
325
+     markdown_files = list(Path(".").glob("*.md"))
326
+
327
+     
328
+
329
+     if not markdown_files:
330
+
331
+         st.warning("No `.md` files found. Please add a markdown file to the directory.")
332
+
333
+     else:
334
+
335
+         total_pdfs = len(markdown_files) * len(LAYOUTS)
336
+
337
+         progress_bar = st.progress(0)
338
+
339
+         pdf_count = 0
340
+
341
+
342
+
343
+         with st.spinner("Generating PDFs using ReportLab..."):
344
+
345
+             for md_file in markdown_files:
346
+
347
+                 st.info(f"Processing: **{md_file.name}**")
348
+
349
+                 for name, properties in LAYOUTS.items():
350
+
351
+                     st.write(f"   - Generating `{name}` format...")
352
+
353
+                     create_pdf_with_reportlab(md_file, name, properties)
354
+
355
+                     pdf_count += 1
356
+
357
+                     progress_bar.progress(pdf_count / total_pdfs)
358
+
359
+
360
+
361
+         st.success("✅ PDF generation complete!")
362
+
363
+         st.rerun()
364
+
365
+
366
+
367
+ display_file_explorer()
368
+