file loading

This commit is contained in:
John Lancaster
2026-06-21 10:06:25 -05:00
parent dab539489a
commit 993dc6a879
+30 -20
View File
@@ -1,10 +1,33 @@
from collections.abc import Generator
from dataclasses import dataclass
from importlib.abc import Traversable
from itertools import starmap
from pathlib import PurePosixPath
from typing import Self
import yaml
from .models.skill import SkillFrontmatter
@dataclass(frozen=True, slots=True)
class LoadedMarkdownDocument:
"""Represents a loaded markdown document with its content and frontmatter."""
relpath: PurePosixPath
"""The relative path of the document within the package resources."""
content: str
"""The raw markdown content of the document."""
frontmatter: str
"""The raw YAML frontmatter of the document, if present."""
@classmethod
def from_root(cls, root: Traversable) -> set[Self]:
"""Recursively load all markdown documents from the root resource."""
return set(starmap(cls.from_resource, walk_resources(root)))
@classmethod
def from_resource(cls, relpath: PurePosixPath, resource: Traversable) -> Self:
"""Load a markdown document from a package resource."""
raw = resource.read_text(encoding="utf-8")
frontmatter = get_raw_frontmatter(raw)
return cls(relpath=relpath, content=raw, frontmatter=frontmatter)
def walk_resources(
@@ -25,27 +48,14 @@ def walk_resources(
yield relpath.as_posix(), child
def get_markdown_content(resource: Traversable) -> dict[str, str]:
"""Read the content of a markdown resource as text."""
return {relpath: doc_file.read_text(encoding="utf-8") for relpath, doc_file in walk_resources(resource)}
def get_idx(raw):
for i, line in enumerate(raw.splitlines()):
if line.strip().startswith("---"):
yield i
def get_raw_frontmatter(raw: str) -> str:
delimiter = iter(get_idx(raw))
delimiter = iter(get_frontmatter_delim_idx(raw, delimiter="---"))
start = next(delimiter) + 1
end = next(delimiter)
return "\n".join(raw.splitlines()[start:end])
def gen_valid_frontmatter(content: dict[str, str]) -> Generator[SkillFrontmatter]:
for relpath, raw in content.items():
if relpath.endswith("SKILL.md"):
fm = get_raw_frontmatter(raw)
validated = SkillFrontmatter.model_validate(yaml.safe_load(fm))
yield validated
def get_frontmatter_delim_idx(raw: str, *, delimiter: str = "---") -> Generator[int]:
for i, line in enumerate(raw.splitlines()):
if line.strip().startswith(delimiter):
yield i