any2pdf — Markdown to Professionally Typeset PDF
Convert Markdown to publication-quality PDF with reportlab — CJK/Latin mixed text, themes, cover pages, watermarks, callouts, formulas, and interactive theme selection
any2pdf — Markdown to Professionally Typeset PDF#
Credits. This skill is adapted from
lovstudio/any2pdfby lovstudio, distributed under the MIT license. The original repository ships the Python implementation (md2pdf.py), preview gallery, and reference theme JSONs. This document is the Mercury-compatibleSKILL.mdadaptation; the runtime code and design credit belong entirely to the original author.
- Upstream: https://github.com/lovstudio/any2pdf
- License: MIT (see upstream
LICENSE)- Author: lovstudio
- Curator (this entry): cosmicstack-labs
This skill converts any Markdown file into a publication-quality PDF using Python's reportlab. It was developed through extensive iteration on real Chinese technical reports and solves several hard problems that naive MD→PDF converters get wrong — CJK/Latin mixed text wrapping, canvas CJK rendering on cover/headers/footers, code-block whitespace preservation, and mixed-font fallbacks across macOS, Linux, and Windows.
When to Use#
Trigger this skill whenever the user:
- Wants to convert
.md→.pdf - Has a markdown report or document and wants professional typesetting
- Mentions "markdown to PDF", "md2pdf", "any2pdf", "md转pdf", "报告生成", or asks for a "typeset" or "professionally formatted" PDF from markdown source
- Has a document with CJK characters mixed with Latin text
- Has fenced code blocks, markdown tables, or nested lists that need to survive conversion
- Needs local/remote images, Obsidian callouts, emoji, or LaTeX-style math formulas
- Wants a cover page, table of contents, watermark, or back cover in their PDF
Where the Runtime Lives#
After installing this skill via the Mercury CLI:
mercury skills install pdf-generation/any2pdfthe SKILL.md lands at ~/.mercury/skills/pdf-generation/any2pdf/SKILL.md.
The Python implementation (md2pdf.py), preview images, and theme files are not vendored into Mercury Skills — they live in the upstream repository. To use the skill end-to-end, also clone or install the upstream runtime:
# Option A: clone alongside (recommended for development)
git clone https://github.com/lovstudio/any2pdf.git
# The script is at: any2pdf/lovstudio-any2pdf/scripts/md2pdf.py
# Option B: install via the upstream's own installer
npx skills add lovstudio/any2pdf -g -yWhen the AI agent runs the conversion, treat the script path as wherever the user cloned it. If unsure, ask:
"Where is the
md2pdf.pyscript on your system? (e.g../any2pdf/lovstudio-any2pdf/scripts/md2pdf.py)"
Quick Start#
python <path-to>/md2pdf.py \
--input report.md \
--output report.pdf \
--title "My Report" \
--author "Author Name" \
--theme warm-academicAll parameters except --input are optional — sensible defaults are applied.
Pre-Conversion Options (MANDATORY)#
IMPORTANT for AI agents: You MUST present these options to the user before running the conversion. Use whatever interactive question primitive your runtime provides (AskUserQuestion, a structured prompt, an MCP tool, etc.). Present all options in a single question so the user answers once.
The tone should be a friendly design assistant, not a config form.
Suggested Prompt Template (English)#
Starting PDF conversion — quick choices first
━━━ Design Style ━━━
a) Warm Academic — terracotta tones, refined and elegant; humanities / social science
b) Classic Thesis — brown tones, LaTeX classicthesis inspired; academic papers
c) Tufte — minimal whitespace, deep red accents; data narratives, technical writing
d) IEEE Journal — navy blue, journal-formal; conferences and journals
e) Elegant Book — coffee tones, book-like; long-form monographs / technical books
f) Chinese Red — vermilion on warm paper; Chinese formal reports / whitepapers
g) Ink Wash — pure grayscale, restrained and elegant; literary / design content
h) GitHub — blue-and-white minimal; developer-familiar
i) Nord Frost — Nordic blue-gray; clean modern
j) Ocean Breeze — teal-green; fresh and natural
━━━ Frontispiece (full-page image after cover) ━━━
1) Skip
2) I'll provide a local image path
3) AI generates one based on document content
━━━ Watermark ━━━
1) None
2) Custom text (e.g. "DRAFT", "Internal Use Only")
━━━ Back Cover Material (business card / QR code / brand) ━━━
1) Skip
2) I'll provide an image
3) Plain text only
Example reply: "a, frontispiece skip, watermark: For Reference Only, back cover: /path/qr.png"
Plain English is fine — no need to memorize the letters.Mapping User Choices to CLI Args#
| Choice | CLI argument |
|---|---|
| Design style a–j | --theme <value-from-table-below> |
| Frontispiece local | --frontispiece <path> |
| Frontispiece AI | Generate image first, then --frontispiece /tmp/frontispiece.png |
| Watermark text | --watermark "TEXT" |
| Back cover image | --banner <path> |
| Back cover text | --disclaimer "..." and/or --copyright "..." |
Theme Name Mapping#
| Choice | --theme value | Inspiration |
|---|---|---|
| a) Warm Academic | warm-academic | Lovstudio design system |
| b) Classic Thesis | classic-thesis | LaTeX classicthesis |
| c) Tufte | tufte | Edward Tufte's books |
| d) IEEE Journal | ieee-journal | IEEE journal format |
| e) Elegant Book | elegant-book | LaTeX ElegantBook |
| f) Chinese Red | chinese-red | Chinese formal documents |
| g) Ink Wash | ink-wash | 水墨画 / ink wash painting |
| h) GitHub | github-light | GitHub Markdown style |
| i) Nord Frost | nord-frost | Nord color scheme |
| j) Ocean Breeze | ocean-breeze | — |
Handling AI-Generated Frontispiece#
If the user chose AI generation: read the document title and the first few paragraphs, use an image-generation tool to create a themed illustration matching the chosen design style, show the result for approval, then pass via --frontispiece /path/to/image.png.
Architecture#
Markdown
→ Preprocess (split merged headings)
→ Parse (code-fence aware)
→ Story (reportlab flowables)
→ PDF buildKey components:
- Font system — Palatino (Latin body), Songti SC (CJK body), Menlo (code) on macOS; auto-fallback on Linux / Windows.
- CJK wrapper —
_font_wrap()wraps CJK character runs in<font>tags for automatic font switching. - Mixed text renderer —
_draw_mixed()handles CJK/Latin mixed text on canvas (cover, headers, footers). - Code block handler —
esc_code()preserves indentation and line breaks in reportlab Paragraphs. - Smart table widths — proportional column widths based on content length, with 18 mm minimum.
- Bookmark system —
ChapterMarkflowable creates PDF sidebar bookmarks and named anchors. - Heading preprocessor —
_preprocess_md()splits merged headings like# Part## Chapterinto separate lines. - Image handler — local, relative,
file://, and remote markdown images are scaled into the body frame with fallback text on errors. - Callout renderer — Obsidian-style
> [!NOTE]blocks render as themed boxed callouts. - Formula renderer — display formulas use optional
matplotlibmathtext images, with styled text fallback. - Emoji fallback — emojis render as cached Twemoji PNGs when available, or with a local emoji font fallback.
Hard-Won Lessons#
These are real bugs that came out of shipping real reports — preserve the fixes if you're customising the script.
CJK Characters Rendering as □#
reportlab's Paragraph only uses the font set in ParagraphStyle. If fontName="Mono" but the text contains Chinese, characters render as □. Fix: always apply _font_wrap() to all text that might contain CJK, including code blocks.
Code Blocks Losing Line Breaks#
reportlab treats \n as whitespace. Fix: esc_code() converts \n → <br/> and all spaces → , preserving indentation and mid-line alignment before _font_wrap().
CJK/Latin Word Wrapping#
Default reportlab breaks lines only at spaces, causing ugly splits like Claude\nCode. Fix: set wordWrap='CJK' on body / bullet styles to allow breaks at CJK character boundaries.
Canvas Text with CJK (Cover / Footer)#
drawString() / drawCentredString() with a Latin font can't render 年/月/日 etc. Fix: use _draw_mixed() for all user-content canvas text (dates, stats, disclaimers).
Configuration Reference#
Most options can also be set in the markdown file's YAML frontmatter. Explicit CLI arguments take precedence over frontmatter values.
| CLI Argument | Frontmatter Key | Default | Description |
|---|---|---|---|
--input | — | (required) | Path to markdown file |
--output | — | output.pdf | Output PDF path |
--title | title | From first H1 | Document title for cover page |
--subtitle | subtitle | "" | Subtitle text |
--author | author | "" | Author name |
--date | date | Today | Date string |
--version | version | "" | Version string for cover |
--watermark | watermark | "" | Watermark text (empty = none) |
--theme | theme | warm-academic | Color theme name |
--theme-file | — | "" | Custom theme JSON file path |
--cover | cover | true | Generate cover page |
--toc | toc | true | Generate table of contents |
--page-size | page-size | A4 | Page size (A4 or Letter) |
--frontispiece | frontispiece | "" | Full-page image after cover |
--banner | banner | "" | Back cover banner image |
--header-title | header-title | "" | Report title in page header |
--footer-left | footer-left | author | Brand / author in footer |
--stats-line | stats-line | "" | Stats on cover |
--stats-line2 | stats-line2 | "" | Second stats line |
--edition-line | edition-line | "" | Edition line at cover bottom |
--disclaimer | disclaimer | "" | Back cover disclaimer |
--copyright | copyright | "" | Back cover copyright |
--code-max-lines | code-max-lines | 30 | Max lines per code block |
Themes#
Built-in: warm-academic, classic-thesis, tufte, ieee-journal, elegant-book, chinese-red, ink-wash, github-light, nord-frost, ocean-breeze.
Each theme defines: page background, ink color, accent color, faded text color, border color, code background, and watermark tint. Preview images for every theme live in the upstream repository under previews/.
Dependencies#
pip install reportlab
# Optional — render display formulas as images instead of styled text:
pip install matplotlibFonts#
-
macOS: Palatino, Songti SC (宋体), Menlo — pre-installed.
-
Windows: Times New Roman, SimSun / 微软雅黑, Consolas — pre-installed.
-
Linux (Ubuntu/Debian recommended setup):
sudo apt install fonts-dejavu-core fonts-liberation fonts-freefont-ttf \ fonts-noto fonts-noto-cjk fonts-noto-color-emoji
Fonts are auto-discovered from system paths. Missing fonts produce a helpful error with the exact install command for your OS.
What You Get#
- Cover page — title, subtitle, author, version, stats lines
- Clickable table of contents — with PDF bookmark sidebar
- Frontispiece — full-page image after cover (local or AI-generated)
- Running headers — stable report / document title without page-lagged chapter labels
- Running footers — author / brand, page number, date
- Watermark — faint diagonal text on every content page
- Back cover — banner image or text branding (QR codes, business cards)
- 10 design themes — from warm academic to ink wash minimalist
- Markdown images — local and remote
with graceful fallback text - Obsidian callouts —
> [!NOTE], warnings, tips, quotes, and related callout types - LaTeX-style formulas — inline
$...$and display$$...$$/\[...\]; installmatplotlibfor rendered math images - Emoji fallback — Twemoji image rendering when online, with local emoji-font fallback when available
- YAML frontmatter — set title, theme, watermark, cover, TOC, and other options inside the Markdown file
License & Attribution#
This skill entry is a derivative work licensed under MIT, matching the upstream project.
- Original work: lovstudio/any2pdf — Copyright (c) lovstudio
- License: MIT
- This SKILL.md adaptation: curated for Mercury Skills by cosmicstack-labs; no code is redistributed, only documentation and workflow guidance.
If you ship this skill in a product, retain the upstream attribution and the MIT license notice from the original repository.
More in PDF Generation
View all →Markdown to PDF Conversion
Converting Markdown to professional PDFs using Pandoc, WeasyPrint, ReportLab, and related tools
LaTeX Typesetting
Professional document preparation with LaTeX for academic papers, resumes, books, presentations, and formal documents
Invoice & Document PDF Generation
Generating invoices, contracts, forms, receipts, and business documents as professional PDFs