typeset
把 Markdown 生成排版规范的中文 .docx(合同、协议、服务确认单、方案书、正式函件等)。凡是要交付一份中文 Word 文档——尤其是要盖章签字、要发给客户或对方法务的——都用这个 skill,即使用户只说"帮我写份合同""转成 Word""给我个 docx""做个协议"而没提排版。它解决的是 pandoc 默认输出拿去当中文正式文书会很难看的问题:青蓝色不加粗的标题、Letter 纸型、Aptos 西文字体、表格被分页劈成两半、签章区甲乙方分到两页。也用于修正已有中文 docx 的版式,或需要 A4 / 宋体 / 1.5 倍行距 / 页眉横线 / 页码 / 封面页 / 签章区这类中文公文版式要求时。
ソース情報
- リポジトリ
- cerul-ai/typeset
- ソースの最終更新活動
- 2026年8月18日 03:31
- 検出された SKILL.md の言語
- 中国語
- スター
- 21
- フォーク
- 3
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
SKILL.md を表示中
SKILL.md
ソースの指示 · 読み取り専用プレビュー- name
- typeset
- description
- 把 Markdown 生成排版规范的中文 .docx(合同、协议、服务确认单、方案书、正式函件等)。凡是要交付一份中文 Word 文档——尤其是要盖章签字、要发给客户或对方法务的——都用这个 skill,即使用户只说"帮我写份合同""转成 Word""给我个 docx""做个协议"而没提排版。它解决的是 pandoc 默认输出拿去当中文正式文书会很难看的问题:青蓝色不加粗的标题、Letter 纸型、Aptos 西文字体、表格被分页劈成两半、签章区甲乙方分到两页。也用于修正已有中文 docx 的版式,或需要 A4 / 宋体 / 1.5 倍行距 / 页眉横线 / 页码 / 封面页 / 签章区这类中文公文版式要求时。
# 中文正式文书的 .docx 生成
## 这个 skill 解决什么
`pandoc x.md -o x.docx` 能跑通,但产物是给英文博客用的:标题 `#0F4761` 青蓝色、20/16/14pt **且不加粗**,Letter 纸型,西文 Aptos。拿去做中文合同,对方法务一眼就觉得不正式。
更麻烦的是三类只有"看了才知道"的问题:表格跨页被劈成两半、条款标题孤零零留在页底而正文在下一页、签章区甲方在上一页乙方在下一页。这些在生成时不报错,在 Word 里打开才看得见。
所以这个 skill 的核心不只是参数,还有**一定要把每页渲染成图片看一眼**的工作流。
## 工作流
```bash
# 1. 写 markdown(模板见 templates/contract.md)
# 2. 生成
python3 scripts/build.py 合同.md
# 3. 检查:结构 lint + 转 PDF + 逐页渲染
python3 scripts/verify.py 合同.docx --render
# 4. 真的去看渲染出来的 jpg —— 至少看封面、表格页、签章页
```
第 4 步不能省。前三步全部通过、文档在 Word 里能打开,版面依然可能很难看。看图发现问题后回到 markdown 或 `build.py` 改,重跑。
`verify.py` 的版面体检会标出"偏空的页",那通常意味着有东西被强行推到了下一页——可能是对的(附件另起页),也可能是表格放不下。看图确认。
### 两个渲染器,各验各的
**LibreOffice 匹配不到「宋体 / 黑体」这类中文字体名**(即使系统里装着),会回退到 Arial Unicode MS 之类。替换字的度量不同,连**页数都会显著变化**——同一份合同实测 Word 出 17 页、LibreOffice 出 27 页,差 59%。
所以不能只用一个渲染器:
| 渲染器 | 解析字体 | 适合验什么 | 不适合 |
| --- | --- | --- | --- |
| **LibreOffice** | 回退(Arial Unicode MS) | 结构机制:表格行有没有被劈开、签章区有没有散、内容有无丢失、XML 有无问题 | **页数、分页位置、留白节奏** |
| **Microsoft Word** | 正确(SimSun / SimHei) | 最终版面与字体外观 | 自动化——GUI 应用,弹对话框就卡住 |
Word 之所以权威,是因为它**自带 SimSun / SimHei**,和对方 Windows Word 看到的一致。
实用节奏:**改稿循环用 LibreOffice**(快、无干扰、能抓结构错误),**定稿前在 Word 里开一次**确认真实分页与字体。
`verify.py` 会自动检查字体有没有被替换,并据此告诉你这次的渲染图能信到什么程度。
## markdown 怎么写
YAML frontmatter 提供封面信息:
```markdown
---
title: 技术服务合同
party_a: 【甲方全称】
party_b: 【乙方全称】
party_a_label: 甲方(客户)
party_b_label: 乙方(服务方)
style: A
---
@@COVER@@
## 第 1 条 定义
1.1 **服务**:……
@@SIGNATURE@@
```
三个占位符:
| 占位符 | 作用 |
| --- | --- |
| `@@COVER@@` | 封面(自动分页到正文) |
| `@@SIGNATURE@@` | 签章区,可出现多次(正文一处、附件一处) |
| `@@PAGEBREAK@@` | 手动分页,用于让长表格独占一页 |
## 四套封面与签章方案
用 `style:` 或 `--style` 选。差别只在封面、签章区、页眉横线,正文版式相同。
| 方案 | 封面 | 签章区 | 页眉横线 |
| --- | --- | --- | --- |
| **A** 复刻参考版 | 编号靠右 / 甲乙左对齐 / 日期下沉 | 竖排,仅标签留白供盖章 | 有 |
| **B** 严格对齐版 | 无框表格做标签-值两列 | 无框表格甲乙并排 | 有 |
| **C** 公文庄重版 | 信息块加外框,标题 22pt | 竖排 + 独立盖章区提示 | 有 |
| **D** 现代简洁版 | 左对齐块 + 细线包夹 | 竖排 + 行内(盖章)标注 | 无 |
拿不准就用 A。它最像国内公司常见的合同范式,对方法务看着眼熟、审得快。
`--all` 一次出四份,把封面页渲染出来给人挑。
## 中文合同的几个惯例
这些不是排版细节,是**不写就显得外行**的东西:
- **封面靠不同对齐区分信息组**:合同编号靠右、缔约方靠左且互相对齐、签订日期单独下沉。全部居中会把这种区分抹平。
- **签章区在正文之后另起,竖排堆叠**(甲方组、乙方组上下分开),不是并排表格——盖章需要留白。
- **`(本行以下无正文,仅供签章之用)`** 这句要有,防止在空白处补写内容。
- **占位符用 `【】`**,不用 `[]` 或下划线。待议的数字也用 `【10】`。
- **页脚要有"第 X 页 / 共 Y 页"**,防抽换页。`build.py` 用 PAGE/NUMPAGES 域自动生成。
更多见 `references/contract-zh.md`。
## 排版参数
正文宋体 12pt、1.5 倍行距;标题黑体纯黑加粗 16/14/12pt;A4,上下 2.54cm、左右 3.00cm。
完整参数与取值依据见 `references/house-style.md`。要改整体风格(比如换仿宋、换字号)就改 `scripts/build.py` 顶部的常量块,那里集中了全部度量。
## 分页控制
Word 里控制分页的四个开关,`build.py` 已经预置,写 markdown 时按需要用:
| 场景 | 机制 | 怎么用 |
| --- | --- | --- |
| 表格行被劈成两半 | `cantSplit` | 自动,所有表格已开 |
| 单行孤行落在页首页尾 | `widowControl` | 自动,全局已开 |
| 引导句留在页底、列表在下一页 | `keepNext` | 自动(列表前一段自动套 LeadIn) |
| 某条款不能被劈开 | `keepLines` | 手动套 `::: {custom-style="Together"}` |
| 长表格要独占一页 | 分页符 | 表格前加 `@@PAGEBREAK@@` |
价格、赔偿上限、责任范围这类条款建议套 `Together`——被分页切成两半会显得很不专业,也容易在传阅中被误读。
```markdown
::: {custom-style="Together"}
**本条单价适用条件**:单次充值不低于人民币【 】元……
:::
```
## 表格列宽
pandoc 的管道表列宽由**分隔行的连字符数量**决定,不是内容。默认全等宽,长内容列会挤成多行而短列一片空白:
```markdown
| 里程碑 | 时间 | 内容 | 付款 |
| ---------- | --------- | -------------------------- | -------- |
```
按各列实际内容量分配连字符。中文全角字在 10.5pt 下约 210 twips,正文宽 8504 twips——照这个估每列需要多少。
## 两个 pandoc 陷阱
**`- (a) 文字` 会变成空项目符号 + 嵌套列表。** pandoc 的 `fancy_lists` 把 `(a)` 当成有序列表标记,于是外层项目符号是空的、真正的内容缩进两层。`build.py` 会自动把这类行转成转义括号 + 悬挂缩进样式。手写 OpenXML 时要记得转义成 `\(a\)`。
**智能引号会把中文引号变成两个右引号。** `"通道存在"` 经 pandoc 的 smart 扩展后可能渲染成 `”通道存在”`——开引号也是右引号。直接在 markdown 里写中文引号 `“ ”` 最省事。
## OpenXML 的硬约束
如果要手写或修改 OpenXML(而不只是调 `build.py` 的常量),先读 `references/openxml-gotchas.md`。最容易踩的是:
**`<w:pPr>` 和 `<w:style>` 的子元素顺序由 XSD 强制。** 顺序写错,Word 打开会报"文档已损坏",而且报错信息完全不提元素顺序,极难 debug。`build.py` 的 `ppr()` 按正确顺序拼装,`verify.py` 的 lint 会检查产物。
常见顺序错误:`spacing` 放在了 `keepNext` 前面;`tblPr` 放在了 `pPr` 前面;`jc` 放在了 `ind` 前面。
## 依赖
```bash
brew install pandoc poppler
brew install --cask libreoffice # 渲染检查用,强烈建议装
```
`pandoc` 必需。`poppler` 提供 `pdftotext` / `pdftoppm`,做版面体检和渲染。
**自动化转换首选 LibreOffice**——headless、不抢屏、不会卡。`verify.py` 没找到它时会回退到调用 Microsoft Word(macOS,AppleScript),那条路能出正确字体但不可靠:Word 是 GUI 应用,弹任何对话框都会把转换卡死,脚本既看不见也关不掉。
两个都装最好:LibreOffice 跑循环,Word 做定稿确认(见上文"两个渲染器")。
## 参考文件
- `references/house-style.md` — 完整排版参数、取值依据、四套方案的设计说明
- `references/openxml-gotchas.md` — XSD 元素顺序、分页控制、页眉页脚注入、字体主题
- `references/contract-zh.md` — 中文合同的结构与惯例(封面、条款编号、签章、附件)
- `templates/contract.md` — 可直接改的合同骨架
GitHubで見る