Add core Python script (yaml2pptx.py) for converting YAML to PowerPoint: - Element rendering: text, image, shape, table, chart - Template system with placeholders - PPTX generation with python-pptx OpenSpec workflow setup: - 3 archived changes: browser-preview, template-dir-cli, yaml-to-pptx - 7 main specifications covering all core modules - Config and documentation structure 30 files changed, 4984 insertions(+)
222 lines
7.0 KiB
Markdown
222 lines
7.0 KiB
Markdown
# PPTX Generation
|
||
|
||
## Purpose
|
||
|
||
PPTX generation 系统负责使用 python-pptx 库创建符合 OOXML 标准的 PowerPoint 文档。它管理演示文稿的整体属性(如尺寸),按顺序添加幻灯片,并提供命令行接口供用户使用。
|
||
|
||
## Requirements
|
||
|
||
### Requirement: 系统必须创建符合 OOXML 标准的 PPTX 文件
|
||
|
||
系统 SHALL 使用 python-pptx 库生成符合 Office Open XML (OOXML) 标准的 .pptx 文件。
|
||
|
||
#### Scenario: 生成的 PPTX 文件可被 PowerPoint 打开
|
||
|
||
- **WHEN** 系统生成 PPTX 文件
|
||
- **THEN** 该文件可被 Microsoft PowerPoint 正常打开和编辑
|
||
|
||
#### Scenario: 生成的 PPTX 文件可被其他软件打开
|
||
|
||
- **WHEN** 系统生成 PPTX 文件
|
||
- **THEN** 该文件可被 LibreOffice Impress、Google Slides 等软件正常打开
|
||
|
||
#### Scenario: PPTX 文件扩展名正确
|
||
|
||
- **WHEN** 系统保存演示文稿
|
||
- **THEN** 输出文件的扩展名为 `.pptx`
|
||
|
||
### Requirement: 系统必须支持设置演示文稿尺寸
|
||
|
||
系统 SHALL 支持设置演示文稿的幻灯片尺寸,支持 16:9 和 4:3 两种标准比例。
|
||
|
||
#### Scenario: 创建 16:9 比例的演示文稿
|
||
|
||
- **WHEN** metadata 中指定 `size: "16:9"`
|
||
- **THEN** 系统创建 10×5.625 英寸的幻灯片
|
||
|
||
#### Scenario: 创建 4:3 比例的演示文稿
|
||
|
||
- **WHEN** metadata 中指定 `size: "4:3"`
|
||
- **THEN** 系统创建 10×7.5 英寸的幻灯片
|
||
|
||
#### Scenario: 默认使用 16:9 比例
|
||
|
||
- **WHEN** metadata 中未指定 size 字段
|
||
- **THEN** 系统默认使用 16:9 比例
|
||
|
||
#### Scenario: 不支持的尺寸比例报错
|
||
|
||
- **WHEN** metadata 中指定了不支持的尺寸比例(如 "21:9")
|
||
- **THEN** 系统抛出错误,提示仅支持 16:9 和 4:3
|
||
|
||
### Requirement: 系统必须按顺序添加幻灯片
|
||
|
||
系统 SHALL 按照 YAML 中 slides 列表的顺序,依次添加幻灯片到 PPTX 文件。
|
||
|
||
#### Scenario: 幻灯片顺序与 YAML 一致
|
||
|
||
- **WHEN** YAML 中 slides 列表为 `[slide1, slide2, slide3]`
|
||
- **THEN** 生成的 PPTX 文件中,幻灯片顺序为 slide1、slide2、slide3
|
||
|
||
#### Scenario: 空幻灯片列表生成空演示文稿
|
||
|
||
- **WHEN** YAML 中 slides 列表为空
|
||
- **THEN** 系统生成一个不包含任何幻灯片的 PPTX 文件(或抛出警告)
|
||
|
||
### Requirement: 系统必须使用空白布局
|
||
|
||
系统 SHALL 为每个幻灯片使用空白布局(blank layout),以便完全自定义内容。
|
||
|
||
#### Scenario: 使用空白布局添加幻灯片
|
||
|
||
- **WHEN** 系统添加幻灯片
|
||
- **THEN** 使用 `prs.slide_layouts[6]`(空白布局)而非预定义布局
|
||
|
||
#### Scenario: 空白幻灯片不包含占位符
|
||
|
||
- **WHEN** 创建新的空白幻灯片
|
||
- **THEN** 幻灯片不包含任何预定义的标题或内容占位符
|
||
|
||
### Requirement: 系统必须保存到指定路径
|
||
|
||
系统 SHALL 将生成的 PPTX 文件保存到用户指定的路径。
|
||
|
||
#### Scenario: 保存到指定文件路径
|
||
|
||
- **WHEN** 用户指定输出路径为 `output/presentation.pptx`
|
||
- **THEN** 系统将 PPTX 文件保存到该路径
|
||
|
||
#### Scenario: 自动创建输出目录
|
||
|
||
- **WHEN** 输出路径包含不存在的目录(如 `output/subdir/file.pptx`)
|
||
- **THEN** 系统自动创建所需的目录结构
|
||
|
||
#### Scenario: 输出路径已存在时覆盖
|
||
|
||
- **WHEN** 指定的输出文件路径已存在
|
||
- **THEN** 系统覆盖原有文件(或提供选项询问用户)
|
||
|
||
#### Scenario: 无写入权限时报错
|
||
|
||
- **WHEN** 输出路径没有写入权限
|
||
- **THEN** 系统抛出错误,提示权限不足
|
||
|
||
### Requirement: 系统必须使用 python-pptx 的单位转换函数
|
||
|
||
系统 SHALL 使用 python-pptx 提供的 Inches() 函数将英寸值转换为 EMU(English Metric Units)。
|
||
|
||
#### Scenario: 使用 Inches() 转换坐标
|
||
|
||
- **WHEN** 元素 box 定义为 `[1, 2, 8, 3]`
|
||
- **THEN** 系统调用 `Inches(1)`, `Inches(2)`, `Inches(8)`, `Inches(3)` 转换为 EMU
|
||
|
||
#### Scenario: EMU 转换的精度
|
||
|
||
- **WHEN** 使用 Inches(1.0)
|
||
- **THEN** 返回值为 914400 EMU(1 英寸 = 914400 EMU)
|
||
|
||
### Requirement: 系统必须处理颜色转换
|
||
|
||
系统 SHALL 将十六进制颜色值(如 "#4a90e2")转换为 python-pptx 的 RGBColor 对象。
|
||
|
||
#### Scenario: 十六进制颜色转 RGB
|
||
|
||
- **WHEN** 颜色值为 "#4a90e2"
|
||
- **THEN** 系统转换为 RGBColor(74, 144, 226)
|
||
|
||
#### Scenario: 短格式十六进制颜色
|
||
|
||
- **WHEN** 颜色值为 "#fff"(短格式)
|
||
- **THEN** 系统扩展为 "#ffffff" 并转换为 RGBColor(255, 255, 255)
|
||
|
||
#### Scenario: 无效颜色格式报错
|
||
|
||
- **WHEN** 颜色值不是有效的十六进制格式
|
||
- **THEN** 系统抛出错误,提示颜色格式无效
|
||
|
||
### Requirement: 系统必须使用 uv 运行 Python 脚本
|
||
|
||
系统 SHALL 使用 uv 运行转换脚本,通过 Inline script metadata 指定依赖。
|
||
|
||
#### Scenario: 脚本包含 Inline script metadata
|
||
|
||
- **WHEN** 查看 `yaml2pptx.py` 文件头部
|
||
- **THEN** 包含 `# /// script` 块,定义 python-pptx 和 PyYAML 依赖
|
||
|
||
#### Scenario: 使用 uv 运行脚本
|
||
|
||
- **WHEN** 执行转换命令
|
||
- **THEN** 使用 `uv run yaml2pptx.py` 而非 `python yaml2pptx.py`
|
||
|
||
#### Scenario: 禁止直接安装依赖
|
||
|
||
- **WHEN** 需要使用 python-pptx 或 PyYAML
|
||
- **THEN** 不使用 `pip install`,而是在 script metadata 中声明依赖
|
||
|
||
### Requirement: 系统架构保持简洁
|
||
|
||
系统 SHALL 采用两层架构(模板 + 演示文稿),颜色和样式直接在模板中定义。
|
||
|
||
#### Scenario: 模板自包含样式
|
||
|
||
- **WHEN** 查看模板文件
|
||
- **THEN** 颜色值直接以十六进制格式指定(如 "#4a90e2")
|
||
|
||
#### Scenario: 无需主题配置
|
||
|
||
- **WHEN** 创建新的演示文稿
|
||
- **THEN** metadata 中不需要指定 theme 字段
|
||
|
||
#### Scenario: 模板独立配色
|
||
|
||
- **WHEN** 创建新模板
|
||
- **THEN** 可以为该模板定义独立的颜色方案,不受其他模板影响
|
||
|
||
### Requirement: 系统必须提供命令行接口
|
||
|
||
系统 SHALL 提供命令行接口,接受输入 YAML 文件路径和输出 PPTX 文件路径。
|
||
|
||
#### Scenario: 基本命令行使用
|
||
|
||
- **WHEN** 执行 `uv run yaml2pptx.py input.yaml output.pptx`
|
||
- **THEN** 系统读取 input.yaml,生成 output.pptx
|
||
|
||
#### Scenario: 仅提供输入文件时自动命名输出
|
||
|
||
- **WHEN** 执行 `uv run yaml2pptx.py input.yaml`
|
||
- **THEN** 系统自动生成输出文件名为 `input.pptx`
|
||
|
||
#### Scenario: 显示帮助信息
|
||
|
||
- **WHEN** 执行 `uv run yaml2pptx.py --help`
|
||
- **THEN** 系统显示使用说明和参数列表
|
||
|
||
#### Scenario: 输入文件不存在时报错
|
||
|
||
- **WHEN** 提供的输入文件路径不存在
|
||
- **THEN** 系统抛出错误,提示输入文件未找到
|
||
|
||
### Requirement: 系统必须报告转换进度
|
||
|
||
系统 SHALL 在转换过程中输出进度信息,包括当前处理的幻灯片数量。
|
||
|
||
#### Scenario: 输出转换开始信息
|
||
|
||
- **WHEN** 开始转换
|
||
- **THEN** 系统输出 "开始转换: input.yaml"
|
||
|
||
#### Scenario: 输出幻灯片处理进度
|
||
|
||
- **WHEN** 处理每个幻灯片
|
||
- **THEN** 系统输出 "处理幻灯片 N/M"
|
||
|
||
#### Scenario: 输出转换完成信息
|
||
|
||
- **WHEN** 转换成功完成
|
||
- **THEN** 系统输出 "转换完成: output.pptx"
|
||
|
||
#### Scenario: 转换失败时输出错误
|
||
|
||
- **WHEN** 转换过程中发生错误
|
||
- **THEN** 系统输出详细的错误信息和堆栈跟踪(调试模式下)
|