"""Intermediate IR blocks between DOCX walk and Markdown emit.""" from __future__ import annotations from dataclasses import dataclass, field @dataclass class InlineSpan: text: str bold: bool = False italic: bool = False strike: bool = False href: str | None = None # external URL math: str | None = None # inline latex-ish @dataclass class HeadingBlock: level: int text: str numbered: bool = True # False → # *TITLE @dataclass class ParagraphBlock: spans: list[InlineSpan] = field(default_factory=list) style: str = "Normal" is_bibliography: bool = False biblio_key: str | None = None @dataclass class CaptionBlock: kind: str # figure | table | listing number: str text: str | None = None is_continuation: bool = False landscape: bool = False unique_id: str = "" @dataclass class ImageBlock: rel_path: str # relative to md file alt: str = "" caption_id: str | None = None caption_text: str | None = None @dataclass class TableBlock: rows: list[list[str]] merges: list[list[tuple[str, str]]] | None = None # (v, h) per cell caption_id: str | None = None caption_text: str | None = None landscape: bool = False @dataclass class ListingBlock: lines: list[str] language: str = "" caption_id: str | None = None caption_text: str | None = None @dataclass class EquationBlock: latex: str number: str | None = None unique_id: str | None = None @dataclass class ListBlock: ordered: bool items: list[str] level: int = 1 @dataclass class TocPlaceholder: """Emitted as # *СОДЕРЖАНИЕ + [TOC].""" @dataclass class PageBreakBlock: pass @dataclass class SkipNote: """Logged skip; not emitted.""" message: str Block = ( HeadingBlock | ParagraphBlock | CaptionBlock | ImageBlock | TableBlock | ListingBlock | EquationBlock | ListBlock | TocPlaceholder | PageBreakBlock | SkipNote )