feat: 完成 DOCX R4 元素级视觉门禁

建立 Chromium、Word 与 WPS 的可编辑内容、段落几何、页眉页脚、封面、媒体和逐页视觉比较链路。

支持封面独立分节、正文页码重启、主题页边距与横向纸张,并将自然分页差异降为诊断项。

修正代码块内边距和折叠表格单元格边框映射,14 套主题生产矩阵与六组布局视觉矩阵通过。
This commit is contained in:
SkyJourney
2026-08-02 03:27:11 +08:00
parent f9f5fccfc9
commit 58f87cc19f
100 changed files with 10409 additions and 386 deletions
@@ -41,7 +41,8 @@ function text(
function group(
role: SemanticDocumentRole,
children: readonly (SemanticDocumentNode | undefined)[]
children: readonly (SemanticDocumentNode | undefined)[],
layout?: SemanticDocumentGroupNode["layout"]
): SemanticDocumentGroupNode | undefined {
const resolved = children.filter(
(child): child is SemanticDocumentNode => child !== undefined
@@ -50,6 +51,7 @@ function group(
? {
kind: "group",
role,
...(layout ? { layout } : {}),
children: resolved
}
: undefined;
@@ -89,11 +91,11 @@ function officialRegions(
const classification = group("official-classification", [
text("official-secrecy", document.secrecy),
text("official-urgency", document.urgency)
]);
], "space-between");
const issueRow = group("official-issue-row", [
text("official-number", document.number),
text("official-signatory", document.signatory, "签发人:")
]);
], "space-between");
const masthead = group("official-masthead", [
classification,
text("official-issuer", document.issuer),
@@ -109,7 +111,7 @@ function officialRegions(
"official-printing-date",
document.date ? `${document.date}印发` : undefined
)
]);
], "space-between");
const edition = group("official-edition", [
text(
"official-copy-to",
@@ -138,7 +140,7 @@ function briefingRegions(
text("briefing-publisher", document.publisher),
text("briefing-signatory", document.signatory, "签发:"),
text("briefing-date", document.date)
]);
], "space-between");
const masthead = group("briefing-masthead", [
text("briefing-masthead-text", document.masthead),
details
@@ -57,6 +57,9 @@ describe("统一语义文档模型", () => {
"suffix"
]);
expect(JSON.stringify(model)).toContain("official-masthead");
expect(JSON.stringify(model)).toContain(
'"layout":"space-between"'
);
expect(JSON.stringify(model)).toContain("抄送:");
expect(JSON.stringify(model)).toContain("2026年7月30日印发");
expect(() => semanticDocumentModelSchema.parse(model))