| name | markdown-to-pdf |
| description | Convert Markdown documents to PDF. Two modes available — (1) Playwright-based conversion with Mermaid diagram support for technical documentation, and (2) fpdf2-based professional PDF generation with cover pages, themed styling, and business-quality table formatting for estimates, proposals, and reports. Use this skill when converting Markdown to PDF, generating business documents from Markdown, or converting Mermaid diagrams to images. Triggers on short phrases like "PDFに変換して", "markdownをpdfにして", "PDFにして", "PDF化して", "PDF出力して", "convert to PDF", "make a PDF", or any request involving converting content to PDF format. |
Markdown to PDF Converter
Overview
Convert Markdown documents into PDF with two rendering engines:
- Playwright mode (
markdown_to_pdf.py) — HTML/CSS-based rendering with Mermaid diagram support. Best for technical documentation with custom CSS styling.
- fpdf2 mode (
markdown_to_fpdf.py) — Professional PDF generation with cover pages, themed headers/footers, styled tables, and CJK font support. Best for business documents (estimates, proposals, reports).
When to Use This Skill
Use this skill when:
- Converting Markdown files to PDF
- Creating professional business documents (estimates, proposals, cost analyses)
- Converting technical documentation with Mermaid diagrams to PDF
- Extracting Mermaid diagrams as standalone images (PNG or SVG)
Decision Matrix — Which mode to use:
| Need | Mode | Script |
|---|
| Cover page, professional styling | fpdf2 | markdown_to_fpdf.py |
| Business documents (estimates, reports) | fpdf2 | markdown_to_fpdf.py |
| Themed headers/footers | fpdf2 | markdown_to_fpdf.py |
| Styled tables (alternating rows, header colors) | fpdf2 | markdown_to_fpdf.py |
| Technical docs with custom CSS | Playwright | markdown_to_pdf.py |
| Mermaid diagrams as primary content | Playwright | markdown_to_pdf.py |
| General Markdown to PDF | Either | Choose by needs |
Typical user requests:
- "Convert this Markdown file to PDF" → Choose based on content
- "Create a professional PDF from this estimate" → fpdf2 mode
- "Generate a PDF report with cover page" → fpdf2 mode
- "Convert this design document with diagrams to PDF" → Playwright mode
- "Export this Mermaid diagram as an image" → mermaid_to_image.py
Prerequisites
For fpdf2 mode (professional PDFs):
pip install fpdf2 mistune pyyaml
For Playwright mode (Mermaid + CSS):
pip install markdown2 playwright
playwright install chromium
npm install -g @mermaid-js/mermaid-cli
Optional (for layout verification):
pip install PyMuPDF
Output
| Mode | Output | Description |
|---|
| fpdf2 | .pdf | Professional PDF with optional cover page, themed styling, headers/footers |
| Playwright | .pdf | HTML/CSS-rendered PDF with embedded Mermaid diagrams |
| mermaid_to_image | .png or .svg | Standalone Mermaid diagram image |
Default paper size: US Letter (8.5 × 11 in / 215.9 × 279.4 mm), portrait orientation. Use --paper-size a4 or set paper_size: a4 in YAML frontmatter for A4 (210 × 297 mm).
fpdf2 mode produces:
- Letter portrait PDF (default) or A4 portrait PDF (
--paper-size a4)
- Optional cover page with title, subtitle, metadata
- Themed headers and footers on content pages
- Styled tables (data tables with colored headers, info tables for key-value pairs)
- Embedded Mermaid diagrams (converted to PNG)
Playwright mode produces:
- Letter portrait PDF (default) or A4 portrait PDF (
--paper-size a4)
- Mermaid diagrams rendered inline (PNG or SVG)
- Custom CSS styling support
Task 1: Convert Markdown with Mermaid to PDF (Playwright mode)
Workflow
- Read the Markdown file and identify Mermaid code blocks
- Execute the conversion script:
python scripts/markdown_to_pdf.py <input.md> <output.pdf>
- Verify the output
- Deliver the PDF
Configuration Options
Theme options: --theme default|forest|dark|neutral
Image format: --image-format png|svg (SVG recommended)
Background color: --background white|transparent|"#f0f0f0"
Paper size: --paper-size letter|a4 (default: letter)
Custom styling: --css styles.css
Mermaid control: --no-strict-mermaid (allow fallback), --debug-mermaid (verbose output)
Debugging: --keep-temp
Task 2: Convert Mermaid Diagrams to Images
Workflow
- Identify the Mermaid diagram source
- Execute the conversion:
python scripts/mermaid_to_image.py <input.mmd> <output.png>
python scripts/mermaid_to_image.py --code "graph TD; A-->B" output.png
- Verify and deliver
Configuration
--format png|svg
--theme default|forest|dark|neutral
--width <pixels> / --height <pixels> (PNG only)
--background white|transparent|<color>
--use-playwright — Force Playwright backend
--debug — Print detailed debug output
Task 3: Convert Markdown to Professional PDF (fpdf2 mode)
Workflow
- Read the Markdown file — Check for YAML frontmatter
- Add frontmatter if not present (for cover page, theme, metadata)
- Execute the conversion:
python scripts/markdown_to_fpdf.py input.md output.pdf
python scripts/markdown_to_fpdf.py input.md output.pdf --theme navy
python scripts/markdown_to_fpdf.py input.md output.pdf --theme gray --confidential
python scripts/markdown_to_fpdf.py input.md output.pdf --no-cover
- Verify the output
- Deliver the PDF
YAML Frontmatter
Add frontmatter at the top of the Markdown file to control cover page, theme, and metadata:
---
title: 御見積書
subtitle: AI プラットフォーム PoC サポート
theme: navy
paper_size: letter
document_number: FSAI-2026-0001
date: 2026年2月17日
author: 山田 太郎
company: FujiSoft America, Inc.
recipient: Client Inc.
confidential: false
cover: true
header_text: "FSAI-2026-0001 | FujiSoft America, Inc."
---
For detailed field reference, see references/fpdf_styling_guide.md.
Markdown Features Supported
| Markdown | Rendered As |
|---|
# H1 | Section title (bold, underlined, theme color) |
## H2 | Subsection title (bold, theme color) |
### H3 | Sub-subsection title |
**bold** / *italic* | Inline formatting via multi_cell(markdown=True) |
- item | Bulleted list |
| table | | Styled table (data_table by default) |
```code``` | Code block (gray background) |
```mermaid``` | Mermaid → PNG image (strict: fail on error, --no-strict-mermaid: fallback to code block) |
> quote | Block quote (left accent bar, light fill, italic text) |
<!-- pagebreak --> | Page break |
--- | Horizontal rule |
<!-- info-table --> | Override next table to info_table style |
<!-- col-widths: 10,45,45 --> | Override next table's column widths (ratios, %, or mm) |
Table Styles
Data Table (default): Multi-column table with colored header row and alternating row colors.
Info Table: Use <!-- info-table --> comment before a table for key-value style rendering:
<!-- info-table -->
| Key | Value |
|-----|-------|
| Phase 1 | $5,000 |
| Phase 2 | TBD |
Column Widths Override: Use <!-- col-widths: ... --> comment to control the next table's column widths. Accepts bare numbers (ratios), percentages, or mm units; values are normalized to the page content width. Applies to both data and info tables, and resets after the next table.
<!-- col-widths: 10,45,45 -->
| # | 項目 | 金額 |
|---|------|------|
| 1 | 初期費用 | $5,000 |
| 2 | 月額費用 | $1,200 |
If the number of values differs from the column count, extra values are truncated and missing values are padded with the average of the provided ones.
Themes
navy — Client-facing documents (deep navy primary, blue-gray accents)
gray — Internal documents (dark gray primary, light gray accents)
CLI Options
python scripts/markdown_to_fpdf.py input.md output.pdf [options]
| Option | Description |
|---|
--theme navy|gray | Color theme (default: from frontmatter or navy) |
--paper-size letter|a4 | Paper size (default: letter; also honors paper_size in YAML frontmatter) |
--confidential | Mark as confidential |
--no-cover | Suppress cover page |
--font-regular PATH | Custom regular font |
--font-bold PATH | Custom bold font |
--no-strict-mermaid | Allow Mermaid fallback to code block on failure (default: strict) |
--debug-mermaid | Print detailed Mermaid conversion debug output |
--verify | Verify PDF layout after generation (detect overflow/clipping via PyMuPDF) |
--verify-save-images | Save page images to /tmp during verification (for debugging) |
Font Requirements
Fonts are auto-discovered per platform with TrueType outline preference (best fpdf2 compatibility):
- macOS: UDEVGothic or Noto Sans JP (TTF) — install to
~/Library/Fonts/
- Hiragino Kaku Gothic (CFF outlines) is used as fallback but may cause garbled CJK text
- Recommended:
brew install --cask font-udev-gothic or download Noto Sans JP TTF
- Windows: Yu Gothic Regular/Bold (usually TrueType, pre-installed)
- Linux: Noto Sans CJK (
sudo apt install fonts-noto-cjk)
Manual override: --font-regular /path/to/font.ttc --font-bold /path/to/bold.ttc
CFF compatibility note: Fonts with CFF outlines (e.g., Hiragino Sans on macOS) may produce garbled CJK text in fpdf2-generated PDFs. The tool warns on stderr when CFF fonts are detected. Install a TrueType CJK font to resolve.
Layout Overflow Protection (fpdf2 mode)
The fpdf2 renderer includes automatic protection against content overflow:
- Cover page title: Auto-shrinks font (28pt → 16pt min) to fit page width. Falls back to
multi_cell wrapping if still too long.
- Section headings (H1/H2/H3): Auto-shrinks font to fit in a single line (no awkward mid-word line breaks). H1: 14pt → 9pt, H2: 11pt → 8pt, H3: 10pt → 7pt.
- Embedded images (Mermaid diagrams): Auto-scales to fit within page height. Adds page break if insufficient space remains on current page.
Post-Generation Layout Verification
Use --verify to automatically check all content pages for overflow after PDF generation. Requires PyMuPDF (pip install PyMuPDF).
python scripts/markdown_to_fpdf.py input.md output.pdf --verify
The verifier renders each page as an image and checks edge margins (15px) for non-background content. Cover pages (page 1) are skipped since they have intentional edge-to-edge design bars.
Standalone verification:
python scripts/verify_pdf_layout.py output.pdf [--margin 15] [--threshold 50] [--save-images]
IMPORTANT: Always use --verify when generating PDFs to catch overflow issues before delivery.
Resources
scripts/markdown_to_fpdf.py
Professional PDF generation from Markdown with fpdf2. Supports YAML frontmatter, cover pages, themed styling, data/info tables, and CJK fonts.
scripts/markdown_to_pdf.py
HTML/CSS-based Markdown to PDF with Mermaid diagram support via Playwright.
scripts/mermaid_renderer.py
Unified Mermaid rendering engine with mmdc/Playwright backends, SHA256 caching, error categorization, and strict/permissive mode support.
scripts/mermaid_to_image.py
CLI wrapper for mermaid_renderer.py. Converts Mermaid diagram code to PNG/SVG images.
scripts/themes.py
Theme definitions (navy, gray) and cross-platform CJK font discovery.
references/mermaid_guide.md
Comprehensive Mermaid diagram syntax reference.
references/fpdf_styling_guide.md
fpdf2 professional PDF styling guide — frontmatter fields, theme options, table modes, font requirements.
assets/sample_frontmatter.yaml
Sample YAML frontmatter templates for estimates, internal documents, and simple reports.
Important: CJK Font Rendering Issues
Key fact: CFF-outline fonts can produce PDFs where text extraction is correct but visual rendering is garbled. Do NOT rely on text extraction alone to judge PDF correctness.
Diagnosis Flow
- Check stderr for
Warning: Using CFF-outline font or Warning: CFF outlines detected.
- If CFF warning is present → the PDF likely has garbled CJK rendering, even if text extraction looks correct. This is a real compatibility issue between CFF outlines and fpdf2.
- Fix: Install a TrueType CJK font (with
glyf table):
- macOS: UDEVGothic (
brew install --cask font-udev-gothic) or Noto Sans JP TTF
- Linux:
sudo apt install fonts-noto-cjk (if CFF variant, use Noto Sans JP TTF instead)
- Windows: Yu Gothic is usually TrueType (pre-installed)
- Re-run PDF generation after installing. Confirm no CFF warning appears.
- If no CFF warning was emitted → the font is TrueType and CJK rendering is correct in the actual PDF.
- Claude Code's Read tool preview may still show garbled glyphs — this is a preview rendering limitation only, not a PDF defect.
- Do NOT switch to Playwright mode as a workaround.
- The
fsSelection bit 5 (bold) warning is cosmetic and does not affect output.
- Only investigate further if the user reports rendering problems in a standard PDF viewer (Preview.app, Adobe Acrobat, Chrome).
Markdown Limitations for fpdf2 Mode
Tables inside list items are NOT supported. The mistune parser cannot recognize Markdown tables that are indented inside list items (- item followed by indented | table |). Tables must be placed at the top level (no leading spaces/indentation) to be parsed and rendered correctly.
<br> tags are NOT rendered as line breaks. fpdf2 mode does not interpret HTML <br> tags. They will appear as literal text in the PDF output. Convert <br>-separated fields to <!-- info-table --> tables or separate lines before conversion.
Before conversion, check for and fix:
<br> tags used for line breaks → Replace with <!-- info-table --> table format or separate paragraphs
- Tables indented under
- list items → Move to top level
- Tables indented under
> blockquotes → Move to top level
After conversion, verify:
- No literal
<br> text visible in the generated PDF
Troubleshooting
fpdf2 mode: Font not found
If automatic font discovery fails, specify fonts manually:
python scripts/markdown_to_fpdf.py input.md output.pdf \
--font-regular /path/to/regular.ttc \
--font-bold /path/to/bold.ttc
Mermaid conversion fails (strict mode)
By default, Mermaid conversion failures halt PDF generation. Error messages include diagnostic information and fix suggestions.
Common errors and fixes:
| Error Category | Fix |
|---|
mmdc_not_found | npm install -g @mermaid-js/mermaid-cli |
browser_launch_failed | pip install playwright && playwright install chromium |
syntax_error | Check syntax at mermaid.live |
timeout | Simplify diagram or increase --timeout |
To allow graceful fallback (renders code block instead of failing):
python scripts/markdown_to_fpdf.py input.md output.pdf --no-strict-mermaid
Playwright mode: Mermaid diagrams not rendering
Install mermaid-cli: npm install -g @mermaid-js/mermaid-cli
Or install Playwright: pip install playwright && playwright install chromium
Note: The Playwright Mermaid backend requires CDN access (cdn.jsdelivr.net) to load the Mermaid library.
Playwright mode: Poor image quality
Use SVG format: --image-format svg (recommended)
Tips
- Business documents → Use fpdf2 mode with frontmatter for professional output
- Technical docs with diagrams → Use Playwright mode with SVG format
- Use
<!-- pagebreak --> for clean section transitions in fpdf2 mode
- Use
<!-- info-table --> for key-value tables in fpdf2 mode
- Preview Mermaid at mermaid.live before conversion
- Mermaid Gantt chart font sizes → fpdf2 mode renders Mermaid at 1200px width then scales to the page content width (Letter ≈ 195.9 mm, A4 = 190 mm). To ensure readability, use
fontSize: 16 or larger in the %%{init: ...}%% block. Recommended settings for Gantt charts:
'gantt': { 'fontSize': 18, 'sectionFontSize': 20, 'barHeight': 30, 'leftPadding': 180 }