81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
|
|
"""
|
||
|
|
Read/write utilities for entity classification files (L2).
|
||
|
|
|
||
|
|
Classification files use YAML frontmatter (machine-readable) plus a
|
||
|
|
markdown body (human-readable), matching the convention used by evaluation
|
||
|
|
files.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
from typing import List
|
||
|
|
|
||
|
|
import yaml
|
||
|
|
|
||
|
|
from .classification import EntityClassification
|
||
|
|
|
||
|
|
|
||
|
|
_FRONTMATTER_SEP = "---"
|
||
|
|
|
||
|
|
|
||
|
|
def write_entity_classification(c: EntityClassification, path: Path) -> None:
|
||
|
|
"""Write a per-entity classification as YAML frontmatter + markdown body."""
|
||
|
|
fm = c.to_dict()
|
||
|
|
|
||
|
|
lines: List[str] = []
|
||
|
|
lines.append(_FRONTMATTER_SEP)
|
||
|
|
lines.append(yaml.safe_dump(fm, default_flow_style=False, sort_keys=False).rstrip())
|
||
|
|
lines.append(_FRONTMATTER_SEP)
|
||
|
|
lines.append("")
|
||
|
|
|
||
|
|
title = c.entity_slug.replace("_", " ").replace("-", " ").title()
|
||
|
|
lines.append(f"# Classification: {title}")
|
||
|
|
lines.append("")
|
||
|
|
|
||
|
|
lines.append("## Entity Type")
|
||
|
|
lines.append("")
|
||
|
|
lines.append(c.entity_type)
|
||
|
|
lines.append("")
|
||
|
|
|
||
|
|
lines.append("## VSM System")
|
||
|
|
lines.append("")
|
||
|
|
lines.append(c.vsm_system)
|
||
|
|
lines.append("")
|
||
|
|
|
||
|
|
if c.type_rationale:
|
||
|
|
lines.append("## Type Rationale")
|
||
|
|
lines.append("")
|
||
|
|
lines.append(c.type_rationale)
|
||
|
|
lines.append("")
|
||
|
|
|
||
|
|
if c.vsm_rationale:
|
||
|
|
lines.append("## VSM Rationale")
|
||
|
|
lines.append("")
|
||
|
|
lines.append(c.vsm_rationale)
|
||
|
|
lines.append("")
|
||
|
|
|
||
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||
|
|
path.write_text("\n".join(lines), encoding="utf-8")
|
||
|
|
|
||
|
|
|
||
|
|
def read_entity_classification(path: Path) -> EntityClassification:
|
||
|
|
"""Read a classification file (YAML frontmatter + markdown body)."""
|
||
|
|
text = path.read_text(encoding="utf-8")
|
||
|
|
parts = text.split(f"{_FRONTMATTER_SEP}\n", maxsplit=2)
|
||
|
|
if len(parts) < 3:
|
||
|
|
raise ValueError(f"No YAML frontmatter found in {path}")
|
||
|
|
fm = yaml.safe_load(parts[1])
|
||
|
|
return EntityClassification.from_dict(fm)
|
||
|
|
|
||
|
|
|
||
|
|
def read_classifications_directory(directory: Path) -> List[EntityClassification]:
|
||
|
|
"""Read all classification files from a directory."""
|
||
|
|
results: List[EntityClassification] = []
|
||
|
|
for p in sorted(directory.glob("*.md")):
|
||
|
|
try:
|
||
|
|
results.append(read_entity_classification(p))
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
return results
|