How Markdown to PDF Rendering Runs in Your Browser
Markdown is designed to be parsed line by line, and this converter exploits exactly that. The file is read as text with File.text(), then a single-pass line scanner walks the document with regular expressions, classifying each line: ATX headings via /^(#{1,6})\s+/, blockquotes by a leading > , bullets by [-*+], numbered items by \d+., horizontal rules by --- or ***, and everything else as body text. Inline emphasis markers — **bold**, *italic*, and `code` — are stripped rather than typeset, because the PDF text primitives used here draw a single styled run per call.
Rendering uses pdf-lib, the same in-browser PDF toolkit as the JPG-to-PDF tool. A blank page starts at US-letter size with 50-point margins, and two standard-14 fonts are embedded by reference: Helvetica for body text and Helvetica Bold for headings. The scanner maintains a vertical cursor down the page — each heading is sized from 22 points down to 12 points by level, each body line advances by 14 points of line height — and the moment the cursor drops below the bottom margin, the renderer calls doc.addPage() and continues on a fresh page. Horizontal rules are drawn as vector lines, and blockquotes are indented and drawn in gray at a reduced visual weight, mirroring the conventions of Markdown renderers.
Because drawing is direct-to-PDF rather than HTML-first, there is no intermediate DOM and no print stylesheet to fight — the output is deterministic: the same Markdown always produces the same pagination. The document is serialized with doc.save() into a Uint8Array, wrapped in an application/pdf Blob, and offered for download. Standard-14 fonts are not embedded in the file, which keeps output small and universally readable; combined with the fully local pipeline, the result is a private, dependency-light way to turn READMEs and docs into shareable PDFs.