2.8 KiB
2.8 KiB
Rendering pipeline (Markdown -> HTML -> PDF)
This doc explains how a page is built. iftypeset always renders HTML + CSS first, then optionally renders PDF.
Flow diagram (file flow)
Markdown (.md)
|
v
parse_markdown (src/iftypeset/md_parser.py)
|
v
render-html (src/iftypeset/rendering.py)
|-- out/render.html
|-- out/render.css
|-- out/typeset-report.json
|-- out/degraded-mode-report.json (if degraded input)
|
v
render-pdf (engine adapter)
|-- out/render.pdf
|-- out/render-log.json
|
v
qa (src/iftypeset/qa.py)
|-- out/layout-report.json
|-- out/qa-report.json
Lint and reporting are parallel entry points that do not require PDF:
lint (src/iftypeset/linting.py)
|-- out/lint-report.json
|-- out/manual-checklist.md
report (src/iftypeset/reporting.py)
|-- out/report/index.html
|-- out/coverage-report.json
|-- out/trust-contract.md
|-- out/trust-contract.json
Step-by-step (what actually happens)
- Read Markdown, normalize newlines, detect degraded input, and unwrap hard wraps when needed.
- Parse Markdown into blocks (heading, paragraph, list, code fence, blockquote, table).
- Render HTML by mapping blocks to tags and applying inline transforms:
- Links and images are preserved
- Citation tokens like [S01] are wrapped for styling
- Optional small-caps wrapping for acronyms (profile-controlled)
- Generate CSS from the selected profile:
- Page size and margins
- Fonts and sizes
- Colors, tables, lists, figures, code blocks
- Running-head config (if enabled for supported engines)
- Render PDF using the requested engine (default: Playwright):
- Writes a render log with engine versions and warnings
- QA scans HTML output, and if a PDF exists it also runs PDF-aware heuristics.
Where to change behavior
- Profiles and tokens:
spec/profiles/*.yaml - HTML mapping + table typing:
src/iftypeset/rendering.py - CSS generation:
src/iftypeset/css_gen.py - Markdown parsing:
src/iftypeset/md_parser.py - QA rules and thresholds:
src/iftypeset/qa.py,spec/quality_gates.yaml - Lint rules and logic:
src/iftypeset/linting.py,spec/rules/**
Commands (repro)
iftypeset render-html --input fixtures/sample.md --out out --profile web_pdf
iftypeset render-pdf --input fixtures/sample.md --out out --profile web_pdf
iftypeset qa --out out --profile web_pdf
Notes on determinism
- HTML + CSS is deterministic for the same input + profile.
- PDF output depends on the renderer and installed fonts; versions are recorded in
out/render-log.json. - Profiles can enable a strict fonts contract (
fonts.require_primary: true) and the CLI can force it via--strict-fonts; use--font-dirto supply corporate fonts and avoid silent fallbacks. - Running heads are injected only for engines that support header/footer templates.