feat: 完成 DOCX R4 元素级视觉门禁
建立 Chromium、Word 与 WPS 的可编辑内容、段落几何、页眉页脚、封面、媒体和逐页视觉比较链路。 支持封面独立分节、正文页码重启、主题页边距与横向纸张,并将自然分页差异降为诊断项。 修正代码块内边距和折叠表格单元格边框映射,14 套主题生产矩阵与六组布局视觉矩阵通过。
This commit is contained in:
@@ -9,7 +9,9 @@ import {
|
||||
import {
|
||||
PandocDocxConverter,
|
||||
PandocRuntime,
|
||||
inspectDocxAcceptance
|
||||
createDocxMediaAcceptanceExpectation,
|
||||
inspectDocxAcceptance,
|
||||
resolveReferencePageOptions
|
||||
} from "@md-to-pdf/docx-engine";
|
||||
import { DOCX_STYLE_SLOT_NAMES } from "@md-to-pdf/docx-theme-engine";
|
||||
|
||||
@@ -49,6 +51,7 @@ function mediaResource(kind, ordinal, dimensions, altText, caption) {
|
||||
kindOrdinal: 1,
|
||||
altText,
|
||||
...(caption ? { caption } : {}),
|
||||
alignment: "center",
|
||||
displayWidthPx: dimensions.width,
|
||||
displayHeightPx: dimensions.height,
|
||||
captureX: 0,
|
||||
@@ -115,6 +118,58 @@ function createThemeTokens(theme) {
|
||||
|
||||
const technicalTheme = loadTheme("typora-like");
|
||||
const officialTheme = loadTheme("gov-red-standard");
|
||||
const coverTheme = loadTheme("formal-feasibility");
|
||||
const semanticDocument = {
|
||||
schemaVersion: 1,
|
||||
titlePolicy: {
|
||||
metadataTitle: "emit",
|
||||
firstBodyHeading: "keep"
|
||||
},
|
||||
regions: []
|
||||
};
|
||||
const coverSemanticDocument = {
|
||||
schemaVersion: 1,
|
||||
profile: "project-report",
|
||||
titlePolicy: {
|
||||
metadataTitle: "suppress",
|
||||
firstBodyHeading: "keep"
|
||||
},
|
||||
regions: [
|
||||
{
|
||||
kind: "cover",
|
||||
nodes: [
|
||||
{
|
||||
kind: "group",
|
||||
role: "project-report-cover",
|
||||
children: [
|
||||
{
|
||||
kind: "text",
|
||||
role: "project-report-project-name",
|
||||
text: "智慧园区建设项目"
|
||||
},
|
||||
{
|
||||
kind: "text",
|
||||
role: "project-report-title",
|
||||
text: "可行性研究报告"
|
||||
},
|
||||
{
|
||||
kind: "text",
|
||||
role: "project-report-owner",
|
||||
label: "建设单位:",
|
||||
text: "示例建设集团"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
section: {
|
||||
headerFooter: "none",
|
||||
pageNumber: "hidden",
|
||||
breakAfter: "next-page",
|
||||
followingPageNumberStart: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
const commonExpectation = {
|
||||
requiredText: [
|
||||
"可编辑的中文正文",
|
||||
@@ -214,6 +269,18 @@ const landscapeLetterConfig = {
|
||||
startFrom: 3
|
||||
}
|
||||
};
|
||||
const coverA4Config = {
|
||||
...defaultExportConfig,
|
||||
name: "可研封面 A4 纵向验收",
|
||||
themeId: coverTheme.id,
|
||||
pageDecorationsMode: "theme",
|
||||
paper: {
|
||||
...defaultExportConfig.paper,
|
||||
format: "A4",
|
||||
orientation: "portrait",
|
||||
marginMode: "theme"
|
||||
}
|
||||
};
|
||||
|
||||
const variants = [
|
||||
{
|
||||
@@ -275,6 +342,41 @@ const variants = [
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "project-cover-a4-portrait",
|
||||
theme: coverTheme,
|
||||
exportConfig: coverA4Config,
|
||||
semanticDocument: coverSemanticDocument,
|
||||
expectation: {
|
||||
...commonExpectation,
|
||||
id: "project-cover-a4-portrait",
|
||||
requiredText: [
|
||||
...commonExpectation.requiredText,
|
||||
"智慧园区建设项目",
|
||||
"可行性研究报告"
|
||||
],
|
||||
page: {
|
||||
widthTwips: 11906,
|
||||
heightTwips: 16838,
|
||||
orientation: "portrait",
|
||||
marginsTwips: {
|
||||
top: 1417,
|
||||
right: 1134,
|
||||
bottom: 1417,
|
||||
left: 1701
|
||||
}
|
||||
},
|
||||
minimumSections: 2,
|
||||
requireFirstSectionWithoutHeaderFooter: true,
|
||||
finalPageNumberStart: 1,
|
||||
requireSectionPagesField: true,
|
||||
requiredParagraphStyleIds: [
|
||||
"MdProjectReportProjectName",
|
||||
"MdProjectReportTitle",
|
||||
"MdProjectReportOwner"
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@@ -299,33 +401,51 @@ fs.mkdirSync(outputDirectory, { recursive: true });
|
||||
|
||||
const results = [];
|
||||
for (const variant of variants) {
|
||||
const variantSemanticDocument =
|
||||
variant.semanticDocument ?? semanticDocument;
|
||||
const fileName = `${variant.id}.md`;
|
||||
const metadata = {
|
||||
title: "v0.6.0 DOCX 自动验收",
|
||||
author: "Markdown PDF 导出器研发组",
|
||||
subject: "Word 与 WPS 可编辑性验收",
|
||||
keywords: ["DOCX", "Pandoc", "OOXML"],
|
||||
language: "zh-CN"
|
||||
};
|
||||
const resolvedPage = resolveReferencePageOptions({
|
||||
exportConfig: variant.exportConfig,
|
||||
theme: variant.theme,
|
||||
fileName,
|
||||
metadata
|
||||
});
|
||||
const media = createMedia();
|
||||
const result = await converter.convert({
|
||||
markdown,
|
||||
fileName: `${variant.id}.md`,
|
||||
fileName,
|
||||
language: "zh-CN",
|
||||
exportConfig: variant.exportConfig,
|
||||
theme: variant.theme,
|
||||
themeTokens: createThemeTokens(variant.theme),
|
||||
metadata: {
|
||||
title: "v0.6.0 DOCX 自动验收",
|
||||
author: "Markdown PDF 导出器研发组",
|
||||
subject: "Word 与 WPS 可编辑性验收",
|
||||
keywords: ["DOCX", "Pandoc", "OOXML"],
|
||||
language: "zh-CN"
|
||||
},
|
||||
semanticDocument: {
|
||||
schemaVersion: 1,
|
||||
titlePolicy: {
|
||||
metadataTitle: "emit",
|
||||
firstBodyHeading: "keep"
|
||||
},
|
||||
regions: []
|
||||
},
|
||||
media: createMedia()
|
||||
fonts: [],
|
||||
metadata,
|
||||
semanticDocument: variantSemanticDocument,
|
||||
media
|
||||
});
|
||||
const report = inspectDocxAcceptance(
|
||||
result.docx,
|
||||
variant.expectation
|
||||
{
|
||||
...variant.expectation,
|
||||
media: createDocxMediaAcceptanceExpectation(
|
||||
media,
|
||||
variant.expectation.page
|
||||
),
|
||||
pageDecorations: {
|
||||
exportConfig: {
|
||||
header: resolvedPage.header,
|
||||
footer: resolvedPage.footer
|
||||
},
|
||||
semanticDocument: variantSemanticDocument
|
||||
}
|
||||
}
|
||||
);
|
||||
const outputPath = path.join(outputDirectory, `${variant.id}.docx`);
|
||||
fs.writeFileSync(outputPath, result.docx);
|
||||
|
||||
Reference in New Issue
Block a user