"""Build the guide's own printable sheet offline; not a browser print test.""" from pathlib import Path from datetime import datetime, timezone import hashlib, json, platform, subprocess import pymupdf HERE = Path(__file__).resolve().parent CSS = """body {font-family: sans-serif; font-size: 10pt; line-height: 1.2; color: #17252f;} h1 {font-size: 24pt; color: #164c63; margin-bottom: 5pt;} h2 {font-size: 13pt; color: #164c63; margin-top: 14pt; margin-bottom: 5pt;} p {margin-top: 6pt; margin-bottom: 7pt;} table {border-collapse: collapse; width: 100%; font-size: 8.4pt;} th {background-color: #e7f0f3; text-align: left;} th, td {border: 0.5pt solid #b8cbd2; padding: 5pt; vertical-align: top;} pre {background-color: #f0f4f5; padding: 9pt; font-size: 9pt; white-space: pre-wrap;} code {font-family: monospace; font-size: 8.3pt;} """ def build(): source = (HERE / 'cheat-sheet.md').read_text() # This explicit build-only separator is not a Markdown syntax claim. parts = source.split('') merged = pymupdf.open() html_parts = [] sheets = [] for index, part in enumerate(parts, 1): html = subprocess.run(['pandoc', '--from=gfm', '--to=html5', '--wrap=none', '--no-highlight'], input=part, text=True, capture_output=True, check=True).stdout html_parts.append(html) story = pymupdf.Story(html=html, user_css=CSS) paper = pymupdf.paper_rect('a4') content = paper + (36, 32, -36, -38) document = story.write_with_links(lambda rect_num, filled: (paper, content, None)) if len(document) != 1: raise RuntimeError(f'Sheet {index} overflows: {len(document)} pages') merged.insert_pdf(document) sheets.append({'sheet': index, 'pages': len(document)}) document.close() for i, page in enumerate(merged): page.insert_text((36, page.rect.height-22), f'Markdown reference | Core and extensions kept separate | {i+1}', fontsize=8, color=(0.18,0.3,0.35)) destination = HERE / 'markdown-cheat-sheet.pdf' merged.set_metadata({'title': 'Markdown cheat sheet: core syntax and extensions', 'author': 'Markovo editorial', 'subject': 'Locally rendered printable reference; editable source supplied separately'}) merged.save(destination, garbage=4, deflate=True) merged.close() (HERE/'cheat-sheet-html.txt').write_text('\n\n'.join(html_parts)) document = pymupdf.open(destination) text = '\n'.join(page.get_text() for page in document) (HERE/'cheat-sheet-extracted.txt').write_text(text) assets = HERE.parents[1] / 'review-assets' assets.mkdir(exist_ok=True) for i, page in enumerate(document): page.get_pixmap(matrix=pymupdf.Matrix(1.4,1.4)).save(assets/f'cheat-sheet-page-{i+1}.png') report = { 'date': datetime.now(timezone.utc).isoformat(), 'python': platform.python_version(), 'pymupdf': pymupdf.__version__, 'pandoc': subprocess.check_output(['pandoc','--version'],text=True).splitlines()[0], 'command': 'tools/lab-venv/bin/python runs/2026-11-02-markovo-markdown-cheat-sheet-pdf/lab/renderers/build_pdf.py', 'markdown_command': 'pandoc --from=gfm --to=html5 --wrap=none --no-highlight (each source half through stdin)', 'layout': {'paper':'A4', 'margin_points':[36,32,36,38], 'font':'built-in sans-serif and monospace', 'build_only_separator':''}, 'pages': len(document), 'sheets': sheets, 'checks': {key: key in text for key in ['# Heading','**bold**','~~removed~~','| Name | State |','| --- | --- |','print("hello")','Find the failed stage','Keep both copies']}, 'pdf': 'lab/renderers/markdown-cheat-sheet.pdf', 'sha256': hashlib.sha256(destination.read_bytes()).hexdigest(), 'scope': 'Own PDF built with Pandoc HTML and PyMuPDF Story. Page images require separate visual inspection. Not browser printing or a PDF extraction benchmark.' } (HERE/'pdf-build.json').write_text(json.dumps(report,indent=2)+'\n') print(json.dumps(report,indent=2)) if __name__ == '__main__': build()