# Font Theme ## Purpose 字体主题系统提供可复用的字体配置管理能力,允许用户在 metadata 中定义字体配置模板,通过引用方式应用到元素,实现统一的字体样式管理。 ## Requirements ### Requirement: 系统必须支持在 metadata 中定义 fonts 字段 系统 SHALL 支持在 YAML metadata 中定义 fonts 字段,用于存储可复用的字体配置。 #### Scenario: 定义 fonts 字段 - **WHEN** metadata 中定义 fonts 字段 - **THEN** 系统成功解析并存储字体配置字典 #### Scenario: fonts 字段为空字典 - **WHEN** metadata 中定义 fonts: {} - **THEN** 系统接受空的字体配置字典 #### Scenario: fonts 字段未定义 - **WHEN** metadata 中未定义 fonts 字段 - **THEN** 系统正常处理,fonts 为空字典 ### Requirement: fonts 字段必须包含命名字体配置 fonts 字段 SHALL 包含一个或多个命名字体配置,每个配置是一个字体属性字典。 #### Scenario: 定义单个字体配置 - **WHEN** fonts 中定义 title: {family: "Arial", size: 44, bold: true} - **THEN** 系统创建名为 title 的字体配置 #### Scenario: 定义多个字体配置 - **WHEN** fonts 中定义 title、subtitle、body 等多个配置 - **THEN** 系统为每个配置创建独立的字体对象 ### Requirement: 系统必须支持 fonts_default 字段 系统 SHALL 支持在 metadata 中定义可选的 fonts_default 字段,指定默认字体配置的引用。 #### Scenario: 定义 fonts_default 引用 - **WHEN** metadata 中定义 fonts_default: "@body" - **THEN** 系统将 fonts_default 解析为对 fonts.body 的引用 #### Scenario: fonts_default 未定义 - **WHEN** metadata 中未定义 fonts_default 字段 - **THEN** 系统使用 python-pptx 的默认字体 #### Scenario: fonts_default 引用不存在的配置 - **WHEN** fonts_default: "@undefined" 且 fonts.undefined 不存在 - **THEN** 系统抛出 ERROR,提示引用的字体配置不存在 #### Scenario: fonts_default 必须引用 fonts 中的配置 - **WHEN** fonts_default: "Arial"(直接字体名称) - **THEN** 系统抛出 ERROR,提示 fonts_default 必须是引用格式 ### Requirement: 元素 font 字段必须支持三种引用方式 元素 font 字段 SHALL 支持字符串引用(整体引用)、字典引用(继承覆盖或独立定义)两种形式。 #### Scenario: 字符串整体引用 - **WHEN** 元素定义 font: "@title" - **THEN** 系统使用 fonts.title 的所有属性 #### Scenario: 字典继承覆盖 - **WHEN** 元素定义 font: {parent: "@title", size: 60} - **THEN** 系统继承 fonts.title 的所有属性,覆盖 size 为 60 #### Scenario: 字典独立定义 - **WHEN** 元素定义 font: {family: "SimSun", size: 24} - **THEN** 系统使用定义的属性,未定义的属性继承 fonts_default #### Scenario: font 字段未定义 - **WHEN** 元素未定义 font 字段 - **THEN** 元素使用 fonts_default 或系统默认字体 ### Requirement: parent 字段必须引用 fonts 中的配置 font 字典中的 parent 字段 SHALL 引用 fonts 中已定义的配置名称。 #### Scenario: parent 引用存在的配置 - **WHEN** parent: "@title" 且 fonts.title 存在 - **THEN** 系统成功继承 fonts.title 的属性 #### Scenario: parent 引用不存在的配置 - **WHEN** parent: "@undefined" 且 fonts.undefined 不存在 - **THEN** 系统抛出 ERROR,提示引用的字体配置不存在 #### Scenario: parent 必须是引用格式 - **WHEN** parent: "Arial"(直接字体名称) - **THEN** 系统抛出 ERROR,提示 parent 必须是引用格式 ### Requirement: 系统必须检测并拒绝引用循环 系统 SHALL 在解析字体引用时检测循环引用,检测到循环时抛出 ERROR。 #### Scenario: 直接循环引用 - **WHEN** fonts.title.parent: "@title"(引用自身) - **THEN** 系统抛出 ERROR,提示检测到自引用 #### Scenario: 间接循环引用 - **WHEN** fonts.a.parent: "@b" 且 fonts.b.parent: "@a" - **THEN** 系统抛出 ERROR,显示完整的引用循环路径 #### Scenario: 深层循环引用 - **WHEN** 引用链深度超过 10 层 - **THEN** 系统抛出 ERROR,提示引用深度超限 #### Scenario: 错误信息包含引用路径 - **WHEN** 系统检测到循环引用 - **THEN** 错误信息包含完整的引用路径,如 "fonts.title -> fonts.subtitle -> fonts.title" ### Requirement: 系统必须支持属性继承链 字体属性解析 SHALL 按照优先级顺序继承:parent → 当前定义 → fonts_default → 系统默认。 #### Scenario: parent 定义了基础属性 - **WHEN** fonts.title 定义 size: 44,元素定义 font: {parent: "@title", bold: true} - **THEN** 元素使用 size: 44(继承)、bold: true(覆盖) #### Scenario: parent 未定义的属性继承 fonts_default - **WHEN** fonts_default 定义 size: 18,元素定义 font: {parent: "@title"} 且 title 未定义 size - **THEN** 元素使用 size: 18(从 fonts_default 继承) #### Scenario: 当前定义覆盖 parent - **WHEN** parent 定义 size: 44,当前定义 size: 60 - **THEN** 元素使用 size: 60(当前定义覆盖 parent) ### Requirement: 模板元素必须支持继承 fonts_default 模板中未定义 font 的元素 SHALL 继承 metadata.fonts_default 配置。 #### Scenario: 模板元素未定义 font - **WHEN** 模板元素未定义 font 字段 - **THEN** 元素继承 metadata.fonts_default 的配置 #### Scenario: 模板元素定义了 font - **WHEN** 模板元素定义 font: "@title" - **THEN** 元素使用 font: "@title",不继承 fonts_default #### Scenario: fonts_default 未定义时模板元素行为 - **WHEN** 模板元素未定义 font 且 metadata 未定义 fonts_default - **THEN** 元素使用系统默认字体 ### Requirement: 表格元素必须支持 font 和 header_font 字段 表格元素 SHALL 支持 font 和 header_font 字段,分别控制数据单元格和表头的字体样式。 #### Scenario: 表格定义整体字体 - **WHEN** 表格定义 font: {family: "Arial", size: 14} - **THEN** 数据单元格和表头都应用该字体(表头可被 header_font 覆盖) #### Scenario: 表格定义表头字体 - **WHEN** 表格定义 header_font: {bold: true, color: "#ffffff"} - **THEN** 表头应用该字体,数据单元格继承 font 或 fonts_default #### Scenario: 表头字体继承表格字体 - **WHEN** 表格定义 font: {size: 14} 且 header_font: {parent: "@font", bold: true} - **THEN** 表头继承 size: 14,覆盖 bold: true #### Scenario: 表格仅定义 header_font - **WHEN** 表格仅定义 header_font: {bold: true} - **THEN** 表头应用 bold: true,数据单元格继承 fonts_default ### Requirement: 系统必须移除旧的表格字体语法 系统 SHALL 移除 style.font_size 和 style.header_color 字段的处理逻辑。 #### Scenario: 旧语法字段不再生效 - **WHEN** 表格定义 style: {font_size: 14, header_color: "#fff"} - **THEN** 系统忽略这些字段,使用 font 和 header_font 替代 #### Scenario: style 字段保留用于非字体属性 - **WHEN** 表格定义 style: {header_bg: "#4a90e2"} - **THEN** 系统正常处理背景色等非字体属性