1
0
Files
PPTX/validators/result.py
lanyuanxiaoyao 98098dc911 feat: 实现模板库metadata和跨域字体引用系统
实现了统一的metadata结构和字体作用域系统,支持文档和模板库之间的单向字体引用。

主要变更:
- 模板库必须包含metadata字段(包括size、fonts、fonts_default)
- 实现文档和模板库的size一致性校验
- 实现字体作用域系统(文档可引用模板库字体,反之不可)
- 实现跨域循环引用检测
- 实现fonts_default级联规则(模板库→文档→系统默认)
- 添加错误代码常量(SIZE_MISMATCH、FONT_NOT_FOUND等)
- 更新文档和开发者指南

测试覆盖:
- 新增33个测试(单元测试20个,集成测试13个)
- 所有457个测试通过

Breaking Changes:
- 模板库文件必须包含metadata字段
- 模板库metadata.size为必填字段
- 文档和模板库的size必须一致

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-05 18:12:05 +08:00

96 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
"""
验证结果数据结构
定义验证问题和验证结果的数据类。
"""
from dataclasses import dataclass, field
from typing import List
@dataclass
class ValidationIssue:
"""验证问题"""
level: str # "ERROR" | "WARNING" | "INFO"
message: str
location: str # "幻灯片 2, 元素 3"
code: str # "ELEMENT_OUT_OF_BOUNDS"
@dataclass
class ValidationResult:
"""验证结果"""
valid: bool # 是否有 ERROR
errors: List[ValidationIssue] = field(default_factory=list)
warnings: List[ValidationIssue] = field(default_factory=list)
infos: List[ValidationIssue] = field(default_factory=list)
def has_errors(self) -> bool:
"""是否有错误"""
return len(self.errors) > 0
def format_output(self) -> str:
"""格式化为命令行输出"""
lines = []
lines.append("🔍 正在检查 YAML 文件...\n")
# 错误
if self.errors:
lines.append(f"❌ 错误 ({len(self.errors)}):")
for issue in self.errors:
location_str = f"[{issue.location}] " if issue.location else ""
lines.append(f" {location_str}{issue.message}")
lines.append("")
# 警告
if self.warnings:
lines.append(f"⚠️ 警告 ({len(self.warnings)}):")
for issue in self.warnings:
location_str = f"[{issue.location}] " if issue.location else ""
lines.append(f" {location_str}{issue.message}")
lines.append("")
# 提示
if self.infos:
lines.append(f" 提示 ({len(self.infos)}):")
for issue in self.infos:
location_str = f"[{issue.location}] " if issue.location else ""
lines.append(f" {location_str}{issue.message}")
lines.append("")
# 总结
if not self.errors and not self.warnings and not self.infos:
lines.append("验证通过,未发现问题")
else:
summary_parts = []
if self.errors:
summary_parts.append(f"{len(self.errors)} 个错误")
if self.warnings:
summary_parts.append(f"{len(self.warnings)} 个警告")
if self.infos:
summary_parts.append(f"{len(self.infos)} 个提示")
lines.append(f"检查完成: 发现 {', '.join(summary_parts)}")
return "\n".join(lines)
# ============= 错误代码常量 =============
# 模板库 metadata 相关错误
ERROR_TEMPLATE_LIBRARY_MISSING_METADATA = "TEMPLATE_LIBRARY_MISSING_METADATA"
ERROR_TEMPLATE_LIBRARY_METADATA_MISSING_SIZE = "TEMPLATE_LIBRARY_METADATA_MISSING_SIZE"
ERROR_TEMPLATE_LIBRARY_METADATA_INVALID_SIZE = "TEMPLATE_LIBRARY_METADATA_INVALID_SIZE"
# Size 一致性错误
ERROR_SIZE_MISMATCH = "SIZE_MISMATCH"
# 字体引用相关错误
ERROR_TEMPLATE_FONT_REF_DOC_FORBIDDEN = "TEMPLATE_FONT_REF_DOC_FORBIDDEN"
ERROR_TEMPLATE_PARENT_REF_DOC_FORBIDDEN = "TEMPLATE_PARENT_REF_DOC_FORBIDDEN"
ERROR_FONT_NOT_FOUND = "FONT_NOT_FOUND"
ERROR_CIRCULAR_REFERENCE = "CIRCULAR_REFERENCE"
ERROR_FONT_DEFAULT_INVALID = "FONT_DEFAULT_INVALID"