feat(docs): generate Section 5 from function comment headers

The man-page-style comment header above each function in functions/*.fish
becomes the SSOT for that function's documentation. Writing a new function
and documenting it are now the same act.

- manualtools.parse_functions() parses every header carrying a # CATEGORY;
  absence of one is the opt-in, keeping bundled-plugin and prompt internals
  out of the manual with no exclusion list to maintain.
- build-manual.py generates entries for both --concat and --site, with
  **Dependencies:** rendered as links and a **Used by:** reverse index
  computed in one pass. Cross-category links are the navigation win.
- docs/manual/05-functions/*.md reduced to frontmatter-only stubs. Every
  intro measured zero words, so the category files were pure entry
  containers; ordering, titles, and helpKeywords routing are untouched.
- _first_sentence() unwraps the leading hard-wrapped paragraph and skips
  the whole Synopsis block, not just its label line. Site cards no longer
  truncate mid-clause or show a synopsis as their description.

Verification, per the design spec:
- test_concat_roundtrips_original scoped to sections 0-4 and 6-11. It
  guarded a format migration; this is a content migration.
- replaced by structural checks: one entry per categorised function, the
  required sections present, every category resolving to a stub with no
  stub empty, and every declared dependency resolving to a real function
  or a type -q-guarded binary.
- public functions lacking # CATEGORY warn rather than fail, so a new
  user-facing function going undocumented stays visible in CI.

24/24 checks pass. 94 entries generated from 94 parsed headers.

Also drops a stale claim from open-url's NOTES: config-help --html calls
xdg-open directly and has never called open-url.
This commit is contained in:
2026-07-26 04:12:48 -04:00
parent 00f70e8558
commit a65e05b661
24 changed files with 1594 additions and 1601 deletions
-34
View File
@@ -7,38 +7,4 @@ helpKeywords:
- network
---
## gip
Synopsis: gip
Fetches and prints both the public IPv4 and IPv6 address via
icanhazip.com.
## gip4
Synopsis: gip4
Fetches and prints the public IPv4 address.
## gip6
Synopsis: gip6
Fetches and prints the public IPv6 address. Returns 1 if IPv6 is
unavailable.
## ping
Synopsis: ping [args...]
Wraps prettyping with --nolegend. Pass --legend to show the legend.
Falls back to system ping.
ping google.com
## qr
Synopsis: qr [text...]
Generates a UTF-8 QR code from text or stdin. Uses qrencode locally;
falls back to the qrenco.de API.
qr "https://example.com"
echo "https://example.com" | qr
---