awacke1 commited on
Commit
8f4148e
ยท
verified ยท
1 Parent(s): 4a870b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -19
app.py CHANGED
@@ -179,6 +179,8 @@ def markdown_to_pdf_content(markdown_text, add_space_before_numbered, headings_t
179
  return pdf_content, total_lines
180
 
181
  def create_pdf(markdown_text, base_font_size, num_columns, add_space_before_numbered, headings_to_fonts, doc_title, longest_line_words, total_lines):
 
 
182
  buffer = io.BytesIO()
183
  page_width = A4[0] * 2
184
  page_height = A4[1]
@@ -198,14 +200,14 @@ def create_pdf(markdown_text, base_font_size, num_columns, add_space_before_numb
198
  available_font_files = glob.glob("*.ttf")
199
  if not available_font_files:
200
  st.error("No .ttf font files found.")
201
- return
202
  selected_font_path = next((f for f in available_font_files if "NotoEmoji-Bold" in f), None)
203
  if selected_font_path:
204
  pdfmetrics.registerFont(TTFont("NotoEmoji-Bold", selected_font_path))
205
  pdfmetrics.registerFont(TTFont("DejaVuSans", "DejaVuSans.ttf"))
206
  except Exception as e:
207
  st.error(f"Font registration error: {e}")
208
- return
209
  total_chars = sum(len(line) for line in pdf_content)
210
  hierarchy_weight = sum(1.5 if line.startswith("<b>") else 1 for line in pdf_content)
211
  content_density = total_lines * hierarchy_weight + total_chars / 50
@@ -216,7 +218,7 @@ def create_pdf(markdown_text, base_font_size, num_columns, add_space_before_numb
216
  suggested_columns = max(2, min(4, int(total_lines / ideal_lines_per_col) + 1))
217
  num_columns = num_columns if num_columns != 0 else suggested_columns
218
  col_width = usable_width / num_columns
219
- min_font_size = 6
220
  max_font_size = 16
221
  lines_per_col = total_lines / num_columns if num_columns > 0 else total_lines
222
  target_height_per_line = usable_height / lines_per_col if lines_per_col > 0 else usable_height
@@ -226,10 +228,10 @@ def create_pdf(markdown_text, base_font_size, num_columns, add_space_before_numb
226
  adjusted_font_size = int(col_width / (avg_line_chars / 10))
227
  adjusted_font_size = max(min_font_size, adjusted_font_size)
228
 
229
- # Adjust font size to fit one page based on longest line
230
- if longest_line_words > 17:
231
- font_scale = 17 / longest_line_words # Scale down from reference (17 words)
232
- adjusted_font_size = max(min_font_size, int(adjusted_font_size * font_scale))
233
 
234
  item_style = ParagraphStyle(
235
  'ItemStyle', parent=styles['Normal'], fontName="DejaVuSans",
@@ -309,6 +311,8 @@ def create_pdf(markdown_text, base_font_size, num_columns, add_space_before_numb
309
  return buffer.getvalue()
310
 
311
  def pdf_to_image(pdf_bytes):
 
 
312
  try:
313
  doc = fitz.open(stream=pdf_bytes, filetype="pdf")
314
  images = []
@@ -325,7 +329,8 @@ def pdf_to_image(pdf_bytes):
325
  # PDF creation and linking functions
326
  WORDS_12 = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"]
327
  WORDS_24 = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
328
- "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "twenty one", "twenty two", "twenty three", "twenty four"]
 
329
 
330
  def create_crossfile_pdfs(source_pdf="TestSource.pdf", target_pdf="TestTarget.pdf"):
331
  """Create two PDFs with cross-file linking."""
@@ -405,7 +410,7 @@ def create_crossfile_pdfs(source_pdf="TestSource.pdf", target_pdf="TestTarget.pd
405
  return source_pdf, target_pdf
406
 
407
  def create_selflinking_pdf(pdf_file="SelfLinking.pdf"):
408
- """Create a PDF with a TOC on page 1 linking to a 1-20 list starting on page 2."""
409
  buffer = io.BytesIO()
410
  c = canvas.Canvas(buffer)
411
 
@@ -420,7 +425,7 @@ def create_selflinking_pdf(pdf_file="SelfLinking.pdf"):
420
  toc_y_positions.append(y)
421
  c.showPage()
422
 
423
- # Page 2: Numbered list 1-20
424
  c.setFont("Helvetica", 12)
425
  list_y_positions = []
426
  for i, word in enumerate(WORDS_24, 1):
@@ -490,10 +495,10 @@ with st.sidebar:
490
  )
491
  base_font_size = st.slider("Font Size (points)", min_value=6, max_value=16, value=8, step=1)
492
 
493
- add_space_before_numbered = st.checkbox("Add Space Ahead of Numbered Lines", value=False)
494
  headings_to_fonts = st.checkbox(
495
  "Headings to Fonts",
496
- value=False,
497
  help="Convert Markdown headings (# Heading) to styled fonts"
498
  )
499
  auto_columns = st.checkbox("AutoColumns", value=True)
@@ -502,7 +507,7 @@ with st.sidebar:
502
  longest_line_words = 0
503
  total_lines = 0
504
  adjusted_font_size_display = base_font_size
505
- if 'markdown_content' in st.session_state:
506
  current_markdown = st.session_state.markdown_content
507
  lines = current_markdown.strip().split('\n')
508
  total_lines = len([line for line in lines if line.strip()])
@@ -520,20 +525,26 @@ with st.sidebar:
520
  else:
521
  recommended_columns = 3
522
  # Adjust font size for one-page fit
523
- if longest_line_words > 17:
524
- font_scale = 17 / longest_line_words
525
- adjusted_font_size_display = max(6, int(base_font_size * font_scale))
526
  st.markdown("**Document Stats**")
527
  st.write(f"- Longest Line: {longest_line_words} words")
528
  st.write(f"- Total Lines: {total_lines}")
529
  st.write(f"- Recommended Columns: {recommended_columns}")
530
  st.write(f"- Adjusted Font Size: {adjusted_font_size_display} points")
 
 
 
 
 
 
531
 
532
  column_options = [2, 3, 4]
533
  num_columns = st.selectbox(
534
  "Number of Columns",
535
  options=column_options,
536
- index=column_options.index(recommended_columns)
537
  )
538
  st.info("Font size and columns adjust to fit one page.")
539
 
@@ -645,7 +656,8 @@ with st.container():
645
  with st.sidebar:
646
  st.download_button(
647
  label="๐Ÿ’พ Save PDF",
648
- data=pdf_bytes,
649
  file_name=f"{prefix} {selected_md}.pdf" if selected_md else f"{prefix} output.pdf",
650
- mime="application/pdf"
 
651
  )
 
179
  return pdf_content, total_lines
180
 
181
  def create_pdf(markdown_text, base_font_size, num_columns, add_space_before_numbered, headings_to_fonts, doc_title, longest_line_words, total_lines):
182
+ if not markdown_text.strip():
183
+ return None # Handle empty markdown gracefully
184
  buffer = io.BytesIO()
185
  page_width = A4[0] * 2
186
  page_height = A4[1]
 
200
  available_font_files = glob.glob("*.ttf")
201
  if not available_font_files:
202
  st.error("No .ttf font files found.")
203
+ return None
204
  selected_font_path = next((f for f in available_font_files if "NotoEmoji-Bold" in f), None)
205
  if selected_font_path:
206
  pdfmetrics.registerFont(TTFont("NotoEmoji-Bold", selected_font_path))
207
  pdfmetrics.registerFont(TTFont("DejaVuSans", "DejaVuSans.ttf"))
208
  except Exception as e:
209
  st.error(f"Font registration error: {e}")
210
+ return None
211
  total_chars = sum(len(line) for line in pdf_content)
212
  hierarchy_weight = sum(1.5 if line.startswith("<b>") else 1 for line in pdf_content)
213
  content_density = total_lines * hierarchy_weight + total_chars / 50
 
218
  suggested_columns = max(2, min(4, int(total_lines / ideal_lines_per_col) + 1))
219
  num_columns = num_columns if num_columns != 0 else suggested_columns
220
  col_width = usable_width / num_columns
221
+ min_font_size = 5 # Reduced to allow tighter fit
222
  max_font_size = 16
223
  lines_per_col = total_lines / num_columns if num_columns > 0 else total_lines
224
  target_height_per_line = usable_height / lines_per_col if lines_per_col > 0 else usable_height
 
228
  adjusted_font_size = int(col_width / (avg_line_chars / 10))
229
  adjusted_font_size = max(min_font_size, adjusted_font_size)
230
 
231
+ # Enhanced font size scaling for one-page fit
232
+ if longest_line_words > 17 or lines_per_col > 20:
233
+ font_scale = min(17 / max(longest_line_words, 17), 60 / max(lines_per_col, 20))
234
+ adjusted_font_size = max(min_font_size, int(base_font_size * font_scale))
235
 
236
  item_style = ParagraphStyle(
237
  'ItemStyle', parent=styles['Normal'], fontName="DejaVuSans",
 
311
  return buffer.getvalue()
312
 
313
  def pdf_to_image(pdf_bytes):
314
+ if pdf_bytes is None:
315
+ return None
316
  try:
317
  doc = fitz.open(stream=pdf_bytes, filetype="pdf")
318
  images = []
 
329
  # PDF creation and linking functions
330
  WORDS_12 = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"]
331
  WORDS_24 = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
332
+ "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty",
333
+ "twenty-one", "twenty-two", "twenty-three", "twenty-four"]
334
 
335
  def create_crossfile_pdfs(source_pdf="TestSource.pdf", target_pdf="TestTarget.pdf"):
336
  """Create two PDFs with cross-file linking."""
 
410
  return source_pdf, target_pdf
411
 
412
  def create_selflinking_pdf(pdf_file="SelfLinking.pdf"):
413
+ """Create a PDF with a TOC on page 1 linking to a 1-24 list starting on page 2."""
414
  buffer = io.BytesIO()
415
  c = canvas.Canvas(buffer)
416
 
 
425
  toc_y_positions.append(y)
426
  c.showPage()
427
 
428
+ # Page 2: Numbered list 1-24
429
  c.setFont("Helvetica", 12)
430
  list_y_positions = []
431
  for i, word in enumerate(WORDS_24, 1):
 
495
  )
496
  base_font_size = st.slider("Font Size (points)", min_value=6, max_value=16, value=8, step=1)
497
 
498
+ add_space_before_numbered = st.checkbox("Add Space Ahead of Numbered Lines", value=True)
499
  headings_to_fonts = st.checkbox(
500
  "Headings to Fonts",
501
+ value=True,
502
  help="Convert Markdown headings (# Heading) to styled fonts"
503
  )
504
  auto_columns = st.checkbox("AutoColumns", value=True)
 
507
  longest_line_words = 0
508
  total_lines = 0
509
  adjusted_font_size_display = base_font_size
510
+ if 'markdown_content' in st.session_state and st.session_state.markdown_content.strip():
511
  current_markdown = st.session_state.markdown_content
512
  lines = current_markdown.strip().split('\n')
513
  total_lines = len([line for line in lines if line.strip()])
 
525
  else:
526
  recommended_columns = 3
527
  # Adjust font size for one-page fit
528
+ if longest_line_words > 17 or total_lines / max(num_columns, 1) > 20:
529
+ font_scale = min(17 / max(longest_line_words, 17), 60 / max(total_lines / max(num_columns, 1), 20))
530
+ adjusted_font_size_display = max(5, int(base_font_size * font_scale))
531
  st.markdown("**Document Stats**")
532
  st.write(f"- Longest Line: {longest_line_words} words")
533
  st.write(f"- Total Lines: {total_lines}")
534
  st.write(f"- Recommended Columns: {recommended_columns}")
535
  st.write(f"- Adjusted Font Size: {adjusted_font_size_display} points")
536
+ else:
537
+ st.markdown("**Document Stats**")
538
+ st.write("- Longest Line: 0 words")
539
+ st.write("- Total Lines: 0")
540
+ st.write("- Recommended Columns: 3")
541
+ st.write(f"- Adjusted Font Size: {base_font_size} points")
542
 
543
  column_options = [2, 3, 4]
544
  num_columns = st.selectbox(
545
  "Number of Columns",
546
  options=column_options,
547
+ index=column_options.index(recommended_columns) if recommended_columns in column_options else 0
548
  )
549
  st.info("Font size and columns adjust to fit one page.")
550
 
 
656
  with st.sidebar:
657
  st.download_button(
658
  label="๐Ÿ’พ Save PDF",
659
+ data=pdf_bytes if pdf_bytes else "",
660
  file_name=f"{prefix} {selected_md}.pdf" if selected_md else f"{prefix} output.pdf",
661
+ mime="application/pdf",
662
+ disabled=pdf_bytes is None
663
  )