fix(docs): render function entries per-section for the Starlight site #149

Merged
rootiest merged 1 commits from claude/starlight-doc-parsing-fix-voyyvi into main 2026-09-14 22:59:27 +00:00
Owner

Summary

Function entry pages on the Starlight site were formatted inconsistently: cat's description and its single-argument Arguments section both rendered as unhighlighted code blocks, copy's Arguments rendered as a table with no heading, and ltr's Arguments/Exit Status rendered as code blocks while its description rendered as prose. All three functions carry the same kind of content — the difference was purely which heuristic in the site pipeline happened to misfire.

  • Root cause: entry pages were built by taking the man-page/pandoc render_entry() output (one 4-space-indented block) and running it back through prettify()'s paragraph-shape heuristics — _is_prose rejects any paragraph with a line under 3 words (breaks on a short wrapped last line like "installed."), and _as_table requires at least 2 rows before it recognizes a table (breaks on a single-argument function). Which heuristic fired depended on incidental text shape, not on which section a block actually was.
  • Fix: docs/build-manual.py gets a site-only renderer, render_entry_site, that builds each entry straight from the parsed functions/*.fish header instead of reconstructing structure from indented text. Every present section (Synopsis, Description, Arguments, Exit Status, Returns, Notes, Example) gets its own ### heading, so sections are independently scannable and jump-to-able as requested. Arguments/Exit Status become a table via a new _kv_rows column parser; everything else is unwrapped into normal flowing paragraphs.
    • _kv_rows also fixes two real formatting bugs it uncovered while auditing every function's header for this: narrow columns where a long term leaves only one space before its description (rm.fish, auto-pull.fish), and name-only lines whose description wraps onto a deeper-indented continuation line (mkrep.fish's --new-remote [<cmd>]) — both previously fell through to an unhighlighted code block too.
  • Scope: site build only. render_entry (the indented block pandoc/build_concat consumes for the man page and config-help) is untouched; build_entries() takes a new site: bool flag that selects which renderer runs, defaulting to the existing man-page behavior.

Docs

docs/build-manual.py and docs/verify-manual.py only — no functions/*.fish headers were changed, this is purely a rendering fix. docs/site/src/content/docs/ is gitignored/generated by CI and not committed here.

Verification

  • python3 docs/verify-manual.py — full suite passes (one pre-existing failure, test_render_registry_is_valid_fish_and_round_trips, is unrelated: it needs the fish binary, which this sandbox doesn't have; confirmed it fails identically on main)
  • Added 8 new regression tests covering: every present section gets a heading in order, a single-argument section still tables, a hard-wrapped description (the exact cat.fish report) stays prose, a one-sentence Exit Status (the exact ltr.fish report) stays prose, the narrow-single-space-column and name-only-continuation cases in _kv_rows, prose sentences are correctly rejected as tables, and site/man-page entry coverage stays identical
  • python3 docs/build-manual.py --site regenerates the site content tree cleanly
  • npx astro build in docs/site — all 161 pages build, internal link validation passes; spot-checked the rendered HTML for cat, copy, ltr, and mkrep and confirmed real <table> and <h3> elements (not literal |/# text)
  • Manually diffed the generated markdown for cat, copy, ltr, mkrep, gi, jr, agents-vault, rm, auto-pull, and fzf_configure_bindings — all now render with consistent headings/tables/prose

Transferred from GitHub mirror PR https://github.com/rootiest/fish-config/pull/2 (branch pushed there instead of Gitea; mirror gets overwritten on next Gitea push).

## Summary Function entry pages on the Starlight site were formatted inconsistently: `cat`'s description and its single-argument Arguments section both rendered as unhighlighted code blocks, `copy`'s Arguments rendered as a table with no heading, and `ltr`'s Arguments/Exit Status rendered as code blocks while its description rendered as prose. All three functions carry the same kind of content — the difference was purely which heuristic in the site pipeline happened to misfire. - **Root cause**: entry pages were built by taking the man-page/pandoc `render_entry()` output (one 4-space-indented block) and running it back through `prettify()`'s paragraph-shape heuristics — `_is_prose` rejects any paragraph with a line under 3 words (breaks on a short wrapped last line like "installed."), and `_as_table` requires at least 2 rows before it recognizes a table (breaks on a single-argument function). Which heuristic fired depended on incidental text shape, not on which section a block actually was. - **Fix**: `docs/build-manual.py` gets a site-only renderer, `render_entry_site`, that builds each entry straight from the parsed `functions/*.fish` header instead of reconstructing structure from indented text. Every present section (Synopsis, Description, Arguments, Exit Status, Returns, Notes, Example) gets its own `### heading`, so sections are independently scannable and jump-to-able as requested. Arguments/Exit Status become a table via a new `_kv_rows` column parser; everything else is unwrapped into normal flowing paragraphs. - `_kv_rows` also fixes two real formatting bugs it uncovered while auditing every function's header for this: narrow columns where a long term leaves only one space before its description (`rm.fish`, `auto-pull.fish`), and name-only lines whose description wraps onto a deeper-indented continuation line (`mkrep.fish`'s `--new-remote [<cmd>]`) — both previously fell through to an unhighlighted code block too. - **Scope**: site build only. `render_entry` (the indented block pandoc/`build_concat` consumes for the man page and `config-help`) is untouched; `build_entries()` takes a new `site: bool` flag that selects which renderer runs, defaulting to the existing man-page behavior. ## Docs `docs/build-manual.py` and `docs/verify-manual.py` only — no `functions/*.fish` headers were changed, this is purely a rendering fix. `docs/site/src/content/docs/` is gitignored/generated by CI and not committed here. ## Verification - [x] `python3 docs/verify-manual.py` — full suite passes (one pre-existing failure, `test_render_registry_is_valid_fish_and_round_trips`, is unrelated: it needs the `fish` binary, which this sandbox doesn't have; confirmed it fails identically on `main`) - [x] Added 8 new regression tests covering: every present section gets a heading in order, a single-argument section still tables, a hard-wrapped description (the exact `cat.fish` report) stays prose, a one-sentence Exit Status (the exact `ltr.fish` report) stays prose, the narrow-single-space-column and name-only-continuation cases in `_kv_rows`, prose sentences are correctly rejected as tables, and site/man-page entry coverage stays identical - [x] `python3 docs/build-manual.py --site` regenerates the site content tree cleanly - [x] `npx astro build` in `docs/site` — all 161 pages build, internal link validation passes; spot-checked the rendered HTML for `cat`, `copy`, `ltr`, and `mkrep` and confirmed real `<table>` and `<h3>` elements (not literal `|`/`#` text) - [x] Manually diffed the generated markdown for `cat`, `copy`, `ltr`, `mkrep`, `gi`, `jr`, `agents-vault`, `rm`, `auto-pull`, and `fzf_configure_bindings` — all now render with consistent headings/tables/prose --- Transferred from GitHub mirror PR https://github.com/rootiest/fish-config/pull/2 (branch pushed there instead of Gitea; mirror gets overwritten on next Gitea push).
rootiest added the Kind/BugArea/Docs labels 2026-09-14 22:57:25 +00:00
rootiest added 1 commit 2026-09-14 22:57:25 +00:00
Function entry pages previously reused the man-page pipeline's single
indented block plus its paragraph-guessing heuristics (_is_prose's
per-line word count, _as_table's 2+ row minimum), so whether a
Description, Arguments, or Exit Status section landed as flowing
prose, a table, or an unhighlighted code block depended on incidental
shape -- a short wrapped line, a single argument, a narrow column --
rather than which section it was. `cat`, `copy`, and `ltr` each ended
up formatted differently for no functional reason.

Add render_entry_site, a site-only renderer that builds each entry
straight from the parsed function header instead of re-deriving
structure from indented text: every present section (Synopsis,
Description, Arguments, Exit Status, Returns, Notes, Example) gets its
own `###` heading, Arguments/Exit Status become a table via the new
_kv_rows column parser (which also fixes narrow single-space columns
and name-only rows with wrapped continuations), and everything else is
unwrapped into normal paragraphs. The man-page/pandoc path
(render_entry, build_concat) is untouched.
rootiest merged commit dfb5de5768 into main 2026-09-14 22:59:27 +00:00
rootiest deleted branch claude/starlight-doc-parsing-fix-voyyvi 2026-09-14 22:59:27 +00:00
Sign in to join this conversation.
No Reviewers
No labels Area/Docs Kind/Bug
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rootiest/fish-config#149