feat(docs): generate Starlight content from the manual tree
Add build_manual.build_site(), which walks docs/manual and emits the Astro Starlight content collection: plain pages copied with pipeline-only frontmatter (man/site/manTitle/helpKeywords) stripped, and *-functions/ category files exploded into one page per function plus a CardGrid/LinkCard overview. Writes src/sidebar.json for astro.config.mjs to import. Wires --site alongside the existing --concat flag. Fixes two latent defects found while building the real site against the strict content.config.ts schema: - _split_entries now tracks fenced code blocks (like manualtools.shift_headings does) so a `## ` inside a fence can't be mistaken for an entry boundary. - LinkCard title/description are escaped for JSX attribute context, since shell synopses routinely contain `<placeholder>` angle brackets that would otherwise open unterminated MDX/JSX parsing. Also fixes the generated sidebar shape for the functions category: Starlight 0.39+ dropped support for a bare `autogenerate` sibling of `label` on a top-level group, so the autogenerate config now nests inside `items`. Verified with a full `astro build` (temporarily pointing astro.config.mjs at the generated sidebar.json, then reverted since replacing that config is a later task's deliverable): 120 pages built cleanly, no content-collection/frontmatter/MDX errors.
This commit is contained in:
@@ -192,6 +192,27 @@ def test_every_index_keyword_resolves():
|
||||
assert not missing, "unresolvable index keywords:\n " + "\n ".join(missing)
|
||||
|
||||
|
||||
def test_site_build_produces_function_pages():
|
||||
import tempfile
|
||||
|
||||
import build_manual
|
||||
|
||||
docs = Path(__file__).parent
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
out = Path(d)
|
||||
sidebar = build_manual.build_site(docs / "manual", out)
|
||||
pages = list(out.rglob("*.md*"))
|
||||
assert (out / "index.md").exists(), "landing page missing"
|
||||
fn_pages = [p for p in pages if "functions" in p.parts and p.name != "index.mdx"]
|
||||
assert len(fn_pages) > 80, f"expected >80 function pages, got {len(fn_pages)}"
|
||||
assert not (out / "00-name.md").exists(), "site:false page was published"
|
||||
assert sidebar, "sidebar structure is empty"
|
||||
for page in pages:
|
||||
fm, _ = mt.parse(page)
|
||||
assert "manTitle" not in fm, f"{page.name} leaked manTitle into site output"
|
||||
assert "title" in fm, f"{page.name} has no title"
|
||||
|
||||
|
||||
TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user