# @deepwhale-cn/dsh-cn-doc-formatter **中文公文排版** —— 给 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 用的 skill 插件。 按 **GB/T 9704-2012《党政机关公文格式》** 生成 `.docx` / `.pdf` / `.txt`, 并自带**输出自检**——生成完逐项核对页边距、字号、行距、字体、页面尺寸, 不符合规范就报错,而不是让你交付一份看起来差不多、实际不合规的文件。 ## ⚠️ 本插件不含字体,字体需你自备 **这是刻意的设计,不是缺失。** 公文规范要求的仿宋(方正仿宋等)是**商业字体**。其授权允许你在文档中使用, 但**不允许再分发字体文件本身**。所以本插件只做「排版引擎」,字体由你提供: ```bash # 方式一:直接指定字体文件(推荐,最明确) export DSH_CN_FANGSONG=/path/to/仿宋.ttf export DSH_CN_FANGSONG_BOLD=/path/to/仿宋加粗.ttf # 可选 # 方式二:指定一个目录,脚本在其中按文件名查找 export DSH_CN_FONT_DIR=~/my-fonts ``` 也可以直接装进**系统字体目录**(一次装好处处可用): | 系统 | 目录 | |---|---| | macOS | `~/Library/Fonts/` | | Windows | `C:\Windows\Fonts\` | | Linux | `~/.fonts/` 或 `~/.local/share/fonts/` | 装 WPS Office 也行 —— 它自带方正仿宋。 **找不到字体时不会静默失败**:PDF 退回系统宋体,并在 stderr 打印上面这张获取指引。 docx 只在文件里声明字体族名(由你机器上的 Word 渲染),不依赖字体文件。 > **一个细节**:如果你只有常规仿宋、没有加粗体,**标题会继续使用仿宋**(只是不加粗), > 而不是换成宋体。因为「全文统一仿宋」是硬规范,宁可字重不够也不换字体族。 > reportlab 不做合成粗体,这是引擎限制。 ## 它管什么 | 项目 | 规范值 | |---|---| | 标题 | 仿宋,二号(22pt)加粗,居中,行距 33–36 磅 | | 一/二/三/四级标题 | 仿宋,三号(16pt)加粗,左空二字 | | 正文 | 仿宋,四号(14pt),固定行距 28 磅,首行缩进严格 2 字 | | 版头(可选) | 份号 / 密级 / 紧急程度 / 发文字号,仿宋三号 | | 署名与日期 | 距正文下空 3 行,日期阿拉伯数字右空 4 字 | | 页码 | 「- 1 -」,单页居右空一字、双页居左空一字 | | 页边距 | 上 3.7 / 下 3.5 / 左 2.8 / 右 2.6 cm | | 文档网格 | 每面 22 行、每行 28 字 | **不出现任何 AI 痕迹**:无水印、无生成标记、无作者信息、无版本说明、无注释。 ## 安装 ```bash dsh plugin --profile add @deepwhale-cn/dsh-cn-doc-formatter ``` 然后重启 dsh。技能会在 agent 需要时自动可用。 ### Python 依赖 排版脚本是 Python,需要这些库: ```bash pip install python-docx reportlab fontTools pypdf ``` | 库 | 用途 | |---|---| | `python-docx` | 生成 Word 文档 | | `reportlab` | 生成 PDF | | `fontTools` | 探测本机已装字体(读字体 name 表) | | `pypdf` | 自检时校验 PDF 是否真的嵌入了目标字体 | ## 它比「套个模板」多做了什么 **1. 输出自检(`verify_output.py`)** 生成完不是结束。自检会真的打开产出文件,逐项核对: ``` ── 公文.docx ✅ 上边距 3.70cm ✓ ✅ 标题 22pt 加粗 ✓ ✅ 正文 14.0pt / 行距 28pt ✓ ✅ 全文统一字体:FangS-SC ✓ ── 公文.pdf ✅ 嵌入字体:/AAAAAA+FangS-SC, /AAAAAA+FangS-SC-Bold ✅ 页面 A4 21.0×29.7cm ✓ ``` 退出码 `0` = 通过,`1` = 有不符合项 —— **可以直接用在 CI 或交付卡口上**。 **2. Markdown 输入适配(`md_adapter.py`)** 内容常以 Markdown 写就,直接喂给脚本会丢失层级(整篇被当正文): | Markdown | 转成 | 公文层级 | |---|---|---| | `## 一、小节` | `一、小节` | 一级标题 | | `### 1.1 小节` | `(一)小节` | 二级标题 | | `#### 更深` | `1. 小节` | 三级标题 | | `- 列表项` | 正文 | 正文 | | `\| 表格 \|` | `表头:值;表头:值。` | 正文 | 它还会把同一段内的软换行合并成一行 —— 源文档常手动折行, 逐行当独立段落会在断句处留下孤立标点(如单独一行的「、」)。 **3. 跨平台字体探测** 早期实现用 `fc-list` 探测字体,而 **macOS 不预装 fontconfig**, 异常被吞掉后恒返回「字体不存在」,于是**即使装了仿宋也检测不到**,会始终走回退分支。 本版改为直接读字体文件的 `name` 表,macOS / Windows / Linux 通用。 ## 用法 技能正文里有完整命令。核心三条: ```bash # 生成 Word / PDF python "<插件目录>/scripts/docx_formatter.py" --output <目录> \ --title "标题" --body "正文..." --sender "发文机关" --date "2026年9月25日" python "<插件目录>/scripts/pdf_formatter.py" --output <目录> \ --title "标题" --body "正文..." --sender "发文机关" --date "2026年9月25日" # 输出自检(不要跳过) python "<插件目录>/scripts/verify_output.py" --dir <输出目录> ``` > ⚠️ **早期文档里的 `--type notice` 参数并不存在**,加上会直接报 > `unrecognized arguments`。文种由内容决定,脚本不做区分。本版已修正文档。 ## 设计取舍 **不分发字体。** 见上文——这不是省事,是避免把商业字体的再分发风险 转嫁给每一个使用者。 **不联网。** 排版、字体探测、自检全部在本地完成,不把文档内容发往任何第三方服务。 **文种不参与排版。** 通知 / 报告 / 函 / 决定的排版规范是一致的, 差别只在正文怎么写。脚本不为文种分叉,避免维护一堆看似不同实则相同的模板。 ## 与其它插件的关系 按 [DSH 插件生态倡议书](https://github.com/anywhere-labs/dsh-desktop/blob/main/docs/plugin-ecosystem.md) 的三条原则开发:**组合优先、声明清晰、兼容优先**。不假设、不覆盖其它插件的内部实现。 ## 许可 MIT。**本软件不包含任何字体文件**;使用者在文档中选用何种字体,由使用者自行负责 取得该字体的合法授权。