Convert Markdown to PDF from the command line with Pandoc
When you need to convert Markdown to PDF repeatedly — as part of a build, across dozens of files, or with a house style — the command line beats any point-and-click tool. The standard for this is Pandoc, a free document converter that reads Markdown and writes almost anything, PDF included. This guide gets you from zero to a good-looking PDF, then covers the options that matter.
Installing Pandoc and a PDF engine
Pandoc itself doesn't draw PDFs — it hands off to a “PDF engine,” and the usual one is a LaTeX distribution. You need both.
# macOS
brew install pandoc
brew install --cask basictex
# Windows
winget install pandoc
# then install MiKTeX from miktex.org
# Debian / Ubuntu
sudo apt install pandoc texlive-xetex
basictex / texlive-xetex are smaller than a full LaTeX install and include xelatex, the engine you'll want because it handles system fonts and Unicode (including CJK) properly.
The simplest conversion
pandoc notes.md -o notes.pdf
That's the whole command: read notes.md, write notes.pdf. Pandoc infers the formats from the file extensions. If it complains that it can't find a PDF engine, install the LaTeX piece above.
Pick the xelatex engine
For anything beyond plain English text, add --pdf-engine=xelatex. It's more robust with fonts and Unicode than the default:
pandoc notes.md -o notes.pdf --pdf-engine=xelatex
Fonts (and CJK)
Set the main font with -V mainfont. This is also the fix for Chinese, Japanese or Korean text turning into empty boxes — you just need a font that actually contains those glyphs:
pandoc notes.md -o notes.pdf \
--pdf-engine=xelatex \
-V mainfont="PingFang SC" # macOS
# -V mainfont="Microsoft YaHei" # Windows
# -V mainfont="Noto Sans CJK SC" # if you installed Noto
You can set a separate monospace font for code blocks with -V monofont="...".
Margins and page size
pandoc notes.md -o notes.pdf --pdf-engine=xelatex \
-V geometry:margin=1in \
-V papersize=a4
Use papersize=letter for US Letter. geometry:margin=1in sets even one-inch margins; you can also set them per side, e.g. -V geometry:"top=2cm,bottom=2cm,left=2.5cm,right=2.5cm".
Add a table of contents
For a long document, --toc builds a clickable contents page from your headings:
pandoc report.md -o report.pdf --pdf-engine=xelatex --toc --toc-depth=2
Syntax highlighting for code
Pandoc highlights fenced code blocks automatically; choose a theme with --highlight-style:
pandoc notes.md -o notes.pdf --pdf-engine=xelatex --highlight-style=tango
Built-in styles include tango, pygments, kate, zenburn and breezedark.
A reusable “house style”
Typing all those flags every time is tedious. Put them in a defaults file (defaults.yaml):
pdf-engine: xelatex
toc: true
variables:
mainfont: "PingFang SC"
geometry: "margin=1in"
papersize: a4
Then every conversion is short and consistent:
pandoc notes.md -o notes.pdf -d defaults.yaml
Converting many files at once
Because it's the command line, you can loop. To turn every .md file in a folder into a matching PDF:
for f in *.md; do
pandoc "$f" -o "${f%.md}.pdf" -d defaults.yaml
done
When not to use Pandoc
Pandoc is the right tool for automation and control, but it's a lot of setup for a single document — you have to install LaTeX, remember flags, and debug font issues. If you just need one clean PDF now, a browser converter does it in seconds with none of that, and it uses your system fonts so CJK works out of the box. Use the right tool for the job: Pandoc for pipelines, the browser for one-offs.