Install
openclaw skills install @sereinone/gongwen-docxConvert Markdown into Chinese official-document (公文) Word files that strictly follow GB/T 9704-2012 党政机关公文格式及通用公文排版规范. Use this skill when the user asks to turn a markdown / IMA-exported md / text into a 公文 Word, or to reformat / revise a 公文 / 标准起草说明 / 请示 / 报告 / 通知 / 函. Also apply it whenever the us
openclaw skills install @sereinone/gongwen-docx将用户提供的材料(Markdown、文本、旧 docx)重排为符合 党政机关公文格式(GB/T 9704-2012) 及通用公文排版规范的 Word 文档。权威规范依据 GB/T 9704-2012《党政机关公文格式》及其实施 细则(层次序数、字体、字号、版式等通用规则)。每次生成前若用户未另给规范,默认以此通用 公文规范为准。
一、:三号黑体(一):三号楷体1、:三号仿宋GB2312(1):三号仿宋GB2312;其与正文同属内容性文字,应首行缩进 2 字、两端对齐,不要顶格。一、、第二层 (一)、第三层 1、 均首行缩进 2 字(与正文一致);第四层分点 (1) 亦首行缩进 2 字。即所有标题层级与正文段落统一首行缩进 2 字。当源稿用 ## 第X部分 / ## 第X章 作顶级分章(典型如"报告""方案""规定"),生成器自动进入报告模式:
第X部分 → 一级标题 一、 二、 … 八、(黑体),并在每个 part 处重置二级计数器,杜绝"一、既是一级又是二级"的混乱。### 一、… / ### (一)… / ### A类… 统一降为二级 (一) (二) …(楷体),按 part 连续编号;源稿里已有的 一、 / (一) 前缀会被剥掉后重排。一、 → (一) → (1) 四级嵌套,不再出现层级错乱或编号被全局计数器污染。一、(一)1、(1) 直接定级)不受影响,两者互斥、自动判别。indent:{firstLine:0, firstLineChars:0}
(非正文);indent:{firstLine:640, firstLineChars:200}(正文)。只写一种单位时,某些
Word/预览会回退到用户模板 Normal 样式的 2 字符缩进,导致标题、表格、页码看起来仍有首行缩进。styles.xml 中显式创建 Normal 样式,并在 Normal 和
docDefaults/pPrDefault 上都写 firstLine=0、firstLineChars=0、left=0、leftChars=0。
否则打开文件时 Word 会套用本地 Normal 模板,出现"明明 XML 写了无缩进,打开却仍有缩进"。1)2)3) 作为层级——公文办法里第四层就是 (1)。源稿若写成 1),
统一改回 (1)。(1)…(n)):除末项外,每项以全角分号 ; 结尾;末项以
句号 。 结尾。1、、(一)、一、 是标题层级,不加句末标点。footers:{default: new Footer({children:[ new Paragraph({alignment:AlignmentType.CENTER, indent:{firstLine:0, firstLineChars:0}, children:[ new TextRun({font:"Times New Roman", size:28, children:[PageNumber.CURRENT]}) ]}) ]})}。GB 45438、年份、条号)。“ ” ‘ ’(及全角 " ')属 Unicode“高 ANSI”码位,Word 默认按 hAnsi 字体(Times New Roman)渲染,会变成“罗马字体的中文引号”。后处理 fix_fonts.py 会把含引号的 run 拆开,引号片段强制用所在 run 的中文(黑体/楷体/仿宋)字体 + hint="eastAsia",使其随上下文字体正确显示;非引号片段仍保持中文用中文字体、数字用 Times New Roman。(1) 必须设置为两端对齐(AlignmentType.JUSTIFIED,OOXML 为 w:jc="both"),不能只是左对齐。一、 / (一) / 1、 / (1))的段前段后间距均为 0 行(spacing:{before:0,after:0}),不额外留白,与正文靠行距和缩进区分。w:tblLayout type="autofit" + w:tblW type="auto",列宽由内容自动决定(单元格保留首选列宽仅作参考)。build() 末尾的落款输出开关;默认保持关闭。源稿顶部若用加粗标记写出公文要素,生成器会自动识别并作正确排版(冒号在加粗标记内外的写法都兼容):
报告模式(含「第X部分/第X章」)一律不渲染任何公文要素——这是用户明确要求的报告版式:
**主送:** / **抄送:** 抬头;**文件编号:** 发文字号行;标准模式(修改/编制/起草说明等无 第X部分 的文档):
**主送:** … / **抄送:** … → 渲染为抬头:三号黑体、顶格、无首行缩进,置于大标题下。**文件编号:** …(发文字号)→ 仿宋、居中,置于大标题下。**呈报单位:** … / **发文机关署名:** … / **日期:** … / **成文日期:** … → 仍会被识别,但因“落款默认删除”规则,默认不输出文末落款(如需输出见“落款”节例外说明)。IMA 导出的 md 常残留 着(着)、独(独)等 HTML 实体。生成器在读取阶段统一 decodeEntities 解码,无需手工预处理;若源稿本身已是干净中文则无影响。
源稿中 markdown 的强调标记 * 与 ** 在生成阶段批量删除(替换为空字符串,绝不是空格),公文不保留任何 markdown 标记——无论 **加粗标题**、*列表项* 还是行内 **xxx**,最终只留纯文本进入文档:
md.replace(/\*/g, ""),所有 * 从源头消失。inline() 兜底):inline() 函数末尾额外 .replace(/\*/g, ""),确保任何不成对的残留星号也清掉。fix_fonts.py 遍历所有 w:t 文本,把残留 * 替换为空并打印清除计数。**1. 性质与地位** 会变成 1. 性质与地位(两侧带空格),破坏公文排版。源稿(尤其 IMA 导出)常在中文与中文、中文与中文标点之间夹杂半角/全角空格(如“第 一 章”“他说 : ”)。公文排版不需要这些空格:
cleanup():仅当空格两侧均为 CJK 字符或中文标点时才删除,保留“中文 + 拉丁/数字”之间的空格(如“标准 GB/T 9704”“2026 年”);fix_fonts.py 的 normalize_spacing() 再做一次兜底(覆盖 run 内部与跨 run 边界两种情形),并打印清除计数。docx 库写入 run 时只生成 ascii/hAnsi/cs 字体,不会写 eastAsia,
导致中文落到默认字体而非仿宋/楷体。必须后处理。
docx:
cd /Users/weidong/.workbuddy/binaries/node/workspace && /Users/weidong/.workbuddy/binaries/node/versions/22.22.2/bin/npm install docxscripts/generate_gongwen_docx.js(解析 markdown -> 公文,已固化全部规则):
NODE_PATH=/Users/weidong/.workbuddy/binaries/node/workspace/node_modules \
/Users/weidong/.workbuddy/binaries/node/versions/22.22.2/bin/node \
scripts/generate_gongwen_docx.js input.md output.docx
# 深度自动编号);② 已带公文编号的
文字(含 **加粗** 伪装成标题的,如 IMA 导出的 md)——按 一、/(一)/1、/(1) 直接定级;
③ 「第X部分 / 第X章」分章型正式报告——自动进入"报告模式"(见上),第X部分→一~八一级、
其下统一降为 (一)~(n) 二级,并按 part 重置计数器。1)2)3) 自动归一为 (1)(2)(3),并按"同组末项用 。、其余用 ;"补标点。(1) 分点;自动加居中页码。#、开头"好的,根据…"、分隔线 ***、重复大标题、(完整版)
均自动忽略;HTML 实体(着 等)自动解码。极脏的对话外壳仍建议先手动删掉再转。**主送:** / **抄送:** / **文件编号:** / **呈报单位:** /
**日期:** 按对应要素处理;其中落款类要素因"落款默认删除"规则默认不输出文末落款(见"主送机关与落款要素""落款"两节)。scripts/fix_fonts.py 后处理(支持任意路径参数):
word/document.xml 与 word/footer*.xml 的每个 w:pPr,补齐 firstLine /
firstLineChars / left / leftChars,确保无缩进段落双单位均为 0、正文段落双单位
对应 2 字符。w:rFonts,把 ascii 当前值抄到 eastAsia,并把 ascii/hAnsi 改为
Times New Roman。styles.xml 中显式创建 Normal 样式(若不存在),并在 Normal 与
docDefaults/pPrDefault 上同时声明无首行缩进、无左缩进。
这样中文用对应中文字体、数字用 Times New Roman,且任何 Word/预览都不会再套用本地
Normal 模板缩进。1)(注意正则陷阱,
见下)。eastAsia,不处理则中文不是仿宋/楷体。ascii/hAnsi 置 Times New Roman,否则数字不是新罗马体。(1) 含子串 1);且中文全角括号 ( 是 U+FF08,不等于 ASCII 半角 (。
校验"是否残留独立 1)"时,否定后顾必须基于中文全角左括号(写法为「否定后顾 全角左括号」),
绝不能基于 ASCII 半角左括号,否则会把 (1) / (图1) / (表1.1) 误判为残留。firstLineChars:0 或只写 firstLine:0,中文 Word/预览
都可能回退到用户本地 Normal 模板的 2 字符缩进,导致"标题/表格/页码仍有首行缩进"。正确做法:
非正文段落 indent:{firstLine:0, firstLineChars:0},正文 indent:{firstLine:640, firstLineChars:200},
且后处理脚本在 styles.xml 显式创建 Normal 样式,并把 Normal 和 docDefaults 的
firstLine/firstLineChars/left/leftChars 都置 0。(1) 分点属于正文性枚举,要与正文一样首行缩进 2 字、两端对齐,不要顶格。w:jc="both",对应 docx 库的 AlignmentType.JUSTIFIED。VerticalAlign.CENTER。常见错误是只居中第一列,第二、三列仍左对齐。(1)…(n) 枚举项,末项用 。、其余用 ;,不要全部用 ; 或 、。PageNumber.CURRENT 生成 PAGE 字段。第X部分→一~八一级、其下统一降为 (一)~(n) 二级并按 part 重置计数器;不要再手工剥离"第X部分"前缀或手动重排,否则会与自动编号冲突。**主送:** **日期:** **呈报单位:** **文件编号:** 标记,生成器自动按公文要素处理,不要把它们写成普通正文段落(落款默认不输出,见“落款”节)。** / * 等 markdown 强调标记在公文里无意义,必须批量替换为空(不是空格)。生成脚本源头 md.replace(/\*/g,"") + inline() 兜底 + 后处理 fix_fonts.py 扫描 w:t 替换空,三重保险确保文档零星号;若误替换为空格会破坏 **1. 性质与地位** 这类行的排版。scripts/generate_gongwen_docx.js:markdown -> 公文 的核心生成脚本(直接复用,含全部规则)。scripts/fix_fonts.py:eastAsia + Times New Roman + 双单位缩进 + 显式 Normal 样式 后处理脚本(支持路径参数)。references/workflow.md:生成工作流要点与校验清单。