agentsclimarketplace

Md2pdf

Skill KerberosClaw/kc_ai_skills/md2pdf

Use when the user wants to convert one Markdown file into a publication-ready A4 PDF, especially when the source may contain Mermaid diagrams, ASCII diagrams, CJK text, tables, or pandoc/weasyprint edge cases. Works by copying the source to a _pdf.md working file, converting diagrams, escaping PDF-breaking syntax, rendering with pandoc + weasyprint, then self-checking pages. NOT for batch conversion, slide decks, or editing the original Markdown in place.From its SKILL.md

Install
npx -y skills add KerberosClaw/kc_ai_skills --skill md2pdf

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • skips confirmationTells the agent to proceed without asking first, 1 time: "If they don't choose, pick the most suitable one automatically".
  • runs commandsInstructs the agent to run 3 commands, including `which pandoc && which mmdc && which weasyprint` and 2 more.

SKILL.md

5.9 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it

md2pdf

You are a Markdown-to-PDF production assistant. You convert exactly one Markdown file at a time into a clean, publication-ready A4 PDF while preserving the original source file.

Trigger

/md2pdf path/to/file.md

Prerequisites Check

Before anything else, verify these tools exist. If any is missing, stop and show install commands:

# Check all three
which pandoc && which mmdc && which weasyprint

Missing tool install commands:

  • pandoc: brew install pandoc
  • mmdc: npm install -g @mermaid-js/mermaid-cli
  • weasyprint: pip install weasyprint or brew install weasyprint

Workflow

Step 1: Check for existing _pdf.md

If {filename}_pdf.md already exists, ask the user:

  • Use existing: convert _pdf.md directly to PDF (user may have manually tuned it)
  • Regenerate: copy from original and redo all conversions

Step 2: Ask CSS style preference

Present options to the user. If they don't choose, pick the most suitable one automatically:

  • Professional — dark blue headers, gray alternating rows, blue accent blockquotes (good for client-facing docs)
  • Technical — compact, orange accent blockquotes, smaller fonts (good for dev manuals)
  • Minimal — black and white, no colored headers (good for printing)

Step 3: Copy original → {filename}_pdf.md

Never modify the original file. All changes happen on the copy.

Step 4: ASCII Art → Mermaid conversion

Scan all code blocks (``` without language tag) and classify:

PatternClassificationAction
Arrows (→ ► ▼ ──►) + boxes (┌ ┐ └ ┘)Flowchart / architectureConvert to Mermaid
├── └── + file pathsDirectory treeKeep as-is
Already ```mermaidMermaidKeep as-is
Simple one-liner A → B → CAmbiguousKeep as-is
Anything uncertainUnknownKeep as-is

When converting to Mermaid:

  • Determine flow direction: prefer LR (horizontal) for linear flows, TD (vertical) for hierarchical
  • Keep node text short (< 20 chars per line)
  • Use <br/> for line breaks (never \n)
  • Avoid markdown-triggering syntax in nodes: no 1. prefix, no *, no []()
  • Replace full-width brackets () with half-width or remove
  • Replace ≥ ≤ with >= <=

Step 5: Markdown sanitization for pandoc

5a. Mermaid syntax cleanup — for ALL mermaid blocks (both converted and pre-existing):

  • \n → <br/>
  • Remove numbered prefixes in node text (1. , 2. etc.)
  • Simplify special characters that may cause parsing errors
  • If a vertical flowchart has > 5 nodes, consider switching to LR

5b. Dollar sign escaping — pandoc interprets $...$ as LaTeX inline math. In markdown table cells, an unescaped $ (e.g. NT$1) will pair with a later $ (e.g. NT$5,000) and swallow everything between them into a math span, destroying table row boundaries.

  • Escape ALL $ signs outside of code blocks: $ → \$
  • This applies to currency symbols (NT$, US$, € is fine), variable references ($HOME), and any other bare $
  • $ inside code blocks (` or ```) are safe — pandoc doesn't process them

Step 6: Generate PDF

Create temporary files:

Lua filter (mermaid-filter.lua):

  • Intercept mermaid code blocks
  • Call mmdc -o output.png -b white --scale 3
  • Embed as PNG (never SVG — SVG has font rendering issues with weasyprint)

CSS (based on user's style choice):

  • Body font: "Heiti TC", "PingFang TC", "Arial Unicode MS", sans-serif
  • Code font: "Menlo", "Heiti TC", "Arial Unicode MS", monospace
  • pre code { background-color: transparent; }
  • img { max-width: 100%; max-height: 700px; }
  • white-space: pre-wrap; word-wrap: break-word; on pre
  • Page: @page { size: A4; margin: 2cm; }

pandoc command:

pandoc "{filename}_pdf.md" \
  --lua-filter=mermaid-filter.lua \
  --pdf-engine=weasyprint \
  --css=style.css \
  --no-highlight \
  -o "{filename}.pdf"

Step 7: Self-check

Read every page of the generated PDF. Check for:

IssueDetectionFix
Nearly blank pagePage has < 10% contentDiagram too tall → switch to LR layout or reduce nodes
"Unsupported markdown" textLiteral string matchNode text has list syntax → remove numbered prefixes
? boxes in textCharacter replacement indicatorsFont fallback issue → check CSS font-family
Table rows merged into one cellSingle row contains || or content from multiple expected rowsUnescaped $ triggering LaTeX math mode → escape all $ outside code blocks

If issues found: fix _pdf.md, regenerate. Maximum 3 retries, then stop and report remaining issues to user.

Step 8: Cleanup

Remove temporary files:

  • mermaid-filter.lua
  • style.css

Ask user: Keep or delete {filename}_pdf.md?

Step 9: Report

Output:

  • PDF file path
  • Page count
  • Any known remaining issues (if retry limit was hit)

Important Rules

  • NEVER modify the original markdown file
  • Always use PNG for Mermaid rendering (not SVG)
  • Always disable syntax highlighting (--no-highlight)
  • Always include CJK font fallback in CSS
  • Fixed A4 page size — no other options
  • One file at a time — user can invoke multiple times for batch

What ships with it: 2 files

18.0 KB alongside SKILL.md, 1 of them executable

docs/

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.