1
0
Files
PPTX/openspec/changes/archive/2026-03-03-add-slide-enabled-control/design.md
lanyuanxiaoyao 01a93ce13b feat: 添加页面级 enabled 参数支持幻灯片启用/禁用控制
添加页面级 enabled 布尔参数,用于临时禁用整个幻灯片,无需删除或注释 YAML 内容。
与元素级 visible 条件渲染独立工作,提供两层控制机制。

主要变更:
- 在 yaml2pptx.py 主循环中检查 enabled 参数,跳过禁用的幻灯片
- 实现独立的 slide_index 计数器,准确统计实际渲染的幻灯片数量
- 在 yaml_loader.py 中添加 enabled 字段验证,确保类型为布尔值
- 添加 11 个测试用例,覆盖各种使用场景
- 更新 README.md 和 README_DEV.md 文档,说明 enabled 和 visible 的区别
- 创建新的 slide-enabled-control capability 规范
- 更新 template-system 规范,添加 enabled 字段支持

使用示例:
  slides:
    - template: title-slide
      vars:
        title: "正常页面"
    - enabled: false
      template: work-in-progress
      vars:
        title: "临时禁用的页面"

测试:所有 282 个单元测试通过
2026-03-03 16:33:10 +08:00

91 lines
3.3 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.
## Context
当前系统支持元素级的 `visible` 条件渲染,通过条件表达式(如 `{subtitle != ''}`)动态控制元素是否显示。但在开发和调试过程中,经常需要临时禁用整个幻灯片,当前只能通过注释或删除 YAML 内容来实现,不够便捷。
现有渲染流程:
- `yaml2pptx.py` 主循环遍历所有幻灯片
- `Presentation.render_slide()` 渲染单个幻灯片
- `Template.render()` 处理模板变量和元素级 `visible` 检查
## Goals / Non-Goals
**Goals:**
- 添加页面级 `enabled` 布尔参数,默认为 `true`
- 在渲染循环中检查 `enabled`,跳过禁用的幻灯片
- 保持与元素级 `visible` 的独立性和兼容性
- 向后兼容现有 YAML 文件
**Non-Goals:**
- 不支持 `enabled` 的条件表达式(仅支持布尔值)
- 不修改元素级 `visible` 的实现
- 不影响预览模式的显示逻辑(本次不涉及)
## Decisions
### 决策 1: 使用 `enabled` 而非 `visible`
**选择**: 页面级使用 `enabled` 参数
**理由**:
- 语义清晰:`enabled` 表示静态开关,`visible` 表示动态条件
- 避免混淆:与元素级 `visible` 区分开
- 符合直觉enabled=false 表示禁用整页
**备选方案**: 使用 `visible` 统一命名
- 缺点:语义不清,容易与元素级混淆
- 缺点:暗示支持条件表达式,但实际只支持布尔值
### 决策 2: 默认值为 `true`
**选择**: 未指定 `enabled` 时默认为 `true`
**理由**:
- 向后兼容:现有 YAML 文件无需修改
- 符合预期:默认行为是渲染所有幻灯片
### 决策 3: 在主循环检查,而非 `render_slide()`
**选择**: 在 `yaml2pptx.py` 的主循环中检查 `enabled`
**理由**:
- 性能:跳过禁用页面,避免不必要的模板加载和渲染
- 清晰:页面级控制在页面级处理,不侵入渲染逻辑
- 日志:可以在跳过时记录日志
**备选方案**: 在 `Presentation.render_slide()` 中检查
- 缺点:已经进入渲染流程,浪费性能
- 缺点:返回值处理复杂(需要返回 None 或特殊标记)
### 决策 4: 渲染计数逻辑
**选择**: 维护独立的 `slide_index` 计数器,只统计实际渲染的幻灯片
**理由**:
- 日志准确:进度显示反映实际渲染数量
- 用户友好:不会显示"处理 3/5"然后跳过 2 个的困惑情况
**实现**:
```python
slide_index = 0
for i, slide_data in enumerate(slides_data, 1):
if not slide_data.get('enabled', True):
continue
slide_index += 1
log_progress(slide_index, total_slides, f"处理幻灯片")
```
## Risks / Trade-offs
**风险 1: 用户误用 `enabled` 作为条件渲染**
- 描述:用户可能期望 `enabled: "{some_var}"` 支持条件表达式
- 缓解:文档明确说明 `enabled` 仅支持布尔值,条件渲染使用元素级 `visible`
**风险 2: 预览模式下禁用页面的显示**
- 描述:预览模式可能需要显示禁用的页面(灰色或标记)
- 缓解:本次不涉及预览模式,后续可扩展
**权衡 1: 简单性 vs 灵活性**
- 选择:简单的布尔值而非条件表达式
- 理由:满足 90% 的使用场景(调试、版本控制),保持简单
**权衡 2: 日志详细度**
- 当前:跳过禁用页面时不记录日志
- 备选:记录"跳过第 X 页(已禁用)"
- 选择:不记录,避免日志噪音