Files
MorphDoc/packages/docx-engine/tests/pandoc-structure.test.ts
T

240 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import type {
SemanticDocumentModel,
SemanticDocumentNode
} from "@md-to-pdf/core";
import type {
DocxResolvedStyleSlot,
DocxStyleSlotName,
DocxThemeTokenSet
} from "@md-to-pdf/docx-theme-engine";
import {
createPandocStructurePlan,
type PandocStructureBlock
} from "../src/index.js";
function slot(
name: DocxStyleSlotName,
hidden = false
): DocxResolvedStyleSlot {
return {
slot: name,
source: "computed-css",
confidence: "exact",
style: {
fontCandidates: [],
...(hidden ? { hidden: true } : {})
}
};
}
function tokens(
slots: DocxResolvedStyleSlot[] = []
): DocxThemeTokenSet {
return {
schemaVersion: 1,
themeId: "test-theme",
themeFingerprint: "c".repeat(64),
mode: "auto-with-overrides",
basePreset: "technical",
slots,
diagnostics: []
};
}
function text(
role: Extract<SemanticDocumentNode, { kind: "text" }>["role"],
value: string,
label?: string
): SemanticDocumentNode {
return {
kind: "text",
role,
text: value,
...(label ? { label } : {})
};
}
function paragraphSegments(block: PandocStructureBlock): string[] {
if (block.kind === "paragraph") {
return block.segments;
}
if (block.kind === "container") {
return block.blocks.flatMap(paragraphSegments);
}
return [];
}
describe("Pandoc 语义结构投影", () => {
it("将公文分组投影为固定 Word 样式和可编辑段落", () => {
const model: SemanticDocumentModel = {
schemaVersion: 1,
profile: "official",
titlePolicy: {
metadataTitle: "suppress",
firstBodyHeading: "suppress"
},
regions: [
{
kind: "prefix",
nodes: [
{
kind: "group",
role: "official-masthead",
children: [
{
kind: "group",
role: "official-classification",
children: [
text("official-secrecy", "秘密"),
text("official-urgency", "特急")
]
},
text("official-issuer", "示例单位"),
{
kind: "group",
role: "official-issue-row",
children: [
text("official-number", "示例〔20261号"),
text(
"official-signatory",
"张三",
"签发人:"
)
]
}
]
},
text("official-title", "关于开展工作的通知")
]
}
]
};
const plan = createPandocStructurePlan(model, tokens(), {
markerSeed: "official"
});
expect(plan.titlePolicy.firstBodyHeading).toBe("suppress");
expect(plan.prefix[0]).toMatchObject({
kind: "container",
styleId: "MdOfficialMasthead",
slot: "official-masthead",
startMarker:
"MD_TO_PDF_CONTAINER_START_official_1",
endMarker: "MD_TO_PDF_CONTAINER_END_official_2",
blocks: [
{
kind: "paragraph",
styleId: "MdOfficialClassification",
segments: ["秘密", "特急"],
separator: "tab"
},
{
kind: "paragraph",
styleId: "MdOfficialIssuer",
segments: ["示例单位"]
},
{
kind: "paragraph",
styleId: "MdOfficialIssueRow",
segments: ["示例〔20261号", "签发人:张三"],
separator: "tab"
}
]
});
expect(plan.prefix[1]).toMatchObject({
kind: "paragraph",
styleId: "MdOfficialTitle",
segments: ["关于开展工作的通知"]
});
});
it("按主题隐藏令牌过滤标书字段并保留封面分页", () => {
const model: SemanticDocumentModel = {
schemaVersion: 1,
profile: "tender",
titlePolicy: {
metadataTitle: "suppress",
firstBodyHeading: "suppress"
},
regions: [
{
kind: "cover",
section: {
headerFooter: "none",
pageNumber: "hidden",
breakAfter: "next-page",
followingPageNumberStart: 1
},
nodes: [
{
kind: "group",
role: "tender-cover",
children: [
text("tender-title", "投标文件"),
text("tender-bidder", "投标单位"),
text(
"tender-representative",
"授权代表"
),
text("tender-date", "2026年7月")
]
}
]
}
]
};
const plan = createPandocStructurePlan(
model,
tokens([
slot("tender-bidder", true),
slot("tender-representative", true)
]),
{ markerSeed: "tender" }
);
expect(plan.prefix.at(-1)).toEqual({
kind: "section-break",
marker: "MD_TO_PDF_SECTION_BREAK_tender_3",
headerFooter: "none",
pageNumber: "hidden",
followingPageNumberStart: 1
});
expect(plan.prefix[0]).toMatchObject({
kind: "container",
styleId: "MdTenderCover"
});
expect(paragraphSegments(plan.prefix[0]!)).toEqual([
"投标文件",
"2026年7月"
]);
});
it("没有结构区域时只传递标题策略", () => {
const plan = createPandocStructurePlan(
{
schemaVersion: 1,
titlePolicy: {
metadataTitle: "emit",
firstBodyHeading: "keep"
},
regions: []
},
tokens(),
{ markerSeed: "empty" }
);
expect(plan).toEqual({
schemaVersion: 1,
titlePolicy: {
metadataTitle: "emit",
firstBodyHeading: "keep"
},
prefix: [],
suffix: []
});
});
});