minimax-pdf
Three tasks. One skill.
Read design/design.md before any CREATE or REFORMAT work.
ZhiYuan/Pi execution
When this skill is run inside ZhiYuan, call run_skill_script for the bundled .py, .js,
and .sh pipeline steps. Pass each argument separately in args; do not call python3,
uv, or bash directly. The application chooses the managed Python/uv/Node/Git Bash runtime
and returns a structured runtime error instead of misreporting the input PDF as missing.
Example:
{
"skillId": "pdf",
"script": "scripts/fill_inspect.py",
"args": ["--input", "form.pdf"]
}
Route table
| User intent |
Route |
Scripts used |
| Generate a new PDF from scratch |
CREATE |
palette.py → cover.py → render_cover.js → render_body.py → merge.py |
| Fill / complete form fields in an existing PDF |
FILL |
fill_inspect.py → fill_write.py |
| Reformat / re-style an existing document |
REFORMAT |
reformat_parse.py → then full CREATE pipeline |
Rule: when in doubt between CREATE and REFORMAT, ask whether the user has an existing document to start from. If yes → REFORMAT. If no → CREATE.
Route A: CREATE
Full pipeline — content → design tokens → cover → body → merged PDF.
bash scripts/make.sh run \
--title "Q3 Strategy Review" --type proposal \
--author "Strategy Team" --date "October 2025" \
--accent "#2D5F8A" \
--content content.json --out report.pdf
Doc types: report · proposal · resume · portfolio · academic · general · minimal · stripe · diagonal · frame · editorial · magazine · darkroom · terminal · poster
| Type |
Cover pattern |
Visual identity |
report |
fullbleed |
Dark bg, dot grid, Playfair Display |
proposal |
split |
Left panel + right geometric, Syne |
resume |
typographic |
Oversized first-word, DM Serif Display |
portfolio |
atmospheric |
Near-black, radial glow, Fraunces |
academic |
typographic |
Light bg, classical serif, EB Garamond |
general |
fullbleed |
Dark slate, Outfit |
minimal |
minimal |
White + single 8px accent bar, Cormorant Garamond |
stripe |
stripe |
3 bold horizontal color bands, Barlow Condensed |
diagonal |
diagonal |
SVG angled cut, dark/light halves, Montserrat |
frame |
frame |
Inset border, corner ornaments, Cormorant |
editorial |
editorial |
Ghost letter, all-caps title, Bebas Neue |
magazine |
magazine |
Warm cream bg, centered stack, hero image, Playfair Display |
darkroom |
darkroom |
Navy bg, centered stack, grayscale image, Playfair Display |
terminal |
terminal |
Near-black, grid lines, monospace, neon green |
poster |
poster |
White bg, thick sidebar, oversized title, Barlow Condensed |
Cover extras (inject into tokens via --abstract, --cover-image):
--abstract "text" — abstract text block on the cover (magazine/darkroom)
--cover-image "url" — hero image URL/path (magazine, darkroom, poster)
Color overrides — always choose these based on document content:
--accent "#HEX" — override the accent color; accent_lt is auto-derived by lightening toward white
--cover-bg "#HEX" — override the cover background color
Accent color selection guidance:
You have creative authority over the accent color. Pick it from the document's semantic context — title, industry, purpose, audience — not from generic "safe" choices. The accent appears on section rules, callout bars, table headers, and the cover: it carries the document's visual identity.
| Context |
Suggested accent range |
| Legal / compliance / finance |
Deep navy #1C3A5E, charcoal #2E3440, slate #3D4C5E |
| Healthcare / medical |
Teal-green #2A6B5A, cool green #3A7D6A |
| Technology / engineering |
Steel blue #2D5F8A, indigo #3D4F8A |
| Environmental / sustainability |
Forest #2E5E3A, olive #4A5E2A |
| Creative / arts / culture |
Burgundy #6B2A35, plum #5A2A6B, terracotta #8A3A2A |
| Academic / research |
Deep teal #2A5A6B, library blue #2A4A6B |
| Corporate / neutral |
Slate #3D4A5A, graphite #444C56 |
| Luxury / premium |
Warm black #1A1208, deep bronze #4A3820 |
Rule: choose a color that a thoughtful designer would select for this specific document — not the type's default. Muted, desaturated tones work best; avoid vivid primaries. When in doubt, go darker and more neutral.
content.json block types:
| Block |
Usage |
Key fields |
h1 |
Section heading + accent rule |
text |
h2 |
Subsection heading |
text |
h3 |
Sub-subsection (bold) |
text |
body |
Justified paragraph; supports <b> <i> markup |
text |
bullet |
Unordered list item (• prefix) |
text |
numbered |
Ordered list item — counter auto-resets on non-numbered blocks |
text |
callout |
Highlighted insight box with accent left bar |
text |
table |
Data table — accent header, alternating row tints |
headers, rows, col_widths?, caption? |
image |
Embedded image scaled to column width |
path/src, caption? |
figure |
Image with auto-numbered "Figure N:" caption |
path/src, caption? |
code |
Monospace code block with accent left border |
text, language? |
math |
Display math — LaTeX syntax via matplotlib mathtext |
text, label?, caption? |
chart |
Bar / line / pie chart rendered with matplotlib |
chart_type, labels, datasets, title?, x_label?, y_label?, caption?, figure? |
flowchart |
Process diagram with nodes + edges via matplotlib |
nodes, edges, caption?, figure? |
bibliography |
Numbered reference list with hanging indent |
items [{id, text}], title? |
divider |
Accent-colored full-width rule |
— |
caption |
Small muted label |
text |
pagebreak |
Force a new page |
— |
spacer |
Vertical whitespace |
pt (default 12) |
chart / flowchart schemas:
{"type":"chart","chart_type":"bar","labels":["Q1","Q2","Q3","Q4"],
"datasets":[{"label":"Revenue","values":[120,145,132,178]}],"caption":"Q results"}
{"type":"flowchart",
"nodes":[{"id":"s","label":"Start","shape":"oval"},
{"id":"p","label":"Process","shape":"rect"},
{"id":"d","label":"Valid?","shape":"diamond"},
{"id":"e","label":"End","shape":"oval"}],
"edges":[{"from":"s","to":"p"},{"from":"p","to":"d"},
{"from":"d","to":"e","label":"Yes"},{"from":"d","to":"p","label":"No"}]}
{"type":"bibliography","items":[
{"id":"1","text":"Author (Year). Title. Publisher."}]}
Mandatory visual QA
After every CREATE or layout-changing REFORMAT, render every page and inspect
the contact sheet before delivery. In the packaged app, uv and Python are
private runtimes; do not install packages into the base interpreter.
uv run --with pypdfium2 --with pillow python \
SKILL_DIR/scripts/pdf_inspect.py final.pdf -o pdf-qa
The command writes one PNG per page, contact-sheet.png, and
inspection.json. Review the contact sheet and every low_content_pages
entry. Fix unexplained blank pages, clipping, overlap, or broken glyphs and
rerun inspection. A PDF that merely opens is not visually validated.
Route B: FILL
Fill form fields in an existing PDF without altering layout or design.
# Step 1: inspect
python3 scripts/fill_inspect.py --input form.pdf
# Step 2: fill
python3 scripts/fill_write.py --input form.pdf --out filled.pdf \
--values '{"FirstName": "Jane", "Agree": "true", "Country": "US"}'
| Field type |
Value format |
text |
Any string |
checkbox |
"true" or "false" |
dropdown |
Must match a choice value from inspect output |
radio |
Must match a radio value (often starts with /) |
Always run fill_inspect.py first to get exact field names.
Route C: REFORMAT
Parse an existing document → content.json → CREATE pipeline.
bash scripts/make.sh reformat \
--input source.md --title "My Report" --type report --out output.pdf
Supported input formats: .md .txt .pdf .json
Environment
bash scripts/make.sh check # verify all deps
bash scripts/make.sh fix # auto-install missing deps
bash scripts/make.sh demo # build a sample PDF
| Tool |
Used by |
Install |
| Python 3.9+ |
all .py scripts |
system |
reportlab |
render_body.py |
pip install reportlab |
pypdf |
fill, merge, reformat |
pip install pypdf |
pypdfium2 + Pillow |
full-page visual QA |
uv run --with pypdfium2 --with pillow ... |
| Node.js 18+ |
render_cover.js |
system |
playwright + Chromium |
render_cover.js |
npm install -g playwright && npx playwright install chromium |
1---2name: minimax-pdf3description: Use this skill when visual quality and design identity matter for a PDF. CREATE (generate from scratch): "make a PDF", "generate a report", "write a proposal", "create a resume", "beautiful PDF", "professional document", "cover page", "polished PDF", "client-ready document". FILL (complete form fields): "fill in the form", "fill out this PDF", "complete the form fields", "write values into PDF", "what fields does this PDF have". REFORMAT (apply design to an existing doc): "reformat this document", "apply our style", "convert this Markdown/text to PDF", "make this doc look good", "re-style this PDF". This skill uses a token-based design system: color, typography, and spacing are derived from the document type and flow through every page. The output is print-ready. Prefer this skill when appearance matters, not just when any PDF output is needed.4license: MIT5---67# minimax-pdf89Three tasks. One skill.1011## Read `design/design.md` before any CREATE or REFORMAT work.1213## ZhiYuan/Pi execution1415When this skill is run inside ZhiYuan, call `run_skill_script` for the bundled `.py`, `.js`,16and `.sh` pipeline steps. Pass each argument separately in `args`; do not call `python3`,17`uv`, or `bash` directly. The application chooses the managed Python/uv/Node/Git Bash runtime18and returns a structured runtime error instead of misreporting the input PDF as missing.1920Example:2122```json23{24 "skillId": "pdf",25 "script": "scripts/fill_inspect.py",26 "args": ["--input", "form.pdf"]27}28```2930---3132## Route table3334| User intent | Route | Scripts used |35|---|---|---|36| Generate a new PDF from scratch | **CREATE** | `palette.py` → `cover.py` → `render_cover.js` → `render_body.py` → `merge.py` |37| Fill / complete form fields in an existing PDF | **FILL** | `fill_inspect.py` → `fill_write.py` |38| Reformat / re-style an existing document | **REFORMAT** | `reformat_parse.py` → then full CREATE pipeline |3940**Rule:** when in doubt between CREATE and REFORMAT, ask whether the user has an existing document to start from. If yes → REFORMAT. If no → CREATE.4142---4344## Route A: CREATE4546Full pipeline — content → design tokens → cover → body → merged PDF.4748```bash49bash scripts/make.sh run \50 --title "Q3 Strategy Review" --type proposal \51 --author "Strategy Team" --date "October 2025" \52 --accent "#2D5F8A" \53 --content content.json --out report.pdf54```5556**Doc types:** `report` · `proposal` · `resume` · `portfolio` · `academic` · `general` · `minimal` · `stripe` · `diagonal` · `frame` · `editorial` · `magazine` · `darkroom` · `terminal` · `poster`5758| Type | Cover pattern | Visual identity |59|---|---|---|60| `report` | `fullbleed` | Dark bg, dot grid, Playfair Display |61| `proposal` | `split` | Left panel + right geometric, Syne |62| `resume` | `typographic` | Oversized first-word, DM Serif Display |63| `portfolio` | `atmospheric` | Near-black, radial glow, Fraunces |64| `academic` | `typographic` | Light bg, classical serif, EB Garamond |65| `general` | `fullbleed` | Dark slate, Outfit |66| `minimal` | `minimal` | White + single 8px accent bar, Cormorant Garamond |67| `stripe` | `stripe` | 3 bold horizontal color bands, Barlow Condensed |68| `diagonal` | `diagonal` | SVG angled cut, dark/light halves, Montserrat |69| `frame` | `frame` | Inset border, corner ornaments, Cormorant |70| `editorial` | `editorial` | Ghost letter, all-caps title, Bebas Neue |71| `magazine` | `magazine` | Warm cream bg, centered stack, hero image, Playfair Display |72| `darkroom` | `darkroom` | Navy bg, centered stack, grayscale image, Playfair Display |73| `terminal` | `terminal` | Near-black, grid lines, monospace, neon green |74| `poster` | `poster` | White bg, thick sidebar, oversized title, Barlow Condensed |7576Cover extras (inject into tokens via `--abstract`, `--cover-image`):77- `--abstract "text"` — abstract text block on the cover (magazine/darkroom)78- `--cover-image "url"` — hero image URL/path (magazine, darkroom, poster)7980**Color overrides — always choose these based on document content:**81- `--accent "#HEX"` — override the accent color; `accent_lt` is auto-derived by lightening toward white82- `--cover-bg "#HEX"` — override the cover background color8384**Accent color selection guidance:**8586You have creative authority over the accent color. Pick it from the document's semantic context — title, industry, purpose, audience — not from generic "safe" choices. The accent appears on section rules, callout bars, table headers, and the cover: it carries the document's visual identity.8788| Context | Suggested accent range |89|---|---|90| Legal / compliance / finance | Deep navy `#1C3A5E`, charcoal `#2E3440`, slate `#3D4C5E` |91| Healthcare / medical | Teal-green `#2A6B5A`, cool green `#3A7D6A` |92| Technology / engineering | Steel blue `#2D5F8A`, indigo `#3D4F8A` |93| Environmental / sustainability | Forest `#2E5E3A`, olive `#4A5E2A` |94| Creative / arts / culture | Burgundy `#6B2A35`, plum `#5A2A6B`, terracotta `#8A3A2A` |95| Academic / research | Deep teal `#2A5A6B`, library blue `#2A4A6B` |96| Corporate / neutral | Slate `#3D4A5A`, graphite `#444C56` |97| Luxury / premium | Warm black `#1A1208`, deep bronze `#4A3820` |9899**Rule:** choose a color that a thoughtful designer would select for this specific document — not the type's default. Muted, desaturated tones work best; avoid vivid primaries. When in doubt, go darker and more neutral.100101**content.json block types:**102103| Block | Usage | Key fields |104|---|---|---|105| `h1` | Section heading + accent rule | `text` |106| `h2` | Subsection heading | `text` |107| `h3` | Sub-subsection (bold) | `text` |108| `body` | Justified paragraph; supports `<b>` `<i>` markup | `text` |109| `bullet` | Unordered list item (• prefix) | `text` |110| `numbered` | Ordered list item — counter auto-resets on non-numbered blocks | `text` |111| `callout` | Highlighted insight box with accent left bar | `text` |112| `table` | Data table — accent header, alternating row tints | `headers`, `rows`, `col_widths`?, `caption`? |113| `image` | Embedded image scaled to column width | `path`/`src`, `caption`? |114| `figure` | Image with auto-numbered "Figure N:" caption | `path`/`src`, `caption`? |115| `code` | Monospace code block with accent left border | `text`, `language`? |116| `math` | Display math — LaTeX syntax via matplotlib mathtext | `text`, `label`?, `caption`? |117| `chart` | Bar / line / pie chart rendered with matplotlib | `chart_type`, `labels`, `datasets`, `title`?, `x_label`?, `y_label`?, `caption`?, `figure`? |118| `flowchart` | Process diagram with nodes + edges via matplotlib | `nodes`, `edges`, `caption`?, `figure`? |119| `bibliography` | Numbered reference list with hanging indent | `items` [{id, text}], `title`? |120| `divider` | Accent-colored full-width rule | — |121| `caption` | Small muted label | `text` |122| `pagebreak` | Force a new page | — |123| `spacer` | Vertical whitespace | `pt` (default 12) |124125**chart / flowchart schemas:**126```json127{"type":"chart","chart_type":"bar","labels":["Q1","Q2","Q3","Q4"],128 "datasets":[{"label":"Revenue","values":[120,145,132,178]}],"caption":"Q results"}129130{"type":"flowchart",131 "nodes":[{"id":"s","label":"Start","shape":"oval"},132 {"id":"p","label":"Process","shape":"rect"},133 {"id":"d","label":"Valid?","shape":"diamond"},134 {"id":"e","label":"End","shape":"oval"}],135 "edges":[{"from":"s","to":"p"},{"from":"p","to":"d"},136 {"from":"d","to":"e","label":"Yes"},{"from":"d","to":"p","label":"No"}]}137138{"type":"bibliography","items":[139 {"id":"1","text":"Author (Year). Title. Publisher."}]}140```141142### Mandatory visual QA143144After every CREATE or layout-changing REFORMAT, render every page and inspect145the contact sheet before delivery. In the packaged app, `uv` and Python are146private runtimes; do not install packages into the base interpreter.147148```bash149uv run --with pypdfium2 --with pillow python \150 SKILL_DIR/scripts/pdf_inspect.py final.pdf -o pdf-qa151```152153The command writes one PNG per page, `contact-sheet.png`, and154`inspection.json`. Review the contact sheet and every `low_content_pages`155entry. Fix unexplained blank pages, clipping, overlap, or broken glyphs and156rerun inspection. A PDF that merely opens is not visually validated.157158---159160## Route B: FILL161162Fill form fields in an existing PDF without altering layout or design.163164```bash165# Step 1: inspect166python3 scripts/fill_inspect.py --input form.pdf167168# Step 2: fill169python3 scripts/fill_write.py --input form.pdf --out filled.pdf \170 --values '{"FirstName": "Jane", "Agree": "true", "Country": "US"}'171```172173| Field type | Value format |174|---|---|175| `text` | Any string |176| `checkbox` | `"true"` or `"false"` |177| `dropdown` | Must match a choice value from inspect output |178| `radio` | Must match a radio value (often starts with `/`) |179180Always run `fill_inspect.py` first to get exact field names.181182---183184## Route C: REFORMAT185186Parse an existing document → content.json → CREATE pipeline.187188```bash189bash scripts/make.sh reformat \190 --input source.md --title "My Report" --type report --out output.pdf191```192193**Supported input formats:** `.md` `.txt` `.pdf` `.json`194195---196197## Environment198199```bash200bash scripts/make.sh check # verify all deps201bash scripts/make.sh fix # auto-install missing deps202bash scripts/make.sh demo # build a sample PDF203```204205| Tool | Used by | Install |206|---|---|---|207| Python 3.9+ | all `.py` scripts | system |208| `reportlab` | `render_body.py` | `pip install reportlab` |209| `pypdf` | fill, merge, reformat | `pip install pypdf` |210| `pypdfium2` + `Pillow` | full-page visual QA | `uv run --with pypdfium2 --with pillow ...` |211| Node.js 18+ | `render_cover.js` | system |212| `playwright` + Chromium | `render_cover.js` | `npm install -g playwright && npx playwright install chromium` |