make-pdf
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHost-neutral runtime bindings
与宿主无关的运行时绑定
These assignments select stable paths only; they do not install anything or grant consent:
bash
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
GSTACK_ROOT="$GSTACK_HOME"
GSTACK_STATE_ROOT="$GSTACK_HOME"
GSTACK_BIN="$GSTACK_HOME/bin"
BUN_CMD="$GSTACK_BIN/bun"
B="$GSTACK_BIN/browse"
P="$GSTACK_BIN/make-pdf"以下配置仅选择稳定路径;不会安装任何内容或获取授权:
bash
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
GSTACK_ROOT="$GSTACK_HOME"
GSTACK_STATE_ROOT="$GSTACK_HOME"
GSTACK_BIN="$GSTACK_HOME/bin"
BUN_CMD="$GSTACK_BIN/bun"
B="$GSTACK_BIN/browse"
P="$GSTACK_BIN/make-pdf"Optional runtime binding
可选运行时绑定
This workflow requires the capability. Read before attempting installation. Pure planning or document review can continue without it.
If unavailable, follow the consent-first capability handoff in . It expands to , , and ; do not guess a checkout-relative setup command.
pdfreferences/RUNTIME.mdpdfreferences/RUNTIME.mdpdfdiagrambrowser此工作流需要功能。尝试安装前请阅读。纯规划或文档审核可在无此功能的情况下继续。
若此功能不可用,请遵循中“先获取授权”的功能移交流程。该功能扩展包含、和;请勿猜测基于检出路径的设置命令。
pdfreferences/RUNTIME.mdreferences/RUNTIME.mdpdfpdfdiagrambrowsermake-pdf: publication-quality PDFs from markdown
make-pdf:从Markdown生成出版级PDF
Turn files into PDFs that look like Faber & Faber essays: 1in margins,
left-aligned body, Helvetica throughout, curly quotes and em dashes, optional
cover page and clickable TOC, diagonal DRAFT watermark when you need it.
Copy-paste from the PDF produces clean words, never "S a i l i n g".
.mdOn Linux, install for correct rendering — Helvetica and Arial
aren't present by default, and Liberation Sans is the standard metric-compatible
fallback. CI and Docker builds install it automatically via Dockerfile.ci.
fonts-liberationEmoji need a color-emoji font. macOS (Apple Color Emoji) and Windows (Segoe UI
Emoji) ship one; most Linux distros and containers ship none, so emoji render as
empty boxes (▯). the explicitly approved runtime capability attempts to install on Linux
(apt/dnf/pacman/apk, best-effort) and the print CSS falls back through Apple /
Segoe / Noto emoji families. Set to skip the install (CI
without sudo, managed or offline machines).
pdffonts-noto-color-emojiGSTACK_SKIP_FONTS=1将.md文件转换为类似Faber & Faber出版社风格的PDF:1英寸边距、正文左对齐、全程使用Helvetica字体、弯引号和破折号,可添加封面和可点击目录,需要时可添加斜向DRAFT水印。从PDF中复制粘贴可得到干净的文本,不会出现“S a i l i n g”这样的拆分字符。
在Linux系统上,需安装以确保正确渲染——Helvetica和Arial字体默认未预装,Liberation Sans是标准的 metric-compatible 替代字体。CI和Docker构建会通过Dockerfile.ci自动安装该字体。
fonts-liberation表情符号需要彩色 emoji 字体。macOS(Apple Color Emoji)和Windows(Segoe UI Emoji)默认自带;大多数Linux发行版和容器则没有,因此表情符号会显示为空框(▯)。已明确批准的运行时功能会尝试在Linux系统上安装(支持apt/dnf/pacman/apk,尽最大努力),打印CSS会依次回退使用Apple/Segoe/Noto emoji字体族。设置可跳过安装(适用于无sudo权限的CI环境、受控或离线机器)。
pdffonts-noto-color-emojiGSTACK_SKIP_FONTS=1Core patterns
核心使用模式
80% case — memo/letter
80%场景——备忘录/信函
One command, no flags. Gets a clean PDF with running header + page numbers
- CONFIDENTIAL footer by default.
bash
$P generate letter.md # writes /tmp/letter.pdf
$P generate letter.md letter.pdf # explicit output path一条命令,无需参数。默认生成包含页眉+页码+CONFIDENTIAL页脚的整洁PDF。
bash
$P generate letter.md # 生成/tmp/letter.pdf
$P generate letter.md letter.pdf # 指定输出路径Publication mode — cover + TOC + chapter breaks
出版模式——封面+目录+章节分页
bash
$P generate --cover --toc --author "Garry Tan" --title "On Horizons" \
essay.md essay.pdfEach top-level H1 in the markdown starts a new page. Disable with
for memos that happen to have multiple H1s.
--no-chapter-breaksbash
$P generate --cover --toc --author "Garry Tan" --title "On Horizons" \
essay.md essay.pdfMarkdown中的每个顶级H1标题都会开启新页面。若备忘录包含多个H1但不需要分页,可使用参数禁用。
--no-chapter-breaksDraft-stage watermark
草稿阶段水印
bash
$P generate --watermark DRAFT memo.md draft.pdfDiagonal 10% opacity DRAFT across every page. When the draft is final, drop
the flag and regenerate.
bash
$P generate --watermark DRAFT memo.md draft.pdf在每一页添加透明度为10%的斜向DRAFT水印。草稿定稿后,移除该参数重新生成即可。
Fast iteration via preview
通过预览快速迭代
bash
$P preview essay.mdRenders HTML with the same print CSS and opens it in your browser. Refresh
as you edit the markdown. Skip the PDF round trip until you're ready.
bash
$P preview essay.md使用相同的打印CSS渲染HTML并在浏览器中打开。编辑Markdown时刷新页面即可预览。在准备就绪前可跳过PDF转换步骤。
Brand-free (no CONFIDENTIAL footer)
无品牌标识(无CONFIDENTIAL页脚)
bash
$P generate --no-confidential memo.md memo.pdfbash
$P generate --no-confidential memo.md memo.pdfDiagrams — mermaid and excalidraw fences render as pictures
图表——Mermaid和Excalidraw代码块渲染为图片
A column-0 or fence in the markdown renders
as a crisp vector diagram, fully offline (vendored bundle, no CDN). Indented
fences (inside lists) stay plain code blocks by design. A broken fence
produces a visible red diagnostic block with the parse error — never silent
raw code.
```mermaid```excalidrawFence info-string options:
```mermaid title="Auth flow" ← caption + aria-label
```mermaid render=false ← keep it as a code block (today's behavior)
```mermaid page=landscape ← force this diagram onto a landscape page
```mermaid page=portrait ← veto auto-landscape for this diagramA fence contains a full .excalidraw scene file (what
excalidraw.com saves). Authoring NEW diagrams from English is 's
job — it emits an editable triplet (source, .excalidraw, SVG/PNG) and pairs
with this skill: embed the source in your markdown, not the PNG.
```excalidraw/diagram.mmdMarkdown中第0列的或代码块会渲染为清晰的矢量图,完全离线(使用本地打包文件,无CDN依赖)。缩进的代码块(位于列表内)默认保持纯代码块格式。若代码块存在错误,会生成带有解析错误的红色可见诊断块——绝不会静默显示原始代码。
```mermaid```excalidraw代码块信息字符串选项:
```mermaid title="Auth flow" ← 标题 + aria-label
```mermaid render=false ← 保持为代码块(当前默认行为)
```mermaid page=landscape ← 强制此图表单独占用横向页面
```mermaid page=portrait ← 否决此图表的自动横向设置```excalidraw/diagramImages — scaled right, never truncated
图片——自动缩放,绝不截断
Local images inline automatically (relative paths resolve against the
markdown file). Every image caps at the content box — zero truncation, ever.
Oversized photos downscale to print resolution (300dpi) so payloads stay
small with no visible quality loss.
Remote (http/https) images are blocked with a visible placeholder by
default — offline posture; pass to fetch them. An image
that resolves outside the markdown's directory (even via symlink) still
inlines, but warns loudly; makes it fatal. Files over 64MB or
non-regular files (fifos, devices) degrade to a placeholder instead of
hanging the run.
--allow-network--strictPer-image directives, written immediately after the image:
{width=full} ← stretch to content-box width
{width=50%} ← percentage or 3in/8cm/200px
{page=landscape} ← give it its own landscape page
{page=portrait} ← veto auto-landscapeWide, small-text diagram images auto-promote to their own landscape page
(conservative: aspect ≥ 1.8, width over ~2.5x the content box, AND a
diagram-ish alt word — diagram/architecture/flowchart/chart/graph). The
promoted page is vertically centered. When the heuristic guesses wrong,
vetoes it; false negatives just need .
{page=portrait}{page=landscape}本地图片会自动嵌入(相对路径基于Markdown文件所在目录解析)。所有图片都会适配内容框大小——绝不出现截断。过大的照片会缩小至打印分辨率(300dpi),因此文件体积更小且无可见画质损失。
远程(http/https)图片默认会被阻止并显示可见占位符——遵循离线策略;添加参数可允许获取远程图片。若图片位于Markdown目录之外(即使通过符号链接),仍会嵌入,但会发出强烈警告;使用参数会将此情况视为致命错误。超过64MB的文件或非常规文件(管道、设备文件)会降级显示为占位符,避免程序挂起。
--allow-network--strict图片专属指令,需紧跟在图片之后:
{width=full} ← 拉伸至内容框宽度
{width=50%} ← 百分比或3in/8cm/200px
{page=landscape} ← 为该图片单独分配横向页面
{page=portrait} ← 否决自动横向设置宽幅、小字的图表图片会自动升级为单独的横向页面(判断条件:宽高比≥1.8,宽度超过内容框约2.5倍,且alt文本包含图表相关词汇——diagram/architecture/flowchart/chart/graph)。升级后的页面会垂直居中。若启发式判断出错,可使用否决;若未自动升级,只需添加即可。
{page=portrait}{page=landscape}Other formats — single-file HTML and Word
其他格式——单文件HTML和Word文档
bash
$P generate readme.md out.html --to html # ONE self-contained file: inline
# SVG diagrams, data-URI images,
# zero network refs, screen-readable
$P generate readme.md out.docx --to docx # Word: content fidelity (headings,
# tables, code, diagrams as PNG) —
# layout is Word's, not ours--to--format--page-sizebash
$P generate readme.md out.html --to html # 生成单个独立文件:内联
# SVG图表、data-URI图片,
# 无网络依赖,适合屏幕阅读
$P generate readme.md out.docx --to docx # Word文档:内容保真(标题、
# 表格、代码、图表转为PNG)——
# 布局由Word控制,而非本工具--to--format--page-sizeCI mode — fail loud on missing assets
CI模式——缺失资源时直接报错
bash
$P generate docs.md --strict # missing, remote, out-of-tree, oversized,
# and non-regular-file images exit non-zero
# instead of warn + placeholderbash
$P generate docs.md --strict # 缺失、远程、目录外、过大或
# 非常规文件的图片会导致非零退出码
# 而非警告+占位符Common flags
常用参数
Page layout:
--margins <dim> 1in (default) | 72pt | 2.54cm | 25mm
--page-size letter|a4|legal
Structure:
--cover Cover page (title, author, date, hairline rule)
--toc Clickable TOC with page numbers
--no-chapter-breaks Don't start a new page at every H1
Branding:
--watermark <text> Diagonal watermark ("DRAFT", "CONFIDENTIAL")
--header-template <html> Custom running header
--footer-template <html> Custom footer (mutex with --page-numbers)
--no-confidential Suppress the CONFIDENTIAL right-footer
Output:
--to pdf|html|docx Output format (default: pdf). html = single
self-contained file; docx = content fidelity.
--strict Missing, remote, out-of-tree, oversized, or
non-regular-file images fail the run (CI mode).
--page-numbers "N of M" footer (default on)
--tagged Accessible PDF (default on)
--outline PDF bookmarks from headings (default on)
--quiet Suppress progress on stderr
--verbose Per-stage timings
Network:
--allow-network Fetch external images. Off by default: remote
images render as a visible blocked placeholder
(no tracking pixels fetch at print time).
Metadata:
--title "..." Document title (defaults to first H1)
--author "..." Author for cover + PDF metadata
--date "..." Date for cover (defaults to today)页面布局:
--margins <dim> 默认1英寸 | 72pt | 2.54cm | 25mm
--page-size letter|a4|legal
结构:
--cover 封面(标题、作者、日期、细线条分隔)
--toc 带页码的可点击目录
--no-chapter-breaks 不在每个H1标题处开启新页面
品牌标识:
--watermark <text> 斜向水印(如“DRAFT”“CONFIDENTIAL”)
--header-template <html> 自定义页眉
--footer-template <html> 自定义页脚(与--page-numbers互斥)
--no-confidential 隐藏右下角的CONFIDENTIAL页脚
输出:
--to pdf|html|docx 输出格式(默认:pdf)。html = 单个
独立文件;docx = 内容保真。
--strict 缺失、远程、目录外、过大或非常规文件的图片
会导致运行失败(CI模式)。
--page-numbers “第N页/共M页”页脚(默认开启)
--tagged 可访问性PDF(默认开启)
--outline 从标题生成PDF书签(默认开启)
--quiet 抑制stderr中的进度输出
--verbose 显示各阶段耗时
网络:
--allow-network 获取外部图片。默认关闭:远程图片
会显示可见的阻止占位符
(打印时不会获取跟踪像素)。
元数据:
--title "..." 文档标题(默认使用第一个H1标题)
--author "..." 封面及PDF元数据中的作者
--date "..." 封面日期(默认使用今日日期)When Claude should run it
Claude应何时运行此工具
Watch for markdown-to-PDF intent. Any of these patterns → run :
$P generate- "Can you make this markdown a PDF"
- "Export it as a PDF"
- "Turn this letter into a PDF"
- "I need a PDF of the essay"
- "Print this as a PDF for me"
If the user has a file open and says "make it look nice", propose
and ask before running.
.md$P generate --cover --toc留意Markdown转PDF的需求意图。出现以下任一表述时,运行:
$P generate- “你能把这个Markdown转成PDF吗”
- “导出为PDF”
- “把这封信转成PDF”
- “我需要这篇文章的PDF版本”
- “帮我把这个打印成PDF”
若用户打开了一个.md文件并说“让它看起来更美观”,可建议使用,并在运行前征得用户同意。
$P generate --cover --tocDebugging
调试
- Output looks empty / blank → check browse daemon is running: .
$B status - Fragmented text on copy-paste → highlight.js output (Phase 4). Retry with
once that flag exists. For now, remove fenced code blocks and regenerate.
--no-syntax - Paged.js timeout → probably no headings in the markdown. Drop .
--toc - "[remote image blocked]" placeholder in the output → add (understand you're giving the markdown file permission to fetch from its image URLs).
--allow-network - Generated PDF too tall/wide → or
--page-size a4.--margins 0.75in
- 输出为空/空白 → 检查browse守护进程是否运行:。
$B status - 复制粘贴时文本碎片化 → 这是highlight.js的输出(第4阶段)。待参数推出后可重试。目前,可移除代码块后重新生成。
--no-syntax - Paged.js超时 → 可能是Markdown中没有标题。移除参数。
--toc - 输出中出现“[remote image blocked]”占位符 → 添加参数(请注意,这会赋予Markdown文件从其图片URL获取资源的权限)。
--allow-network - 生成的PDF过高/过宽 → 使用或
--page-size a4参数。--margins 0.75in
Output contract
输出约定
stdout: /tmp/letter.pdf ← just the path, one line
stderr: Rendering HTML... ← progress spinner (unless --quiet)
Generating PDF...
Done in 1.5s. 43 words · 22KB · /tmp/letter.pdf
exit code: 0 success / 1 bad args / 2 render error / 3 Paged.js timeout
/ 4 browse unavailableCapture the path: — then use .
PDF=$($P generate letter.md)$PDF标准输出:/tmp/letter.pdf ← 仅输出路径,单行
标准错误输出:Rendering HTML... ← 进度提示(除非使用--quiet)
Generating PDF...
Done in 1.5s. 43 words · 22KB · /tmp/letter.pdf
退出码:0 成功 / 1 参数错误 / 2 渲染错误 / 3 Paged.js超时
/ 4 browse不可用捕获路径: —— 之后可使用变量。
PDF=$($P generate letter.md)$PDF