refactor: 重构文档结构,采用渐进式信息披露模式
将 README.md 拆分为多个专题文档,减少认知负荷: - 用户文档迁移到 docs/ (用户指南、元素、模板、参考等) - 开发文档迁移到 docs/development/ (架构、模块、规范) - README.md 精简至 ~290 行,仅保留概览和导航 - 删除 README_DEV.md,内容已迁移 - 归档 OpenSpec 变更 refactor-docs-progressive-disclosure
This commit is contained in:
153
docs/development/modules/renderers.md
Normal file
153
docs/development/modules/renderers.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Renderers 模块
|
||||
|
||||
`renderers/` 目录包含 PPTX 和 HTML 渲染器。
|
||||
|
||||
## 模块组成
|
||||
|
||||
### pptx_renderer.py
|
||||
|
||||
PPTX 文件生成器:
|
||||
|
||||
```python
|
||||
class PptxGenerator:
|
||||
def __init__(self, size="16:9"):
|
||||
self.presentation = Presentation()
|
||||
self.slide_width = 10 # 英寸
|
||||
self.slide_height = 5.625 if size == "16:9" else 7.5
|
||||
|
||||
def add_slide(self):
|
||||
"""添加新幻灯片"""
|
||||
slide = self.presentation.slides.add_slide(self.blank_layout)
|
||||
return slide
|
||||
|
||||
def _render_element(self, slide, elem, base_path):
|
||||
"""分发元素到对应的渲染方法"""
|
||||
if isinstance(elem, TextElement):
|
||||
self._render_text(slide, elem)
|
||||
elif isinstance(elem, ImageElement):
|
||||
self._render_image(slide, elem, base_path)
|
||||
# ...
|
||||
|
||||
def _render_text(self, slide, elem):
|
||||
"""渲染文本元素"""
|
||||
# 实现...
|
||||
|
||||
def _render_image(self, slide, elem, base_path):
|
||||
"""渲染图片元素"""
|
||||
# 实现...
|
||||
|
||||
def _render_shape(self, slide, elem):
|
||||
"""渲染形状元素"""
|
||||
# 实现...
|
||||
|
||||
def _render_table(self, slide, elem):
|
||||
"""渲染表格元素"""
|
||||
# 实现...
|
||||
|
||||
def save(self, output_path):
|
||||
"""保存 PPTX 文件"""
|
||||
self.presentation.save(output_path)
|
||||
```
|
||||
|
||||
### html_renderer.py
|
||||
|
||||
HTML 预览渲染器:
|
||||
|
||||
```python
|
||||
class HtmlRenderer:
|
||||
def __init__(self, size="16:9"):
|
||||
self.slide_width = 960 # 96 DPI * 10"
|
||||
self.slide_height = 540 if size == "16:9" else 720
|
||||
|
||||
def render_slide(self, slide_data, index, base_path=None):
|
||||
"""渲染幻灯片为 HTML"""
|
||||
elements_html = ""
|
||||
|
||||
for elem in slide_data:
|
||||
if isinstance(elem, TextElement):
|
||||
elements_html += self.render_text(elem)
|
||||
elif isinstance(elem, ImageElement):
|
||||
elements_html += self.render_image(elem, base_path)
|
||||
# ...
|
||||
|
||||
return self.SLIDE_TEMPLATE.format(
|
||||
width=self.slide_width,
|
||||
height=self.slide_height,
|
||||
content=elements_html
|
||||
)
|
||||
|
||||
def render_text(self, elem):
|
||||
"""渲染文本为 HTML"""
|
||||
# 实现...
|
||||
|
||||
def render_image(self, elem, base_path):
|
||||
"""渲染图片为 HTML"""
|
||||
# 实现...
|
||||
|
||||
def render_shape(self, elem):
|
||||
"""渲染形状为 HTML"""
|
||||
# 实现...
|
||||
|
||||
def render_table(self, elem):
|
||||
"""渲染表格为 HTML"""
|
||||
# 实现...
|
||||
```
|
||||
|
||||
## 设计特点
|
||||
|
||||
### 渲染器内置在生成器中
|
||||
|
||||
- **封装性**:渲染逻辑与生成器紧密相关
|
||||
- **简单性**:不需要额外的渲染器接口
|
||||
- **性能**:避免额外的方法调用开销
|
||||
|
||||
### 使用 isinstance() 检查类型
|
||||
|
||||
```python
|
||||
if isinstance(elem, TextElement):
|
||||
self._render_text(slide, elem)
|
||||
```
|
||||
|
||||
### 通过元素对象属性访问数据
|
||||
|
||||
```python
|
||||
def _render_text(self, slide, elem):
|
||||
text_box = elem.box
|
||||
content = elem.content
|
||||
font_config = elem.font
|
||||
```
|
||||
|
||||
## 共享元素抽象层
|
||||
|
||||
两个渲染器共享相同的元素数据类:
|
||||
- `TextElement`
|
||||
- `ImageElement`
|
||||
- `ShapeElement`
|
||||
- `TableElement`
|
||||
|
||||
## 单位转换
|
||||
|
||||
### HTML 渲染器
|
||||
|
||||
使用固定 DPI (96) 进行单位转换:
|
||||
|
||||
```python
|
||||
DPI = 96
|
||||
pixels = inches * DPI
|
||||
```
|
||||
|
||||
### PPTX 渲染器
|
||||
|
||||
python-pptx 使用 Inches 单位:
|
||||
|
||||
```python
|
||||
from pptx.util import Inches
|
||||
left = Inches(box[0])
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Elements 模块](elements.md) - 元素数据类
|
||||
- [预览功能](../../user-guide.md) - 用户指南
|
||||
|
||||
[返回开发文档索引](../README.md)
|
||||
Reference in New Issue
Block a user