| 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 的核心不只是参数,还有一定要把每页渲染成图片看一眼的工作流。
工作流
# 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 提供封面信息:
---
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——被分页切成两半会显得很不专业,也容易在传阅中被误读。
::: {custom-style="Together"}
**本条单价适用条件**:单次充值不低于人民币【 】元……
:::
表格列宽
pandoc 的管道表列宽由分隔行的连字符数量决定,不是内容。默认全等宽,长内容列会挤成多行而短列一片空白:
| 里程碑 | 时间 | 内容 | 付款 |
| ---------- | --------- | -------------------------- | -------- |
按各列实际内容量分配连字符。中文全角字在 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 前面。
依赖
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— 可直接改的合同骨架
