Convert Markdown to PDF Without Pandoc or LaTeX
Markdown to PDF needs no Pandoc or LaTeX: upload a .md file, get A4 pages. Tables and task lists print; footnotes, math and Mermaid do not.
Upload a .md file to Markdown to PDF and download an A4 PDF. Nothing is installed on your side, and the service uses neither Pandoc nor LaTeX: it reads the CommonMark, turns it into HTML and prints that with WeasyPrint. In a test, a note with a table, struck-out text and a task list came back as one page with all three drawn. A footnote, an emoji shortcode, a formula and a Mermaid diagram came back as the plain text you typed.
How do I convert Markdown to PDF without Pandoc or LaTeX?
On the website, choose the .md file and press Process. The page has no fields for paper size, theme or fonts. From a script, send the file to the endpoint as fileInput:
curl -X POST https://pdf123.xyz/api/v1/convert/markdown/pdf \
-F [email protected] \
-o notes.pdf
With the pdfx command line (installed with npm install -g @pdf123/cli):
pdfx markdown-to-pdf notes.md -o notes.pdf
Both commands were run on 2026-10-23 against a local copy of the server, with the origin swapped for https://pdf123.xyz in the first one. The curl call returned HTTP 200 with content-type: application/pdf. pdfx printed notes.pdf and exited 0. pdfinfo reported 1 page of 595.276 x 841.89 points, which is A4, and a Producer field of WeasyPrint 70.0. The result is named after the upload: notes.md gives notes.pdf.
What renders, and what stays as typed
The test file held a heading, bold and italic text, a table, strikethrough, a task list, a fenced code block, a footnote, an emoji shortcode, a formula, a Mermaid block and a <script> line. I checked the result by extracting its text with pdftotext and looking at a rendering of the page.
| In the Markdown | In the PDF |
|---|---|
| Heading, bold, italic, inline code | Rendered |
| Table | Rendered with cell borders, a grey header row and right-aligned numbers where the column was marked that way |
~~strikethrough~~ |
Rendered as struck-out text |
- [x] and - [ ] task list |
Rendered, with a filled box for done and an empty box for open |
| Fenced code block | Rendered in a grey box, with no syntax colours |
Footnote ([^1] and its definition) |
Not converted: [^1] stayed in the sentence and the definition printed as a line of text |
Emoji shortcode (:smile:) |
Not converted: printed as :smile: |
Formula ($E = mc^2$) |
Not typeset: printed as typed |
A fenced block labelled mermaid |
Not drawn: printed as a code block holding the source |
<script> tag |
Not run, and its text did not appear in the page |
Tables, strikethrough and task lists are extensions that the GitHub Flavored Markdown specification lists on top of CommonMark (sections "Tables (extension)", "Strikethrough (extension)" and "Task list items (extension)"). The converter turns on those three. The CommonMark specification is the base it parses. Anything else a particular Markdown tool adds is not converted.
A long table keeps its header. A 90-row table with a two-column header printed as 4 pages, and pdftotext found the header row at the top of pages 2 and 3 as well. For the reverse direction and what survives a round trip, see Markdown to PDF and Back: What the Conversion Preserves.
What are the page size, margins and fonts?
The page is A4 with a 2 cm page margin, and the body text is 11 pt with a line height of 1.6 in near-black (#111). These values are fixed. Measuring the rendered test page at 144 dpi, the leftmost ink sat 62.5 pt from the left edge and the rightmost 63.5 pt from the right edge. That is about 6 pt more than 2 cm (56.7 pt), which is the size of the default 8 px body margin; the built-in stylesheet does not reset it.
The font list starts with Noto Sans CJK and the other CJK, Arabic, Thai and Devanagari families, then Noto Sans and DejaVu Sans. The PDF embeds whichever of them the server has. On my test machine, pdffonts listed Hiragino Sans, so the font on pdf123.xyz can differ from what I saw. The converter also looks at your text and sets the document language to English, Simplified or Traditional Chinese, Japanese, Korean, Arabic, Thai or Hindi, and lays Arabic out right to left. A test note written in Simplified Chinese, with English words and a number in the same sentence, came back as one page whose extracted text matched the input. If you write in a script the server has no font for, check the output for empty boxes.
If you need another paper size, margins or fonts, there is no setting for it here. Convert the Markdown to HTML yourself, add your own CSS, and use HTML to PDF, which prints the page size and margins your CSS asks for.
How do images work?
A plain .md upload carries only the text, so a local path such as images/logo.png has nothing to load. In the test,  printed the alt text local and no image. A public http or https address does load: an image from a public site was embedded as a 72 x 48 pixel image. An address on a private or internal network is blocked. The call still returned 200, with the alt text and no image, so check the page when an image matters.
To use local images, send a ZIP to the API. The ZIP renders one Markdown file: index.md at the archive root if there is one, otherwise the first .md the converter finds while walking the folders. If several .md files could match, name the one you want index.md. Image paths resolve from the archive root, not from the folder the .md file sits in:
curl -X POST https://pdf123.xyz/api/v1/convert/markdown/pdf \
-F [email protected] \
-o a.pdf
In the first test, a.zip held index.md and images/logo.png, and index.md pointed at images/logo.png. The result was one A4 page with one embedded 300 x 120 image. In the second, b.zip held docs/guide.md and docs/logo.png. The reference logo.png (relative to the file) printed only its alt text, and the reference docs/logo.png (relative to the archive root) embedded the image. The tool page and pdfx accept .md only; pdfx markdown-to-pdf a.zip -o a.pdf stopped with accepts .md files, but "a.zip" is .zip and exit code 2. A ZIP needs a direct API call such as the one above.
Three inputs are refused with HTTP 400 and reason set to unsupported_file_type: a name that is neither .md nor .zip (The file must be Markdown (.md) or a ZIP archive.), a .md that is not UTF-8 text (The Markdown file is not valid UTF-8 text.), and a ZIP with no .md inside (The ZIP archive must contain a .md file.). The body is the same application/problem+json shape as in every other call; see Error codes.
Questions people ask
Can I change the page size or margins?
Not on this tool. A4 with 2 cm margins is built in. Use HTML to PDF with your own @page rule to get another size.
Are footnotes, formulas and Mermaid diagrams supported?
No. In the test, the footnote marker, the emoji shortcode and the formula printed as typed, and the Mermaid block printed as a code block. Draw the diagram or render the formula first and add it as an image in a ZIP.
Does it run JavaScript in the HTML I put in Markdown?
No. A <script> line in the test file did not run and added nothing to the page. WeasyPrint prints HTML and CSS and has no JavaScript engine.
Why did my .md upload return 400?
The three causes are in the section on images above: the name, a file that is not UTF-8, or a ZIP with no .md inside. Re-save the file as UTF-8 and check the extension.