1
0

refactor: modularize yaml2pptx into layered architecture

Refactor yaml2pptx.py from a 1,245-line monolithic script into a modular
architecture with clear separation of concerns. The entry point is now
127 lines, with business logic distributed across focused modules.

Architecture:
- core/: Domain models (elements, template, presentation)
- loaders/: YAML loading and validation
- renderers/: PPTX and HTML rendering
- preview/: Flask preview server
- utils.py: Shared utilities

Key improvements:
- Element abstraction layer using dataclass with validation
- Renderer logic built into generator classes
- Single-direction dependencies (no circular imports)
- Each module 150-300 lines for better readability
- Backward compatible CLI interface

Documentation:
- README.md: User-facing usage guide
- README_DEV.md: Developer documentation

OpenSpec:
- Archive refactor-yaml2pptx-modular change (63/70 tasks complete)
- Sync 5 delta specs to main specs (2 new + 3 updated)
This commit is contained in:
2026-03-02 16:43:45 +08:00
parent b2132dc06b
commit ed940f0690
31 changed files with 3142 additions and 1307 deletions

305
README.md
View File

@@ -1,68 +1,50 @@
# yaml2pptx
YAML PowerPoint (PPTX) 工具 - 使用 YAML 格式的声明式语法定义演示文稿,并生成 PPTX 文件
使用 YAML 声明式语法创建 PowerPoint 演示文稿的工具
## 功能特性
## 功能特性
- **YAML 声明式语法** - 使用简单易读的 YAML 定义演示文稿
- **模板系统** - 支持参数化模板,复用幻灯片布局
- **多种元素类型** - 文本、图片、形状、表格
- **实时预览** - 浏览器预览模式,支持热重载,快速开发迭代
- **灵活尺寸** - 支持 16:9 和 4:3 两种宽高比
- 📝 **YAML 声明式语法** - 使用简单易读的 YAML 定义演示文稿
- 🎨 **模板系统** - 支持参数化模板,复用幻灯片布局
- 🧩 **丰富的元素类型** - 文本、图片、形状、表格
- 👁️ **实时预览** - 浏览器预览模式,支持热重载
- 📐 **灵活尺寸** - 支持 16:9 和 4:3 两种宽高比
- 🔧 **模块化架构** - 易于扩展和维护
## 安装
## 🚀 快速开始
脚本使用 [uv](https://github.com/astral-sh/uv) 管理 Python 依赖。运行时会自动安装所需依赖。
### 安装
依赖项:
- `python-pptx` - PowerPoint 文件生成
- `pyyaml` - YAML 解析
- `flask` - 预览服务器(预览模式需要)
- `watchdog` - 文件监控(预览模式需要)
本工具使用 [uv](https://github.com/astral-sh/uv) 管理依赖,运行时会自动安装所需的 Python 包。
## 基本用法
### 生成 PPTX 文件
### 基本用法
```bash
# 基本用法 - 输出文件自动生成(input.pptx
# 生成 PPTX 文件自动命名为 input.pptx
uv run yaml2pptx.py presentation.yaml
# 指定输出文件名
uv run yaml2pptx.py presentation.yaml output.pptx
# 指定模板目录
# 使用模板
uv run yaml2pptx.py presentation.yaml output.pptx --template-dir ./templates
```
### 实时预览模式
### 实时预览
```bash
# 启动预览服务器(随机端口 20000-30000
# 启动预览服务器(自动打开浏览器
uv run yaml2pptx.py presentation.yaml --preview
# 指定端口
uv run yaml2pptx.py presentation.yaml --preview --port 8080
# 指定模板目录
uv run yaml2pptx.py presentation.yaml --preview --template-dir ./templates
```
预览模式会自动打开浏览器窗口显示演示文稿,修改 YAML 文件时页面会自动刷新。
预览模式会自动监听文件变化,修改 YAML 文件后浏览器会自动刷新。
## 命令行选项
## 📖 YAML 语法
| 选项 | 说明 |
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `output` | 输出的 PPTX 文件路径(可选,默认为 `input.pptx` |
| `--template-dir` | 模板 YAML 文件所在目录 |
| `--preview` | 启用浏览器预览模式(不生成 PPTX 文件) |
| `--port` | 预览服务器端口(默认:随机 20000-30000 |
## YAML 结构
### 基本演示文稿
### 最小示例
```yaml
metadata:
@@ -74,7 +56,7 @@ slides:
elements:
- type: text
box: [1, 1, 8, 1]
content: "你好,世界!"
content: "Hello, World!"
font:
size: 44
bold: true
@@ -92,7 +74,7 @@ slides:
- template: title-slide
vars:
title: "我的演示文稿"
subtitle: "yaml2pptx 简介"
subtitle: "使用 yaml2pptx 创建"
author: "张三"
- template: content-slide
@@ -101,65 +83,67 @@ slides:
content: "yaml2pptx 支持多种元素类型..."
```
## 元素类型
## 🎨 元素类型
### 文本
### 文本元素
```yaml
- type: text
box: [x, y, width, height] # 位置和尺寸(单位:英寸)
box: [x, y, width, height] # 位置和尺寸(英寸)
content: "文本内容"
font:
size: 18 # 字号(磅)
bold: true/false # 粗体
italic: true/false # 斜体
color: "#ff0000" # 颜色#RGB 或 #RRGGBB
align: left/center/right # 对齐方式
bold: true # 粗体
italic: false # 斜体
color: "#ff0000" # 颜色
align: center # left/center/right
```
**文本自动换行**:文本框默认启用自动换行功能。当文字内容超过文本框宽度时会自动换行显示,确保文字不会溢出边界
**特性**:文本框默认启用自动换行,文字超出宽度时会自动换行。
### 图片
### 图片元素
```yaml
- type: image
box: [x, y, width, height]
src: "path/to/image.png" # 相对路径绝对路径
src: "path/to/image.png" # 支持相对路径绝对路径
```
### 形状
### 形状元素
```yaml
- type: shape
box: [x, y, width, height]
shape: rectangle/ellipse/rounded_rectangle
fill: "#4a90e2" # 填充颜色
shape: rectangle # rectangle/ellipse/rounded_rectangle
fill: "#4a90e2" # 填充颜色
line:
color: "#000000" # 边框颜色
width: 1 # 边框宽度(磅)
color: "#000000" # 边框颜色
width: 2 # 边框宽度(磅)
```
### 表格
### 表格元素
```yaml
- type: table
position: [x, y] # 表格位置
col_widths: [2, 2, 2] # 列宽(英寸)
position: [x, y]
col_widths: [2, 2, 2] # 列宽(英寸)
data:
- ["表头1", "表头2", "表头3"]
- ["1", "数据", "数据"]
- ["行2", "数据", "数据"]
- ["数据1", "数据2", "数据3"]
- ["数据4", "数据5", "数据6"]
style:
font_size: 14
header_bg: "#4a90e2"
header_color: "#ffffff"
```
## 模板系统
## 📋 模板系统
模板允许你定义可复用的幻灯片布局,支持参数化
模板允许你定义可复用的幻灯片布局。
### 模板文件 (`templates/title-slide.yaml`)
### 创建模板
创建模板文件 `templates/title-slide.yaml`
```yaml
vars:
@@ -184,7 +168,7 @@ elements:
- type: text
box: [1, 3.5, 8, 0.5]
content: "{subtitle}"
visible: "{subtitle != ''}" # 仅当 subtitle 不为空时显示
visible: "{subtitle != ''}" # 条件渲染
font:
size: 24
align: center
@@ -204,141 +188,100 @@ slides:
- template: title-slide
vars:
title: "我的演示文稿"
subtitle: "演示"
author: "李四"
subtitle: "副标题"
author: "作者"
```
### 模板变量说明
| 字段 | 说明 |
|------|------|
| `name` | 变量名(必需) |
| `required` | 是否必需(默认:`false` |
| `default` | 默认值(未提供时使用) |
### 条件渲染
使用 `visible` 属性控制元素显示条件
使用 `visible` 属性控制元素显示:
```yaml
- type: text
content: "{subtitle}"
visible: "{subtitle != ''}" # 仅当提供了 subtitle 时显示
visible: "{subtitle != ''}" # 仅当 subtitle 不为空时显示
```
## 背景设置
## 🎯 命令行选项
幻灯片支持纯色背景:
```yaml
slides:
- background:
color: "#f5f5f5" # 浅灰色背景
elements:
- type: text
content: "灰色背景上的内容"
```
## 颜色格式
颜色使用十六进制格式:
- **短格式**`#RGB`(如 `#fff` 表示白色)
- **完整格式**`#RRGGBB`(如 `#ffffff` 表示白色)
## 完整示例
### 演示文稿文件 (`demo.yaml`)
```yaml
metadata:
size: 16:9
slides:
# 使用模板的标题页
- template: title-slide
vars:
title: "yaml2pptx 入门"
subtitle: "用 YAML 编写演示文稿"
# 自定义元素的内容页
- background:
color: "#ffffff"
elements:
- type: text
box: [0.5, 0.5, 9, 0.8]
content: "功能特性"
font:
size: 36
bold: true
color: "#2c3e50"
- type: shape
box: [0.5, 1.5, 3, 2.5]
shape: rounded_rectangle
fill: "#3498db"
line:
color: "#2980b9"
width: 2
- type: text
box: [1, 2, 2, 1]
content: "易于使用"
font:
size: 18
color: "#ffffff"
align: center
- type: table
position: [5, 2]
col_widths: [2, 2]
data:
- ["功能", "状态"]
- ["模板支持", "✓"]
- ["实时预览", "✓"]
- ["表格支持", "✓"]
style:
font_size: 14
header_bg: "#2c3e50"
header_color: "#ffffff"
# 图片页
- elements:
- type: image
box: [1, 1, 8, 4]
src: "chart.png"
```
## 错误提示
脚本提供详细的错误信息:
| 错误 | 说明 |
| 选项 | 说明 |
|------|------|
| `文件不存在: presentation.yaml` | 找不到输入文件 |
| `YAML 语法错误: presentation.yaml, 第 5 行: ...` | YAML 语法问题 |
| `模板文件不存在: title-slide` | 模板文件未找到 |
| `缺少必需变量: title` | 未提供必需的模板变量 |
| `图片文件未找到: image.png` | 图片文件不存在 |
| `input` | 输入的 YAML 文件路径(必需) |
| `output` | 输出的 PPTX 文件路径(可选) |
| `--template-dir` | 模板文件目录 |
| `--preview` | 启用浏览器预览模式 |
| `--port` | 预览服务器端口(默认:随机) |
## 使用技巧
1. **使用模板** - 保持幻灯片布局一致
2. **启用预览模式** - 开发时快速迭代
3. **使用相对路径** - 图片路径相对于 YAML 文件位置
4. **指定模板目录** - 使用模板时必须指定 `--template-dir`
5. **先预览后生成** - 预览确认无误后再生成最终 PPTX
## 坐标系统
## 📐 坐标系统
- **单位**:英寸 (inch)
- **原点**:幻灯片左上角
- **原点**:幻灯片左上角 (0, 0)
- **方向**X 轴向右Y 轴向下
| 尺寸比例 | 幻灯片尺寸 |
|----------|------------|
| 16:9 | 10" × 5.625" |
| 4:3 | 10" × 7.5" |
**幻灯片尺寸**
- 16:9 → 10" × 5.625"
- 4:3 → 10" × 7.5"
## 许可证
**示例**`box: [1, 2, 8, 1]` 表示:
- 左上角位置:(1", 2")
- 尺寸:宽 8",高 1"
## 🎨 颜色格式
支持两种十六进制格式:
- **短格式**`#RGB`(如 `#fff` = 白色)
- **完整格式**`#RRGGBB`(如 `#ffffff` = 白色)
## 💡 使用技巧
1. **开发流程**:使用 `--preview` 模式实时查看效果,确认无误后再生成 PPTX
2. **模板复用**:为常用布局创建模板,保持演示文稿风格一致
3. **相对路径**:图片路径相对于 YAML 文件位置,便于项目管理
4. **模板目录**:使用模板时必须指定 `--template-dir` 参数
5. **文本换行**:文本框默认启用自动换行,无需手动处理长文本
## 📚 完整示例
查看 `temp/` 目录下的示例文件:
- `temp/test_refactor.yaml` - 基本示例
- `temp/template_demo.yaml` - 模板使用示例
- `temp/complex_presentation.yaml` - 复杂演示文稿示例
## ⚠️ 常见错误
| 错误信息 | 原因 | 解决方法 |
|---------|------|---------|
| `文件不存在: xxx.yaml` | 找不到输入文件 | 检查文件路径是否正确 |
| `YAML 语法错误: 第 X 行` | YAML 格式错误 | 检查缩进和语法 |
| `模板文件不存在: xxx` | 模板文件未找到 | 检查模板名称和 `--template-dir` |
| `缺少必需变量: xxx` | 未提供必需的模板变量 | 在 `vars` 中提供该变量 |
| `图片文件未找到: xxx` | 图片文件不存在 | 检查图片路径 |
## 🔧 扩展性
yaml2pptx 采用模块化架构,易于扩展:
- **添加新元素类型**:定义新的元素数据类和渲染方法
- **添加新渲染器**:支持输出到其他格式(如 PDF
- **自定义模板**:创建符合你需求的模板库
详见 [开发文档](README_DEV.md)。
## 📦 依赖项
- `python-pptx` - PowerPoint 文件生成
- `pyyaml` - YAML 解析
- `flask` - 预览服务器
- `watchdog` - 文件监听
所有依赖由 uv 自动管理,无需手动安装。
## 🤝 贡献
欢迎贡献代码、报告问题或提出建议!
开发者请参阅 [开发文档](README_DEV.md) 了解代码结构和开发规范。
## 📄 许可证
MIT License