feat: 建立 DOCX 主题映射引擎

This commit is contained in:
SkyJourney
2026-07-30 20:28:47 +08:00
parent e7c688df6e
commit 6fed666f44
15 changed files with 851 additions and 25 deletions
+29 -8
View File
@@ -27,6 +27,16 @@ export type DocxStylePreset = z.infer<
typeof docxStylePresetSchema
>;
export const docxThemeStyleModeSchema = z.enum([
"auto",
"auto-with-overrides",
"explicit"
]);
export type DocxThemeStyleMode = z.infer<
typeof docxThemeStyleModeSchema
>;
export const docxFontFamilySchema = z.object({
latin: fontNameSchema,
eastAsia: fontNameSchema,
@@ -37,7 +47,7 @@ export type DocxFontFamily = z.infer<
typeof docxFontFamilySchema
>;
const docxBodyStyleSchema = z.object({
export const docxBodyStyleSchema = z.object({
fonts: docxFontFamilySchema.optional(),
sizePt: pointSizeSchema.optional(),
color: colorSchema.optional(),
@@ -47,7 +57,7 @@ const docxBodyStyleSchema = z.object({
spacingAfterPt: spacingSchema.optional()
});
const docxHeadingStyleSchema = z.object({
export const docxHeadingStyleSchema = z.object({
fonts: docxFontFamilySchema.optional(),
sizesPt: z
.tuple([
@@ -65,7 +75,7 @@ const docxHeadingStyleSchema = z.object({
spacingAfterPt: spacingSchema.optional()
});
const docxCodeStyleSchema = z.object({
export const docxCodeStyleSchema = z.object({
fonts: docxFontFamilySchema.optional(),
sizePt: pointSizeSchema.optional(),
color: colorSchema.optional(),
@@ -74,7 +84,7 @@ const docxCodeStyleSchema = z.object({
lineSpacing: z.number().min(1).max(3).optional()
});
const docxBlockStyleSchema = z.object({
export const docxBlockStyleSchema = z.object({
color: colorSchema.optional(),
backgroundColor: colorSchema.optional(),
borderColor: colorSchema.optional(),
@@ -82,7 +92,7 @@ const docxBlockStyleSchema = z.object({
italic: z.boolean().optional()
});
const docxTableStyleSchema = z.object({
export const docxTableStyleSchema = z.object({
fonts: docxFontFamilySchema.optional(),
sizePt: pointSizeSchema.optional(),
color: colorSchema.optional(),
@@ -92,7 +102,7 @@ const docxTableStyleSchema = z.object({
cellMarginMm: z.number().min(0).max(20).optional()
});
const docxCaptionStyleSchema = z.object({
export const docxCaptionStyleSchema = z.object({
fonts: docxFontFamilySchema.optional(),
sizePt: pointSizeSchema.optional(),
color: colorSchema.optional(),
@@ -100,8 +110,7 @@ const docxCaptionStyleSchema = z.object({
alignment: z.enum(["left", "center", "right"]).optional()
});
export const docxThemeStyleSchema = z.object({
preset: docxStylePresetSchema,
export const docxThemeStyleOverridesSchema = z.object({
body: docxBodyStyleSchema.optional(),
headings: docxHeadingStyleSchema.optional(),
code: docxCodeStyleSchema.optional(),
@@ -116,6 +125,18 @@ export const docxThemeStyleSchema = z.object({
.optional()
});
export type DocxThemeStyleOverrides = z.infer<
typeof docxThemeStyleOverridesSchema
>;
export const docxThemeStyleSchema =
docxThemeStyleOverridesSchema.extend({
mode: docxThemeStyleModeSchema.optional(),
preset: docxStylePresetSchema.optional(),
basePreset: docxStylePresetSchema.optional(),
overrides: docxThemeStyleOverridesSchema.optional()
});
export type DocxThemeStyle = z.infer<
typeof docxThemeStyleSchema
>;
+22
View File
@@ -209,4 +209,26 @@ describe("DOCX 主题样式协议", () => {
})
).toThrow();
});
it("接受自动映射模式和兼容预设", () => {
expect(
docxThemeStyleSchema.parse({
mode: "auto-with-overrides",
basePreset: "technical",
overrides: {
table: {
headerBackgroundColor: "#f6f8fa"
}
}
})
).toMatchObject({
mode: "auto-with-overrides",
basePreset: "technical",
overrides: {
table: {
headerBackgroundColor: "#f6f8fa"
}
}
});
});
});