Implements comprehensive validation before PPTX conversion to catch errors early. Includes element-level validation (colors, fonts, table consistency) and system-level validation (geometry, resources). Supports standalone check command and automatic validation during conversion.
132 lines
3.7 KiB
Python
132 lines
3.7 KiB
Python
"""
|
||
几何验证器
|
||
|
||
验证元素的位置和尺寸是否在页面范围内。
|
||
"""
|
||
|
||
from validators.result import ValidationIssue
|
||
|
||
|
||
# 容忍度:0.1 英寸
|
||
TOLERANCE = 0.1
|
||
|
||
|
||
class GeometryValidator:
|
||
"""几何验证器"""
|
||
|
||
def __init__(self, slide_width: float, slide_height: float):
|
||
"""
|
||
初始化几何验证器
|
||
|
||
Args:
|
||
slide_width: 幻灯片宽度(英寸)
|
||
slide_height: 幻灯片高度(英寸)
|
||
"""
|
||
self.slide_width = slide_width
|
||
self.slide_height = slide_height
|
||
|
||
def validate_element(self, element, slide_index: int, elem_index: int) -> list:
|
||
"""
|
||
验证元素的几何属性
|
||
|
||
Args:
|
||
element: 元素对象
|
||
slide_index: 幻灯片索引(从 1 开始)
|
||
elem_index: 元素索引(从 1 开始)
|
||
|
||
Returns:
|
||
验证问题列表
|
||
"""
|
||
issues = []
|
||
location = f"幻灯片 {slide_index}, 元素 {elem_index}"
|
||
|
||
# 检查元素边界
|
||
if hasattr(element, 'box'):
|
||
issues.extend(self._check_element_bounds(
|
||
element.box, location
|
||
))
|
||
|
||
# 检查表格边界
|
||
if hasattr(element, 'position') and hasattr(element, 'col_widths'):
|
||
if element.col_widths:
|
||
issues.extend(self._check_table_bounds(
|
||
element.position, element.col_widths, location
|
||
))
|
||
|
||
return issues
|
||
|
||
def _check_element_bounds(self, box: list, location: str) -> list:
|
||
"""
|
||
检查元素边界是否在页面范围内
|
||
|
||
Args:
|
||
box: [left, top, width, height]
|
||
location: 位置信息
|
||
|
||
Returns:
|
||
验证问题列表
|
||
"""
|
||
issues = []
|
||
left, top, width, height = box
|
||
right = left + width
|
||
bottom = top + height
|
||
|
||
# 检查元素是否完全在页面外
|
||
if (right <= 0 or bottom <= 0 or
|
||
left >= self.slide_width or top >= self.slide_height):
|
||
issues.append(ValidationIssue(
|
||
level="WARNING",
|
||
message="元素完全在页面外",
|
||
location=location,
|
||
code="ELEMENT_COMPLETELY_OUT_OF_BOUNDS"
|
||
))
|
||
return issues
|
||
|
||
# 检查右边界
|
||
if right > self.slide_width + TOLERANCE:
|
||
issues.append(ValidationIssue(
|
||
level="WARNING",
|
||
message=f"元素右边界超出: {right:.2f} > {self.slide_width}",
|
||
location=location,
|
||
code="ELEMENT_OUT_OF_BOUNDS"
|
||
))
|
||
|
||
# 检查下边界
|
||
if bottom > self.slide_height + TOLERANCE:
|
||
issues.append(ValidationIssue(
|
||
level="WARNING",
|
||
message=f"元素下边界超出: {bottom:.2f} > {self.slide_height}",
|
||
location=location,
|
||
code="ELEMENT_OUT_OF_BOUNDS"
|
||
))
|
||
|
||
return issues
|
||
|
||
def _check_table_bounds(self, position: list, col_widths: list, location: str) -> list:
|
||
"""
|
||
检查表格边界是否在页面范围内
|
||
|
||
Args:
|
||
position: [left, top]
|
||
col_widths: 列宽列表
|
||
location: 位置信息
|
||
|
||
Returns:
|
||
验证问题列表
|
||
"""
|
||
issues = []
|
||
left, top = position
|
||
table_width = sum(col_widths)
|
||
right = left + table_width
|
||
|
||
# 检查表格右边界
|
||
if right > self.slide_width + TOLERANCE:
|
||
issues.append(ValidationIssue(
|
||
level="WARNING",
|
||
message=f"表格超出页面宽度: {right:.2f} > {self.slide_width}",
|
||
location=location,
|
||
code="TABLE_OUT_OF_BOUNDS"
|
||
))
|
||
|
||
return issues
|