The request always comes from outside engineering. Legal wants the incident runbook "as a PDF for the file." A client wants the integration guide as an attachment, because they can't open your private repo and wouldn't want to.
You have all of it in Markdown. You type pandoc runbook.md -o runbook.pdf, and pandoc tells you it needs a LaTeX engine. On a Mac, the full MacTeX distribution is about 6.4 GB. For one PDF.
Quick answer: to convert Markdown to PDF without installing anything, paste the text or import the .md file into Markdown to PDF, choose A4 or Letter, and download. It runs in your browser and produces a clean monospace PDF in which code blocks come out character for character. It does not typeset or syntax-highlight. For a styled document, use pandoc or print a rendered preview.
That last sentence matters, so here's the longer version.
Two very different things called "Markdown to PDF"
Every Markdown to PDF converter makes one of two choices, and most don't tell you which.
A rendering converter treats Markdown the way GitHub's preview does. Headings get big and code gets a shaded box with syntax colors. To do that it needs a typesetting engine behind it: LaTeX, a headless browser, Typst, or WeasyPrint. That's what pandoc does, and it does it very well. It's also why pandoc's own manual says that by default it "will use LaTeX to create the PDF, which requires that a LaTeX engine be installed" (pandoc manual).
A literal converter takes the text itself, strips the syntax that only makes sense to a Markdown parser, and lays out what remains on real pages. There's no styling engine to install because there's no styling. What you get is closer to a printout of a well-formatted text file.
OxygenPDF's Markdown to PDF is the second kind. I'd rather say that up front than have you find out after sending a PDF to a client expecting syntax colors.
The literal approach has a real advantage for developer docs, though: nothing is reinterpreted. That turns out to matter more than it sounds.
The bug every naive converter has with code
Markdown's own specification is clear that code is not Markdown. CommonMark says "the content of a code fence is treated as literal text, not parsed as inlines." A double underscore inside a code block is two underscores, not bold.
A quick-and-dirty converter ignores that. It runs its find-and-replace rules over the whole file, code included, and then the damage starts:
def __init__(self):loses its underscores and becomesdef init(self):, because__init__looks like bold.MAX_RETRY_COUNTturns intoMAXRETRYCOUNT, because_RETRY_looks like italics.total = a * b * closes both asterisks.- A
# install dependenciescomment in a shell block gets promoted to an uppercase heading.
The result looks fine at a glance and is wrong in exactly the places a reader will copy from. A runbook that tells an on-call engineer to run a command with its underscores stripped is worse than no runbook.
Here's the uncomfortable part: until September 2026, ours did it too. The fix that shipped alongside this post sets code blocks and inline code aside before any other rule runs, then puts them back untouched. It also stops underscores in the middle of a word from counting as emphasis anywhere in the document, which is the CommonMark rule and the reason snake_case in plain prose survives now too. So my_config_file in a sentence stays my_config_file.
What survives the conversion
Here's exactly what happens to each piece of Markdown, read from the converter's source rather than from marketing:
| Markdown | In the PDF |
|---|---|
| Fenced code blocks | Fences removed, every character and indent kept exactly |
| Inline code | Kept exactly, backticks removed |
Headings (# to ######) |
Their own line, in UPPERCASE |
| Bold, italic, strikethrough | Markers removed, words kept |
| Links | text (url), so the URL is on paper |
| Images | [Image: alt text] placeholder |
| Bullet and numbered lists | • bullets, numbers kept |
| Task lists | ☑ and ☐ |
| Blockquotes | A │ bar down the left |
| Pipe tables | The table source, as written |
| Mermaid, raw HTML | Printed as text |
The whole document is set in JetBrains Mono, a monospace face. That's a trade-off I'm happy with for this job: every character is the same width, so indentation in code means what it meant in your editor, and ASCII diagrams stay drawn.
The text is real text, too. You can search the PDF, select a command, and paste it into a terminal.
Tables: format the source first
Tables deserve their own note. The GFM spec defines a table as rows of pipes with a delimiter row of hyphens under the header. The converter doesn't draw that as a grid. It prints the source, in monospace.
If your source table is ragged, the PDF is ragged:
| Flag | Default |
|---|---|
| --dry-run | false |
If the source is aligned, the PDF looks like a table:
| Flag | Default |
|-----------|---------|
| --dry-run | false |
Most editors can do this for you. Prettier formats Markdown tables on save, and VS Code's Markdown extensions have a "format table" command. Run it before converting and your tables print as clean grids.
When pandoc really is the better tool
Pick the literal converter when the PDF is a record: a runbook, a changelog, meeting notes, an internal spec, a README for someone who won't browse a repo. It's there in the time it takes to paste, and no file leaves your laptop, which matters when the document is a security runbook or an unreleased API.
Pick a rendering tool when the PDF is a product. A whitepaper or a published guide will look better typeset, and that's worth an install. Two ways to get there without the 6.4 GB:
- Pandoc with a lighter engine. Pandoc can hand off to engines other than LaTeX, including
typstandweasyprint, via--pdf-engine. Something likepandoc README.md --pdf-engine=typst -o README.pdfneeds pandoc and Typst, both single binaries. - Print the rendered preview. Open the file in GitHub's web view or VS Code's Markdown preview, then use your browser's Print to PDF. You get syntax highlighting and rendered tables for free. You also get page breaks wherever the browser feels like putting them.
Neither is wrong. They answer a different question.
Step by step: Markdown to PDF in the browser
- Open Markdown to PDF. Nothing to install, and it works the same on macOS, Windows, Linux and ChromeOS.
- Paste or import. Paste Markdown into the editor, or click Import .md. It accepts
.md,.markdown,.mdxand.txtfiles. - Strip the front matter. If the file starts with a YAML block between
---lines (Jekyll, Hugo and Docusaurus all do this), delete it first, or it prints as a line and a list of keys. - Align your tables. See above. Thirty seconds in your editor saves a ragged page.
- Set the page. A4 or Letter, font size from 8 to 24 pt (12 is the default), and a single margin from half an inch to an inch and a half. For code with long lines, drop to 10 pt so fewer lines wrap.
- Convert and download. Long lines wrap at the margin, and pages break automatically. The PDF is built in the tab, and you can rename it before you download.
If the PDF is going into a larger packet, Merge PDF joins it to the rest. If it's a formal handoff, Add Page Numbers stamps a number on every page, so a missing one is obvious. And if you need to go the other direction, PDF to Markdown pulls text and tables out of a PDF back into Markdown.
Frequently asked questions
Does it support syntax highlighting?
No. Code blocks come out in the same monospace font as everything else, with no colors. What you do get is the exact text, down to every underscore and every indent. For highlighted code, render the Markdown in a browser or use pandoc.
Can I convert a GitHub README to PDF?
Yes. Open the README on GitHub, click Raw, copy everything, and paste it into Markdown to PDF. Images become [Image: …] placeholders, since the PDF is built from text and doesn't fetch anything from the web.
Can I add page breaks?
There's no page-break syntax. Pages break when they're full. If a section must start on a new page, convert the sections separately and join them with Merge PDF.
What happens to Mermaid diagrams?
A Mermaid diagram is a fenced code block, so it prints as its source code, exactly as written. Rendering it would need a diagram engine. If you need the drawing, export it as an image from the Mermaid Live Editor and add it to the PDF separately.
Are links clickable in the PDF?
The URL is printed next to the link text, like docs (https://example.com), so it survives on paper. It isn't a link annotation, though. Many PDF viewers will detect the URL and make it clickable anyway.
Is my Markdown uploaded anywhere?
No. The conversion runs in your browser tab, and the PDF is generated on your machine. You can load the page, disconnect from the network, and it still works.
The short version
If what you need is a PDF with the words and the code exactly right, you don't need a typesetting system. You need something that won't touch your code. That's a much smaller tool, and it's the one we built.
Convert your Markdown to PDF in your browser, with every line of code intact.
Rohman

