induwara.lk
induwara.lkDocuments · Privacy-first

Markdown to PDF Converter

Paste any Markdown — CommonMark or GitHub-Flavored — pick page size, orientation, and margin, and save it as a PDF in your browser. No signup, no upload, the file never leaves your device. Text stays selectable in the output, not flattened to an image.

By Induwara AshinsanaUpdated May 11, 2026
Markdown to PDF ConverterIn-browser · no upload
Files stay on your device
Everything happens in your browser. Nothing is uploaded.
Max 5.0 MB.

Paste Markdown on the left to see a live preview here.

The preview applies the same @page rule the printer will use, so what you see is close to what your PDF will look like.

Parser
Page size
Orientation
Margin
Input size
0 B
Headings
0
Cross-checked by 2 parsers
Code blocks
0
Cross-checked by 2 parsers
Tables · Links · Words
0 · 0 · 0
Add Markdown to begin

Paste Markdown or upload a .md file above.

Built against the CommonMark 0.31.2 spec, the GitHub-Flavored Markdown extensions, and the W3C CSS Paged Media Level 3. Verified 2026-05-11— full source list in the “Sources & references” section below.

How it works

A PDF made from Markdown can be produced two ways: by rendering the HTML to a canvas and stitching the canvas into a PDF (the html2canvas + jsPDF approach), or by handing the rendered HTML to the browser's own print engine via window.print(). The first approach turns every glyph into pixels — the PDF prints fuzzily, the text is unsearchable, and accessibility breaks. The second approach uses the same Blink, Gecko, or WebKit code path that powers Print Preview in the browser's File menu, so the output is a real, text-selectable PDF. This tool uses the second approach.

The pipeline has three stages, each implemented as a pure function in lib/data/markdown-to-pdf.ts:

  1. Parse. The Markdown is run through marked 14.x with async: false for a synchronous string return. GFM extensions (tables, strikethrough, task lists) are on by default per the GitHub-Flavored Markdown spec; the user can switch back to strict CommonMark with a chip toggle.
  2. Cross-check. Two independent counters — one regex pass over the raw Markdown (skipping fenced code blocks), one walk of the marked lexer's token tree — count headings and code blocks. If they disagree, a tokenCountConsistent: false flag surfaces the discrepancy in the stats grid above. Validation errors (empty input, over the 5.0 MB ceiling) produce a specific message, not a silent zero.
  3. Wrap. The rendered HTML is wrapped in a full HTML5 skeleton with a @page rule (CSS Paged Media Level 3, §3) that fixes the chosen page size, orientation, and margin. A short print-tuned stylesheet sits inline: serif-free body type, monospace code blocks with a light grey fill, table borders, and page-break-after: avoid on every heading so a heading never orphans at the bottom of a page.
  4. Render and print. The built document is set as the iframe's srcdoc attribute. The sandbox is allow-modals allow-same-origin — scripts stay disabled but the print dialog can open (HTML Living Standard §4.8.5). The “Download as PDF” button calls iframe.contentWindow.print(), scoped to the iframe so only the document — not the surrounding induwara.lk page — appears in the printed PDF.

5 page sizes are supported — A4, A3, A5, US Letter, US Legal — each in portrait or landscape, with three margin presets from narrow (10 mm) to wide (25 mm). All width and height values are expressed in millimetres so the @page rule needs only one unit. US sizes are converted from inches at 25.4 mm per inch (per ANSI/ASME Y14.1).

Worked examples

Short article on A4 portrait

A one-page article: an H1, an H2, a single unordered list, and an inline link. Renders to A4 portrait with 18 mm margins — the most common newspaper-and-CV combination.

  1. Headings: 2 · Code blocks: 0
  2. Tables: 0 · Lists: 1
  3. Links: 1 · Images: 0
  4. Page: A4 portrait · 18 mm margin
  5. Built document size: 2.5 KB

Technical doc on US Letter

A README-style document: H1 + H2 + a TypeScript code fence + a 3×2 GFM table. US Letter portrait, normal margin. Exercises the table and fenced-code tokenisers in marked.

  1. Headings: 2 · Code blocks: 1
  2. Tables: 1 · Lists: 0
  3. Links: 0 · Images: 0
  4. Page: US Letter portrait · 18 mm margin
  5. Built document size: 2.8 KB

Heading-heavy outline on A5 narrow

An edge case: six consecutive H2 headings with one-line bullets — the kind of input a chapter outline produces. A5 portrait, 10 mm margin, no code or tables, so the lexer's heading path runs cleanly with no fenced-block noise.

  1. Headings: 7 · Code blocks: 0
  2. Tables: 0 · Lists: 6
  3. Links: 0 · Images: 0
  4. Page: A5 portrait · 10 mm margin
  5. Built document size: 2.5 KB

Frequently asked questions

Sources & references

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found a bug, edge case, or want to suggest an improvement?

Email me at [email protected] — most fixes ship within 24 hours.