tutorialguide14 min read

Markdown to PDF Formatting Issues: Fix Every Common Bug (2026)

Eight bugs that turn a clean markdown file into a broken PDF — diagnosed, and fixed. Tables, page breaks, fonts, math, and the rest.

Mohammed AgratUpdated May 26, 2026

Markdown is a forgiving language. PDFs are not. Eight bugs turn a clean .md file into a broken PDF — diagnosed, with the quick fix and the structural fix for each.

TL;DR — the eight bugs

Almost every markdown to PDF formatting issuetraces back to one of three structural causes: the converter uses a Chromium print engine that wasn’t built for typography, the rendering passes happen in the wrong order, or the source content was authored for the screen and the PDF inherited the screen’s assumptions. The fixes fall into the same three buckets.

  • Tables overflow or break across pages.
  • Code blocks lose syntax highlighting.
  • Page breaks land mid-image or mid-heading.
  • Footnotes disappear or merge.
  • Custom fonts don’t embed.
  • Math (KaTeX/LaTeX) doesn’t render.
  • Images pixelate at print resolution.
  • Table-of-contents page numbers are wrong.

Each gets a quick fix you can apply today and a structural fix that prevents the bug from recurring. The structural fix is almost always the same recommendation: use a converter built for designed output (mdclaudy, Pandoc with Eisvogel, Typst) rather than a tool that wraps browser print.

The eight bugs at a glance

SymptomRoot causeQuick fixStructural fix
Tables overflow or break across pagesWider than the page; no column scaling; CSS page-break-inside ignoredRotate to landscape or shrink the font for tablesUse a template that sizes tables to column and repeats headers
Code blocks lose syntax highlightingHighlighter ran in the editor but the export pipeline strips classesPre-render with highlight.js or Prism before exportUse a converter that highlights server-side (Pandoc + listings, mdclaudy)
Page breaks land mid-image or mid-headingBrowser print uses CSS heuristics; no widow/orphan controlAdd a hard page break before the affected elementUse a Typst or LaTeX engine with real widow/orphan control
Footnotes disappear or mergeMost Chromium converters don't implement footnote paginationConvert footnotes to endnotes manuallyUse Pandoc or a template with footnote-aware pagination
Custom fonts don't embedFont referenced by name but not subsetted into the PDFConvert text to outlines (loses copy-paste)Use a converter that subsets fonts on export (mdclaudy does)
Math (KaTeX/LaTeX) renders as raw $...$No math rendering pass between markdown and HTMLConvert math to images in Notion or Obsidian firstUse Pandoc --mathjax or a tool with first-class KaTeX
Images pixelate at print resolutionSource image is screen-resolution (72-96 dpi); PDF needs 300Resize the source up before embeddingEmbed SVG where possible; raster at 2x source for 150dpi
Table of contents page numbers are wrongTOC generated before final pagination; no second passManually update TOC after exportUse a tool that does a two-pass render (Pandoc, mdclaudy)

1. Tables overflow or break across pages

The single most reported bug in any markdown-to-PDF pipeline. You write a tidy GFM table; the PDF shows a table that runs off the right edge of the page or splits across pages with no header repeat.

Why it happens

Three reasons usually compound. The table is wider than the page in characters. The CSS doesn’t scale columns to fit. And the Chromium printer ignores page-break-inside: avoidfor large blocks — there’s nowhere else to put a 40-row table.

How to fix it

  • Quick: rotate the page to landscape with a per-page CSS rule, or drop the font size for the table.
  • Better: add <style>table { width: 100%; table-layout: fixed; word-break: break-word; }</style> to your CSS so columns share the available width.
  • Structural: use Pandoc with the longtableLaTeX package (Eisvogel includes it), or mdclaudy’s templates, which size tables to column and repeat the header on every page. For the markdown-side of tables, see the guide at markdown tables.

2. Code blocks lose syntax highlighting

You wrote ```python, the editor showed colored tokens, the PDF shows monochrome text. The highlight worked in the editor; it didn’t survive the export.

Why it happens

Most editors apply highlighting via a client-side library (highlight.js, Prism, Shiki) at render time. The export pipeline either strips the resulting <span class="hljs-keyword"> tags or hits the print job before highlighting completes.

How to fix it

  • Pandoc: add --highlight-style=pygments (or one of the built-in styles like tango, kate, monochrome). With Eisvogel, also pass --listings for proper code formatting.
  • md-to-pdf: configure the markdown-it highlight callback in the config file to call highlight.js in Node before render.
  • VS Code Markdown PDF:the extension reads VS Code’s color theme — it works if your theme is light, breaks on dark themes. Switch to a light theme before export.
  • mdclaudy: highlighting is server-side by default, themed to match the template. No configuration.

3. Page breaks land mid-image or mid-heading

A heading sits alone at the bottom of page 4. An image splits halfway across the page boundary. A paragraph ends one orphaned line on the next page. The PDF reads as broken because the breaks don’t respect the structure of the document.

Why it happens

The Chromium print engine implements only a subset of the CSS Paged Media spec. Widow/orphan control is partial; break-after and break-before are honored unevenly; page-break-inside: avoid fails on tall elements. LaTeX and Typst engines do this correctly because they were built to.

How to fix it

  • Force a break: insert <div style="page-break-before: always" /> in markdown before a heading that should start on a new page. In Pandoc, the equivalent is \newpage.
  • Keep elements together: wrap an image and its caption in a <div style="page-break-inside: avoid"> — works in most Chromium converters.
  • Structural:use Pandoc with Eisvogel (handles widows/orphans via LaTeX), or mdclaudy’s designed templates, which set widows/orphans to 3 by default.

4. Footnotes disappear or merge

You wrote [^1] in markdown. In the PDF, the footnote markers are gone, or all the footnotes are crammed at the end as endnotes, or every footnote on a page renders as 1.

Why it happens

Footnote pagination is one of the harder problems in document rendering. Most Chromium converters skip it — there’s no native CSS for footnote-at-bottom-of-page. Pandoc does it correctly via LaTeX. mdclaudy’s designed templates implement it explicitly.

How to fix it

  • If you’re on Pandoc: make sure the reader is markdown or gfm+footnotes, not markdown_strict. Eisvogel handles the rest.
  • If you’re on a Chromium pipeline: accept that footnotes will render as endnotes at the document end, or rewrite inline.
  • If you’re on mdclaudy:footnotes render at the bottom of the page they’re cited on, with proper numbering carry-over between pages.

5. Custom fonts don’t embed

You set font-family: "Charter" in your CSS. The recipient opens the PDF and sees Times New Roman. Or worse — Arial.

Why it happens

A PDF must embed the font for the recipient to see it, not just reference it by name. Browser print embeds whatever font is loaded in the print job, but only as a subset of the glyphs used — and only if the converter passes the font through to the PDF. Some Chromium-based tools strip embedded fonts at export to keep PDFs small.

How to fix it

  • Use a font loaded by URL, not by name: in CSS, use @font-face with a local file or a URL. Browser print handles this better than name-only references.
  • Pandoc with XeLaTeX: pandoc input.md --pdf-engine=xelatex --variable mainfont="Charter" -o out.pdf embeds the font properly.
  • mdclaudy: the templates ship with embedded fonts; the export subsets them into the PDF automatically.

6. Math (KaTeX/LaTeX) doesn’t render

You wrote $\frac{a}{b}$. The PDF shows $\frac{a}{b}$. The math didn’t render at all, or it rendered in the editor but not in the export.

Why it happens

KaTeX is a JavaScript library — it transforms LaTeX-style math into HTML at render time, in the browser. The Chromium printer captures whatever is in the DOM at print time, so if the print fires before the KaTeX pass completes, you get raw markdown.

How to fix it

  • Pandoc: pandoc input.md --mathjax -o out.pdf or --katex to render math properly to MathML / images.
  • md-to-pdf: add a markdown-it-katex plugin via the config file; the rendering happens in Node before the print job fires.
  • mdclaudy: KaTeX renders server-side as part of the export pass — you get the same math in the PDF that you see in the editor.

7. Images pixelate at print resolution

The image looks crisp in the editor. In the PDF, especially when printed, it looks blurry.

Why it happens

Screen images are 72 to 96 dpi. Print is 300 dpi. When a 600px-wide screenshot is embedded at 6 inches wide in the PDF, it’s effectively 100 dpi — fine on screen, blurry when printed.

How to fix it

  • Export source images at 2x or 3xthe size they’ll appear at. macOS “take a screenshot” at 2x retina works; on Linux/Windows use a screenshot tool that captures at scale.
  • Use SVG where possible — diagrams, charts, icons, logos. SVG is vector; it stays crisp at any size.
  • mdclaudywarns at export when an image’s effective dpi is below 150 — it’s the cheapest QA check we could ship.

8. Table of contents page numbers are wrong

Your TOC says “Chapter 3 — page 12”. Chapter 3 is on page 17. The page numbers are off by a few, or wildly off.

Why it happens

Generating an accurate TOC needs the document’s final pagination, which depends on the TOC itself — a chicken-and-egg problem. The fix is a two-pass render: lay out without a TOC, measure page numbers, lay out again with the real TOC. Most one-pass Chromium converters skip this.

How to fix it

  • Pandoc: two-pass is the default with --toc --pdf-engine=xelatex.
  • md-to-pdf: generate the TOC manually, then export.
  • mdclaudy: two-pass renders ship in Phase 1 — TOC page numbers match the document.
Most markdown-to-PDF bugs aren’t bugs in the markdown. They are bugs in the renderer pretending to be a typographer.

The structural fix, in one sentence

Use a tool that was built for designed output, not a tool that wraps browser print. Pandoc + Eisvogel and Typst-based tools fix most of the bugs above by virtue of their engines. mdclaudy fixes them by virtue of its templates. If your tool ends in “PDF” and starts with “print to”, you will keep fighting Chromium.

Adjacent reading

Frequently asked questions

Why does my markdown table break in PDF?

Almost always one of three reasons. (1) The table is wider than the page — fix by rotating to landscape, shrinking the font, or splitting the table. (2) The converter renders the table as one block and Chromium can’t paginate it — fix by switching to a Pandoc or Typst engine that handles table pagination. (3) Header rows don’t repeat on page two — fix by using a template that supports longtable or repeating thead.

Why does my markdown to PDF lose code syntax highlighting?

Because most converters apply syntax highlighting via JavaScript at render time (Prism, highlight.js), and the PDF pipeline often strips the resulting CSS classes. Fix by pre-rendering: tell the converter to run highlighting server-side. In Pandoc, use --highlight-style; in md-to-pdf, configure the markdown-it highlight callback; in mdclaudy it’s on by default.

Why does my PDF have page breaks in the wrong places?

Chromium’s print engine — the one used by browser print, md-to-pdf, VS Code Markdown PDF, and most online converters — uses crude CSS page-break heuristics. It doesn’t implement widow/orphan control properly, so it splits inside images, between a heading and its first paragraph, mid-row in tables. The structural fix is a LaTeX or Typst engine; the quick fix is inserting explicit \pagebreak or <div style="page-break-before: always" /> markers.

How do I make Pandoc footnotes work in PDF?

Pandoc supports footnotes natively via the footnotesmarkdown extension (it’s on by default for the markdownreader). If footnotes are disappearing, you’re probably using markdown_strict — switch the reader to markdown or gfm+footnotes. For PDFs specifically, pair with the Eisvogel template, which formats footnotes properly at the bottom of each page.

Why don't my custom fonts show up in the exported PDF?

The font must be both referenced in the stylesheet and embeddedin the PDF. Browser print and many Chromium converters reference the font but don’t subset it into the output — so when the recipient opens it on a machine that doesn’t have your font installed, it falls back to whatever’s closest. mdclaudy and Pandoc with --pdf-engine=xelatex embed the font properly via subsetting.

Why does KaTeX math not render in my PDF?

Because KaTeX renders math in the browser at view-time using JavaScript. When a Chromium print job runs, it captures whatever HTML/CSS is present, and if the KaTeX pass hasn’t completed when the print fires, you get raw $\frac{a}{b}$ in the PDF. Fixes: render math to MathML server-side, use Pandoc with --mathjax or --katex, or use a tool that knows to wait for the math pass before printing.

Why do images pixelate in the PDF?

Screen images are typically 72 to 96 dpi. Print expects 300 dpi. Embedding a screen-resolution image in a PDF at print size scales it up, and pixels appear. Fix by exporting source images at 2x or 3x the display size, or use SVG where possible. mdclaudy will warn at export if an image is too low-resolution for its declared size.

Why is the table of contents page numbering wrong?

Generating a TOC requires knowing the final page numbers, which requires laying out the entire document — a two-pass operation. Some markdown-to-PDF tools only do one pass and the TOC reflects pre-layout estimates. Use a tool that does a two-pass render (Pandoc, mdclaudy) or accept that you’ll regenerate the TOC after layout settles.

The honest final word

You can spend a week tuning CSS to coax a browser-print pipeline into producing a presentable PDF. Or you can use a tool whose entire job is the PDF and ship the same afternoon. Both are valid choices. The first one teaches you a lot. The second one ships the document.

If the document is the point — and it usually is — let the tool do the typography. Try mdclaudy at /tools/markdown-to-pdf, or sign up at /sign-up for the library and the full template set.

─── try mdclaudy ───

Write markdown. Ship a designed PDF.

Fifteen hand-built templates. Optional AI. Free up to 50 documents.

No card. 50 documents included.
─── Related reading