awacke1/Pillow-PyMuPDF-ReportLab
2
1import streamlit as st2import base643from reportlab.lib.pagesizes import A44from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle5from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle6from reportlab.lib import colors7import pikepdf8import fpdf9import fitz # pymupdf10import cv211import numpy as np12from PIL import Image13import io14import os15import re16 17# Define the ML outline as a markdown string for multilevel content18ml_markdown = """# Cutting-Edge ML Outline19 20## Core ML Techniques211. π **Mixture of Experts (MoE)**22 - Conditional computation techniques23 - Sparse gating mechanisms24 - Training specialized sub-models25 262. π₯ **Supervised Fine-Tuning (SFT) using PyTorch**27 - Loss function customization28 - Gradient accumulation strategies29 - Learning rate schedulers30 313. π€ **Large Language Models (LLM) using Transformers**32 - Attention mechanisms33 - Tokenization strategies34 - Position encodings35 36## Training Methods374. π **Self-Rewarding Learning using NPS 0-10 and Verbatims**38 - Custom reward functions39 - Feedback categorization40 - Signal extraction from text41 425. π **Reinforcement Learning from Human Feedback (RLHF)**43 - Preference datasets44 - PPO implementation45 - KL divergence constraints46 476. π **MergeKit: Merging Models to Same Embedding Space**48 - TIES merging49 - Task arithmetic50 - SLERP interpolation51 52## Optimization & Deployment537. π **DistillKit: Model Size Reduction with Spectrum Analysis**54 - Knowledge distillation55 - Quantization techniques56 - Model pruning strategies57 588. π§ **Agentic RAG Agents using Document Inputs**59 - Vector database integration60 - Query planning61 - Self-reflection mechanisms62 639. β³ **Longitudinal Data Summarization from Multiple Docs**64 - Multi-document compression65 - Timeline extraction66 - Entity tracking67 68## Knowledge Representation6910. π **Knowledge Extraction using Markdown Knowledge Graphs**70 - Entity recognition71 - Relationship mapping72 - Hierarchical structuring73 7411. πΊοΈ **Knowledge Mapping with Mermaid Diagrams**75 - Flowchart generation76 - Sequence diagram creation77 - State diagrams78 7912. π» **ML Code Generation with Streamlit/Gradio/HTML5+JS**80 - Code completion81 - Unit test generation82 - Documentation synthesis83"""84 85# Process multilevel markdown for PDF output86def markdown_to_pdf_content(markdown_text):87 """Convert markdown text to a format suitable for PDF generation"""88 import re89 90 # Convert markdown headers to styled text for PDF91 lines = markdown_text.strip().split('\n')92 pdf_content = []93 in_list_item = False94 current_item = None95 sub_items = []96 97 for line in lines:98 line = line.strip()99 if not line:100 continue101 102 if line.startswith('# '):103 # Main header - will be handled separately in the PDF generation104 pass105 elif line.startswith('## '):106 # Section header - add as a bold item107 if current_item and sub_items:108 # Store the previous item with its sub-items109 pdf_content.append([current_item, sub_items])110 sub_items = []111 current_item = None112 113 section = line.replace('## ', '').strip()114 pdf_content.append(f"<b>{section}</b>")115 in_list_item = False116 elif re.match(r'^\d+\.', line):117 # Numbered list item118 if current_item and sub_items:119 # Store the previous item with its sub-items120 pdf_content.append([current_item, sub_items])121 sub_items = []122 123 current_item = line.strip()124 in_list_item = True125 elif line.startswith('- ') and in_list_item:126 # Sub-item under a numbered list item127 sub_items.append(line.strip())128 else:129 # Regular line130 if not in_list_item:131 pdf_content.append(line.strip())132 133 # Add the last item if there is one134 if current_item and sub_items:135 pdf_content.append([current_item, sub_items])136 137 # Split the content for two columns138 mid_point = len(pdf_content) // 2139 left_column = pdf_content[:mid_point]140 right_column = pdf_content[mid_point:]141 142 return left_column, right_column143 144# Demo functions for PDF libraries145def demo_pikepdf():146 """Create a two-column PDF with the markdown outline using pikepdf"""147 # Process markdown content148 left_column, right_column = markdown_to_pdf_content(ml_markdown)149 150 # We'll use pymupdf (fitz) to create the content, then save with pikepdf151 doc = fitz.open()152 page = doc.new_page(width=842, height=595) # A4 Landscape153 154 # Set up fonts and colors155 title_font = "helv-b"156 section_font = "helv-b"157 item_font = "helv-b"158 subitem_font = "helv"159 blue_color = (0, 0, 0.8)160 black_color = (0, 0, 0)161 162 # Add title163 page.insert_text((50, 40), "Cutting-Edge ML Outline (PikePDF Demo)", fontname=title_font, fontsize=16, color=blue_color)164 165 # First column166 x1, y1 = 50, 80167 current_y = y1168 169 for item in left_column:170 if isinstance(item, str) and item.startswith('<b>'):171 # Section header172 # Add extra space before sections (except the first one)173 if current_y > y1:174 current_y += 10175 176 text = item.replace('<b>', '').replace('</b>', '')177 page.insert_text((x1, current_y), text, fontname=section_font, fontsize=14, color=blue_color)178 current_y += 25179 elif isinstance(item, list):180 # Main item with sub-items181 main_item, sub_items = item182 page.insert_text((x1, current_y), main_item, fontname=item_font, fontsize=12, color=black_color)183 current_y += 20184 185 # Add sub-items186 for sub_item in sub_items:187 page.insert_text((x1 + 20, current_y), sub_item, fontname=subitem_font, fontsize=10, color=black_color)188 current_y += 15189 190 current_y += 5 # Extra space after a group191 else:192 # Regular item193 page.insert_text((x1, current_y), item, fontname=item_font, fontsize=12, color=black_color)194 current_y += 20195 196 # Second column197 x2, y2 = 450, 80198 current_y = y2199 200 for item in right_column:201 if isinstance(item, str) and item.startswith('<b>'):202 # Section header203 # Add extra space before sections (except the first one)204 if current_y > y2:205 current_y += 10206 207 text = item.replace('<b>', '').replace('</b>', '')208 page.insert_text((x2, current_y), text, fontname=section_font, fontsize=14, color=blue_color)209 current_y += 25210 elif isinstance(item, list):211 # Main item with sub-items212 main_item, sub_items = item213 page.insert_text((x2, current_y), main_item, fontname=item_font, fontsize=12, color=black_color)214 current_y += 20215 216 # Add sub-items217 for sub_item in sub_items:218 page.insert_text((x2 + 20, current_y), sub_item, fontname=subitem_font, fontsize=10, color=black_color)219 current_y += 15220 221 current_y += 5 # Extra space after a group222 else:223 # Regular item224 page.insert_text((x2, current_y), item, fontname=item_font, fontsize=12, color=black_color)225 current_y += 20226 227 # Draw a dividing line228 page.draw_line((421, 70), (421, 550))229 230 # Convert to pikepdf231 temp_buffer = io.BytesIO()232 doc.save(temp_buffer)233 temp_buffer.seek(0)234 235 pdf = pikepdf.Pdf.open(temp_buffer)236 237 # Save to buffer238 buffer = io.BytesIO()239 pdf.save(buffer)240 buffer.seek(0)241 return buffer.getvalue()242 243def demo_fpdf():244 """Create a two-column PDF with the markdown outline using FPDF"""245 # Process markdown content246 left_column, right_column = markdown_to_pdf_content(ml_markdown)247 248 pdf = fpdf.FPDF(orientation='L') # Landscape249 pdf.add_page()250 251 # Set title252 pdf.set_font("Arial", 'B', size=16)253 pdf.set_text_color(0, 0, 128) # Dark blue254 pdf.cell(0, 10, txt="Cutting-Edge ML Outline (FPDF Demo)", ln=True, align='C')255 pdf.ln(10)256 257 # Define coordinates for columns258 x_col1 = 20259 x_col2 = pdf.w / 2 + 10260 y_start = pdf.get_y()261 262 # Function to render a column263 def render_column(items, x_start, y_start):264 y_pos = y_start265 266 for item in items:267 if isinstance(item, str) and item.startswith('<b>'):268 # Section header269 text = item.replace('<b>', '').replace('</b>', '')270 pdf.set_font("Arial", 'B', size=14)271 pdf.set_text_color(0, 0, 128) # Dark blue272 pdf.set_xy(x_start, y_pos)273 pdf.cell(0, 10, txt=text, ln=True)274 y_pos += 10275 elif isinstance(item, list):276 # Main item with sub-items277 main_item, sub_items = item278 279 # Main item280 pdf.set_font("Arial", 'B', size=11)281 pdf.set_text_color(0, 0, 0) # Black282 pdf.set_xy(x_start, y_pos)283 pdf.multi_cell(180, 6, txt=main_item, align='L')284 main_height = pdf.get_y() - y_pos285 y_pos += main_height + 2286 287 # Sub-items288 pdf.set_font("Arial", size=10)289 for sub_item in sub_items:290 pdf.set_xy(x_start + 10, y_pos)291 pdf.multi_cell(170, 5, txt=sub_item, align='L')292 sub_height = pdf.get_y() - y_pos293 y_pos += sub_height + 1294 295 y_pos += 2 # Extra space after a group296 else:297 # Regular item298 pdf.set_font("Arial", 'B', size=11)299 pdf.set_text_color(0, 0, 0) # Black300 pdf.set_xy(x_start, y_pos)301 pdf.multi_cell(180, 6, txt=item, align='L')302 item_height = pdf.get_y() - y_pos303 y_pos += item_height + 4304 305 # Render both columns306 render_column(left_column, x_col1, y_start)307 render_column(right_column, x_col2, y_start)308 309 # Draw a dividing line310 pdf.line(pdf.w/2, 30, pdf.w/2, 280)311 312 buffer = io.BytesIO()313 pdf.output(buffer)314 buffer.seek(0)315 return buffer.getvalue()316 317def demo_pymupdf():318 """Create a two-column PDF with the markdown outline using PyMuPDF"""319 # Process markdown content320 left_column, right_column = markdown_to_pdf_content(ml_markdown)321 322 doc = fitz.open()323 page = doc.new_page(width=842, height=595) # A4 Landscape324 325 # Set up fonts and colors326 title_font = "helv-b"327 section_font = "helv-b"328 item_font = "helv-b"329 subitem_font = "helv"330 blue_color = (0, 0, 0.8)331 black_color = (0, 0, 0)332 333 # Add title334 page.insert_text((300, 40), "Cutting-Edge ML Outline (PyMuPDF Demo)", fontname=title_font, fontsize=16, color=blue_color)335 336 # First column337 x1, y1 = 50, 80338 current_y = y1339 340 for item in left_column:341 if isinstance(item, str) and item.startswith('<b>'):342 # Section header343 # Add extra space before sections (except the first one)344 if current_y > y1:345 current_y += 10346 347 text = item.replace('<b>', '').replace('</b>', '')348 page.insert_text((x1, current_y), text, fontname=section_font, fontsize=14, color=blue_color)349 current_y += 25350 elif isinstance(item, list):351 # Main item with sub-items352 main_item, sub_items = item353 page.insert_text((x1, current_y), main_item, fontname=item_font, fontsize=12, color=black_color)354 current_y += 20355 356 # Add sub-items357 for sub_item in sub_items:358 page.insert_text((x1 + 20, current_y), sub_item, fontname=subitem_font, fontsize=10, color=black_color)359 current_y += 15360 361 current_y += 5 # Extra space after a group362 else:363 # Regular item364 page.insert_text((x1, current_y), item, fontname=item_font, fontsize=12, color=black_color)365 current_y += 20366 367 # Second column368 x2, y2 = 450, 80369 current_y = y2370 371 for item in right_column:372 if isinstance(item, str) and item.startswith('<b>'):373 # Section header374 # Add extra space before sections (except the first one)375 if current_y > y2:376 current_y += 10377 378 text = item.replace('<b>', '').replace('</b>', '')379 page.insert_text((x2, current_y), text, fontname=section_font, fontsize=14, color=blue_color)380 current_y += 25381 elif isinstance(item, list):382 # Main item with sub-items383 main_item, sub_items = item384 page.insert_text((x2, current_y), main_item, fontname=item_font, fontsize=12, color=black_color)385 current_y += 20386 387 # Add sub-items388 for sub_item in sub_items:389 page.insert_text((x2 + 20, current_y), sub_item, fontname=subitem_font, fontsize=10, color=black_color)390 current_y += 15391 392 current_y += 5 # Extra space after a group393 else:394 # Regular item395 page.insert_text((x2, current_y), item, fontname=item_font, fontsize=12, color=black_color)396 current_y += 20397 398 # Draw a dividing line399 page.draw_line((421, 70), (421, 550))400 401 buffer = io.BytesIO()402 doc.save(buffer)403 buffer.seek(0)404 return buffer.getvalue()405 406# Demo function for image capture407def demo_image_capture():408 """Generate a demo image (fake capture) since we can't access the camera in this environment"""409 # Create a simple gradient image using numpy and PIL410 width, height = 640, 480411 412 # Create a gradient array413 x = np.linspace(0, 1, width)414 y = np.linspace(0, 1, height)415 xx, yy = np.meshgrid(x, y)416 gradient = (xx + yy) / 2417 418 # Convert to RGB image419 img_array = (gradient * 255).astype(np.uint8)420 rgb_array = np.stack([img_array, img_array//2, img_array*2], axis=2)421 422 # Create PIL Image423 img = Image.fromarray(rgb_array)424 425 # Add text to the image426 from PIL import ImageDraw, ImageFont427 draw = ImageDraw.Draw(img)428 try:429 font = ImageFont.truetype("arial.ttf", 30)430 except:431 font = ImageFont.load_default()432 433 draw.text((width//4, height//2), "OpenCV Demo Image", fill=(255, 255, 255), font=font)434 435 # Save to buffer436 buffer = io.BytesIO()437 img.save(buffer, format="JPEG")438 buffer.seek(0)439 return buffer.getvalue()440 441# Main PDF creation using ReportLab442def create_main_pdf(markdown_text):443 """Create a single-page landscape PDF with the outline in two columns"""444 from reportlab.platypus import Table, TableStyle, Paragraph, Spacer445 from reportlab.lib import pagesizes446 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle447 448 # Process markdown content449 left_column, right_column = markdown_to_pdf_content(markdown_text)450 451 buffer = io.BytesIO()452 doc = SimpleDocTemplate(453 buffer, 454 pagesize=(A4[1], A4[0]), # Landscape455 leftMargin=50,456 rightMargin=50,457 topMargin=50,458 bottomMargin=50459 )460 461 styles = getSampleStyleSheet()462 story = []463 464 # Create custom styles465 title_style = styles['Heading1']466 title_style.textColor = colors.darkblue467 title_style.alignment = 1 # Center alignment468 469 section_style = ParagraphStyle(470 'SectionStyle',471 parent=styles['Heading2'],472 textColor=colors.darkblue,473 spaceAfter=6474 )475 476 item_style = ParagraphStyle(477 'ItemStyle',478 parent=styles['Normal'],479 fontSize=11,480 leading=14,481 fontName='Helvetica-Bold'482 )483 484 subitem_style = ParagraphStyle(485 'SubItemStyle',486 parent=styles['Normal'],487 fontSize=10,488 leading=12,489 leftIndent=20490 )491 492 # Add title493 story.append(Paragraph("Cutting-Edge ML Outline (ReportLab)", title_style))494 story.append(Spacer(1, 20))495 496 # Prepare data for table497 left_cells = []498 for item in left_column:499 if isinstance(item, str) and item.startswith('<b>'):500 # Section header501 text = item.replace('<b>', '').replace('</b>', '')502 left_cells.append(Paragraph(text, section_style))503 elif isinstance(item, list):504 # Main item with sub-items505 main_item, sub_items = item506 left_cells.append(Paragraph(main_item, item_style))507 508 # Sub items509 for sub_item in sub_items:510 left_cells.append(Paragraph(sub_item, subitem_style))511 else:512 # Regular item513 left_cells.append(Paragraph(item, item_style))514 515 right_cells = []516 for item in right_column:517 if isinstance(item, str) and item.startswith('<b>'):518 # Section header519 text = item.replace('<b>', '').replace('</b>', '')520 right_cells.append(Paragraph(text, section_style))521 elif isinstance(item, list):522 # Main item with sub-items523 main_item, sub_items = item524 right_cells.append(Paragraph(main_item, item_style))525 526 # Sub items527 for sub_item in sub_items:528 right_cells.append(Paragraph(sub_item, subitem_style))529 else:530 # Regular item531 right_cells.append(Paragraph(item, item_style))532 533 # Make sure both columns have the same number of rows by adding empty cells534 max_cells = max(len(left_cells), len(right_cells))535 if len(left_cells) < max_cells:536 for i in range(max_cells - len(left_cells)):537 left_cells.append("")538 if len(right_cells) < max_cells:539 for i in range(max_cells - len(right_cells)):540 right_cells.append("")541 542 # Create table data (one row per cell)543 table_data = []544 for i in range(max_cells):545 table_data.append([left_cells[i], right_cells[i]])546 547 # Calculate column widths548 col_width = (A4[1] - 120) / 2.0 # Page width minus margins divided by 2549 550 # Create the table with the data551 table = Table(table_data, colWidths=[col_width, col_width])552 553 # Style the table554 table.setStyle(TableStyle([555 ('VALIGN', (0, 0), (-1, -1), 'TOP'),556 ('ALIGN', (0, 0), (0, -1), 'LEFT'),557 ('ALIGN', (1, 0), (1, -1), 'LEFT'),558 ('BACKGROUND', (0, 0), (-1, -1), colors.white),559 ('GRID', (0, 0), (-1, -1), 0.5, colors.white),560 ('LINEAFTER', (0, 0), (0, -1), 1, colors.grey),561 ]))562 563 story.append(table)564 565 doc.build(story)566 buffer.seek(0)567 return buffer.getvalue()568 569def get_binary_file_downloader_html(bin_data, file_label='File'):570 """Create a download link for binary data"""571 bin_str = base64.b64encode(bin_data).decode()572 href = f'<a href="data:application/octet-stream;base64,{bin_str}" download="{file_label}">Download {file_label}</a>'573 return href574 575# Streamlit UI576st.title("π Cutting-Edge ML Outline Generator")577 578col1, col2 = st.columns(2)579 580with col1:581 st.header("π Markdown Outline")582 583 # Display the markdown content584 st.markdown(ml_markdown)585 586 # Create a download button for the markdown file587 st.download_button(588 label="Download Markdown",589 data=ml_markdown,590 file_name="ml_outline.md",591 mime="text/markdown"592 )593 594 # Show the markdown source code in an expandable section595 with st.expander("View Markdown Source"):596 st.code(ml_markdown, language="markdown")597 598with col2:599 st.header("π PDF Preview & Demos")600 601 # Library Demos602 st.subheader("Library Demos")603 604 # PikePDF demo605 if st.button("Generate PikePDF Demo"):606 with st.spinner("Generating PikePDF demo..."):607 pike_pdf = demo_pikepdf()608 st.download_button("Download PikePDF Demo", pike_pdf, "pikepdf_demo.pdf")609 st.success("PikePDF demo created successfully!")610 st.info("This PDF contains the multilevel markdown outline in a two-column layout.")611 612 # FPDF demo613 if st.button("Generate FPDF Demo"):614 with st.spinner("Generating FPDF demo..."):615 fpdf_pdf = demo_fpdf()616 st.download_button("Download FPDF Demo", fpdf_pdf, "fpdf_demo.pdf")617 st.success("FPDF demo created successfully!")618 st.info("This PDF contains the multilevel markdown outline in a two-column layout.")619 620 # PyMuPDF demo621 if st.button("Generate PyMuPDF Demo"):622 with st.spinner("Generating PyMuPDF demo..."):623 pymupdf_pdf = demo_pymupdf()624 st.download_button("Download PyMuPDF Demo", pymupdf_pdf, "pymupdf_demo.pdf")625 st.success("PyMuPDF demo created successfully!")626 st.info("This PDF contains the multilevel markdown outline in a two-column layout.")627 628 # Image demo629 if st.button("Generate Demo Image"):630 with st.spinner("Generating demo image..."):631 img_data = demo_image_capture()632 st.image(img_data, caption="Demo Image (Camera simulation)")633 634 # Add download button for the image635 st.download_button(636 label="Download Image", 637 data=img_data,638 file_name="demo_image.jpg",639 mime="image/jpeg"640 )641 642 # Main PDF Generation643 st.subheader("Main Outline PDF")644 if st.button("Generate Main PDF"):645 with st.spinner("Generating PDF..."):646 try:647 pdf_bytes = create_main_pdf(ml_markdown)648 649 st.download_button(650 label="Download Main PDF",651 data=pdf_bytes,652 file_name="ml_outline.pdf",653 mime="application/pdf"654 )655 656 # Display the PDF in the app657 base64_pdf = base64.b64encode(pdf_bytes).decode('utf-8')658 pdf_display = f'''659 <embed 660 src="data:application/pdf;base64,{base64_pdf}" 661 width="100%" 662 height="400px" 663 type="application/pdf">664 '''665 st.markdown(pdf_display, unsafe_allow_html=True)666 667 st.success("PDF generated successfully! The PDF displays the multilevel markdown outline in a two-column layout.")668 except Exception as e:669 st.error(f"Error generating PDF: {str(e)}")670 671 # Show the PDF rendering code in an expandable section672 with st.expander("View PDF Rendering Code"):673 st.code("""674# Process multilevel markdown for PDF output675def markdown_to_pdf_content(markdown_text):676 # Convert markdown headers to styled text for PDF677 lines = markdown_text.strip().split('\\n')678 pdf_content = []679 680 for line in lines:681 if line.startswith('# '):682 # Main header - will be handled separately683 pass684 elif line.startswith('## '):685 # Section header - add as a bold item686 section = line.replace('## ', '').strip()687 pdf_content.append(f"<b>{section}</b>")688 elif re.match(r'^\\d+\\.', line):689 # Numbered list item690 item = line.strip()691 pdf_content.append(item)692 elif line.startswith('- '):693 # Sub-item under a numbered list item694 sub_item = line.strip()695 pdf_content.append(" " + sub_item)696 697 # Split the content for two columns698 mid_point = len(pdf_content) // 2699 left_column = pdf_content[:mid_point]700 right_column = pdf_content[mid_point:]701 702 return left_column, right_column703 """, language="python")704 705# Add custom CSS for better appearance706st.markdown("""707<style>708 .stButton>button {709 background-color: #4CAF50;710 color: white;711 font-weight: bold;712 }713 .stTabs [data-baseweb="tab-list"] {714 gap: 2px;715 }716 .stTabs [data-baseweb="tab"] {717 height: 50px;718 white-space: pre-wrap;719 background-color: #f0f2f6;720 border-radius: 4px 4px 0px 0px;721 gap: 1px;722 padding-top: 10px;723 padding-bottom: 10px;724 }725</style>726""", unsafe_allow_html=True)