Files
MorphDoc/docs/V0.6.0_DOCX_THEME_AUDIT.md

16 KiB
Raw Permalink Blame History

v0.6.0 DOCX 全主题视觉与结构审计

审计日期:2026-07-30

本文第 3~8 节记录阶段 10 的首轮审计基线。阶段 12C 已于 2026-07-31 完成对应结构修复和自动化门禁,最新状态见第 9 节;真实 Word/WPS 视觉、编辑和互存结论仍需阶段 12D 复验。

1. 审计目标

本轮按 v0.6.0 已冻结的两条 DOCX 发布门禁检查全部内置主题:

  1. 导出的 DOCX 必须保留完整纸张设置与文本样式,包括字体、段落、标题、 列表、代码块、表格、图片、Mermaid、ECharts、封面和结构化公文元素。
  2. 导出的 DOCX 必须能被 Microsoft Word 与 WPS 正常打开、编辑和互存。

项目实际包含 14 套内置主题,而不是此前口头统计的 13 套。本轮没有只做 OOXML 自动检查,还使用本机 Microsoft Word 原生排版引擎逐份导出 PDF, 并检查全部 22 个渲染页面。

2. 审计方法与证据

  • 使用 Pandoc 3.9.0.2 和当前动态 reference.docx 生成 14 份 DOCX。
  • 使用每套主题自己的 samples/themes/<theme-id>.md 和导出配置。
  • 检查 DOCX 包结构、纸张尺寸、四边页边距、样式、表格、图片关系、 页眉页脚、页码字段、分页符和 altChunk
  • 使用 Microsoft Word 原生 COM 导出 14 份 PDF,共 22 页。
  • 将 Word PDF 以 150 DPI 栅格化,逐页按原始分辨率检查。
  • 从 Word PDF 提取实际使用字体,排查字体替换。
  • 检查 Front Matter 结构字段是否真正进入可编辑 Word 正文。

可复现命令:

npm run verify:docx-themes

本地审计产物位于:

output/docx-theme-matrix/
├── *.docx
├── theme-matrix-report.json
├── word-pdf-isolated/
└── word-png/

output/ 已被 Git 忽略,审计产物不会进入仓库。

3. 总体结论

当前实现通过了“原生可编辑 DOCX”基础能力,但没有通过“完整主题样式映射” 发布门禁。

检查项 结果 结论
Word 可打开并原生排版 14/14 通过
正文、标题、列表、表格和代码为原生 OOXML 14/14 通过
禁止 altChunk 14/14 通过
A4、方向和四边页边距符合主题配置 14/14 通过
页眉页脚和页码为 Word 原生区域/字段 14/14 通过
本机字体无异常替换 14/14 通过
独立封面完整生成 0/4 阻塞
结构化公文/简报 Front Matter 完整映射 0/4 阻塞
主题视觉完整映射 0/14 阻塞
全宽表格 0/14 个含表格主题 阻塞
无重复标题 8/14 需修复

因此,本轮结论不是 Node.js 或 Pandoc 路线不可行,而是当前 reference.docx + 原始 Markdown 直送 Pandoc 的实现层级不足。Pandoc 仍适合作为可编辑 OOXML 的底座,但必须增加项目自有的结构化 AST 转换、 分节和主题专属 Word 样式映射,不能期待 Pandoc 自动理解浏览器主题 CSS 与项目 Front Matter。

4. 关键阻塞问题

4.1 结构化 Front Matter 没有进入 Word 正文

浏览器预览通过 render-document-structure.tsdocument.profile 转成 红头、文号、签发人、版记、封面等结构;DOCX 转换当前将原始 Markdown 直接交给 Pandoc,两条链路没有复用同一份结构化文档模型。

主题 Profile 结构字段覆盖率 主要缺失
enterprise-red-simple official 14% 文号、签发人、日期、抄送、印发机关
gov-red-letter official 17% 文号、日期、抄送、印发机关
gov-red-standard official 22% 文号、紧急程度、签发人、日期、抄送、版记
red-briefing briefing 17% 期号、编发单位、日期、联系方式等
formal-feasibility project-report 33% 项目名、建设单位、版本、日期和独立封面
tender-blind tender 20% 正副本、项目名、编号、分册、投标人等封面字段
tender-business-blue tender 14% 正副本、项目名、编号、分册、代表、日期
tender-classic tender 14% 正副本、项目名、编号、分册、代表、日期

四套声明独立封面的主题均没有生成封面,也没有显式分页符或分节:

  • formal-feasibility
  • tender-blind
  • tender-business-blue
  • tender-classic

4.2 14 套主题实际收敛成少量通用 Word 预设

当前 DOCX 样式主要来自 officialformaltendertechnicalgeneral 几个预设。多个网页视觉差异明显的主题,在 DOCX 中使用完全相同 或近似的正文、标题和表格样式。

  • formal-regulationformal-report 基本相同。
  • typora-githubtypora-like 基本相同。
  • typora-pixylltypora-whitey 基本相同。
  • 三套红头公文正文样式基本相同,但没有各自红头版式结构。
  • 三套标书共用蓝色系表格预设,破坏暗标和经典黑白主题语义。

这说明当前是“按主题选择一个通用 Word 模板”,尚不是“完整映射每套主题”。

4.3 标题重复

以下 6 套样例的 YAML title 与正文第一个 H1 相同。Pandoc 同时输出文档 标题块和 H1,Word 中出现重复标题:

  • formal-regulation
  • formal-report
  • typora-github
  • typora-like
  • typora-pixyll
  • typora-whitey

此外,文档标题当前基于 H1 再增加 4pt,实际约 26pt;在红头信函中产生 过大的标题和不自然换行,例如“函”被孤立到第二行。

4.4 表格没有继承网页主题的全宽布局

Pandoc 生成的表格宽度是:

<w:tblW w:type="auto" w:w="0"/>

Word 会按内容自动收缩,导致所有表格明显窄于正文内容区。网页主题中的 width: 100%、列宽和部分表头视觉没有被映射到 Word 表格网格。

4.5 分页质量不足

当前 14 份文档均没有显式分页符。Word 只能根据通用段落属性自动分页, 出现以下问题:

  • typora-like 第 2 页只剩最后一行审核人信息,属于严重孤行页。
  • formal-feasibilityformal-regulationformal-reporttender-blind 的末页内容很少,下半页大面积空白。
  • 代码块可以跨页,但没有专门的代码块续排或避免不佳断点策略。
  • 封面与正文无法通过 Word 分节控制首页页眉页脚、起始页码和封面不计页码。

4.6 字体在本机正确,但没有嵌入

Word 实际导出的 PDF 中可见字体符合当前样式意图:

  • 公文、正式报告和标书主要使用 SimSunSimHeiTimes New RomanArial
  • 技术主题主要使用 Microsoft YaHeiArialConsolas

但 14 份 DOCX 均没有嵌入字体文件,也没有嵌入字体引用。这意味着:

  • 在本机和安装了相同字体的公司电脑上表现稳定。
  • 在缺少宋体、黑体、微软雅黑或对应英文字体的环境中,Word/WPS 会替换字体, 进而改变换行、页数和视觉。
  • 默认嵌入字体会显著增大文件,并涉及字体再分发许可,不适合作为默认策略。

建议明确“受支持字体清单 + fallback”,并在 Desktop/Docker 安装或内置 所需可分发字体;除非业务明确要求,不默认嵌入字体到每份 DOCX。

5. 逐主题视觉结论

主题 Word 页数 主要视觉与结构问题 门禁结论
enterprise-red-simple 1 无企业红头、文号、签发和版记;呈现为通用 Word 文档;表格偏窄 阻塞
formal-feasibility 2 无独立封面;项目、建设单位、版本等封面字段缺失;末页留白大 阻塞
formal-regulation 2 标题重复;视觉为通用蓝灰报告;表格偏窄;末页留白大 阻塞
formal-report 2 标题重复;主题区分度弱;末页只有少量内容 阻塞
gov-red-letter 2 无红头、文号、落款和版记;超大标题换行不佳;第 2 页外侧公文页码正确 阻塞
gov-red-standard 2 无红头、文号、紧急程度、签发和版记;奇偶外侧公文页码正确 阻塞
red-briefing 1 无简报报头、期号、编发单位和联系信息;正文段落间视觉空隙偏大 阻塞
tender-blind 2 无封面;标题和表头为蓝色,违反技术暗标黑白要求;末页留白大 阻塞
tender-business-blue 1 无封面;蓝色体系基本协调,但仍是通用标书模板;表格偏窄 阻塞
tender-classic 1 无封面;标题过大;表头仍为浅蓝色,违反经典黑白语义 阻塞
typora-github 2 标题重复;代码样式可用;表格偏窄;审计占位图黑块不计入产品缺陷 需修复
typora-like 2 标题重复;正文、引用和代码基本可用;第 2 页仅一行,孤行严重 阻塞
typora-pixyll 1 标题重复;整体可用,但与 Whitey 的 Word 风格区分不足;表格偏窄 需修复
typora-whitey 1 标题重复;整体可用,但主题专属字体和细节映射不足;表格偏窄 需修复

typora-github 审计图中的大黑块来自矩阵脚本使用 1×1 像素占位 PNG 后按 计划尺寸拉伸,只用于验证图片关系和 Word 尺寸,不代表真实 Mermaid 导出。 真实 Mermaid/ECharts PNG 管线已经在独立验收样例中验证,正式全主题回归 仍应改用真实捕获媒体,避免视觉报告产生歧义。

6. 已确认正常的能力

  • DOCX 是标准 OOXML,而不是 HTML 或 PDF 嵌套。
  • 正文、标题、列表、表格、代码和链接可在 Word 中继续编辑。
  • A4 尺寸、方向和主题声明的四边页边距正确。
  • 页眉页脚位于 Word 原生页眉区/页脚区,不再以正文表格模拟。
  • 页码使用 PAGE/NUMPAGES 字段。
  • gov-red-letter 首页不显示页码,第 2 页显示外侧 — 2 —
  • gov-red-standard 奇偶页外侧公文页码正确。
  • 视觉上较淡的 tender-classictypora-whitey 页码经 PDF 文本提取 确认存在,不是字段丢失。
  • 所有 DOCX 均未发现 altChunk,可编辑性基础路线正确。

7. 建议修复顺序

P0:建立统一的结构化 DOCX 文档模型

在进入 Pandoc 前,将 Markdown AST、Front Matter 和主题结构合成为统一 中间模型,再输出 Pandoc AST 或通过项目 Lua Filter 注入原生 Word 段落、 表格、分页符和分节信息。公文、简报、项目报告和标书封面不能依赖 reference.docx 自动生成。

P0:实现封面与分节

  • 封面使用原生段落和可编辑文字。
  • 封面结束后插入 Word 分节符。
  • 支持封面无页眉页脚、封面不计页码、正文从 1 开始。
  • 公文首页、奇偶页脚继续使用 Word 原生节属性。

P0:扩展主题 DOCX 清单

为主题增加可显式覆盖的 Word 语义样式,而不是只选择通用预设:

  • 文档标题、作者和元数据块;
  • 红头、文号、签发人、落款、抄送和版记;
  • 封面项目名、分册、正副本和日期;
  • H1~H6、正文、列表、引用、代码、图注;
  • 表格宽度、列宽、表头、边框和底色;
  • 段前段后、孤行控制、标题与下一段同页。

P1:修复通用排版问题

  • 对 YAML 标题与首个 H1 去重。
  • 表格按内容区宽度生成 pct=5000 或明确网格宽度。
  • 为标题设置 keepNext,为正文设置 widow/orphan 控制。
  • 收敛过大的 26pt 文档标题,并按主题单独配置。
  • 暗标和经典黑白主题禁止蓝色标题、表头和装饰。

P1:完善字体可复现策略

  • 固化每套主题的首选字体和 fallback。
  • 在发布说明中列出 Word/WPS 目标环境所需字体。
  • 仅使用许可证允许随应用分发的字体作为可选内置字体。
  • 增加“字体不可用”诊断,不默认把字体嵌入每份 DOCX。

P2:升级全主题回归门禁

  • 使用真实 Mermaid、ECharts 和普通图片,不再使用纯色占位图做视觉验收。
  • 自动检测标题重复、表格内容区占比、孤行页和封面分节。
  • Word 与 WPS 各完成一次打开、编辑、保存、重开。
  • 保存后再次校验页数、字体、页眉页脚、字段和原生结构。

8. 阶段判定

当前 DOCX 引擎可以认定为:

Pandoc 路线与 Node.js 编排可行,原生可编辑基础链路成立;但完整主题 映射、结构化公文、封面、表格宽度和分页控制尚未达到 v0.6.0 发布门禁。

在完成 P0 项目前,不建议将阶段 10 标记为通过,也不建议创建 v0.6.0 正式发布提交或版本标签。

9. 阶段 12C 自动修复复验

阶段 12C 保留 Pandoc 作为可编辑 OOXML 底座,并增加项目自有的通用转换 层:统一语义文档模型生成结构计划,Lua Filter 注入可编辑段落与样式, 最终 OOXML 收口层写入真实分节、页码重启、表格宽度和分页属性。映射只 依赖语义角色与主题令牌,不包含主题 ID 分支,因此同一机制也可服务未来 外部主题。

2026-07-31 使用 Playwright Chromium 151 重新采集 14 套主题各 56 个 计算样式槽位,并由 Pandoc 3.9.0.2 重新生成全部 DOCX,自动结构结果如下:

检查项 阶段 12C 结果 结论
主题使用本轮真实 Chromium 令牌 14/14 通过
结构化主题字段完整映射 8/8 通过
项目报告与标书独立封面真实分节 4/4 通过
封面隐藏页眉页脚、正文页码从 1 重启 4/4 通过
封面文档使用 SECTIONPAGES 4/4 通过
含表格主题的表格铺满内容区 11/11 通过
YAML 标题与正文首个 H1 去重 14/14 通过
内部结构标记清理 14/14 通过
禁止 altChunk、保留原生可编辑结构 14/14 通过

统一复现命令仍为:

npm run verify:docx-themes

该命令不会回退到合成令牌或陈旧快照。它先生成本轮 Chromium 令牌,再 执行 14 主题 Pandoc 矩阵和硬断言。阶段 10 的 P0/P1 结构阻塞因此已由 自动门禁关闭;“完整主题样式映射”的最终判定仍保留到阶段 12D,必须在 Microsoft Word 与 WPS 中完成视觉检查、编辑、保存、重开和双向互存后 才能通过。

10. 阶段 12C-R1 OOXML 严格性复验

2026-07-31 对阶段 12C 生成的 14 份 DOCX 做 Microsoft Word 原生打开 时,最初仅 7 份可直接打开,另外 7 份触发“发现无法读取的内容”且无法 恢复。WPS 可以容错打开,但会报告缺失字体,因此不能据此判定 OOXML 合格。

深度审计确认根因集中在生成样式与 OOXML 模式约束:

  • Pandoc 消费 custom-style 后会追加同名降级样式,造成重复 w:styleId
  • CSS text-align: justify 被直接写成非法的 w:jc="justify",正确 WordprocessingML 枚举应为 both
  • 表格条件样式中的 w:rPrw:tcPr 顺序不符合模式;
  • w:tblW 被写入表格样式层,和正文表格的直接宽度属性混在一起;
  • 多类段落、文本、表格、单元格和分节属性缺少统一的有序写入门禁。

通用引擎已经增加有序插入、序列化规范化和严格校验,并在最终 DOCX 收口层保留前置主题样式、移除 Pandoc 同名降级样式。修复不按主题 ID 分支,也不改变正文表格的内容区全宽属性。

复验结果:

检查项 结果 结论
14 主题结构矩阵 14/14 通过
Microsoft Open XML SDK 非兼容性错误 0 通过
Microsoft Word 禁止修复打开 14/14 通过
WPS 原生只读打开 14/14 通过
Word 原生 PDF 导出 14/14,共 31 页 通过
31 页逐页结构检查 31/31 通过

Open XML SDK 2.20 仍会按 Office 2007 模式报告 Pandoc 表格上的 Office 2010 tblLook 六个兼容属性;这些属性在本轮 Word/WPS 实测中正常,不计 为生成错误。

逐页检查没有发现内容丢失、裁切、重叠或空白正文,但保留以下阶段 12D 视觉问题:

  • 深色表头文字对比度不足;
  • 部分短文档尾页留白过大;
  • gov-red-standard 在 Word 与 WPS 中分别为 2 页和 3 页,说明字体与 客户端排版差异尚未收口;
  • 当前主题矩阵的 Mermaid 仍使用黑色占位 PNG,不代表真实媒体效果。

因此 R1 只关闭 OOXML 合法性和 Word/WPS 无修复打开门禁。字体可移植性、 PDF 与 DOCX 自动视觉差异、真实媒体和双向编辑互存继续由 R2~R4 验收。