Convert markdown paper (with LaTeX math, tables, figures) to publication-quality PDF via Mermaid + MathJax + Puppeteer pipeline.
41:T1122,
Convert a markdown document with LaTeX formulas, tables, and images to a publication-quality PDF.
convert-md-to-pdf/
skill.md # This file
scripts/
build-pdf.ps1 # PowerShell orchestrator (Windows)
build-pdf.sh # Bash orchestrator (Linux/macOS)
md-to-pdf.config.js # All-in-one config: MathJax injection, math protection, CSS, PDF options
Runtime:
Global npm packages (install once):
npm install -g md-to-pdf @mermaid-js/mermaid-cli
| Package | What it does |
|---|---|
md-to-pdf | Markdown -> PDF via Puppeteer (headless Chrome). Handles HTML/CSS, script injection, PDF printing |
@mermaid-js/mermaid-cli | Provides mmdc command. Renders mermaid code blocks to SVG images |
MathJax 3 is loaded from CDN at generation time (requires internet).
Two arguments:
Verify Node.js, mmdc, and md-to-pdf are installed:
node --version && mmdc --version && md-to-pdf --version
If any are missing, instruct the user to install them.
Windows (PowerShell):
powershell <skill-dir>/scripts/build-pdf.ps1 <input.md> <output.pdf>
Linux/macOS (Bash):
bash <skill-dir>/scripts/build-pdf.sh <input.md> <output.pdf>
Replace <skill-dir> with the path to this skill directory in your project.
Check the output PDF exists and report file size.
Step 1: Mermaid -> SVG (mmdc)
```mermaid code blocks.svg file using headless Chrome in the outputStep 2: Markdown + MathJax -> PDF (md-to-pdf with md-to-pdf.config.js)
Three things happen internally:
Markdown -> HTML (via marked parser)
marked treats _ as emphasis, breaking LaTeX subscripts in $$...$$ blocksmd-to-pdf.config.js adds a marked_extensions tokenizer that intercepts $$...$$ blocks before marked's default processing — no underscore manglingInject scripts + styles into the HTML
<script>) + CDN (<script src="...">)HTML -> PDF (via Puppeteer / headless Chrome)
$$...$$ and $...$ as mathnetworkidle0 (MathJax CDN loaded and rendered)printBackground: true)Why Mermaid first: if MathJax ran first, $ signs inside Mermaid labels would be interpreted as math.
| Problem | Root cause | Solution |
|---|---|---|
LaTeX _ subscripts broken | marked treats _ as emphasis | marked_extensions tokenizer intercepts $$ blocks as raw HTML passthrough |
| Math formulas not rendered | md-to-pdf doesn't know about LaTeX | script injects MathJax 3 config + CDN; Puppeteer executes it before printing |
| Tables/images unstyled | md-to-pdf default CSS is minimal | css adds borders, headers, striped rows, centered images, blockquotes |
If your paper references PDF figures, PNG may work better for md-to-pdf (HTML rendering). Generate PNG versions and ensure image paths in the markdown resolve correctly relative to the input file's directory.
mmdc not found: npm install -g @mermaid-js/mermaid-climd-to-pdf not found: npm install -g md-to-pdfdata-mathjax-done attribute in the intermediate HTML.md-to-pdf resolves images relative to the input markdown file's directory.PYTHONIOENCODING=utf-8 or pipe through chcp 65001.