1
0
Files
PPTX/yaml2pptx.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

128 lines
3.5 KiB
Python
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.
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.8"
# dependencies = [
# "python-pptx",
# "pyyaml",
# "flask",
# "watchdog",
# ]
# ///
"""
YAML to PPTX Converter
将 YAML 格式的演示文稿源文件转换为 PPTX 文件
使用方法:
uv run yaml2pptx.py input.yaml output.pptx
uv run yaml2pptx.py input.yaml # 自动生成 input.pptx
"""
import sys
import argparse
from pathlib import Path
# 导入模块
from utils import log_info, log_success, log_error, log_progress
from loaders.yaml_loader import YAMLError
from core.presentation import Presentation
from renderers.pptx_renderer import PptxGenerator
from preview.server import start_preview_server
def parse_args():
"""解析命令行参数"""
parser = argparse.ArgumentParser(
description="将 YAML 格式的演示文稿源文件转换为 PPTX 文件"
)
parser.add_argument(
"input",
type=str,
help="输入的 YAML 文件路径"
)
parser.add_argument(
"output",
type=str,
nargs="?",
help="输出的 PPTX 文件路径(可选,默认为输入文件名.pptx"
)
parser.add_argument(
"--template-dir",
type=str,
default=None,
help="模板文件目录路径(如果 YAML 中使用了模板则必须指定)。可以是绝对路径或相对路径(相对于当前工作目录)"
)
parser.add_argument(
"--preview",
action="store_true",
help="启动浏览器预览模式,而不是生成 PPTX 文件"
)
parser.add_argument(
"--port",
type=int,
default=None,
help="预览服务器端口(默认随机选择 20000-30000 之间的端口)"
)
return parser.parse_args()
def main():
"""主函数:加载 YAML → 渲染幻灯片 → 生成 PPTX"""
try:
args = parse_args()
# 处理输入文件路径
input_path = Path(args.input)
# 预览模式
if args.preview:
start_preview_server(input_path, args.template_dir, args.port)
return
# PPTX 生成模式
# 处理输出文件路径
if args.output:
output_path = Path(args.output)
else:
# 自动生成输出文件名
output_path = input_path.with_suffix(".pptx")
log_info(f"开始转换: {input_path}")
log_info(f"输出文件: {output_path}")
# 1. 加载演示文稿
log_info("加载演示文稿...")
pres = Presentation(input_path, templates_dir=args.template_dir)
# 2. 创建 PPTX 生成器
log_info(f"创建演示文稿 ({pres.size})...")
generator = PptxGenerator(pres.size)
# 3. 渲染所有幻灯片
slides_data = pres.data.get('slides', [])
total_slides = len(slides_data)
for i, slide_data in enumerate(slides_data, 1):
log_progress(i, total_slides, f"处理幻灯片")
rendered_slide = pres.render_slide(slide_data)
generator.add_slide(rendered_slide, input_path.parent)
# 4. 保存 PPTX 文件
log_info("保存 PPTX 文件...")
generator.save(output_path)
log_success(f"转换完成: {output_path}")
except YAMLError as e:
log_error(str(e))
sys.exit(1)
except Exception as e:
log_error(f"未知错误: {str(e)}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()