file loading
This commit is contained in:
@@ -1,10 +1,33 @@
|
|||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
|
from dataclasses import dataclass
|
||||||
from importlib.abc import Traversable
|
from importlib.abc import Traversable
|
||||||
|
from itertools import starmap
|
||||||
from pathlib import PurePosixPath
|
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(
|
def walk_resources(
|
||||||
@@ -25,27 +48,14 @@ def walk_resources(
|
|||||||
yield relpath.as_posix(), child
|
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:
|
def get_raw_frontmatter(raw: str) -> str:
|
||||||
delimiter = iter(get_idx(raw))
|
delimiter = iter(get_frontmatter_delim_idx(raw, delimiter="---"))
|
||||||
start = next(delimiter) + 1
|
start = next(delimiter) + 1
|
||||||
end = next(delimiter)
|
end = next(delimiter)
|
||||||
return "\n".join(raw.splitlines()[start:end])
|
return "\n".join(raw.splitlines()[start:end])
|
||||||
|
|
||||||
|
|
||||||
def gen_valid_frontmatter(content: dict[str, str]) -> Generator[SkillFrontmatter]:
|
def get_frontmatter_delim_idx(raw: str, *, delimiter: str = "---") -> Generator[int]:
|
||||||
for relpath, raw in content.items():
|
for i, line in enumerate(raw.splitlines()):
|
||||||
if relpath.endswith("SKILL.md"):
|
if line.strip().startswith(delimiter):
|
||||||
fm = get_raw_frontmatter(raw)
|
yield i
|
||||||
validated = SkillFrontmatter.model_validate(yaml.safe_load(fm))
|
|
||||||
yield validated
|
|
||||||
|
|||||||
Reference in New Issue
Block a user