1
0

refactor: 重构外部模板系统,改为单文件模板库模式

主要变更:
- 将 templates_dir 参数改为 template_file,支持单个模板库 YAML 文件
- 添加模板库 YAML 验证功能
- 为模板添加 base_dir 支持,正确解析相对路径资源
- 内联模板与外部模板同名时改为警告(内联优先)
- 移除模板缓存机制,直接使用模板库字典
- 更新所有相关测试以适配新的模板加载方式

此重构简化了模板管理,使模板资源的路径解析更加清晰明确。
This commit is contained in:
2026-03-05 13:26:29 +08:00
parent bd12fce14b
commit f1aae96a04
27 changed files with 2141 additions and 1988 deletions

247
README.md
View File

@@ -4,15 +4,15 @@
## ✨ 功能特性
- 📝 **YAML 声明式语法** - 使用简单易读的 YAML 定义演示文稿
- **智能验证** - 转换前自动检查 YAML 文件,提前发现问题
- 🎨 **模板系统** - 支持参数化模板,复用幻灯片布局
- 🧩 **丰富的元素类型** - 文本、图片、形状、表格
- 👁️ **实时预览** - 浏览器预览模式,支持热重载
- 📐 **灵活尺寸** - 支持 16:9 和 4:3 两种宽高比
- 🔧 **模块化架构** - 易于扩展和维护
- - **YAML 声明式语法** - 使用简单易读的 YAML 定义演示文稿
- - **智能验证** - 转换前自动检查 YAML 文件,提前发现问题
- - **模板系统** - 支持参数化模板,复用幻灯片布局
- - **丰富的元素类型** - 文本、图片、形状、表格
- - **实时预览** - 浏览器预览模式,支持热重载
- - **灵活尺寸** - 支持 16:9 和 4:3 两种宽高比
- - **模块化架构** - 易于扩展和维护
## 🚀 快速开始
## 快速开始
### 安装
@@ -27,8 +27,8 @@ uv run yaml2pptx.py convert presentation.yaml output.pptx
# 自动生成输出文件名
uv run yaml2pptx.py convert presentation.yaml
# 使用模板
uv run yaml2pptx.py convert presentation.yaml output.pptx --template-dir ./templates
# 使用模板
uv run yaml2pptx.py convert presentation.yaml output.pptx --template ./templates.yaml
```
### 实时预览
@@ -58,16 +58,16 @@ uv run yaml2pptx.py preview presentation.yaml --no-browser
uv run yaml2pptx.py check presentation.yaml
# 使用模板时验证
uv run yaml2pptx.py check presentation.yaml --template-dir ./templates
uv run yaml2pptx.py check presentation.yaml --template ./templates.yaml
```
验证功能会检查:
- YAML 语法和结构
- 元素是否超出页面范围
- 图片和模板文件是否存在
- 颜色格式是否正确
- 字体大小是否合理
- 表格数据是否一致
- - YAML 语法和结构
- - 元素是否超出页面范围
- - 图片和模板文件是否存在
- - 颜色格式是否正确
- - 字体大小是否合理
- - 表格数据是否一致
**自动验证**:转换时默认会自动验证,如果发现错误会终止转换。可以使用 `--skip-validation` 跳过验证:
@@ -79,13 +79,13 @@ uv run yaml2pptx.py convert presentation.yaml --skip-validation
**验证结果示例**
```
🔍 正在检查 YAML 文件...
正在检查 YAML 文件...
错误 (2):
- 错误 (2):
[幻灯片 2, 元素 1] 无效的颜色格式: red (应为 #RRGGBB)
[幻灯片 3, 元素 2] 图片文件不存在: logo.png
⚠️ 警告 (1):
- 警告 (1):
[幻灯片 1, 元素 1] 元素右边界超出: 10.50 > 10
检查完成: 发现 2 个错误, 1 个警告
@@ -95,7 +95,7 @@ uv run yaml2pptx.py convert presentation.yaml --skip-validation
- **WARNING**:影响视觉效果的问题(元素超出页面、字体太小等)
- **INFO**:优化建议
## 📖 YAML 语法
## YAML 语法
### 最小示例
@@ -146,7 +146,7 @@ slides:
content: "yaml2pptx 支持多种元素类型..."
```
## 🎨 元素类型
## - 元素类型
### 文本元素
@@ -220,7 +220,7 @@ slides:
- `header_font`:表头单元格的字体样式(未定义时继承 `font`
- `style.header_bg`:表头背景色
## 🎨 字体主题系统
## - 字体主题系统
字体主题系统允许你定义可复用的字体配置,统一管理演示文稿的字体样式。
@@ -373,7 +373,7 @@ slides:
header_bg: "#3498db"
```
## 📋 模板系统
## 模板系统
模板允许你定义可复用的幻灯片布局。yaml2pptx 支持两种模板方式:
@@ -425,11 +425,11 @@ slides:
#### 内联模板特性
- 支持变量替换和条件渲染
- 可以与外部模板混合使用
- 无需指定 `--template-dir` 参数
- ⚠️ 内联模板不能相互引用
- ⚠️ 内联和外部模板不能同名(会报错)
- - 支持变量替换和条件渲染
- - 可以与外部模板混合使用
- - 无需指定 `--template` 参数
- - 内联模板不能相互引用
- - 内联和外部模板同名时会发出警告,优先使用内联模板
#### 何时使用内联模板
@@ -465,84 +465,145 @@ slides:
4. **迁移策略**
- 原型阶段使用内联模板快速迭代
- 模板稳定后,如需复用则迁移到外部模板
- 使用 `--template-dir` 参数指定外部模板目录
- 使用 `--template` 参数指定外部模板库文件
#### 内联模板限制
- ⚠️ 内联模板不能相互引用(会报错)
- ⚠️ 内联和外部模板不能同名(会报错)
- ⚠️ 内联模板不支持继承或组合
- - 内联模板不能相互引用(会报错)
- - 内联和外部模板同名时会发出警告,优先使用内联模板
- - 内联模板不支持继承或组合
### 创建外部模板
### 外部模板
创建模板文件 `templates/title-slide.yaml`
外部模板库是一个包含多个模板的 YAML 文件,适合跨文档复用和团队共享。
#### 创建模板库文件
创建模板库文件 `templates.yaml`
```yaml
vars:
- name: title
required: true
- name: subtitle
required: false
default: ""
- name: author
required: false
default: ""
# 模板库元数据(可选)
description: "公司标准模板库"
version: "1.0.0"
author: "设计团队"
elements:
- type: text
box: [1, 2, 8, 1]
content: "{title}"
font:
size: 44
bold: true
align: center
# 模板定义(必需)
templates:
title-slide:
description: "标题页模板"
vars:
- name: title
required: true
- name: subtitle
required: false
default: ""
elements:
- type: text
box: [1, 2, 8, 1]
content: "{title}"
font:
size: 44
bold: true
align: center
- type: text
box: [1, 3.5, 8, 0.5]
content: "{subtitle}"
visible: "{subtitle != ''}"
font:
size: 24
align: center
- type: text
box: [1, 3.5, 8, 0.5]
content: "{subtitle}"
visible: "{subtitle != ''}" # 条件渲染
font:
size: 24
align: center
- type: text
box: [1, 5, 8, 0.5]
content: "{author}"
font:
size: 18
align: center
content-slide:
description: "内容页模板"
vars:
- name: title
required: true
- name: content
required: true
elements:
- type: text
box: [1, 1, 8, 0.8]
content: "{title}"
font:
size: 32
bold: true
- type: text
box: [1, 2, 8, 3]
content: "{content}"
font:
size: 20
```
### 使用外部模板
#### 使用外部模板
在命令行中指定模板库文件:
```bash
uv run yaml2pptx.py convert presentation.yaml output.pptx --template ./templates.yaml
```
在 YAML 文件中引用模板:
```yaml
slides:
- template: title-slide
vars:
title: "我的演示文稿"
subtitle: "副标题"
author: "作者"
subtitle: "使用外部模板库"
- template: content-slide
vars:
title: "第一章"
content: "这是内容"
```
#### 模板库特性
- - 单个文件包含多个模板
- - 支持模板库元数据description、version、author
- - 每个模板可以有独立的 description
- - 便于版本控制和分发
- - 支持相对路径的图片资源(相对于模板库文件所在目录)
#### 模板库文件结构
```yaml
# 顶层元数据(可选)
description: "模板库描述"
version: "版本号"
author: "作者"
# 模板定义(必需)
templates:
模板名称1:
description: "模板描述(可选)"
vars: [...]
elements: [...]
模板名称2:
description: "模板描述(可选)"
vars: [...]
elements: [...]
```
#### 模板 description 字段
模板文件可以包含可选的 `description` 字段,用于描述模板的用途和设计意图,仅用于文档目的
模板可以包含可选的 `description` 字段,用于描述模板的用途和设计意图:
```yaml
# templates/title-slide.yaml
description: "用于章节标题页的模板,包含主标题和副标题"
vars:
- name: title
required: true
elements:
- type: text
box: [1, 2, 8, 1]
content: "{title}"
font:
size: 44
bold: true
templates:
title-slide:
description: "用于章节标题页的模板,包含主标题和副标题"
vars:
- name: title
required: true
elements:
- type: text
box: [1, 2, 8, 1]
content: "{title}"
font:
size: 44
bold: true
```
### 混合模式模板
@@ -877,7 +938,7 @@ slides:
| 选项 | 说明 |
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `--template-dir` | 模板文件目录 |
| `--template` | 模板文件路径 |
### convert 命令
@@ -887,7 +948,7 @@ slides:
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `output` | 输出的 PPTX 文件路径(可选) |
| `--template-dir` | 模板文件目录 |
| `--template` | 模板文件路径 |
| `--skip-validation` | 跳过自动验证 |
| `--force` / `-f` | 强制覆盖已存在文件 |
@@ -898,12 +959,12 @@ slides:
| 选项 | 说明 |
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `--template-dir` | 模板文件目录 |
| `--template` | 模板文件路径 |
| `--port` | 服务器端口(默认:随机端口 30000-40000 |
| `--host` | 主机地址默认127.0.0.1 |
| `--no-browser` | 不自动打开浏览器 |
## 📐 坐标系统
## - 坐标系统
- **单位**:英寸 (inch)
- **原点**:幻灯片左上角 (0, 0)
@@ -917,7 +978,7 @@ slides:
- 左上角位置:(1", 2")
- 尺寸:宽 8",高 1"
## 🎨 颜色格式
## - 颜色格式
支持两种十六进制格式:
- **短格式**`#RGB`(如 `#fff` = 白色)
@@ -928,7 +989,7 @@ slides:
1. **开发流程**:使用 `--preview` 模式实时查看效果,确认无误后再生成 PPTX
2. **模板复用**:为常用布局创建模板,保持演示文稿风格一致
3. **相对路径**:图片路径相对于 YAML 文件位置,便于项目管理
4. **模板目录**:使用模板时必须指定 `--template-dir` 参数
4. **模板库文件**:使用模板时必须指定 `--template` 参数
5. **文本换行**:文本框默认启用自动换行,无需手动处理长文本
## 📚 完整示例
@@ -938,17 +999,17 @@ slides:
- `temp/template_demo.yaml` - 模板使用示例
- `temp/complex_presentation.yaml` - 复杂演示文稿示例
## ⚠️ 常见错误
## - 常见错误
| 错误信息 | 原因 | 解决方法 |
|---------|------|---------|
| `文件不存在: xxx.yaml` | 找不到输入文件 | 检查文件路径是否正确 |
| `YAML 语法错误: 第 X 行` | YAML 格式错误 | 检查缩进和语法 |
| `模板文件不存在: xxx` | 模板文件未找到 | 检查模板名称和 `--template-dir` |
| `模板文件不存在: xxx` | 模板文件未找到 | 检查模板名称和 `--template` |
| `缺少必需变量: xxx` | 未提供必需的模板变量 | 在 `vars` 中提供该变量 |
| `图片文件未找到: xxx` | 图片文件不存在 | 检查图片路径 |
## 🔧 扩展性
## - 扩展性
yaml2pptx 采用模块化架构,易于扩展: