1
0
Files
PPTX/openspec/specs/html-rendering/spec.md
lanyuanxiaoyao b2132dc06b feat: enable text auto-wrap for text boxes by default
- Set text_frame.word_wrap = True in add_text_element() for PPTX
- Change CSS from white-space: pre-wrap to normal in HTML preview
- Add overflow-wrap: break-word for better word breaking
- Update README.md with auto-wrap documentation
- Update element-rendering and html-rendering specs
- Archive change: 2026-03-02-add-text-auto-wrap
2026-03-02 15:23:14 +08:00

237 lines
8.1 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.
# HTML Rendering
## Purpose
HTML Rendering 系统负责将 YAML 中定义的各类元素(文本、图片、形状、表格)转换为 HTML/CSS 代码,在浏览器中显示。它复用现有的 YAML 解析和模板渲染逻辑,但将输出目标从 PPTX 改为 HTML/CSS提供快速的预览体验。
## Requirements
### Requirement: 系统必须将 YAML 元素转换为 HTML
系统 SHALL 将解析后的 YAML 元素转换为 HTML 代码,在浏览器中渲染。
#### Scenario: 生成完整的 HTML 页面
- **WHEN** 浏览器请求预览页面
- **THEN** 系统生成包含 HTML、CSS 和 JavaScript 的完整页面
#### Scenario: 动态生成 HTML
- **WHEN** YAML 文件变化
- **THEN** 系统重新解析 YAML动态生成新的 HTML 内容,无需生成中间文件
#### Scenario: HTML 页面包含 SSE 客户端代码
- **WHEN** 生成 HTML 页面
- **THEN** 页面包含 JavaScript 代码,连接到 SSE 端点,监听更新事件
### Requirement: 系统必须使用固定 DPI 进行单位转换
系统 SHALL 使用固定 DPI (96) 将 YAML 中的英寸单位转换为 CSS 像素单位。
#### Scenario: 英寸转换为像素
- **WHEN** 元素定义 `box: [1, 2, 8, 3]`(单位为英寸)
- **THEN** 系统转换为 CSS`left: 96px; top: 192px; width: 768px; height: 288px`
#### Scenario: 幻灯片尺寸固定
- **WHEN** 渲染 16:9 幻灯片
- **THEN** 系统使用固定尺寸 960x540 像素10 英寸 x 5.625 英寸 x 96 DPI
#### Scenario: 4:3 幻灯片尺寸
- **WHEN** 渲染 4:3 幻灯片
- **THEN** 系统使用固定尺寸 960x720 像素10 英寸 x 7.5 英寸 x 96 DPI
### Requirement: 系统必须渲染文本元素
系统 SHALL 将 YAML 中的文本元素转换为 HTML `<div>` 标签,应用相应的样式,并默认启用文字自动换行。
#### Scenario: 渲染基本文本元素
- **WHEN** 元素定义为 `{type: text, content: "Hello", box: [1, 2, 8, 3]}`
- **THEN** 系统生成 `<div>` 标签,内容为 "Hello",位置为 (96px, 192px),尺寸为 768x288 像素
#### Scenario: 应用文本字体样式
- **WHEN** 文本元素定义了 `font: {size: 32, bold: true, color: "#333333"}`
- **THEN** 系统应用 CSS`font-size: 32pt; font-weight: bold; color: #333333`
#### Scenario: 应用文本对齐方式
- **WHEN** 文本元素定义了 `font: {align: center}`
- **THEN** 系统应用 CSS`text-align: center`
#### Scenario: 支持多行文本(保留换行符)
- **WHEN** 文本内容包含换行符(`\n`
- **THEN** 系统使用 `white-space: pre-wrap` 保留换行符
#### Scenario: 文本元素默认启用自动换行
- **WHEN** 系统渲染任何文本元素
- **THEN** 系统应用 CSS`white-space: normal`,允许文字在容器边界处自动换行
#### Scenario: 使用 pt 单位表示字体大小
- **WHEN** 文本字体大小为 44
- **THEN** 系统使用 CSS`font-size: 44pt`(与 PPTX 保持一致)
### Requirement: 系统必须渲染形状元素
系统 SHALL 将 YAML 中的形状元素转换为 HTML `<div>` 标签,使用 CSS 样式模拟形状。
#### Scenario: 渲染矩形形状
- **WHEN** 元素定义为 `{type: shape, shape: rectangle, box: [1, 2, 3, 1], fill: "#4a90e2"}`
- **THEN** 系统生成 `<div>` 标签,背景色为 #4a90e2`border-radius: 0`
#### Scenario: 渲染圆形形状
- **WHEN** 元素的 `shape` 字段为 `ellipse`
- **THEN** 系统应用 CSS`border-radius: 50%`
#### Scenario: 渲染圆角矩形
- **WHEN** 元素的 `shape` 字段为 `rounded_rectangle`
- **THEN** 系统应用 CSS`border-radius: 8px`
#### Scenario: 应用形状边框样式
- **WHEN** 形状定义了 `line: {color: "#000000", width: 2}`
- **THEN** 系统应用 CSS`border: 2pt solid #000000`
#### Scenario: 形状无填充色时透明
- **WHEN** 形状未定义 `fill` 字段
- **THEN** 系统应用 CSS`background: transparent`
### Requirement: 系统必须渲染表格元素
系统 SHALL 将 YAML 中的表格元素转换为 HTML `<table>` 标签。
#### Scenario: 渲染基本表格
- **WHEN** 元素定义为 `{type: table, position: [1, 2], data: [["A", "B"], ["C", "D"]], col_widths: [2, 2]}`
- **THEN** 系统生成 `<table>` 标签,位置为 (96px, 192px),包含 2 行 2 列
#### Scenario: 应用表格样式
- **WHEN** 表格定义了 `style: {font_size: 14, header_bg: "#4a90e2", header_color: "#ffffff"}`
- **THEN** 系统将第一行设置为表头样式,背景色为 #4a90e2,文字颜色为白色,字体大小为 14pt
#### Scenario: 表格单元格边框
- **WHEN** 渲染表格
- **THEN** 系统为所有单元格添加边框:`border: 1px solid #ddd`
#### Scenario: 表格单元格内边距
- **WHEN** 渲染表格
- **THEN** 系统为所有单元格添加内边距:`padding: 8px`
### Requirement: 系统必须渲染图片元素
系统 SHALL 将 YAML 中的图片元素转换为 HTML `<img>` 标签。
#### Scenario: 渲染本地图片
- **WHEN** 元素定义为 `{type: image, src: "images/logo.png", box: [2, 3, 4, 3]}`
- **THEN** 系统生成 `<img>` 标签src 为图片的文件路径,位置为 (192px, 288px),尺寸为 384x288 像素
#### Scenario: 处理相对路径
- **WHEN** 图片 src 使用相对路径 `"assets/logo.png"`
- **THEN** 系统基于 YAML 文件所在目录解析相对路径
#### Scenario: 图片不存在时显示占位符
- **WHEN** 图片文件不存在
- **THEN** 系统显示占位符或错误提示,而不是崩溃
### Requirement: 系统必须渲染幻灯片背景
系统 SHALL 支持为幻灯片设置纯色背景。
#### Scenario: 设置纯色背景
- **WHEN** 幻灯片定义了 `background: {color: "#ffffff"}`
- **THEN** 系统为幻灯片容器应用 CSS`background: #ffffff`
#### Scenario: 无背景时使用白色
- **WHEN** 幻灯片未定义 `background` 字段
- **THEN** 系统使用默认白色背景
### Requirement: 系统必须使用绝对定位
系统 SHALL 使用 CSS 绝对定位(`position: absolute`)渲染所有元素,模拟 PPTX 的坐标系统。
#### Scenario: 元素使用绝对定位
- **WHEN** 渲染任何元素
- **THEN** 系统应用 CSS`position: absolute`
#### Scenario: 幻灯片容器使用相对定位
- **WHEN** 渲染幻灯片容器
- **THEN** 系统应用 CSS`position: relative`,作为元素的定位上下文
#### Scenario: 元素层次按定义顺序
- **WHEN** elements 列表为 `[shape1, text1, image1]`
- **THEN** 系统按顺序渲染,后定义的元素显示在前面元素之上(通过 DOM 顺序控制)
### Requirement: 系统必须提供视觉反馈
系统 SHALL 在预览页面中提供视觉反馈,帮助用户了解预览状态。
#### Scenario: 幻灯片添加阴影效果
- **WHEN** 渲染幻灯片
- **THEN** 系统为幻灯片容器添加阴影:`box-shadow: 0 2px 8px rgba(0,0,0,0.1)`
#### Scenario: 幻灯片之间有间距
- **WHEN** 渲染多个幻灯片
- **THEN** 每个幻灯片之间有 20px 的垂直间距
### Requirement: 系统必须复用现有的解析逻辑
系统 SHALL 复用 `yaml2pptx.py` 中现有的 `Presentation` 类和模板渲染逻辑。
#### Scenario: 使用 Presentation 类解析 YAML
- **WHEN** 预览模式启动
- **THEN** 系统使用 `Presentation` 类加载和解析 YAML 文件
#### Scenario: 使用 render_slide 方法渲染幻灯片
- **WHEN** 生成预览 HTML
- **THEN** 系统调用 `Presentation.render_slide()` 方法获取渲染后的幻灯片数据
#### Scenario: 支持模板系统
- **WHEN** YAML 文件使用模板(如 `template: title_slide`
- **THEN** 系统正确解析模板变量,渲染模板元素
### Requirement: 系统必须处理渲染错误
系统 SHALL 在元素渲染失败时,显示错误信息,而不是崩溃。
#### Scenario: 元素类型不支持时显示错误
- **WHEN** 元素的 `type` 为未定义的值(如 "video"
- **THEN** 系统在预览页面显示错误信息,提示不支持该元素类型
#### Scenario: 元素缺少必需字段时显示错误
- **WHEN** 元素缺少必需字段(如文本元素缺少 `content`
- **THEN** 系统在预览页面显示错误信息,提示缺少字段
#### Scenario: 部分元素错误不影响其他元素
- **WHEN** 某个元素渲染失败
- **THEN** 系统继续渲染其他元素,仅在失败位置显示错误提示