feat: 实现 DOCX 主题令牌归一化

This commit is contained in:
SkyJourney
2026-07-30 22:57:46 +08:00
parent d2acc9c5ce
commit 7f72258126
18 changed files with 1571 additions and 25 deletions
@@ -5,7 +5,9 @@ import { fileURLToPath } from "node:url";
import { createApplicationService } from "@md-to-pdf/application";
import {
DOCX_STYLE_SLOT_NAMES,
createDocxThemeStyleFingerprint
createDocxThemeStyleFingerprint,
normalizeDocxThemeMappingConfig,
resolveDocxThemeTokens
} from "@md-to-pdf/docx-theme-engine";
import { chromium } from "playwright";
import { captureDocxThemeStyleWithPlaywrightPage } from "../dist/playwright-docx-theme-style.js";
@@ -99,8 +101,9 @@ try {
.filter((theme) => theme.source === "bundled")
.sort((first, second) =>
first.id.localeCompare(second.id, "en")
);
);
const snapshots = [];
const tokenSets = [];
for (const theme of bundledThemes) {
console.error(`[DOCX theme styles] capturing ${theme.id}`);
const themeCss = await application.getThemeCss(theme.id);
@@ -126,11 +129,28 @@ try {
.join("、")}`
);
snapshots.push(snapshot);
tokenSets.push(
resolveDocxThemeTokens({
snapshot,
config: normalizeDocxThemeMappingConfig(theme)
})
);
}
assert(
snapshots.length === 14,
`内置主题数量应为 14,实际为 ${snapshots.length}`
);
const invalidDiagnostics = tokenSets.flatMap((tokens) =>
tokens.diagnostics.filter(
(diagnostic) =>
diagnostic.severity === "error" ||
diagnostic.code === "css-value-invalid"
)
);
assert(
invalidDiagnostics.length === 0,
`DOCX 样式令牌存在 ${invalidDiagnostics.length} 条无效诊断`
);
const paragraphStyles = new Set(
snapshots.map(
(snapshot) =>
@@ -151,7 +171,8 @@ try {
chromiumVersion: browser.version(),
themeCount: snapshots.length,
slotCount: DOCX_STYLE_SLOT_NAMES.length,
snapshots
snapshots,
tokenSets
},
null,
2
@@ -164,7 +185,12 @@ try {
themes: snapshots.length,
slotsPerTheme: DOCX_STYLE_SLOT_NAMES.length,
totalSlots:
snapshots.length * DOCX_STYLE_SLOT_NAMES.length
snapshots.length * DOCX_STYLE_SLOT_NAMES.length,
tokenSets: tokenSets.length,
diagnostics: tokenSets.reduce(
(count, tokens) => count + tokens.diagnostics.length,
0
)
})
);
await context.close();