关于 render-pdf-doc
使用原生 pandoc 和 xelatex 将 Markdown 文档渲染为 PDF 的技能,重点处理 CJK 字体和表格列宽。适合需要版式检查与字形覆盖诊断、且不使用 Quarto 的文档作者。
主要功能
- 01使用 pandoc 和 xelatex 渲染 Markdown
- 02推算表格比例列宽
- 03检查 CJK 与符号字形覆盖
- 04检测渲染中的缺失字形
- 05配置字体与 PDF 版式
适用场景
- 01将 Markdown 论文生成 PDF
- 02调整 PDF 输出的表格列宽
- 03检查 CJK 和科学符号的字体覆盖
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aperivue/ medsci-skills --skill render-pdf-doc安装后在 Claude Code 中输入/render-pdf-doc确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
skill.ymlreferences/known_pitfalls.mdpandoc_korean_cheatsheet.mdscripts/check_deps.shinfer_colwidths.pyrender_pdf.shscan_glyph_coverage.pyxecjk_korean.luaxecjk_korean.textemplates/anchor-doc_ko.mdanchor-doc.mdbriefing-handout_ko.mdbriefing-handout.mdproposal-cover_ko.mdproposal-cover.mdreference-table_ko.mdreference-table.mdtests/test_font_faces.pytest_glyph_coverage.shtest_render_pdf.pytests/fixtures/glyph_plain.mdglyph_risky.md详细介绍
Render-PDF-Doc 技能
此技能仅处理布局(CJK 字体、表格列宽),使用原生 pandoc + xelatex — 不使用 Quarto,因为其 tbl-colwidths 据报告存在 PDF 回归问题(issues 6089/9200)。不适用于:带参考文献的手稿(/manage-refs scripts/render_pandoc.sh)、机构 .docx 表格(/fill-protocol)、ICMJE COI 表格(/fill-icmje-coi)、图片或 PPTX(/make-figures、/present-paper)。
依赖项
包装脚本需要 Python 3。FontTools 为可选项,用于检查字体文件覆盖范围(python3 -m pip install fonttools)。
# macOS
brew install pandoc
brew install --cask mactex-no-gui # xelatex + xeCJK (~5 GB)
# Linux
sudo apt-get install pandoc texlive-xetex texlive-lang-cjk fonts-noto-cjk
# Windows (PowerShell) — run in Git Bash afterwards
winget install --id JohnMacFarlane.Pandoc
winget install --id MiKTeX.MiKTeX # xelatex; installs missing LaTeX packages on demand
# No CJK font download needed: Malgun Gothic ships with Windows 7+ and is the default here.
检测:
bash scripts/check_deps.sh
在 Windows / Git Bash 上,MiKTeX 的 bin 目录
(%LOCALAPPDATA%\Programs\MiKTeX\miktex\bin\x64)通常不在 PATH 中;check_deps.sh 和
render_pdf.sh 都会探测该目录。如果 xelatex 仍显示 [MISS],请将该目录添加到 PATH。
工作流
第 1 步 — 编写带 frontmatter 的 Markdown
---
title: "Paper 2 Calibration Anchor — Q&A Grid"
author: "<Author Group>"
date: "2026-05-01"
mainfont: "Apple SD Gothic Neo" # macOS default
CJKmainfont: "Apple SD Gothic Neo"
geometry: "margin=0.85in"
fontsize: 11pt
linestretch: 1.25
colorlinks: true
---
- 设置
mainfont和CJKmainfont:如果不设置CJKmainfont,韩文将回退到 Times New Roman(字形异常或空白)。Linux/CI 上使用Noto Sans CJK KR,Windows 上使用Malgun Gothic;如果缺少这些字段,渲染脚本会自动检测对应操作系统的默认字体。 - 表格中的每个数字都应从源 CSV 或分析输出中读取。不要从正文中重新抄写数字,也不要沿用早期草稿中的数字——v3 中正确的表格并不能证明它在 v4 中仍然正确。
- 用于传阅的 PDF 不应包含修改历史、内部版本号(例如 v3.2.2)或 PI 署名:请将这些内容放入单独的传阅文件或补充材料中。将收到的原始来源文件(合作者发送的
.docx或.eml)作为独立文件保留,不要修改——PDF 是衍生文件,下一轮修订时会与来源文件进行差异比较。如果该来源文件由合作者使用 AI 起草,在将其纳入 PDF 前,请根据底层论文或分析输出重新推导其中的每个数字、分母和作者年份。
第 2 步 — 推算列宽
切勿将管道表格的列等宽分配:这样一来,仅包含短标签的列会与数据列同宽,挤压数据列。应根据内容确定列宽:
python3 scripts/infer_colwidths.py input.md > input.colwidths.md
对于每个管道表格,脚本会计算每列的显示宽度 = max(len(header), max(len(cell)))
(CJK 字符占 2 格,ASCII 字符占 1 格),并按比例重写分隔行中的短横线数量。若要手动设置列宽,请自行编写分隔行中的短横线,并在渲染时省略 --infer-colwidths。
步骤 3 — 渲染
bash scripts/render_pdf.sh -i input.colwidths.md -o output.pdf
或一次性执行:
bash scripts/render_pdf.sh -i input.md -o output.pdf --infer-colwidths
Frontmatter 优先于封装器默认值,包括 --font / --cjk-font。
缺失字段使用封装器或操作系统默认值。geometry、
fontsize、linestretch 和 colorlinks(包括 false)也适用此规则。显式传入的 pandoc
-V / -M 参数仍会覆盖 frontmatter;例如:
-- -V fontsize=10pt。封装器记录的是字体回退信息,而非最终字体。
标准 article 类仅支持 10pt、11pt 和 12pt,其他字号会被静默忽略。当生效的
fontsize 为其他值且未设置 documentclass 时,封装器会切换到 KOMA-Script scrartcl(pandoc
文档中推荐的做法);如果你未设置 classoption,则会添加 classoption: fontsize=<size>(KOMA 只能通过此方式读取 8.5pt 这样的分数字号),
并记录此次切换。自行设置 documentclass 即可覆盖此行为。
xeCJK 的默认值针对中文进行了设置:它会删除弯引号和 en/em dash 后的空格,并在拉丁字母或数字与韩文之间插入空格:
typed: “no difference” and AI를 썼다 3개
printed: “no difference”and AI 를 썼다 3 개
封装器会关闭这两项功能(scripts/xecjk_korean.tex),以便 PDF 保留你输入的空格。该文件会追加到你的
header-includes 中;如果你在 -- 后传入 -H(这会替换
header-includes),该文件会作为另一个 -H 添加。如果以其他方式指定页眉(通过带有
include-in-header 的 --defaults 文件,或 -V header-includes=...),则会覆盖追加的内容,因此请同时传入
-H "${CLAUDE_SKILL_DIR}/scripts/xecjk_korean.tex"。--xecjk-defaults 会保留
xeCJK 自带的空格处理方式,例如用于中文或日文文本。可通过
pdftotext -layout out.pdf - | grep -cE '[”’][A-Za-z]' 检查(除所有格外,结果应为 0)。
步骤 3.5 — 科学符号与 CJK 字形扫描(渲染前)
xelatex 即使缺少字形也可能成功运行。render_pdf.sh 会统计 pandoc 转发的
Missing character 警告:如有警告,它会列出每个字形(码位、计数、字体),并以状态码 4 退出——PDF 会写入,但内容不完整。警告从 pandoc 的 JSON --log 中读取(如果你在 -- 后传入日志文件,则使用该文件),因此透传的 --quiet 不会将其隐藏。
--allow-missing-glyphs 会打印相同的列表并以状态码 0 退出。学术 Markdown
中常见一些默认拉丁字体缺失的字形:转向箭头(→ ↑ ↓)、
数学运算符(− ≤ ≥ ± √ ∪ × ≈ ≠)、统计学希腊字母(κ μ σ β)、项目符号/标记(• ★ ✓)
以及 CJK 字符。请先扫描源文件,以便在提交前发现字形被静默丢弃的情况:
python3 scripts/scan_glyph_coverage.py input.md --strict
# real cmap check when you have the font file + fonttools:
python3 scripts/scan_glyph_coverage.py input.md --font "/path/to/body.otf" --strict
# TTC/OTC collections require the zero-based face index used by the renderer:
python3 scripts/scan_glyph_coverage.py input.md --font "/path/to/body.ttc" --font-index 0 --strict --json glyphs.json
不带 --font 时,它会按类别对有风险的字形进行分组(仅供参考);使用 --font 和 fonttools 时,它会检查源文件中的每个非 ASCII 字符,确认指定字体是否能绘制这些字符——不局限于上述五类,因此 °、µ、²、‰、∞ 和 – 也会纳入检查——并报告哪些字形不在单个字体字面的首选 Unicode cmap 中(不会查找格式字符,例如 BOM 或零宽连接符,以及 pandoc 会转写为 ASCII TeX 的不换行空格和 …)。各字体集合字面之间不会合并覆盖情况——请选择与渲染字体相符的字面(报告中包含索引和 PostScript 名称)。如果依赖项缺失、字体不可读、未选择字面或索引无效,结果会显示为 font_checked: false,并在 font_check 中说明原因;此时 missing_in_font 列表为空表示未经验证,而非完全覆盖。默认模式以状态码 0 退出;当有风险的字形未经验证或缺失时,--strict 会以状态码 1 退出(仅含 ASCII 的输入仍以状态码 0 退出)。扫描不会验证字形塑形、回退字体、数学字体或最终 PDF 字形。
如果存在有风险的字形,请确保 mainfont/CJKmainfont 能覆盖这些字形——支持 CJK 的字体,例如 Apple SD Gothic Neo / Noto Sans CJK,通常可以覆盖箭头和韩文,但仍可能缺少真正的减号 − U+2212 和 ★。DOCX 是权威版本;PDF 是便于查看的副本——绝不能让 PDF 渲染丢失文档所需的字形。
步骤 4 — 目视核验
打开 PDF 并检查:
- 第一列的标签保持在一行;数据列宽度足够。
- 没有显示异常的韩文字符(回退到 Times New Roman 表示未应用
CJKmainfont)。 - 没有缺失的科学符号(箭头、−、≤、±、√)——步骤 3.5 的扫描会标出候选项。
- 没有泄露变更历史或内部版本号。
如果渲染结果仍有问题(长破折号溢出、CJKmainfont 下的智能引号、单元格内的 |),请阅读 references/known_pitfalls.md;有关韩文 frontmatter 和字体模式,请阅读 references/pandoc_korean_cheatsheet.md。
模板
templates/ 中的 Markdown 起始模板(默认英文;每个模板都附有韩文变体 *_ko.md),其中的占位符标记为 ``:
anchor-doc.md— 问答网格proposal-cover.md— 研究提案封面briefing-handout.md— 会议简报(1 页)reference-table.md— 对照表格式