awacke1 commited on
Commit
f6e161c
ยท
verified ยท
1 Parent(s): c774c45

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -63
app.py CHANGED
@@ -464,23 +464,60 @@ def create_selflinking_pdf(pdf_file="SelfLinking.pdf"):
464
 
465
  # ๐Ÿ–ผ๏ธ 13. Image-linked PDF creator - wisdom: Link images to text, like windows opening to new worlds!
466
  def create_pdf_with_images(source_pdf_bytes, output_pdf="ImageLinked.pdf"):
467
- """Create a PDF with links to images on numbered items 1-12."""
468
  image_files = sorted(glob.glob("*.png"))
469
  if not source_pdf_bytes:
470
  st.error("No source PDF provided.")
471
  return None
 
 
 
 
472
  reader = PdfReader(io.BytesIO(source_pdf_bytes))
473
  writer = PdfWriter()
 
 
 
474
  for page in reader.pages:
475
  writer.add_page(page)
476
- page = writer.pages[0]
477
- number_pattern = re.compile(r'^\d+\.\s')
478
- y_positions = []
479
- for i in range(1, 13):
480
- y = 800 - (i * 20)
481
- y_positions.append(y)
482
- for idx, (y, image_file) in enumerate(zip(y_positions, image_files[:12])):
483
- if os.path.exists(image_file):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  buffer = io.BytesIO()
485
  c = canvas.Canvas(buffer)
486
  c.setFont("Helvetica", 8)
@@ -490,12 +527,16 @@ def create_pdf_with_images(source_pdf_bytes, output_pdf="ImageLinked.pdf"):
490
  buffer.seek(0)
491
  text_pdf = PdfReader(buffer)
492
  page.merge_page(text_pdf.pages[0])
 
 
493
  link = Link(
494
  rect=(90, y - 10, 150, y + 10),
495
- url=f"file://{os.path.abspath(image_file)}"
 
496
  )
497
  writer.add_annotation(page_number=0, annotation=link)
498
  buffer.close()
 
499
  output_buffer = io.BytesIO()
500
  writer.write(output_buffer)
501
  output_buffer.seek(0)
@@ -507,45 +548,15 @@ def create_pdf_with_images(source_pdf_bytes, output_pdf="ImageLinked.pdf"):
507
  md_files = [f for f in glob.glob("*.md") if os.path.basename(f) != "README.md"]
508
  md_options = [os.path.splitext(os.path.basename(f))[0] for f in md_files]
509
 
510
- # ๐Ÿ–ฅ๏ธ 15. Main PDF generation - wisdom: Spin up the PDF like a weaver at the loom, crafting beauty!
511
- with st.spinner("Generating PDF..."):
512
- # Initialize defaults for PDF generation
513
- selected_md = None
514
- base_font_size = 8
515
- num_columns = 3
516
- add_space_before_numbered = True
517
- headings_to_fonts = True
518
- longest_line_words = 0
519
- total_lines = 0
520
-
521
- # Calculate document stats if markdown exists
522
- if 'markdown_content' in st.session_state and st.session_state.markdown_content.strip():
523
- current_markdown = st.session_state.markdown_content
524
- lines = current_markdown.strip().split('\n')
525
- total_lines = len([line for line in lines if line.strip()])
526
- for line in lines:
527
- if line.strip():
528
- word_count = len(line.split())
529
- longest_line_words = max(longest_line_words, word_count)
530
-
531
- pdf_bytes = create_pdf(
532
- st.session_state.get('markdown_content', ''),
533
- base_font_size,
534
- num_columns,
535
- add_space_before_numbered,
536
- headings_to_fonts,
537
- doc_title=selected_md if selected_md else "Untitled",
538
- longest_line_words=longest_line_words,
539
- total_lines=total_lines
540
- )
541
-
542
  with st.sidebar:
543
  # ๐Ÿ“š 14.1 Markdown selector - wisdom: Offer choices like a librarian, guiding users to their story!
544
  st.markdown("### ๐Ÿ“„ PDF Options")
545
  if md_options:
546
- selected_md = st.selectbox("Select Markdown File", options=md_options, index=0)
547
- with open(f"{selected_md}.md", "r", encoding="utf-8") as f:
548
- st.session_state.markdown_content = f.read()
 
 
549
  else:
550
  st.warning("No markdown file found. Please add one to your folder.")
551
  selected_md = None
@@ -706,22 +717,18 @@ with st.sidebar:
706
  mime="application/pdf"
707
  )
708
 
709
- if st.button("๐Ÿ–ผ๏ธ Generate PDF With Images"):
710
- with st.spinner("Generating PDF with image links..."):
711
- linked_pdf_bytes = create_pdf_with_images(pdf_bytes)
712
- if linked_pdf_bytes:
713
- st.success("Generated PDF with image links")
714
- images = pdf_to_image(linked_pdf_bytes)
715
- if images:
716
- st.subheader("Preview of Image-Linked PDF")
717
- for i, img in enumerate(images):
718
- st.image(img, caption=f"Image-Linked PDF Page {i+1}", use_container_width=True)
719
- st.download_button(
720
- label="๐Ÿ’พ Download Image-Linked PDF",
721
- data=linked_pdf_bytes,
722
- file_name=f"{prefix} {selected_md}_image_linked.pdf" if selected_md else f"{prefix} image_linked.pdf",
723
- mime="application/pdf"
724
- )
725
 
726
  # ๐Ÿ–ผ๏ธ 16. PDF preview - wisdom: Show the masterpiece before itโ€™s framed, delighting the creator!
727
  with st.container():
@@ -733,12 +740,29 @@ with st.container():
733
  else:
734
  st.info("Download the PDF to view it locally.")
735
 
736
- # ๐Ÿ’พ 17. PDF saver - wisdom: Offer the final scroll, ready to be shared like wisdom across ages!
737
  with st.sidebar:
 
738
  st.download_button(
739
  label="๐Ÿ’พ Save PDF",
740
  data=pdf_bytes if pdf_bytes else "",
741
  file_name=f"{prefix} {selected_md}.pdf" if selected_md else f"{prefix} output.pdf",
742
  mime="application/pdf",
743
  disabled=pdf_bytes is None
744
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
 
465
  # ๐Ÿ–ผ๏ธ 13. Image-linked PDF creator - wisdom: Link images to text, like windows opening to new worlds!
466
  def create_pdf_with_images(source_pdf_bytes, output_pdf="ImageLinked.pdf"):
467
+ """Create a PDF with links on numbered headings to new pages with images."""
468
  image_files = sorted(glob.glob("*.png"))
469
  if not source_pdf_bytes:
470
  st.error("No source PDF provided.")
471
  return None
472
+ if not image_files:
473
+ st.error("No PNG images found in the directory.")
474
+ return source_pdf_bytes
475
+
476
  reader = PdfReader(io.BytesIO(source_pdf_bytes))
477
  writer = PdfWriter()
478
+
479
+ # Copy all pages from source PDF
480
+ original_page_count = len(reader.pages)
481
  for page in reader.pages:
482
  writer.add_page(page)
483
+
484
+ # Add image pages
485
+ image_page_indices = []
486
+ for image_file in image_files[:12]: # Limit to 12 images
487
+ buffer = io.BytesIO()
488
+ c = canvas.Canvas(buffer, pagesize=A4)
489
+ try:
490
+ img = Image.open(image_file)
491
+ img_width, img_height = img.size
492
+ page_width, page_height = A4
493
+ scale = min((page_width - 40) / img_width, (page_height - 40) / img_height)
494
+ new_width = img_width * scale
495
+ new_height = img_height * scale
496
+ x = (page_width - new_width) / 2
497
+ y = (page_height - new_height) / 2
498
+ c.drawImage(image_file, x, y, new_width, new_height)
499
+ c.showPage()
500
+ c.save()
501
+ buffer.seek(0)
502
+ img_pdf = PdfReader(buffer)
503
+ writer.add_page(img_pdf.pages[0])
504
+ image_page_indices.append(original_page_count + len(image_page_indices))
505
+ buffer.close()
506
+ except Exception as e:
507
+ st.error(f"Failed to process image {image_file}: {e}")
508
+ buffer.close()
509
+ continue
510
+
511
+ # Add links to numbered headings on first page
512
+ if image_page_indices:
513
+ page = writer.pages[0]
514
+ y_positions = []
515
+ for i in range(1, 13):
516
+ y = 800 - (i * 20) # Matches layout from create_pdf
517
+ y_positions.append(y)
518
+
519
+ for idx, (y, target_page_idx) in enumerate(zip(y_positions, image_page_indices)):
520
+ # Add "link" text
521
  buffer = io.BytesIO()
522
  c = canvas.Canvas(buffer)
523
  c.setFont("Helvetica", 8)
 
527
  buffer.seek(0)
528
  text_pdf = PdfReader(buffer)
529
  page.merge_page(text_pdf.pages[0])
530
+
531
+ # Add link annotation
532
  link = Link(
533
  rect=(90, y - 10, 150, y + 10),
534
+ target_page_index=target_page_idx,
535
+ fit=Fit(fit_type="/Fit")
536
  )
537
  writer.add_annotation(page_number=0, annotation=link)
538
  buffer.close()
539
+
540
  output_buffer = io.BytesIO()
541
  writer.write(output_buffer)
542
  output_buffer.seek(0)
 
548
  md_files = [f for f in glob.glob("*.md") if os.path.basename(f) != "README.md"]
549
  md_options = [os.path.splitext(os.path.basename(f))[0] for f in md_files]
550
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  with st.sidebar:
552
  # ๐Ÿ“š 14.1 Markdown selector - wisdom: Offer choices like a librarian, guiding users to their story!
553
  st.markdown("### ๐Ÿ“„ PDF Options")
554
  if md_options:
555
+ selected_md = st.selectbox("Select Markdown File", options=md_options, index=0, key="markdown_select")
556
+ if selected_md != st.session_state.get('last_selected_md'):
557
+ with open(f"{selected_md}.md", "r", encoding="utf-8") as f:
558
+ st.session_state.markdown_content = f.read()
559
+ st.session_state.last_selected_md = selected_md
560
  else:
561
  st.warning("No markdown file found. Please add one to your folder.")
562
  selected_md = None
 
717
  mime="application/pdf"
718
  )
719
 
720
+ # ๐Ÿ–ฅ๏ธ 15. Main PDF generation - wisdom: Spin up the PDF like a weaver at the loom, crafting beauty!
721
+ with st.spinner("Generating PDF..."):
722
+ pdf_bytes = create_pdf(
723
+ st.session_state.get('markdown_content', ''),
724
+ base_font_size,
725
+ num_columns,
726
+ add_space_before_numbered,
727
+ headings_to_fonts,
728
+ doc_title=selected_md if selected_md else "Untitled",
729
+ longest_line_words=longest_line_words,
730
+ total_lines=total_lines
731
+ )
 
 
 
 
732
 
733
  # ๐Ÿ–ผ๏ธ 16. PDF preview - wisdom: Show the masterpiece before itโ€™s framed, delighting the creator!
734
  with st.container():
 
740
  else:
741
  st.info("Download the PDF to view it locally.")
742
 
 
743
  with st.sidebar:
744
+ # ๐Ÿ’พ 17. PDF saver - wisdom: Offer the final scroll, ready to be shared like wisdom across ages!
745
  st.download_button(
746
  label="๐Ÿ’พ Save PDF",
747
  data=pdf_bytes if pdf_bytes else "",
748
  file_name=f"{prefix} {selected_md}.pdf" if selected_md else f"{prefix} output.pdf",
749
  mime="application/pdf",
750
  disabled=pdf_bytes is None
751
+ )
752
+
753
+ if st.button("๐Ÿ–ผ๏ธ Generate PDF With Images"):
754
+ with st.spinner("Generating PDF with image links..."):
755
+ linked_pdf_bytes = create_pdf_with_images(pdf_bytes)
756
+ if linked_pdf_bytes and linked_pdf_bytes != pdf_bytes:
757
+ st.success("Generated PDF with image links")
758
+ images = pdf_to_image(linked_pdf_bytes)
759
+ if images:
760
+ st.subheader("Preview of Image-Linked PDF")
761
+ for i, img in enumerate(images):
762
+ st.image(img, caption=f"Image-Linked PDF Page {i+1}", use_container_width=True)
763
+ st.download_button(
764
+ label="๐Ÿ’พ Download Image-Linked PDF",
765
+ data=linked_pdf_bytes,
766
+ file_name=f"{prefix} {selected_md}_image_linked.pdf" if selected_md else f"{prefix} image_linked.pdf",
767
+ mime="application/pdf"
768
+ )