ppt-eval-benchmark/src/eval_ppt2html/models.py

115 lines
3.1 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field, asdict
from pathlib import Path
from typing import Dict, List, Optional, Tuple
# (x, y, width, height) in pixels
BBox = Tuple[float, float, float, float]
@dataclass
class TextElement:
"""문서 내 텍스트 요소 하나를 표현한다."""
id: str
page_index: int
content: str
role: str # "title", "subtitle", "body", "bullet", ...
hierarchy_level: Optional[int] = None
bbox: Optional[BBox] = None
font_family: Optional[str] = None
font_size: Optional[float] = None
font_weight: Optional[str] = None
color: Optional[str] = None
@dataclass
class LayoutElement:
"""레이아웃 요소 (텍스트, 이미지, 도형 등)."""
id: str
page_index: int
element_type: str # "text", "image", "shape", ...
bbox: BBox
z_index: Optional[int] = None
role: Optional[str] = None
@dataclass
class ImageElement:
"""이미지 요소 + 저장된 파일 경로 + 캡션."""
id: str
page_index: int
bbox: BBox
file_path: Path
caption: Optional[str] = None
@dataclass
class PageSnapshot:
"""한 페이지(또는 화면)의 스크린샷."""
page_index: int
file_path: Path
@dataclass
class EvalUnit:
"""
평가 단위 (주로 페이지/화면 단위).
원본/변환본의 텍스트, 레이아웃, 스냅샷 id를 매핑해 둔다.
"""
unit_id: str
input_page_index: int
output_page_index: int
input_text_ids: List[str] = field(default_factory=list)
output_text_ids: List[str] = field(default_factory=list)
input_layout_ids: List[str] = field(default_factory=list)
output_layout_ids: List[str] = field(default_factory=list)
input_snapshot: Optional[Path] = None
output_snapshot: Optional[Path] = None
@dataclass
class SamplePair:
"""
하나의 (input_pptx, output_html) 샘플 쌍.
전처리 결과(T_i/T_o/L_i/L_o/I_i/I_o/S_i/S_o)와 평가 단위(eval_units)를 포함한다.
"""
sample_id: str
input_pptx: Path
output_html: Path
T_i: List[TextElement] = field(default_factory=list)
T_o: List[TextElement] = field(default_factory=list)
L_i: List[LayoutElement] = field(default_factory=list)
L_o: List[LayoutElement] = field(default_factory=list)
I_i: List[ImageElement] = field(default_factory=list)
I_o: List[ImageElement] = field(default_factory=list)
S_i: List[PageSnapshot] = field(default_factory=list)
S_o: List[PageSnapshot] = field(default_factory=list)
eval_units: List[EvalUnit] = field(default_factory=list)
def to_dict(self) -> Dict:
"""JSON 직렬화를 위한 dict 변환 (Path → str 처리 포함)."""
def _convert_path(value):
if isinstance(value, Path):
return str(value)
return value
raw = asdict(self)
def _walk(obj):
if isinstance(obj, dict):
return {k: _walk(v) for k, v in obj.items()}
if isinstance(obj, list):
return [_walk(v) for v in obj]
return _convert_path(obj)
return _walk(raw)