286 lines
7.5 KiB
Python
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)
|
|
|