1
0
Files
PPTX/README.md
lanyuanxiaoyao 98098dc911 feat: 实现模板库metadata和跨域字体引用系统
实现了统一的metadata结构和字体作用域系统,支持文档和模板库之间的单向字体引用。

主要变更:
- 模板库必须包含metadata字段(包括size、fonts、fonts_default)
- 实现文档和模板库的size一致性校验
- 实现字体作用域系统(文档可引用模板库字体,反之不可)
- 实现跨域循环引用检测
- 实现fonts_default级联规则(模板库→文档→系统默认)
- 添加错误代码常量(SIZE_MISMATCH、FONT_NOT_FOUND等)
- 更新文档和开发者指南

测试覆盖:
- 新增33个测试(单元测试20个,集成测试13个)
- 所有457个测试通过

Breaking Changes:
- 模板库文件必须包含metadata字段
- 模板库metadata.size为必填字段
- 文档和模板库的size必须一致

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-05 18:12:05 +08:00

1103 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# yaml2pptx
使用 YAML 声明式语法创建 PowerPoint 演示文稿的工具。
## ✨ 功能特性
- - **YAML 声明式语法** - 使用简单易读的 YAML 定义演示文稿
- - **智能验证** - 转换前自动检查 YAML 文件,提前发现问题
- - **模板系统** - 支持参数化模板,复用幻灯片布局
- - **丰富的元素类型** - 文本、图片、形状、表格
- - **实时预览** - 浏览器预览模式,支持热重载
- - **灵活尺寸** - 支持 16:9 和 4:3 两种宽高比
- - **模块化架构** - 易于扩展和维护
## 快速开始
### 安装
本工具使用 [uv](https://github.com/astral-sh/uv) 管理依赖。项目依赖在 pyproject.toml 中声明,运行时会自动安装所需的 Python 包。
### 基本用法
```bash
# 转换 YAML 为 PPTX
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 ./templates.yaml
```
### 实时预览
```bash
# 启动预览服务器(自动打开浏览器)
uv run yaml2pptx.py preview presentation.yaml
# 指定端口
uv run yaml2pptx.py preview presentation.yaml --port 8080
# 允许局域网访问
uv run yaml2pptx.py preview presentation.yaml --host 0.0.0.0
# 不自动打开浏览器
uv run yaml2pptx.py preview presentation.yaml --no-browser
```
预览模式会自动监听文件变化,修改 YAML 文件后浏览器会自动刷新。
### 验证功能
在转换前验证 YAML 文件,提前发现问题:
```bash
# 独立验证命令
uv run yaml2pptx.py check presentation.yaml
# 使用模板时验证
uv run yaml2pptx.py check presentation.yaml --template ./templates.yaml
```
验证功能会检查:
- - YAML 语法和结构
- - 元素是否超出页面范围
- - 图片和模板文件是否存在
- - 颜色格式是否正确
- - 字体大小是否合理
- - 表格数据是否一致
**自动验证**:转换时默认会自动验证,如果发现错误会终止转换。可以使用 `--skip-validation` 跳过验证:
```bash
# 跳过自动验证
uv run yaml2pptx.py convert presentation.yaml --skip-validation
```
**验证结果示例**
```
正在检查 YAML 文件...
- 错误 (2):
[幻灯片 2, 元素 1] 无效的颜色格式: red (应为 #RRGGBB)
[幻灯片 3, 元素 2] 图片文件不存在: logo.png
- 警告 (1):
[幻灯片 1, 元素 1] 元素右边界超出: 10.50 > 10
检查完成: 发现 2 个错误, 1 个警告
```
- **ERROR**:阻止转换的严重问题(文件不存在、语法错误等)
- **WARNING**:影响视觉效果的问题(元素超出页面、字体太小等)
- **INFO**:优化建议
## YAML 语法
### 最小示例
```yaml
metadata:
size: "16:9" # 或 "4:3"
slides:
- background:
color: "#ffffff"
elements:
- type: text
box: [1, 1, 8, 1]
content: "Hello, World!"
font:
size: 44
bold: true
color: "#333333"
align: center
```
#### description 字段
`metadata.description` 字段用于描述整个演示文稿的概要和用途,仅用于文档目的,不影响生成的 PPTX 文件:
```yaml
metadata:
size: "16:9"
description: "2024年度项目进展总结包含背景、成果和展望"
```
### 使用模板
```yaml
metadata:
size: "16:9"
slides:
- template: title-slide
vars:
title: "我的演示文稿"
subtitle: "使用 yaml2pptx 创建"
author: "张三"
- template: content-slide
vars:
title: "功能概览"
content: "yaml2pptx 支持多种元素类型..."
```
## - 元素类型
### 文本元素
```yaml
- type: text
box: [x, y, width, height] # 位置和尺寸(英寸)
content: "文本内容"
font:
size: 18 # 字号(磅)
bold: true # 粗体
italic: false # 斜体
color: "#ff0000" # 颜色
align: center # left/center/right
```
**特性**:文本框默认启用自动换行,文字超出宽度时会自动换行。
### 图片元素
```yaml
- type: image
box: [x, y, width, height]
src: "path/to/image.png" # 支持相对路径和绝对路径
```
**示例**
```yaml
slides:
- elements:
- type: image
src: "photo.jpg"
box: [1, 1, 4, 3]
```
### 形状元素
```yaml
- type: shape
box: [x, y, width, height]
shape: rectangle # rectangle/ellipse/rounded_rectangle
fill: "#4a90e2" # 填充颜色
line:
color: "#000000" # 边框颜色
width: 2 # 边框宽度(磅)
```
### 表格元素
```yaml
- type: table
position: [x, y]
col_widths: [2, 2, 2] # 每列宽度(英寸)
data:
- ["表头1", "表头2", "表头3"]
- ["数据1", "数据2", "数据3"]
- ["数据4", "数据5", "数据6"]
font:
family: "Arial"
size: 14
color: "#333333"
header_font:
bold: true
color: "#ffffff"
style:
header_bg: "#4a90e2"
```
**字体配置**
- `font`:表格数据单元格的字体样式
- `header_font`:表头单元格的字体样式(未定义时继承 `font`
- `style.header_bg`:表头背景色
## - 字体主题系统
字体主题系统允许你定义可复用的字体配置,统一管理演示文稿的字体样式。
### 定义字体主题
`metadata.fonts` 中定义命名字体配置:
```yaml
metadata:
size: "16:9"
fonts:
title:
family: "cjk-sans"
size: 44
bold: true
color: "#2c3e50"
body:
family: "sans"
size: 18
color: "#34495e"
line_spacing: 1.5
fonts_default: "@body" # 默认字体(可选)
slides:
- elements:
- type: text
content: "标题文本"
box: [1, 1, 8, 1]
font: "@title" # 引用字体主题
- type: text
content: "正文内容"
box: [1, 2.5, 8, 2]
# 未定义 font 时使用 fonts_default
```
### 预设字体类别
系统提供五种预设字体类别,自动映射到跨平台通用字体:
| 类别 | 映射字体 | 说明 |
|------|---------|------|
| `sans` | Arial | 西文无衬线 |
| `serif` | Times New Roman | 西文衬线 |
| `mono` | Courier New | 等宽字体 |
| `cjk-sans` | Microsoft YaHei | 中文无衬线 |
| `cjk-serif` | SimSun | 中文衬线 |
**使用示例**
```yaml
metadata:
fonts:
body:
family: "cjk-sans" # 自动映射到 Microsoft YaHei
size: 18
```
### 字体引用方式
支持三种字体引用方式:
**1. 整体引用**:完全使用定义的字体配置
```yaml
font: "@title"
```
**2. 继承覆盖**:继承字体配置并覆盖特定属性
```yaml
font:
parent: "@title"
size: 60 # 覆盖字号
color: "#ff0000" # 覆盖颜色
```
**3. 独立定义**:完全自定义字体
```yaml
font:
family: "SimSun"
size: 24
bold: true
```
### 扩展字体属性
除了基础属性size、bold、italic、color、align还支持
**字体样式**
- `family`:字体族名称或预设类别
- `underline`下划线true/false
- `strikethrough`删除线true/false
**段落属性**
- `line_spacing`:行距倍数(如 1.5
- `space_before`:段前间距(磅)
- `space_after`:段后间距(磅)
**高级属性**
- `baseline`基线位置normal/superscript/subscript
- `caps`大小写转换normal/allcaps/smallcaps
**完整示例**
```yaml
metadata:
fonts:
heading:
family: "cjk-sans"
size: 32
bold: true
color: "#2c3e50"
line_spacing: 1.2
space_after: 12
body:
family: "sans"
size: 18
color: "#34495e"
line_spacing: 1.5
fonts_default: "@body"
slides:
- elements:
- type: text
content: "章节标题"
box: [1, 1, 8, 1]
font: "@heading"
- type: text
content: "正文内容\n支持多行文本"
box: [1, 2, 8, 2]
font:
parent: "@body"
underline: true
- type: table
position: [1, 4]
col_widths: [3, 3]
data:
- ["列1", "列2"]
- ["数据1", "数据2"]
font: "@body"
header_font:
parent: "@body"
bold: true
color: "#ffffff"
style:
header_bg: "#3498db"
```
## 模板系统
模板允许你定义可复用的幻灯片布局。yaml2pptx 支持两种模板方式:
- **外部模板**:独立的 YAML 文件,适合跨文档复用
- **内联模板**:在源文件中定义,适合单文档使用
### 内联模板
内联模板允许你在 YAML 源文件中直接定义模板,无需创建单独的模板文件。
#### 定义内联模板
在 YAML 文件顶层添加 `templates` 字段:
```yaml
metadata:
size: "16:9"
templates:
title-slide:
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
slides:
- template: title-slide
vars:
title: "我的演示文稿"
subtitle: "使用内联模板"
```
#### 内联模板特性
- - 支持变量替换和条件渲染
- - 可以与外部模板混合使用
- - 无需指定 `--template` 参数
- - 内联模板不能相互引用
- - 内联和外部模板同名时会发出警告,优先使用内联模板
#### 何时使用内联模板
**适合使用内联模板**
- 模板仅在单个文档中使用
- 快速原型开发
- 简单的模板定义1-3 个元素)
- 文档自包含,无需外部依赖
**适合使用外部模板**
- 需要跨多个文档复用
- 复杂的模板定义(>5 个元素)
- 团队共享的模板库
- 需要版本控制和独立维护
**最佳实践**
1. **命名规范**
- 内联模板使用描述性名称(如 `title-slide`, `content-slide`
- 避免与外部模板同名,否则会报错
- 使用一致的命名风格kebab-case 推荐)
2. **模板大小**
- 内联模板建议不超过 50 行
- 超过 50 行考虑拆分或使用外部模板
- 保持 YAML 文件可读性
3. **混合使用**
- 可以在同一文档中混合使用内联和外部模板
- 通用模板使用外部模板(如标题页、结束页)
- 文档特定模板使用内联模板
4. **迁移策略**
- 原型阶段使用内联模板快速迭代
- 模板稳定后,如需复用则迁移到外部模板
- 使用 `--template` 参数指定外部模板库文件
#### 内联模板限制
- - 内联模板不能相互引用(会报错)
- - 内联和外部模板同名时会发出警告,优先使用内联模板
- - 内联模板不支持继承或组合
### 外部模板库
外部模板库是一个包含多个模板的 YAML 文件,适合跨文档复用和团队共享。
#### 创建模板库文件
创建模板库文件 `templates.yaml`
```yaml
# 模板库元数据(必需)
metadata:
size: "16:9" # 必需:模板库尺寸,必须与使用它的文档一致
description: "公司标准模板库" # 可选:描述信息
fonts: # 可选:模板库字体主题
template-title:
family: "cjk-sans"
size: 44
bold: true
color: "#2c3e50"
template-body:
family: "sans"
size: 20
color: "#34495e"
fonts_default: "@template-body" # 可选:模板库默认字体
# 模板定义(必需)
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: "@template-title" # 引用模板库字体
- type: text
box: [1, 3.5, 8, 0.5]
content: "{subtitle}"
visible: "{subtitle != ''}"
font:
parent: "@template-title"
size: 24
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:
parent: "@template-title"
size: 32
- type: text
box: [1, 2, 8, 3]
content: "{content}"
# 未指定 font 时使用 fonts_default
```
**重要说明**
1. **metadata 字段是必需的**
- `metadata.size` 必须指定("16:9" 或 "4:3"
- 模板库的 size 必须与使用它的文档 size 一致,否则会报错
2. **字体主题系统**
- 模板库可以定义自己的字体主题(`metadata.fonts`
- 文档可以引用模板库的字体(跨域引用)
- 模板库不能引用文档的字体(单向引用)
- 模板库的 `fonts_default` 只能引用模板库内部字体
3. **字体级联规则**
- 模板元素未指定字体时,使用模板库的 `fonts_default`
- 如果模板库没有 `fonts_default`,使用文档的 `fonts_default`
- 如果都没有,使用系统默认字体
#### 使用外部模板库
在命令行中指定模板库文件:
```bash
uv run yaml2pptx.py convert presentation.yaml output.pptx --template ./templates.yaml
```
在 YAML 文件中引用模板:
```yaml
slides:
- template: title-slide
vars:
title: "我的演示文稿"
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` 字段,用于描述模板的用途和设计意图:
```yaml
templates:
title-slide:
description: "用于章节标题页的模板,包含主标题和副标题"
vars:
- name: title
required: true
elements:
- type: text
box: [1, 2, 8, 1]
content: "{title}"
font:
size: 44
bold: true
```
### 混合模式模板
混合模式允许你在使用模板的同时添加自定义元素,实现更灵活的布局组合。
#### 基本用法
在使用模板的幻灯片中,同时指定 `template``elements` 字段:
```yaml
slides:
# 混合模式:模板 + 自定义元素
- template: standard-header
vars:
title: "混合模式示例"
theme_color: "#3949ab"
elements:
# 自定义内容区域
- type: text
box: [1, 1.5, 8, 1]
content: "这是自定义内容"
font:
size: 24
# 自定义形状
- type: shape
shape: rectangle
box: [1, 3, 8, 2]
fill: "#f5f5f5"
```
#### 变量共享
自定义元素可以访问模板中定义的变量:
```yaml
templates:
branded-header:
vars:
- name: title
- name: theme_color
default: "#3949ab"
elements:
- type: shape
box: [0, 0, 10, 0.8]
fill: "{theme_color}"
- type: text
box: [0.5, 0.2, 9, 0.5]
content: "{title}"
slides:
- template: branded-header
vars:
title: "我的页面"
theme_color: "#4caf50"
elements:
# 自定义元素使用模板变量
- type: shape
box: [1, 2, 8, 3]
fill: "{theme_color}" # 使用模板的 theme_color
```
#### 元素渲染顺序
混合模式中元素按以下顺序渲染z 轴顺序):
1. **模板元素**(先渲染,在底层)
2. **自定义元素**(后渲染,在上层)
这意味着自定义元素会覆盖在模板元素之上。
```yaml
slides:
- template: background-template # 提供背景和头部
vars:
title: "标题"
elements:
# 这些元素会显示在模板元素之上
- type: shape
box: [2, 2, 6, 3]
fill: "#ffffff" # 白色框会覆盖背景
```
#### 使用场景
**适合使用混合模式**
- 复用统一的头部/底部,自定义中间内容
- 使用模板提供的背景和品牌元素,添加页面特定内容
- 需要在标准布局基础上添加特殊元素
**示例:统一头部 + 自定义内容**
```yaml
templates:
standard-header:
vars:
- name: title
elements:
# 统一的头部样式
- type: shape
box: [0, 0, 10, 0.8]
fill: "#3949ab"
- type: text
box: [0.5, 0.2, 9, 0.5]
content: "{title}"
font:
color: "#ffffff"
slides:
# 页面 1头部 + 文本内容
- template: standard-header
vars:
title: "文本页面"
elements:
- type: text
box: [1, 1.5, 8, 3]
content: "页面内容..."
# 页面 2头部 + 表格
- template: standard-header
vars:
title: "数据页面"
elements:
- type: table
position: [1, 1.5]
data: [[...]]
# 页面 3头部 + 图片
- template: standard-header
vars:
title: "图片页面"
elements:
- type: image
box: [2, 1.5, 6, 3.5]
src: "chart.png"
```
#### 向后兼容性
混合模式完全向后兼容:
- **纯模板模式**:只指定 `template`,行为不变
- **纯自定义模式**:只指定 `elements`,行为不变
- **混合模式**:同时指定 `template``elements`,新功能
```yaml
slides:
# 纯模板模式(原有行为)
- template: title-slide
vars:
title: "标题"
# 纯自定义模式(原有行为)
- elements:
- type: text
content: "自定义内容"
# 混合模式(新功能)
- template: title-slide
vars:
title: "标题"
elements:
- type: text
content: "额外内容"
```
#### 幻灯片 description 字段
幻灯片可以包含可选的 `description` 字段,用于描述该幻灯片的作用和内容。**`description` 内容会自动写入 PPT 备注页**,方便在演示时查看演讲说明:
```yaml
slides:
- description: "介绍项目背景和目标"
template: title-slide
vars:
title: "项目背景"
- description: "展示核心功能特性"
elements:
- type: text
content: "功能特性"
```
**注意事项**
- 仅幻灯片级别的 `description` 会写入备注
- 模板的 `description` 不会继承到幻灯片备注
- `metadata.description` 用于描述整个演示文稿,不写入单个幻灯片备注
### 条件渲染
#### 元素级条件渲染
使用 `visible` 属性控制元素显示,支持强大的条件表达式:
**基本示例**
```yaml
# 简单比较
- type: text
content: "有数据"
visible: "{count > 0}"
# 字符串比较
- type: text
content: "草稿状态"
visible: "{status == 'draft'}"
# 非空检查(向后兼容)
- type: text
content: "{subtitle}"
visible: "{subtitle != ''}"
```
**支持的表达式类型**
1. **比较运算**`==`, `!=`, `>`, `<`, `>=`, `<=`
```yaml
visible: "{score >= 60}"
visible: "{price <= 100}"
```
2. **逻辑运算**`and`, `or`, `not`
```yaml
visible: "{count > 0 and status == 'active'}"
visible: "{is_draft or is_preview}"
visible: "{not (count == 0)}"
```
3. **成员测试**`in`, `not in`
```yaml
visible: "{status in ['draft', 'review', 'published']}"
visible: "{level in (1, 2, 3)}"
visible: "{'test' in version}" # 字符串包含
```
4. **数学运算**`+`, `-`, `*`, `/`, `%`, `**`
```yaml
visible: "{(price * discount) > 50}"
visible: "{(total / count) >= 10}"
```
5. **内置函数**`int()`, `float()`, `str()`, `len()`, `bool()`, `abs()`, `min()`, `max()`
```yaml
visible: "{len(items) > 0}"
visible: "{int(value) > 100}"
```
**复杂条件示例**
```yaml
# 范围检查
- type: text
content: "评分: {score}"
visible: "{score >= 60 and score <= 100}"
# 多条件组合
- type: text
content: "管理员或高分用户"
visible: "{is_admin or (score >= 90)}"
# 嵌套条件
- type: text
content: "符合条件"
visible: "{((count > 0) and (status == 'active')) or (is_admin and (level >= 3))}"
```
#### 页面级启用控制
使用 `enabled` 参数控制整个幻灯片是否渲染:
```yaml
slides:
# 正常渲染的幻灯片
- template: title-slide
vars:
title: "主标题"
# 临时禁用的幻灯片(开发调试)
- enabled: false
template: work-in-progress
vars:
title: "未完成的内容"
# 继续渲染后续幻灯片
- template: content-slide
vars:
title: "内容页"
```
**enabled 参数说明**
- 类型:布尔值(`true` 或 `false`
- 默认值:`true`(未指定时默认启用)
- 用途:临时禁用幻灯片,无需删除或注释 YAML 内容
- 场景开发调试、版本控制、A/B 测试
**enabled vs visible 的区别**
| 特性 | `enabled`(页面级) | `visible`(元素级) |
|------|-------------------|-------------------|
| 作用范围 | 整个幻灯片 | 单个元素 |
| 类型 | 布尔值 | 条件表达式 |
| 判断时机 | 加载时(静态) | 渲染时(动态) |
| 使用场景 | 临时禁用页面 | 条件显示元素 |
**示例**
```yaml
slides:
# 页面启用,但副标题元素可能隐藏
- enabled: true
template: title-slide
vars:
title: "标题"
subtitle: "" # 空字符串,元素级 visible 会隐藏副标题
# 整页禁用,不渲染
- enabled: false
elements:
- type: text
content: "这一页不会出现在最终 PPTX 中"
box: [1, 1, 8, 1]
font: {size: 44}
```
## 🎯 命令行选项
### check 命令
验证 YAML 文件的正确性。
| 选项 | 说明 |
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `--template` | 模板库文件路径 |
### convert 命令
将 YAML 文件转换为 PPTX 文件。
| 选项 | 说明 |
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `output` | 输出的 PPTX 文件路径(可选) |
| `--template` | 模板库文件路径 |
| `--skip-validation` | 跳过自动验证 |
| `--force` / `-f` | 强制覆盖已存在文件 |
### preview 命令
启动预览服务器,实时查看演示文稿效果。
| 选项 | 说明 |
|------|------|
| `input` | 输入的 YAML 文件路径(必需) |
| `--template` | 模板库文件路径 |
| `--port` | 服务器端口(默认:随机端口 30000-40000 |
| `--host` | 主机地址默认127.0.0.1 |
| `--no-browser` | 不自动打开浏览器 |
## - 坐标系统
- **单位**:英寸 (inch)
- **原点**:幻灯片左上角 (0, 0)
- **方向**X 轴向右Y 轴向下
**幻灯片尺寸**
- 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` 参数
5. **文本换行**:文本框默认启用自动换行,无需手动处理长文本
## 📚 完整示例
查看 `temp/` 目录下的示例文件:
- `temp/test_refactor.yaml` - 基本示例
- `temp/template_demo.yaml` - 模板使用示例
- `temp/complex_presentation.yaml` - 复杂演示文稿示例
## - 常见错误
| 错误信息 | 原因 | 解决方法 |
|---------|------|---------|
| `文件不存在: xxx.yaml` | 找不到输入文件 | 检查文件路径是否正确 |
| `YAML 语法错误: 第 X 行` | YAML 格式错误 | 检查缩进和语法 |
| `模板文件不存在: xxx` | 模板文件未找到 | 检查模板名称和 `--template` |
| `缺少必需变量: xxx` | 未提供必需的模板变量 | 在 `vars` 中提供该变量 |
| `图片文件未找到: xxx` | 图片文件不存在 | 检查图片路径 |
## - 扩展性
yaml2pptx 采用模块化架构,易于扩展:
- **添加新元素类型**:定义新的元素数据类和渲染方法
- **添加新渲染器**:支持输出到其他格式(如 PDF
- **自定义模板**:创建符合你需求的模板库
详见 [开发文档](README_DEV.md)。
## 📦 依赖项
- `python-pptx` - PowerPoint 文件生成
- `pyyaml` - YAML 解析
- `flask` - 预览服务器
- `watchdog` - 文件监听
依赖在 pyproject.toml 中声明,由 uv 自动管理,无需手动安装。
## 🧪 测试
项目包含完整的测试套件,使用 pytest 框架。
### 运行测试
```bash
# 安装测试依赖
uv pip install -e ".[dev]"
# 运行所有测试
uv run pytest
# 运行特定类型的测试
uv run pytest tests/unit/ # 单元测试
uv run pytest tests/integration/ # 集成测试
uv run pytest tests/e2e/ # 端到端测试
# 运行特定测试文件
uv run pytest tests/unit/test_elements.py
# 显示详细输出
uv run pytest -v
# 显示测试覆盖率
uv run pytest --cov=. --cov-report=html
```
### 测试结构
```
tests/
├── unit/ # 单元测试 - 测试各模块独立功能
├── integration/ # 集成测试 - 测试模块间协作
├── e2e/ # 端到端测试 - 测试完整用户场景
└── fixtures/ # 测试数据
```
## 🤝 贡献
欢迎贡献代码、报告问题或提出建议!
开发者请参阅 [开发文档](README_DEV.md) 了解代码结构和开发规范。
## 📄 许可证
MIT License