#!/usr/bin/env python3 """ Generate PDF from Architectural Safeguards Against LLM Hierarchical Dominance (Prose version) """ import markdown from weasyprint import HTML, CSS from pathlib import Path def generate_pdf(): """Convert the prose markdown document to PDF with professional styling""" # Paths script_dir = Path(__file__).parent project_root = script_dir.parent input_file = project_root / 'docs' / 'research' / 'ARCHITECTURAL-SAFEGUARDS-Against-LLM-Hierarchical-Dominance-Prose.md' output_file = project_root / 'docs' / 'research' / 'ARCHITECTURAL-SAFEGUARDS-Against-LLM-Hierarchical-Dominance-Prose.pdf' print(f"Reading markdown from: {input_file}") # Read markdown content with open(input_file, 'r', encoding='utf-8') as f: md_content = f.read() print("Converting markdown to HTML...") # Convert markdown to HTML with extensions html_content = markdown.markdown( md_content, extensions=[ 'markdown.extensions.tables', 'markdown.extensions.fenced_code', 'markdown.extensions.toc', 'markdown.extensions.sane_lists' ] ) # Wrap in full HTML document with professional styling full_html = f""" Architectural Safeguards Against LLM Hierarchical Dominance {html_content} """ # Professional CSS styling css = CSS(string=""" @page { size: Letter; margin: 1in; @bottom-center { content: counter(page); font-size: 10pt; color: #666; } } body { font-family: "Georgia", "Times New Roman", serif; font-size: 11pt; line-height: 1.6; color: #333; } h1 { font-size: 24pt; font-weight: bold; color: #1976d2; margin-top: 24pt; margin-bottom: 12pt; page-break-after: avoid; } h2 { font-size: 18pt; font-weight: bold; color: #1976d2; margin-top: 20pt; margin-bottom: 10pt; page-break-after: avoid; border-bottom: 2px solid #1976d2; padding-bottom: 4pt; } h3 { font-size: 14pt; font-weight: bold; color: #424242; margin-top: 16pt; margin-bottom: 8pt; page-break-after: avoid; } h4 { font-size: 12pt; font-weight: bold; color: #424242; margin-top: 12pt; margin-bottom: 6pt; page-break-after: avoid; } p { margin-top: 0; margin-bottom: 10pt; text-align: justify; } strong { font-weight: bold; color: #000; } em { font-style: italic; } ul, ol { margin-top: 8pt; margin-bottom: 8pt; padding-left: 24pt; } li { margin-bottom: 4pt; } table { width: 100%; border-collapse: collapse; margin-top: 12pt; margin-bottom: 12pt; page-break-inside: avoid; } th { background-color: #1976d2; color: white; font-weight: bold; padding: 8pt; text-align: left; border: 1px solid #1976d2; } td { padding: 6pt; border: 1px solid #ddd; } tr:nth-child(even) { background-color: #f5f5f5; } blockquote { margin: 12pt 24pt; padding: 8pt 12pt; background-color: #f5f5f5; border-left: 4px solid #1976d2; font-style: italic; } hr { border: none; border-top: 2px solid #ddd; margin: 20pt 0; } /* Prevent orphans and widows */ p, li, h1, h2, h3, h4 { orphans: 3; widows: 3; } /* Keep related content together */ h1, h2, h3, h4 { page-break-after: avoid; } /* Table styling improvements */ table { font-size: 10pt; } /* Code/technical terms */ code { font-family: "Courier New", monospace; font-size: 10pt; background-color: #f5f5f5; padding: 2pt 4pt; border-radius: 2pt; } """) print("Generating PDF...") # Generate PDF with metadata from weasyprint import __version__ as weasyprint_version # Create HTML object and write PDF with metadata html_obj = HTML(string=full_html) html_obj.write_pdf( output_file, stylesheets=[css], pdf_forms=True ) # Add PDF metadata using PyPDF2 try: from PyPDF2 import PdfReader, PdfWriter # Read the generated PDF reader = PdfReader(output_file) writer = PdfWriter() # Copy all pages for page in reader.pages: writer.add_page(page) # Add metadata writer.add_metadata({ '/Title': 'Architectural Safeguards Against LLM Hierarchical Dominance', '/Author': 'Agentic Governance Research Team', '/Subject': 'AI Safety, LLM Governance, Value Pluralism, Deliberative AI', '/Keywords': 'AI Safety, LLM, Hierarchical Dominance, Pluralistic Deliberation, Tractatus', '/Creator': 'Tractatus Framework', '/Producer': f'WeasyPrint {weasyprint_version}', }) # Write the updated PDF with open(output_file, 'wb') as f: writer.write(f) print("āœ“ PDF metadata added successfully") except ImportError: print("⚠ PyPDF2 not installed - PDF generated without metadata") print(" Install with: pip install PyPDF2") print(f"āœ“ PDF generated successfully: {output_file}") print(f" File size: {output_file.stat().st_size / 1024:.1f} KB") return output_file if __name__ == '__main__': try: output_path = generate_pdf() print("\n" + "="*60) print("PDF Generation Complete") print("="*60) print(f"\nOutput: {output_path}") print("\nYou can now:") print(" - Open the PDF in any PDF viewer") print(" - Share with stakeholders, funders, researchers") print(" - Print for offline reading") except Exception as e: print(f"\nāœ— Error generating PDF: {e}") import traceback traceback.print_exc() exit(1)