1
0

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)
This commit is contained in:
2026-03-02 16:43:45 +08:00
parent b2132dc06b
commit ed940f0690
31 changed files with 3142 additions and 1307 deletions

74
utils.py Normal file
View File

@@ -0,0 +1,74 @@
"""
工具函数模块
提供日志输出和颜色转换等通用功能。
"""
import sys
# ============= 日志输出函数 =============
def log_info(message):
"""输出信息日志"""
print(f"[INFO] {message}")
def log_success(message):
"""输出成功日志"""
print(f"[SUCCESS] ✓ {message}")
def log_error(message):
"""输出错误日志"""
print(f"[ERROR] ✗ {message}", file=sys.stderr)
def log_progress(current, total, message=""):
"""输出进度日志"""
print(f"[PROGRESS] {current}/{total} {message}")
# ============= 颜色转换函数 =============
def hex_to_rgb(hex_color):
"""
将十六进制颜色转换为 RGB 元组
Args:
hex_color: 十六进制颜色字符串,如 "#4a90e2""#fff"
Returns:
tuple: (R, G, B) 元组
"""
hex_color = hex_color.lstrip('#')
# 处理短格式 #RGB -> #RRGGBB
if len(hex_color) == 3:
hex_color = ''.join([c*2 for c in hex_color])
if len(hex_color) != 6:
raise ValueError(f"无效的颜色格式: #{hex_color}")
try:
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
except ValueError:
raise ValueError(f"无效的颜色格式: #{hex_color}")
def validate_color(color_value):
"""
验证颜色值格式(十六进制 #RRGGBB 或 #RGB
Args:
color_value: 颜色字符串
Returns:
bool: 是否有效
"""
import re
if not isinstance(color_value, str):
return False
# 匹配 #RRGGBB 或 #RGB 格式
pattern = r'^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$'
return re.match(pattern, color_value) is not None