"""Markdown bible -> raw yaml-block entries. Knows only fences + YAML; nothing about the schema's meaning. A block is opened by a line that is exactly ```yaml (after strip) and closed by a line that is exactly ```.""" from dataclasses import dataclass from pathlib import Path import yaml from .errors import BuildError @dataclass class RawEntry: data: dict source: str # "duncarrow.md:53" def parse_bible(path: Path) -> list[RawEntry]: lines = path.read_text().splitlines() entries: list[RawEntry] = [] i, n = 0, len(lines) while i < n: if lines[i].strip() == "```yaml": fence_line = i + 1 # 1-based line of the opening fence i += 1 block: list[str] = [] while i < n and lines[i].strip() != "```": block.append(lines[i]) i += 1 if i >= n: raise BuildError("unterminated ```yaml block", source=f"{path.name}:{fence_line}") data = yaml.safe_load("\n".join(block)) if not isinstance(data, dict): raise BuildError("yaml block is not a mapping", source=f"{path.name}:{fence_line}") entries.append(RawEntry(data=data, source=f"{path.name}:{fence_line}")) i += 1 return entries