Files
cremote/generate_pdf_report.py
Josh at WLTechBlog ccd8c77a3e remove sensory tools
2025-10-07 11:47:47 -05:00

286 lines
7.5 KiB
Python

#!/usr/bin/env python3
"""
Generate PDF report from markdown with embedded screenshots
"""
import markdown2
from weasyprint import HTML, CSS
from pathlib import Path
import base64
def embed_image_as_base64(image_path):
"""Convert image to base64 for embedding in HTML"""
try:
with open(image_path, 'rb') as img_file:
img_data = base64.b64encode(img_file.read()).decode('utf-8')
return f"data:image/png;base64,{img_data}"
except Exception as e:
print(f"Warning: Could not embed image {image_path}: {e}")
return ""
def create_html_with_screenshots(md_content, screenshots_dir):
"""Convert markdown to HTML and embed screenshots"""
# Convert markdown to HTML
html_content = markdown2.markdown(md_content, extras=['tables', 'fenced-code-blocks'])
# Find all screenshot references and embed them
screenshot_files = {
'homepage-full-page.png': 'Homepage - Full Page View',
'about-page.png': 'About Us Page',
'vision-program-page.png': 'Vision Program Page',
'protege-program-page.png': 'Protégé Program Page',
'calendar-page.png': 'Calendar Page',
'contact-page.png': 'Contact Us Page',
'gala-page.png': 'Graduation Gala Page'
}
# Build screenshots section HTML
screenshots_html = '<div class="page-break"></div>\n<h2>APPENDIX: PAGE SCREENSHOTS</h2>\n'
for filename, caption in screenshot_files.items():
img_path = Path(screenshots_dir) / filename
if img_path.exists():
img_base64 = embed_image_as_base64(img_path)
if img_base64:
screenshots_html += f'''
<div class="screenshot-container">
<h3>{caption}</h3>
<img src="{img_base64}" alt="{caption}" class="screenshot" />
<p class="screenshot-caption">File: {filename}</p>
</div>
<div class="page-break"></div>
'''
# Replace the appendix section with embedded images
if 'APPENDIX: SCREENSHOTS' in html_content:
html_content = html_content.split('APPENDIX: SCREENSHOTS')[0] + screenshots_html
else:
html_content += screenshots_html
return html_content
def create_pdf_report(md_file, output_pdf, screenshots_dir):
"""Generate PDF report from markdown file"""
print(f"Reading markdown file: {md_file}")
with open(md_file, 'r', encoding='utf-8') as f:
md_content = f.read()
print("Converting markdown to HTML with embedded screenshots...")
html_body = create_html_with_screenshots(md_content, screenshots_dir)
# Create complete HTML document with styling
html_template = f'''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vision Leadership ADA Assessment Report</title>
<style>
@page {{
size: letter;
margin: 0.75in;
@bottom-center {{
content: "Page " counter(page) " of " counter(pages);
font-size: 9pt;
color: #666;
}}
}}
body {{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 11pt;
line-height: 1.6;
color: #333;
max-width: 100%;
}}
h1 {{
color: #0066CC;
font-size: 24pt;
margin-top: 0;
margin-bottom: 0.5em;
border-bottom: 3px solid #0066CC;
padding-bottom: 0.3em;
}}
h2 {{
color: #0066CC;
font-size: 18pt;
margin-top: 1.5em;
margin-bottom: 0.5em;
border-bottom: 2px solid #E0E0E0;
padding-bottom: 0.2em;
page-break-after: avoid;
}}
h3 {{
color: #333;
font-size: 14pt;
margin-top: 1.2em;
margin-bottom: 0.4em;
page-break-after: avoid;
}}
h4 {{
color: #555;
font-size: 12pt;
margin-top: 1em;
margin-bottom: 0.3em;
}}
p {{
margin: 0.5em 0;
text-align: justify;
}}
strong {{
color: #000;
}}
code {{
background-color: #F5F5F5;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 10pt;
}}
pre {{
background-color: #F5F5F5;
padding: 12px;
border-left: 4px solid #0066CC;
border-radius: 4px;
overflow-x: auto;
font-size: 9pt;
line-height: 1.4;
}}
pre code {{
background-color: transparent;
padding: 0;
}}
table {{
width: 100%;
border-collapse: collapse;
margin: 1em 0;
font-size: 10pt;
page-break-inside: avoid;
}}
th {{
background-color: #0066CC;
color: white;
padding: 10px;
text-align: left;
font-weight: bold;
}}
td {{
padding: 8px 10px;
border: 1px solid #DDD;
}}
tr:nth-child(even) {{
background-color: #F9F9F9;
}}
ul, ol {{
margin: 0.5em 0;
padding-left: 2em;
}}
li {{
margin: 0.3em 0;
}}
.page-break {{
page-break-before: always;
}}
.screenshot-container {{
margin: 2em 0;
text-align: center;
page-break-inside: avoid;
}}
.screenshot {{
max-width: 100%;
height: auto;
border: 1px solid #DDD;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
margin: 1em 0;
}}
.screenshot-caption {{
font-size: 9pt;
color: #666;
font-style: italic;
margin-top: 0.5em;
}}
hr {{
border: none;
border-top: 2px solid #E0E0E0;
margin: 2em 0;
}}
blockquote {{
border-left: 4px solid #0066CC;
padding-left: 1em;
margin-left: 0;
color: #555;
font-style: italic;
}}
/* Status badges */
.status-compliant {{
background-color: #4CAF50;
color: white;
padding: 3px 8px;
border-radius: 3px;
font-weight: bold;
}}
.status-warning {{
background-color: #FF9800;
color: white;
padding: 3px 8px;
border-radius: 3px;
font-weight: bold;
}}
/* Checkmarks and X marks */
.check {{
color: #4CAF50;
font-weight: bold;
}}
.cross {{
color: #F44336;
font-weight: bold;
}}
</style>
</head>
<body>
{html_body}
</body>
</html>
'''
print("Generating PDF...")
HTML(string=html_template).write_pdf(output_pdf)
print(f"✅ PDF report generated successfully: {output_pdf}")
if __name__ == '__main__':
# File paths
md_file = 'VISIONLEADERSHIP_ADA_ASSESSMENT_REPORT_2025-10-03.md'
output_pdf = 'VISIONLEADERSHIP_ADA_ASSESSMENT_REPORT_2025-10-03.pdf'
screenshots_dir = 'screenshots'
# Generate PDF
create_pdf_report(md_file, output_pdf, screenshots_dir)