60 lines
2.3 KiB
Python
60 lines
2.3 KiB
Python
from structure_builder import (
|
|
DefinitionElement,
|
|
HeadingElement,
|
|
ImageElement,
|
|
ImportantElement,
|
|
OrderedListElement,
|
|
ParagraphElement,
|
|
Structure,
|
|
StructureElement,
|
|
UnorderedListElement,
|
|
)
|
|
from utils import Event, Timeline
|
|
|
|
|
|
class MarkdownBuilder:
|
|
"""Render a document structure to Markdown without using AI."""
|
|
|
|
def __init__(self, timeline: Timeline) -> None:
|
|
self._events: dict[int, Event] = {}
|
|
for event in timeline.events:
|
|
if event.id in self._events:
|
|
raise ValueError(f"Duplicate event ID: {event.id}")
|
|
self._events[event.id] = event
|
|
|
|
def _render_image(self, element: ImageElement) -> str:
|
|
event = self._events.get(element.event_id)
|
|
if event is None or event.type != "vis" or not event.payload:
|
|
raise ValueError(
|
|
f"Image element references invalid visual event: {element.event_id}"
|
|
)
|
|
alt = event.text.replace("[", "").replace("]", "").replace("\n", " ")
|
|
return f""
|
|
|
|
def _render_element(self, element: StructureElement) -> str:
|
|
if isinstance(element, HeadingElement):
|
|
return f"{'#' * element.level} {element.text}"
|
|
if isinstance(element, ParagraphElement):
|
|
return element.text
|
|
if isinstance(element, UnorderedListElement):
|
|
return "\n".join(f"- {item}" for item in element.items)
|
|
if isinstance(element, OrderedListElement):
|
|
return "\n".join(
|
|
f"{index}. {item}"
|
|
for index, item in enumerate(element.items, start=1)
|
|
)
|
|
if isinstance(element, DefinitionElement):
|
|
return f"**{element.term}.** {element.text}"
|
|
if isinstance(element, ImportantElement):
|
|
text = f"**Важно:** {element.text}"
|
|
return "\n".join(f"> {line}" for line in text.splitlines())
|
|
if isinstance(element, ImageElement):
|
|
return self._render_image(element)
|
|
raise TypeError(f"Unsupported structure element: {type(element).__name__}")
|
|
|
|
def build(self, structure: Structure) -> str:
|
|
blocks = [self._render_element(element) for element in structure.elements]
|
|
if not blocks:
|
|
return ""
|
|
return "\n\n".join(blocks) + "\n"
|