Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
lovstudio avatar

Md2pdf

  • 2 installs
  • 198 repo stars
  • Updated May 30, 2026
  • lovstudio/md2pdf

Converts Markdown into typeset PDF with reportlab, handling CJK/Latin text, code blocks, tables, cover pages, clickable TOC, bookmarks, and watermarks.

About

Turns Markdown into print-ready, professionally typeset PDFs with themes, handling CJK/Latin mixed text, fenced code, tables, TOC, and bookmarks. A user uses it to generate a report PDF from markdown, especially for Chinese technical reports.

  • Handles CJK/Latin text, code blocks, tables, and clickable TOC
  • Multiple color themes and PDF bookmarks/watermarks

Md2pdf by the numbers

  • 2 all-time installs (skills.sh)
  • Ranked #548 of 688 Office & Documents skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lovstudio/md2pdf --skill md2pdf

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs2
repo stars198
Last updatedMay 30, 2026
Repositorylovstudio/md2pdf

What it does

Converts Markdown into typeset PDF with reportlab, handling CJK/Latin text, code blocks, tables, cover pages, clickable TOC, bookmarks, and watermarks.

Files

SKILL.mdMarkdownGitHub ↗

md2pdf — Markdown to Professional PDF

This skill converts any Markdown file into a publication-quality PDF using Python's reportlab library. It was developed through extensive iteration on real Chinese technical reports and solves several hard problems that naive MD→PDF converters get wrong.

When to Use

  • User wants to convert .md.pdf
  • User has a markdown report/document and wants professional typesetting
  • Document contains CJK characters (Chinese/Japanese/Korean) mixed with Latin text
  • Document has fenced code blocks, markdown tables, or nested lists
  • User wants a cover page, table of contents, or watermark in their PDF

Quick Start

python md2pdf/scripts/md2pdf.py \
  --input report.md \
  --output report.pdf \
  --title "My Report" \
  --author "Author Name" \
  --theme warm-academic

All parameters except --input are optional — sensible defaults are applied.

Pre-Conversion Options (MANDATORY)

IMPORTANT: You MUST use the `AskUserQuestion` tool to ask these questions BEFORE running the conversion. Do NOT list options as plain text — use the tool so the user gets a proper interactive prompt. Ask all three in a SINGLE `AskUserQuestion` call.

Use AskUserQuestion with this exact format:

转 PDF 前需要确认几个选项:

1. 扉页图片(封面后的全页插图)
   a) 跳过
   b) 我提供本地图片路径
   c) AI 根据内容自动生成

2. 水印(每页淡色对角线文字)
   a) 不加水印
   b) 自定义水印文字(如 "DRAFT"、"内部资料"、"仅供学习")

3. 封底宣传物料(名片/二维码/品牌信息)
   a) 跳过
   b) 我提供图片(名片/二维码/logo 等)
   c) 纯文字(网站/公众号/版权声明等)

请回复你的选择,如 "1a 2b:仅供学习参考 3b:/path/to/qr.png"

Handling Responses

  • Frontispiece "AI generate": Read the document title + first paragraphs, use an

image generation tool to create a themed illustration, show for approval, then pass via --frontispiece /path/to/image.png

  • Frontispiece "local": Use path directly via --frontispiece <path>
  • Watermark: Pass via --watermark "文字内容"
  • Back cover image: Pass via --banner <path> (recommend 1200px+ wide)
  • Back cover text: Use --disclaimer "声明文字" and --copyright "© 版权信息"

Architecture

Markdown → Preprocess (split merged headings) → Parse (code-fence-aware) → Story (reportlab flowables) → PDF build

Key components: 1. Font system: Palatino (Latin body), Songti SC (CJK body), Menlo (code) on macOS; auto-fallback on Linux 2. CJK wrapper: _font_wrap() wraps CJK character runs in <font> tags for automatic font switching 3. Mixed text renderer: _draw_mixed() handles CJK/Latin mixed text on canvas (cover, headers, footers) 4. Code block handler: esc_code() preserves indentation and line breaks in reportlab Paragraphs 5. Smart table widths: Proportional column widths based on content length, with 18mm minimum 6. Bookmark system: ChapterMark flowable creates PDF sidebar bookmarks + named anchors 7. Heading preprocessor: _preprocess_md() splits merged headings like # Part## Chapter into separate lines

Hard-Won Lessons

CJK Characters Rendering as □

reportlab's Paragraph only uses the font in ParagraphStyle. If fontName="Mono" but text contains Chinese, they 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 leading spaces → &nbsp;, applied 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

ArgumentDefaultDescription
--input(required)Path to markdown file
--outputoutput.pdfOutput PDF path
--titleFrom first H1Document title for cover page
--subtitle""Subtitle text
--author""Author name
--dateTodayDate string
--version""Version string for cover
--watermark""Watermark text (empty = none)
--themewarm-academicColor theme name
--theme-file""Custom theme JSON file path
--covertrueGenerate cover page
--toctrueGenerate table of contents
--page-sizeA4Page size (A4 or Letter)
--frontispiece""Full-page image after cover
--banner""Back cover banner image
--header-title""Report title in page header
--footer-leftauthorBrand/author in footer
--stats-line""Stats on cover
--stats-line2""Second stats line
--edition-line""Edition line at cover bottom
--disclaimer""Back cover disclaimer
--copyright""Back cover copyright
--code-max-lines30Max lines per code block

Themes

Available: warm-academic, nord-frost, github-light, solarized-light, paper-classic, ocean-breeze.

Each theme defines: page background, ink color, accent color, faded text, border, code background, watermark tint.

Dependencies

pip install reportlab --break-system-packages

Related skills

Office & Documentsnotesworkflow

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.