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)
75 lines
1.6 KiB
Python
75 lines
1.6 KiB
Python
"""
|
||
工具函数模块
|
||
|
||
提供日志输出和颜色转换等通用功能。
|
||
"""
|
||
|
||
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
|