English ・ 繁體中文
Produce Chinese A4 documents that go straight from HTML → Cmd+P → PDF: reports, quotes, contracts, meeting minutes, forms, résumés, slides, and study sheets — with the option to embed infographics inside the page.
This is a Claude Code Skill, but it also works by hand: just copy a template. Every template is a single, self-contained HTML file with Chinese fonts configured to embed into PDF — so the classic "looks fine on screen, Chinese vanishes when printed" bug never happens.
This skill isn't a pile of templates — it stitches five things into one pipeline. Each part stands alone, and they layer on top of one another. The typical flow: pick a style, choose a template, lay down a grid when you need columns, drop in infographics, and chunk into pages once the document grows.
| # | Capability | What it does | Entry point |
|---|---|---|---|
| 1 | Google Design | A DESIGN.md style contract with 3-tier override |
design.py |
| 2 | Template | 39 A4 templates with font/pagination pitfalls pre-solved | templates/ |
| 3 | Grid System | One CSS block to give any template multi-column layout | built-in CSS |
| 4 | Infographic | 165 pre-rendered SVG chart modules, offline-printable | infographic/ |
| 5 | Chunk Page | _shell.html + pages/ assembly; update a single page in isolation |
assemble.py |
One rule cuts across all five: never touch the Chinese-font declaration in
<head> (see bottom).
On macOS, Chrome cannot embed the system Chinese font PingFang when printing
to PDF. Any font stack that falls through to system-ui, -apple-system, or a
bare sans-serif looks fine on screen but drops entire blocks of Chinese
once printed. Every template, SVG tool, and page shell here ships the fix — an
explicit, embeddable font stack:
font-family: 'Noto Sans TC', 'Heiti TC', 'Arial Unicode MS', 'Microsoft JhengHei', sans-serif;printable-docs/
├── SKILL.md # Claude Code skill definition (AI workflow + hard rules)
├── README.md / README-zh-tw.md
│
├── design.py # ① style switcher (3-tier priority)
├── DESIGN.md # factory-default style contract (editorial print)
├── design-themes/ # alternative style library (editorial-print / atmospheric-glass …)
│
├── templates/ # ② 39 A4 Chinese templates (31 general + 8 study)
│ ├── README.md # full catalog, usage, print settings
│ └── memory/ # memory-method series (Cornell notes, error log, flashcards…)
│
├── infographic/ # ④ 165 tested infographic modules (AntV Infographic)
│ ├── catalog.md # selection guide, category table, hard rules
│ ├── templates.json # machine-readable list (name / category / data_shape)
│ ├── make-svg.py # syntax → clean SVG
│ ├── embed-svg.py # replace <!--SVG:file--> placeholders in HTML in place
│ ├── preview.html # visual overview of all 165 templates
│ └── vendor/infographic.min.js
│
└── assemble.py # ⑤ multi-page assembly (pages/ → output.html)
(③ The grid system isn't a file — it's a CSS block you paste into <style>, below.)
Drop this folder into your skills path (e.g. ~/.claude/skills/printable-docs/)
and just tell Claude what you need:
Make me a "System X adoption assessment report," printable to A4 PDF.
Use the quote template to produce a quote for these line items… and add a timeline chart at the end.
Triggers: print to PDF, A4 document, Cmd+P, quote, weekly report, infographic, "Chinese disappears when printing PDF." The AI decides whether to chunk pages, selects a template, applies the style, generates charts, and verifies with a real print.
- Copy the closest template from
templates/(see the catalog intemplates/README.md) and rename it. - The
<!-- ... -->comment at the top of each file says which blocks you may add, remove, or duplicate. - Edit content only — leave the
<head>font declaration alone. - Open in Chrome → Cmd+P → Save as PDF (tick "Background graphics," untick "Headers and footers").
A document's visual style is defined by a DESIGN.md file
(Google design.md format).
design.py resolves which one is active using a 3-tier priority:
| Priority | Source | Scope | Versioned |
|---|---|---|---|
| 1 | project-root DESIGN.md (searched upward from CWD) |
this project's style | ✅ with the project |
| 2 | ~/.cache/printable-docs/current-design.md |
personal cross-project default | ❌ personal |
| 3 | <skill>/DESIGN.md |
factory default: restrained editorial print | ✅ with the skill |
python3 design.py active # active style + which tier it came from
python3 design.py list # list available styles (design-themes/)
python3 design.py set <name> # set personal style → ~/.cache/printable-docs/
python3 design.py reset # clear personal style, fall back to factory/projectThe factory default is this library's editorial-print style and usually needs
no change. design-themes/ also ships web-leaning examples (glassmorphism,
etc.) for full-replacement use — don't mix them in when they clash with the
print philosophy.
Author your own style — design.py set can only pick a style that already
exists in design-themes/. To make your own, there are three routes:
| You want | How | Lands in |
|---|---|---|
| One specific project only | Drop a DESIGN.md at the project root |
Tier 1 (versioned with the project) |
| A personal cross-project default | Create design-themes/<name>/DESIGN.md, then design.py set <name> |
Tier 2 (personal library) |
| A one-off personal override | Write ~/.cache/printable-docs/current-design.md directly (or set one, then edit in place) |
Tier 2 |
The fastest start is to copy design-themes/editorial-print/DESIGN.md and
edit its tokens. DESIGN.md follows the
Google design.md format: the
front-matter name: shows up in design.py list, and the body is an 8-section
design system plus a block of YAML design tokens (color, type scale, and spacing
all live in the tokens). After editing, run python3 design.py active to confirm
the right tier is active, then generate documents.
Full catalog and print settings in templates/README.md.
Grouped summary:
| Group | Templates |
|---|---|
| Reports & docs | report, proposal/SOW, spec (PRD/SRS), uat, postmortem, 8d, esg, sop |
| Business & finance | quote, expense, budget, mou (memo/short contract), letter, press release |
| Meetings & projects | minutes, agenda, sign-in, weekly status, worklog, handover |
| HR | resume, jd, interview eval, performance review, workplace-grievance |
| Analytical / diagram | swot (SWOT+TOWS), bmc (business model canvas), iso45001 (risk matrix) |
| Other layouts | slides-16x9, certificate (landscape) |
| Study sheets | study-plan + memory/ series: review-cycle (forgetting curve), mistakes (error log), cornell, recall (active recall), flashcards (Leitner), feynman, loci (memory palace), sq3r |
No exact match? Pick the closest structure and adapt — always copy an existing template, never write HTML from scratch. The font, pagination, and layout pitfalls are already solved.
When you need side-by-side layout, paste this CSS at the end of the template's
<style> (don't touch the font declaration or @page):
/* ── Grid system: multi-column layout ────────────── */
:root { --gap: 5mm; }
.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
.cols-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--gap); }
.cols-4 { display: grid; grid-template-columns: repeat(4,1fr); gap: var(--gap); }
.cols-2-1 { display: grid; grid-template-columns: 2fr 1fr; gap: var(--gap); }
.cols-1-2 { display: grid; grid-template-columns: 1fr 2fr; gap: var(--gap); }
.cols-3-1 { display: grid; grid-template-columns: 3fr 1fr; gap: var(--gap); }
.cols-2, .cols-3, .cols-4, .cols-2-1, .cols-1-2, .cols-3-1 {
align-items: start; break-inside: avoid; margin-bottom: 1.2rem;
}
.cols-2 > *, .cols-3 > *, .cols-4 > *,
.cols-2-1 > *, .cols-1-2 > *, .cols-3-1 > * { min-width: 0; }<div class="cols-2-1"> <!-- main body 2/3 + sidebar 1/3 -->
<section><h2>Main content</h2>…</section>
<aside><h3>Key numbers</h3>…</aside>
</div>Notes: column widths are based on the A4 type area (174mm); for 4+ columns
drop --gap to 3mm; when an infographic sits in a grid column, shrink its
outer max-height to match (cols-2 → 80mm, cols-3 → 50mm); if a column's
content exceeds half a page, remove break-inside: avoid and let it flow.
infographic/ holds 165 chart templates built on
AntV Infographic, all passing render regression
tests. The flow is pre-render to SVG, then embed — no runtime JS, so the
output stays single-file, self-contained, and offline-printable.
| Category | Count | Representative layouts | Use for |
|---|---|---|---|
| sequence | 68 | steps, timeline, roadmap, funnel, pyramid | processes, milestones, schedules, funnels |
| list | 37 | row, column, grid, waterfall, zigzag | responsibility lists, deliverables |
| compare | 24 | binary (vs/fold), quadrant, swot | option comparisons, quadrants |
| chart | 15 | bar, column, line, pie, wordcloud | budgets, shares, statistics |
| hierarchy | 14 | mindmap, structure, tree | org charts, knowledge structures |
| relation | 7 | dagre-flow, network, circle | causal chains, system architecture |
Three steps:
- Pick a template from the table: read
infographic/catalog.mdandtemplates.json, choose anameby category, shape your data todata_shape— or openpreview.htmlto browse visually. - Write syntax, generate SVG:
python3 infographic/make-svg.py file.syntax -o chart.svg
make-svg.pyswaps in the embeddable font stack, strips editor noise, and measures text collisions (on a layout error, shorten the label or switch templates — don't force dimensions; internal layouts use fixed coordinates). - Embed via placeholder: write
<figure><!--SVG: chart.svg--></figure>in the HTML (don't read the SVG content in and paste it — many charts will blow up your context), then run:The outer CSS must includepython3 infographic/embed-svg.py file.html
figure svg { width:100%; height:auto; max-height:110mm; }.
Hard rules: vertical layouts (timeline, roadmap-vertical) require
max-height; for formal documents pick -simple / -plain-text variants or
override the primary color to #1e4e79 via theme; keep chart labels within 8
full-width characters. Full rules in
infographic/catalog.md.
When a document runs 5+ pages and some pages need independent updates later, chunk first, then write (chunking after the fact is double the work):
project/
├── _shell.html ← <head> + shared CSS + <body>, with a <!-- PAGES --> slot
├── pages/
│ ├── 01-cover.html ← content fragment only (no <html>/<head>/<body>)
│ ├── 02-exec.html
│ └── …
└── output.html ← produced by assemble.py, used for the PDF
python3 assemble.py project/ # pages/ → output.html
python3 infographic/embed-svg.py project/output.html # if there are chartsSubsequent pages get break-before: page automatically during assembly (the
first page doesn't). To update one page, edit only pages/02-exec.html (a
few dozen lines) and re-assemble — no need to read the whole document.
output.html is generated; never hand-edit it — edit the source in pages/.
The one non-negotiable across all five capabilities: never change a single
character of the Chinese-font declaration in <head> or inside SVGs. No
system-ui, no -apple-system, no bare sans-serif. make-svg.py handles
SVGs automatically; for hand-extracted SVGs, swap in the embeddable stack above
yourself.
Don't trust the screen — print a real PDF:
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless=new --disable-gpu --no-pdf-header-footer \
--print-to-pdf=/tmp/check.pdf "file:///absolute/path/file.html"
open /tmp/check.pdfCheck three things: Chinese intact (text is selectable), page count correct (a single-page template printing two pages = overflow; delete content and tighten spacing first, shrink font size only as a last resort), and no tables sliced mid-row. Note that sips/screenshots only show the first page — overflow always lands on the last page, so review every page.
- Single-file, self-contained: one HTML file is one document (only Google Fonts needs a first-time network fetch; offline it falls back to Heiti TC and still prints).
- Restrained editorial style: no gradients, emoji, or rounded cards; reuse the template's existing styles.
- Print-first:
@pagealready sets paper and margins; slide decks go landscape automatically.
The development source lives in the html-demo repo (with regression tests);
this folder is the release copy. For the sync procedure see
SKILL.md (catalog.md paths are rewritten to relative references
and must not be overwritten directly).