PluginBench
Skill
Review
Audit score 70

pdf-creator

daymade/claude-code-skills

How to install pdf-creator

npx skills add https://github.com/daymade/claude-code-skills --skill pdf-creator
Claude Code
Cursor
Windsurf
Cline
Full instructions (SKILL.md)

Source of truth, from daymade/claude-code-skills.


name: pdf-creator description: Convert markdown files to professional PDF documents with proper Chinese font support, theme system, and visual self-check. Use whenever the user asks to create PDFs, convert markdown to PDF, generate printable documents, or needs documents formatted for print or mobile reading. This skill MUST be used instead of manual pandoc/Chrome invocations — it handles CJK typography, Chrome header/footer suppression, and mandatory visual verification that manual approaches miss. Scope — markdown → PDF only. For Word (.docx) output use minimax-docx; this skill does not produce docx and the two pipelines are intentionally orthogonal.

PDF Creator

Create professional PDF documents from markdown with Chinese font support and theme system.

Quick Start

# Default theme (formal: Songti SC + black/grey, A4 print)
uv run --with weasyprint scripts/md_to_pdf.py input.md output.pdf

# Warm theme (training: PingFang SC + terra cotta)
uv run --with weasyprint scripts/md_to_pdf.py input.md --theme warm-terra

# Mobile theme (narrow page, large font — for phone reading / WeChat sharing)
uv run --with weasyprint scripts/md_to_pdf.py input.md --theme mobile

# Batch convert all markdown files with a specific theme
uv run --with weasyprint scripts/batch_convert.py *.md --theme warm-terra --no-preview

# No weasyprint? Use Chrome backend (auto-detected if weasyprint unavailable)
python scripts/md_to_pdf.py input.md --theme warm-terra --backend chrome

# List available themes
python scripts/md_to_pdf.py --list-themes dummy.md

Themes

Stored in themes/*.css. Each theme is a standalone CSS file.

ThemePage SizeFontColorBest for
defaultA4Songti SC + Heiti SCBlack/greyLegal docs, contracts, formal reports
cjk-autoA4Songti SC + Heiti SCBlack/greyTables with uneven column content (course schedules, itemized lists)
warm-terraA4PingFang SCTerra cotta (#d97756) + warm neutralsCourse outlines, training materials, workshops
warm-terra-menuA4PingFang SCTerra cotta (#d97756) + warm neutralswarm-terra variant hardened for module menus/lists: 2-column long-text tables wrap without first-column overflow + Menlo unicode-range keeps CJK inline-code from rendering blank in Preview/Adobe
mobile148mm × 210mmPingFang SCTerra cotta + warm neutralsPhone reading, WeChat sharing, on-the-go reference

To create a new theme: copy themes/default.css, modify, save as themes/your-theme.css.

Print vs Mobile: Choose the Right Theme

ScenarioRecommended ThemeWhy
Print on A4 paper, handouts, contractsdefaultStandard page size, formal typography
Training materials, course outlineswarm-terraWarm accent color, readable for workshop contexts
Send via WeChat, read on phonemobileNarrow page (148mm), 15px font, 1.9 line-height — comfortable on small screens
Both print AND mobile neededRun twice with different themesThe skill is fast; generate both versions

Decision rule: If the user does not specify, default to warm-terra for training/course content and default for formal documents. Ask "是否需要手机版?" only when the output channel is unclear.

Backends

The script auto-detects the best available backend based on content:

  • CJK content detected → auto-selects Chrome (weasyprint subset-embeds PingFang SC as CID Type 0C OpenType, which macOS Preview / Adobe Reader fail to render — appears as garbled text on recipient devices even though it looks fine in Chrome's PDF viewer)
  • Non-CJK content → auto-selects weasyprint (faster, no browser startup)
BackendInstallProsCons
weasyprintpip install weasyprintPrecise CSS rendering, no browser neededCJK font embedding bug on some readers
chromeGoogle Chrome installedZero Python deps, reliable CJK renderingLarger binary, slightly less CSS control

Override with --backend chrome or --backend weasyprint.

Batch Convert

# Default theme, same directory
uv run --with weasyprint scripts/batch_convert.py *.md

# Specific theme, output directory, skip previews for speed
uv run --with weasyprint scripts/batch_convert.py *.md --theme warm-terra --output-dir ./pdfs --no-preview

# Mobile theme for phone reading
uv run --with weasyprint scripts/batch_convert.py *.md --theme mobile --output-dir ./mobile-pdfs --no-preview

Anti-Pattern: Do NOT Manually Invoke pandoc + Chrome

Why this skill exists: Manual pandoc input.md -o out.html + chrome --headless --print-to-pdf workflows silently fail in ways that are hard to detect:

Manual StepWhat Goes WrongThis Skill Fixes
pandoc -o out.htmlNo CJK-aware CSS → boxes/blanks for ChineseInjects CJK font stack + typography patch
Chrome --print-to-pdfDefault header/footer appears (filename, date, URL, page numbers)Passes --no-pdf-header-footer
No post-render check"Exit code 0" assumed success; rendering bugs hiddenAuto-generates per-page PNG previews + typography lint
No theme systemOne-size-fits-all; phone reading impossibleThree curated themes (default / warm-terra / mobile)
batch_convert.py missingWriting ad-hoc loops, inconsistent flagsBuilt-in batch mode with --theme support

Rule: When the user asks for PDF conversion, ALWAYS use this skill. Never bypass it with manual pandoc/Chrome commands.

Troubleshooting

Chinese characters display as boxes: Ensure Chinese fonts are installed (Songti SC, PingFang SC, etc.)

weasyprint import error: Run with uv run --with weasyprint or use --backend chrome instead.

CJK text in code blocks garbled (weasyprint): The script auto-detects code blocks containing Chinese/Japanese/Korean characters and converts them to styled divs with CJK-capable fonts. If you still see issues, use --backend chrome which has native CJK support. Alternatively, convert code blocks to markdown tables before generating the PDF.

Chrome header/footer appearing: The script passes --no-pdf-header-footer. If it still appears, your Chrome version may not support this flag — update Chrome. Note: If you bypassed this skill and used manual Chrome headless, this is the first symptom — see "Anti-Pattern" section above.

Inline code with mixed CJK + ASCII shows blanks in macOS Preview (e.g. `Terminal/终端` renders only Terminal/ with the CJK part missing): weasyprint subset-embeds PingFang SC as OpenType (CID Type 0C), which strict PDF readers (macOS Preview / Adobe Reader) fail to render. Chrome's PDF viewer falls back automatically and hides the bug. Fix is in the default theme: code font-family chain prioritizes CID TrueType CJK fonts (Songti SC / Heiti SC) before OpenType ones (PingFang SC). To verify: pdfplumber + check font['fontname'] of CJK chars — if any references PingFang-SC (CID Type 0C OT), readers will likely fail. Reorder font chain to put CID TrueType first.

Table column 1 with short label gets mid-broken (e.g. 4/28(周|二)下|午): pandoc auto-emits <colgroup><col style="width:X%"> from dash counts in the markdown separator row. For | ----- | --- | --- | -------- | (uneven dash widths), pandoc allocates col 1 ~17% — too narrow for a 9-char CJK label. Inline style="" beats external CSS at equal specificity, so td:first-child { width:... } is silently shadowed. Fix is in default theme: table colgroup col { width: auto !important } neutralizes pandoc's hint, letting table-layout: fixed distribute equally (25% per column for a 4-col table). To verify: pandoc input.md -t html | grep colgroup — if it shows <col style="width:X%">, the bug applies. Scope: the neutralizer lives only in default.css; warm-terra and mobile themes use different strategies (nowrap on th/td with last-child wrap, and full-flow wrap respectively) and intentionally omit it. The neutralizer is locked in by scripts/tests/test_cjk_tables.py::test_default_theme_neutralizes_pandoc_colgroup_hint.

Visual Self-Check (MANDATORY — Do Not Skip)

This is not optional. After every PDF generation, the script automatically:

  1. 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). The exact path is printed after the run as Previews: <path>/page-NN.png
  2. Prints a structured self-check checklist reminding the caller to visually inspect each page
  3. Runs typography lint to detect CJK line-break anti-patterns

Why mandatory: "PDF generated cleanly" ≠ "rendering matches markdown intent". Common silent failures include:

  • Paragraphs collapsing into one (CommonMark soft-break on consecutive non-blank lines)
  • Tables overflowing page margins
  • Missing CJK / emoji glyphs
  • Code block garbling
  • Chrome default headers/footers (if bypassed this skill)

Workflow: After running the script, Read each page-NN.png at the printed Previews: path and verify against the markdown source. If anything renders differently from intent, fix the markdown (use - real lists instead of pseudo-lists, insert blank lines, restructure tables) and rerun. The script does NOT silently "fix" non-standard markdown — that would mask the signal that the source is wrong, causing the same markdown to render incorrectly in other processors (Obsidian, GitHub, VS Code preview).

Disable with --no-preview for batch / non-interactive runs:

python scripts/md_to_pdf.py input.md output.pdf --no-preview

Requires pdftoppm (brew install poppler on macOS). If not installed, the script logs a hint and skips preview generation but still produces the PDF.

CJK Typography (default behavior)

The script applies two layers of CJK-aware processing automatically — without modifying the user's markdown source or theme CSS files:

Layer 1: CSS patch (auto-injected, fixes ~80% of cases)

_load_theme() appends a CJK typography CSS patch to the loaded theme CSS. 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
  • td, th { word-break: keep-all; overflow-wrap: normal; line-break: strict } — don't slice CJK characters apart. The deliberate trade-off encoded by overflow-wrap: normal (not break-word) is to let content overflow slightly rather than fall back to mid-token breaks — rationale documented in md_to_pdf.py L109-146 inline comments and locked in by scripts/tests/test_cjk_tables.py
  • th { white-space: nowrap } — short headers stay one line for predictable column widths

This silently fixes the most common anti-pattern (cell content forcibly wrapped between CJK characters producing single-char-only lines), without touching the user's source. The user's theme CSS file on disk is never modified.

Layer 2: Typography lint (post-render detection, catches the rest)

After PDF generation, the script runs pdftotext -layout per page and scans for known CJK anti-patterns per "中文文案排版指北" (Chinese typography style guide):

  • Single CJK character alone on a line (cell still too narrow even after Layer 1)
  • Line ending with followed by content next line (broken bracket pair)
  • Line starting with (broken from previous bracket pair)
  • Short line ending with mid-thought punctuation 、,;:

Findings are printed to stderr with page+line locations. They are warnings, not errors — PDF still generates. The author sees the finding and decides:

  1. Accept (e.g. one orphan char in a long doc may be acceptable)
  2. Shorten the offending cell content to fit the column width
  3. Restructure (e.g. move long content into a paragraph below the table)

Why not silently auto-fix everything?

Layer 2 deliberately does NOT modify the markdown. Per CLAUDE.md "禁止隐式行为" rule: silently rewriting non-standard markdown (e.g. expanding pseudo-lists into real lists) would mask the signal that the source is wrong, causing the same markdown to render incorrectly in other processors. Layer 1 is acceptable because it patches rendering behavior for already-standard markdown (a standard table that weasyprint happens to render imperfectly for CJK), not the markdown source itself.

Known limitations

When a single cell's content is just slightly longer than the available column width (e.g. 10 CJK chars in a 9-char-wide cell after equal split), weasyprint will fall back to forced break despite keep-all. Layer 1 cannot fix this — Layer 2 will catch it and prompt the author to shorten cell content or restructure.

Related skills

More from daymade/claude-code-skills and the wider catalog.

TW

twitter-reader

daymade/claude-code-skills

Fetch Twitter/X post content including long-form Articles with full images and metadata. Use when Claude needs to retrieve tweet/article content, author info, engagement metrics, and embedded media. Supports individual posts and X Articles (long-form content). Automatically downloads all images to local attachments folder and generates complete Markdown with proper image references. Preferred over Jina for X Articles with images.

1.9k installs
PR

prompt-optimizer

daymade/claude-code-skills

Transform vague prompts into precise, well-structured specifications using EARS (Easy Approach to Requirements Syntax) methodology. This skill should be used when users provide loose requirements, ambiguous feature descriptions, or need to enhance prompts for AI-generated code, products, or documents. Triggers include requests to "optimize my prompt", "improve this requirement", "make this more specific", or when raw requirements lack detail and structure.

1.2k installs
PP

ppt-creator

daymade/claude-code-skills

Create professional slide decks from topics or documents. Generates structured content with data-driven charts, speaker notes, and complete PPTX files. Applies persuasive storytelling principles (Pyramid Principle, assertion-evidence). Supports multiple formats (Marp, PowerPoint). Use for presentations, pitches, slide decks, or keynotes.

1.2k installs
I1

i18n-expert

daymade/claude-code-skills

This skill should be used when setting up, auditing, or enforcing internationalization/localization in UI codebases (React/TS, i18next or similar, JSON locales), including installing/configuring the i18n framework, replacing hard-coded strings, ensuring en-US/zh-CN coverage, mapping error codes to localized messages, and validating key parity, pluralization, and formatting.

1.1k installs
QA

qa-expert

daymade/claude-code-skills

This skill should be used when establishing comprehensive QA testing processes for any software project. Use when creating test strategies, writing test cases following Google Testing Standards, executing test plans, tracking bugs with P0-P4 classification, calculating quality metrics, or generating progress reports. Includes autonomous execution capability via master prompts and complete documentation templates for third-party QA team handoffs. Implements OWASP security testing and achieves 90% coverage targets.

1.1k installs
MA

macos-cleaner

daymade/claude-code-skills

Analyze and reclaim macOS disk space through intelligent cleanup recommendations. This skill should be used when users report disk space issues, need to clean up their Mac, or want to understand what's consuming storage. Focus on safe, interactive analysis with user confirmation before any deletions.

887 installs