1
0
Files
PPTX/core/presentation.py
lanyuanxiaoyao ed940f0690 refactor: modularize yaml2pptx into layered architecture
Refactor yaml2pptx.py from a 1,245-line monolithic script into a modular
architecture with clear separation of concerns. The entry point is now
127 lines, with business logic distributed across focused modules.

Architecture:
- core/: Domain models (elements, template, presentation)
- loaders/: YAML loading and validation
- renderers/: PPTX and HTML rendering
- preview/: Flask preview server
- utils.py: Shared utilities

Key improvements:
- Element abstraction layer using dataclass with validation
- Renderer logic built into generator classes
- Single-direction dependencies (no circular imports)
- Each module 150-300 lines for better readability
- Backward compatible CLI interface

Documentation:
- README.md: User-facing usage guide
- README_DEV.md: Developer documentation

OpenSpec:
- Archive refactor-yaml2pptx-modular change (63/70 tasks complete)
- Sync 5 delta specs to main specs (2 new + 3 updated)
2026-03-02 16:43:45 +08:00

92 lines
2.6 KiB
Python

"""
演示文稿模块
管理整个演示文稿的生成流程。
"""
from pathlib import Path
from loaders.yaml_loader import load_yaml_file, validate_presentation_yaml
from core.template import Template
from core.elements import create_element
class Presentation:
"""演示文稿类,管理整个演示文稿的生成流程"""
def __init__(self, pres_file, templates_dir=None):
"""
初始化演示文稿
Args:
pres_file: 演示文稿 YAML 文件路径
templates_dir: 模板目录
"""
self.pres_file = Path(pres_file)
self.templates_dir = templates_dir
# 加载演示文稿文件
self.data = load_yaml_file(pres_file)
validate_presentation_yaml(self.data, str(pres_file))
# 获取演示文稿尺寸
metadata = self.data.get('metadata', {})
self.size = metadata.get('size', '16:9')
# 模板缓存
self.template_cache = {}
def get_template(self, template_name):
"""
获取模板(带缓存)
Args:
template_name: 模板名称
Returns:
Template 对象
"""
if template_name not in self.template_cache:
self.template_cache[template_name] = Template(
template_name, self.templates_dir
)
return self.template_cache[template_name]
def render_slide(self, slide_data):
"""
渲染单个幻灯片
Args:
slide_data: 幻灯片数据字典
Returns:
dict: 包含 background 和 elements 的字典
"""
if 'template' in slide_data:
# 使用模板
template_name = slide_data['template']
template = self.get_template(template_name)
vars_values = slide_data.get('vars', {})
elements = template.render(vars_values)
# 合并背景(如果有)
background = slide_data.get('background', None)
# 将元素字典转换为元素对象
element_objects = [create_element(elem) for elem in elements]
return {
'background': background,
'elements': element_objects
}
else:
# 自定义幻灯片
elements = slide_data.get('elements', [])
# 将元素字典转换为元素对象
element_objects = [create_element(elem) for elem in elements]
return {
'background': slide_data.get('background'),
'elements': element_objects
}