Home / All Skills / Docs & Knowledge / pdf-creator
Docs & Knowledge · daymade/claude-code-skills

pdf-creator

Convert markdown files to professional PDF documents with proper Chinese font support, theme system, and visual self-check. Use for Markdown → PDF, printable Markdown documents, and Markdown formatted for print or mobile reading. Prefer its CJK typography, header/footer suppression, and visual verification over manual pandoc/Chrome commands. Scope is Markdown → PDF only. Existing Word/WPS → PDF, including manuscript excerpts and layout repair, routes to daymade-docs:docx-creator; do not round-trip an authoritative Word manuscript through Markdown. Word output also routes to docx-creator.

L4 High-Privilege · Graded auth & full auditV1 Commit-PinnedExecute CommandData ExfiltrationNetwork AccessWrite FileDual-pass Audit
Author daymadeGitHub daymade/claude-code-skills ↗Stars 1385License MIT(仓库根 LICENSE;Copyright (c) 2025 daymade;GitHub API spdx MIT)Commit d5c4678cb5
Control levels describe skill capabilities and suggested control measures; they do not represent quality or safety certifications, nor do they dictate usability. Usage decisions rest entirely with users and administrators. Different agent hosts apply varying constraints; do not assume hosts provide automatic protection. Third-party skill copyrights belong to their original authors. Use at your own risk.

1How It Works & Mechanism

The pipeline is pandoc (md → HTML) + CSS themes + weasyprint/headless-Chrome rendering + poppler self-check, with scripts automatically applying CJK font stacks and typography patches—the core is in md_to_pdf.py (813 lines).

daymade-docs/pdf-creator/scripts/md_to_pdf.py
result = subprocess.run( ["pandoc", "-f", "markdown", "-t", "html"], input=md_content, capture_output=True,
The Chrome backend passes `--no-pdf-header-footer` to prevent default headers and footers (avoiding the pitfalls of manual pandoc+Chrome listed in the SKILL Anti-Pattern table); the weasyprint backend calls `HTML(string).write_pdf` directly.

Backend selection automatically routes based on "content × theme font stack" rather than whether Chinese is present: default/cjk-auto (Songti/Heiti CID TrueType) routes to weasyprint, while PingFang-style themes route to Chrome because weasyprint embeds PingFang SC subsets as CID Type 0C, which macOS Preview/Adobe cannot read.

daymade-docs/pdf-creator/SKILL.md
**CJK + a Songti/Heiti theme** (`default`, `cjk-auto`) → **weasyprint**. These themes embed CID TrueType, which every reader renders, so Chrome buys nothing and costs the clip described below.
Routing is locked down by tests/test_backend_routing.py; the explicit `--backend` parameter always overrides auto-detection. This engineers font embedding format knowledge (PDF reader compatibility) into code.

Themes are standalone CSS files (themes/*.css); 5 built-in themes cover formal, training, and mobile reading. Creating a new theme simply involves copying default.css and renaming it.

daymade-docs/pdf-creator/SKILL.md
To create a new theme: copy `themes/default.css`, modify, save as `themes/your-theme.css`.
The mobile theme uses 148×210mm specifically for WeChat/mobile reading; warm-terra-menu is a variant reinforced for line breaks in long menu text (using Menlo unicode-range to fix missing CJK glyphs in inline code).

CJK typography two-layer defense: Layer 1 automatically injects CSS patches (`table-layout: fixed`, `keep-all`, `th nowrap`, etc., without modifying the user's source file); Layer 2 runs `pdftotext -layout` after rendering to scan for anti-patterns such as orphan characters and broken brackets according to the "Chinese Copywriting Guidelines" and emits warnings.

daymade-docs/pdf-creator/SKILL.md
The patch: - `table { table-layout: fixed; width: 100% }` — equal column widths prevent weasyprint auto-layout from squeezing one column to ~10% width when an adjacent column has 5x more content
Layer 2 only warns and does not auto-modify—following CLAUDE.md's rule of "no implicit behavior" as stated in SKILL: silently rewriting Markdown masks underlying issues in the source itself.

Chrome clipping defects are studied down to the pixel level and paired with dual-mode inspection: Chrome's `@page` clip path cuts off table right borders that exceed the content box (538.90pt vs 545.18pt), yet the object remains in the PDF, undetectable by preview or coordinates alone. check_table_borders.py provides two modes: ink check + `--reference` comparison, with only the latter acting as a definitive verdict for Chrome rendering.

daymade-docs/pdf-creator/SKILL.md
It takes two forms, and for a Chrome-rendered PDF only the second one is a verdict.
The script docstring provides empirical evidence: 'a table styled with vertical rules and no cell fills, rendered through Chrome past the clip, loses its right border from the object layer entirely; the ink check then reports 5/5 promised rules painted — PASS'—this turns the mechanism of 'why manual verification fails' into an automated check.

Enforced visual self-check: Each generation automatically runs `pdftoppm` to output per-page PNGs (placed in the system temp directory, never committed to the working tree), printing a checklist reminding the user to inspect page-by-page; files containing tables must pass border check before clearance.

daymade-docs/pdf-creator/SKILL.md
Converts each page to PNG via `pdftoppm` (poppler-utils) into a `<pdf-name>/` subdirectory under the **system temp dir** (NOT next to the PDF — previews are a throwaway self-check artifact and must never linger in your working tree / git repo).
`--no-preview` only disables PNG generation, not the obligation: batch mode requires running check_table_borders.py against the outputs.

2Core Capabilities

01Markdown → Professional PDF (Chinese typography + theme system), single-file or batch
025 built-in themes (default/cjk-auto/warm-terra/warm-terra-menu/mobile) and custom theme mechanism
03Automatic weasyprint/Chrome dual-backend routing (content × theme font stack) with explicit override
04Automatic CJK typography patches + post-render typography linting (orphan characters/broken brackets/punctuation line breaks)
05Chrome clipping detection: ink check + `--reference` dual-backend comparison (the sole definitive verdict for Chrome)
06Enforced visual self-check: per-page PNGs + checklist (temp dir avoids polluting the working tree)

3External Dependencies

KindDependency / Endpoint
clipandoc(markdown→HTML)
packageweasyprint(uv run --with weasyprint / pip install)
cliGoogle Chrome(headless --print-to-pdf 后端)
clipoppler:pdftoppm(预览 PNG)/ pdftotext / pdfinfo(排版 lint)
packagepdfplumber / pillow / numpy(check_table_borders,uv --with)

4Recommended Governance & Evidence

Suggested Controls for Safe Operation
For Agent Runtime
Graded/per-use authorization, sandbox recommended
For Administrators
Approval workflow, rollback support, full audit
Evidence & Triggers (File Paths & Excerpts)
  • scripts/: Execute local scripts or commands: `python md_to_pdf.py` (local: pandoc subprocess, weasyprint import, or headless Chrome subprocess)
  • 外部端点: Exfiltrate local content or conversation sessions to third-party cloud storage
  • 本地工作目录: File read/write and artifact output: generates PDF alongside input or at specified output path; preview PNGs are written to system temp directory `pdf-creator-previews/<stem>/` (automatically cleaning up old pages)
Audit Notes: Purely local toolchain (pandoc/weasyprint/Chrome/poppler) with zero outbound network traffic and zero credential reading during runtime; writes only the user-specified PDF and self-check PNGs in the system temp directory. Note: Initial usage requires uv/pip to pull packages like weasyprint/pdfplumber (official PyPI, predictable); DYLD_LIBRARY_PATH is only appended in-process.

5Second-Pass Verification

  • [ok] pandoc→HTML→渲染器管线 — md_to_pdf.py subprocess.run(["pandoc","-f","markdown","-t","html"]) + _render_weasyprint/_render_chrome 均存在。
  • [ok] 后端按内容×主题路由 — _detect_backend 中 _WEASYPRINT_SAFE_CJK_THEMES={'default','cjk-auto'} 与 SKILL 路由表一致;test_backend_routing.py 存在。
  • [ok] Chrome clip 缺陷数字 — SKILL 与 check_table_borders.py docstring 均载 538.90pt/545.18pt 与 '5/5 promised rules painted — PASS' 反例,跨文件一致。
  • [ok] 预览进 temp dir 而非工作树 — 代码 preview_dir = Path(tempfile.gettempdir()) / 'pdf-creator-previews' / pdf_path.stem;SKILL 同述。
  • [ok] Layer1 CSS 补丁 / Layer2 lint 不隐改源 — _TYPOGRAPHY_CSS_PATCH 注入与 pdftotext -layout 扫描代码均在;无对用户 md/css 的写回路径。
  • [ok] 无网络无凭证 — 代码扫描零 curl/requests/API key;env 读取仅 DYLD_LIBRARY_PATH(进程内)。
  • [ok] 元数据 — GitHub API:MIT / 1385 stars / pushed 2026-09-09T12:33:29Z;本地 HEAD==pin d5c4678。

6Verdict & Scenarios

  • Comprehensive Chinese PDF quality gates: font embedding format compatibility (CID TrueType routing), typography linting, and Chrome clipping detection are all backed by scripts and tests.
  • Deeply investigates the mechanism of "why manual workflows fail" (clipped objects remain in the object layer without laying down ink) and implements it as executable checks rather than mere reminders.
  • Theme system enables one-step multi-version conversion for training, formal, and mobile reading, with low barrier for pure CSS customization.
  • Hygiene and discipline: self-check artifacts never touch the working tree, and source Markdown is never silently rewritten—ideal for team pipelines.
  • Best for: Ideal for individuals and teams converting Chinese Markdown into formal, training, or mobile-friendly PDFs (contracts, lecture notes, course syllabi, WeChat sharing docs); requires pandoc + weasyprint or Chrome + poppler installed and a willingness to perform page-by-page visual verification.
    Not for: Not suitable for converting existing authoritative Word/WPS manuscripts to PDF (use docx-creator's word-to-pdf workflow instead; Markdown round-tripping is prohibited); not suitable for offline environments without Chinese fonts installed; pixel-perfect layout control (exact per-page layout) exceeds CSS rendering capabilities.
    Install Agent-Ready
    ① Verified Mirror 2026-09-09
    Option A · Direct DownloadDownload pdf-creator.tar.gz
    sha256: 77a0f5b23369e727…
    Option B · Copy Guide for Agent
    install.json
    Agents automatically download and verify mirrors from this JSON guide.
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit d5c4678cb5.