feat: 实现动态 DOCX 模板与样式映射

This commit is contained in:
SkyJourney
2026-07-30 14:10:43 +08:00
parent fe5d67fb6d
commit fa159d916f
41 changed files with 3610 additions and 7 deletions
@@ -0,0 +1,64 @@
import {
defaultExportConfig,
getPaperDimensionsMm,
lengthToMillimeters,
resolvePageMargins,
type ExportConfig,
type MarkdownDocumentMetadata,
type ThemeManifest
} from "@md-to-pdf/core";
export interface DynamicReferenceDocxOptions {
exportConfig: ExportConfig;
theme: ThemeManifest;
fileName: string;
metadata: Pick<MarkdownDocumentMetadata, "title" | "author">;
}
export function resolveReferencePageOptions(
options: DynamicReferenceDocxOptions
) {
const { exportConfig, theme } = options;
const themeDefaults = theme.pageDefaults;
const dimensions = getPaperDimensionsMm(
exportConfig.paper.format,
exportConfig.paper.orientation
);
const margins = resolvePageMargins(
exportConfig.paper,
themeDefaults?.margins
);
const useThemeDecorations =
exportConfig.pageDecorationsMode === "theme";
return {
dimensions,
margins: {
top: lengthToMillimeters(margins.top),
right: lengthToMillimeters(margins.right),
bottom: lengthToMillimeters(margins.bottom),
left: lengthToMillimeters(margins.left)
},
orientation: exportConfig.paper.orientation,
header: useThemeDecorations
? themeDefaults?.header ?? defaultExportConfig.header
: exportConfig.header,
footer: useThemeDecorations
? themeDefaults?.footer ?? defaultExportConfig.footer
: exportConfig.footer
};
}
export function resolveHeaderTemplate(
value: string,
options: DynamicReferenceDocxOptions
) {
const replacements: Record<string, string> = {
title: options.metadata.title,
author: options.metadata.author,
filename: options.fileName
};
return value.replace(
/\$\{(title|author|filename)\}/gu,
(_match, name: string) => replacements[name] ?? ""
);
}