Commit Graph

22 Commits

Author SHA1 Message Date
rootiest e63fd8b525 docs(site): add Home entry to Starlight sidebar
Generate documentation / build-docs (push) Successful in 3m26s
The sidebar previously started with 'Configuration Variables' which felt abrupt. Add a 'Home' link at the top pointing to the landing page (the one with install/functions-ref buttons). Seeded the sidebar list in build_site() so it persists across --site rebuilds.
2026-07-27 00:14:32 -04:00
rootiest f02714416c docs: add dynamic CardGrids to overview pages and fix button text color 2026-07-26 23:20:31 -04:00
rootiest 25fb02b7ac build(docs): strip LinkButton from concatenated terminal output 2026-07-26 22:55:12 -04:00
rootiest c126296935 docs: add LinkButton call-to-actions to the manual index 2026-07-26 22:52:35 -04:00
rootiest c4980a15b1 fix(docs): allow multi-level nesting in Starlight file trees 2026-07-26 22:04:02 -04:00
rootiest ef384b9c7c fix(docs): scope aside regression test to its contents, reject nested file trees
- test_customization_notes_render_as_aside now asserts the four NOTE
  bullets live inside the <Aside> tags, not merely anywhere on the
  page — a re-wrapped bullet previously still passed because the
  bullet text leaked into an untouched sibling paragraph.
- TREE_BRANCH_RE no longer matches an indented/continuation branch
  line (dropped the leading `[│ ]*`), so a second-level tree falls
  through to verbatim rendering instead of being silently flattened
  to one level. Added test_as_file_tree_rejects_deeper_trees to guard it.
2026-07-26 21:20:34 -04:00
rootiest 1c671d71ac feat(docs): promote pages with asides or file trees to .mdx 2026-07-26 20:43:07 -04:00
rootiest 690bfd64d0 feat(docs): add _as_file_tree detector for box-drawing trees 2026-07-26 20:29:42 -04:00
rootiest d972de3df5 feat(docs): render flat LABEL: paragraphs as Starlight asides in prettify() 2026-07-26 20:25:51 -04:00
rootiest 413b8d8fa1 feat(docs): add _as_aside detector for LABEL: callout paragraphs 2026-07-26 19:51:44 -04:00
rootiest e651566e14 docs(functions): split RETURNS into EXIT STATUS and stdout RETURNS
RETURNS previously conflated fish's $status exit code with genuine
stdout/printed output, e.g. rm listing "0/1" as if they were print
values rather than exit codes. Rename RETURNS to EXIT STATUS across
all 83 documented functions, and reintroduce RETURNS as a distinct
label reserved for the 15 functions that actually print to stdout.

Update build-manual.py's ENTRY_HEADS to render Exit Status before
Returns, manualtools.py's SECTIONS constant, and AGENTS.md's label
order and label-usage guidance to match. Add two verify-manual.py
regression tests: EXIT STATUS bodies must never contain stray
stdout/printed language, and Returns: must always render after
Exit Status: when both are present. Regenerate docs/fish-config.md.
2026-07-26 16:41:57 -04:00
rootiest 4ca008836c fix(docs): recognize RST-style per-column dashed rules as tables
Generate documentation / build-docs (push) Successful in 3m22s
_as_ruled_table() only matched a single solid run of dashes under the
header row. The "Fish Universal Variables" table in
07-customization.md uses the other common convention instead: one
dash run per column, gapped the same as the header (RST simple-table
style) — e.g. "------  ----------". That line failed RULE_RE's
whole-line match, so the table still fell through to a code block.

Split the rule line on the same CELL_SPLIT boundary used for data
rows and require every resulting group to be a solid dash run, which
accepts both conventions without adding a second code path.

No SSOT changes needed — the source table was already well-formed,
docs/fish-config.md round-trips unchanged, confirming this is a
site-only fix.
2026-07-26 16:06:36 -04:00
rootiest 05ba0a4f10 fix(docs): render Component Reference tables as real Markdown tables
_as_table() only detects tables whose data rows are indented deeper
than a ":"-terminated label. The "Component Reference" tables use a
different convention (header, dashed rule, rows all at the same
indent), so they never matched and fell through to a plain indented
code block on the Starlight site.

Add _as_ruled_table() to recognize that header+rule+rows shape. It
supports N columns, folds word-wrapped continuation lines into the
previous row, and backtick-escapes cells containing "<" or "{" instead
of rejecting the table outright (unlike _as_table's stricter guard,
which those tables would otherwise trip on for angle-bracket
placeholders and brace globs).

Also fixes four ambiguous rows in 07-customization.md where two
columns had collapsed to a single space, making them indistinguishable
from a word-wrapped continuation.
2026-07-26 15:55:48 -04:00
rootiest 625a58fa9f docs(site): title Examples fences and auto-title file-scoped snippets
Function EXAMPLE blocks now render as their own fish fence titled
"Examples" (matching the existing "Usage" title on the Synopsis fence),
triggered by a flat Example: label line mirroring the Synopsis: prefix.

Prose pages get two new generic titling signals in _render_para: a bare
indented path ending in a known extension is titled by its basename, and
a leading "# in <file>" / "# <file>" comment on a shell paragraph is
promoted to the fence title and stripped from the body. This picks up
local.fish/secrets.fish path displays and override examples in
07-customization.md for free, plus a bonus .logging_disabled hit.

10-personalization.md's secrets.fish block gets an explicit "# secrets.fish"
comment to title it the same way. The four local.fish examples keep their
existing descriptive comments rather than a redundant local.fish title.
2026-07-26 05:27:26 -04:00
rootiest e20cff41d4 docs(site): replace starter README and title synopsis fences
Swap the Starlight scaffold README for one describing this project's
two-source SSOT and dev/deploy workflow. Give the generated function
synopsis fence a Starlight filename title (`fish title="name.fish"`)
so it reads as a snippet of the function it documents.
2026-07-26 05:01:01 -04:00
rootiest a65e05b661 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.
2026-07-26 04:12:48 -04:00
rootiest 67fb29687c docs(site): render aligned option blocks as markdown tables
Two-column option and subcommand blocks in the manual were falling through
to the indented-code fallback, rendering as an unhighlighted grey slab on
the site. `_as_table` detects a contiguous, column-aligned indented run and
emits a headerless GFM table instead; anything it cannot prove is tabular
still takes the old path.

15 blocks convert, 20 are correctly left alone. The concat and man-page
outputs are untouched — `prettify` is site-only, and the byte-exact
round-trip test stays green.
2026-07-26 03:38:07 -04:00
rootiest 6cd0de7ccf fix(docs-site): publish function pages under /reference/
Generate documentation / build-docs (push) Successful in 2m59s
Cloudflare Pages reserves a top-level `functions/` directory in the deploy
output for Pages Functions (server-side handlers) and strips it from the
static-asset upload. The wrangler log for run 812 shows the collision
exactly: 159 files uploaded, which is precisely the number of files in
dist/ outside functions/ — all 108 files under it were dropped.

Nothing failed loudly. Astro built all 120 pages, wrangler reported
success, and the site worked under `astro preview`; only the deployed
copy 404'd on every function entry and category index.

Move the generated tree to /reference/ and add a test asserting the site
output never emits a name Pages reserves.
2026-07-26 00:48:26 -04:00
rootiest ab2f03213b feat(docs-site): syntax-highlight examples and restyle the site
The manual is authored man-page style: every synopsis, example, option
table, and description sits in one 4-space-indented block. On the site
that renders as a single unhighlighted grey slab, because an indented
block declares no language.

Split each block into its paragraphs at site-build time and classify
them: synopsis and shell examples become ```fish fences, descriptions
become real prose, and column-aligned reference tables keep their
indentation. 175 blocks now highlight; the 412 lines of genuine tables
are left alone.

The transform is site-only. docs/manual/** keeps the indented form the
pandoc man-page pipeline and config-help depend on, and a test enforces
that no fence is ever written back to the SSOT.

Also:
- Point Expressive Code at the bundled Catppuccin Mocha/Latte themes so
  code blocks match the palette in catppuccin.css.
- Build the functions sidebar group explicitly. `autogenerate` labelled
  it with the raw directory slug and republished the directory index as
  a child of the group it already titled, producing the duplicate
  "Functions Reference" row.
- Skip `Synopsis:` lines when deriving card descriptions; they restated
  the calling convention the card already shows as its title.
- Widen the palette: tinted heading levels, inline code, links, card
  hover accents, aside accents, and table headers.

Fixes a bug where _split_entries stripped the leading indentation of an
entry's first line, detaching `Synopsis:` from the block it opens.
2026-07-26 00:12:33 -04:00
rootiest a4054de4f6 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.
2026-07-25 22:44:28 -04:00
rootiest beb89e406a fix(docs): move pandoc metadata out of index.md frontmatter
index.md is both the man-page LANDING section and a Starlight content
page. Astro errors on any frontmatter key outside the fixed
man/site/manTitle/helpKeywords schema, so folding the source
fish-config.md pandoc header (title/section/header/date/author) onto
index.md under a fifth "pandoc" key would break the docs-site build
the moment it's scaffolded.

Relocate that block to docs/manual/_pandoc.yml: a plain, fence-free
YAML file that Astro content collections ignore (leading underscore).
split-manual.py now extracts it as raw text (no yaml.safe_load/
safe_dump round-trip) so build-manual.py's --concat re-emits it
byte-for-byte instead of merely "verbatim" in comment only. Also guard
build_concat against a manual/ tree with no _pandoc.yml/index.md,
removing the unconditional index.md parse that previously raised
FileNotFoundError on such a tree.

Regenerated docs/manual/ via split-manual.py; concat output remains
byte-identical to the pre-migration docs/fish-config.md.
2026-07-25 21:52:54 -04:00
rootiest 63e71ac9dd feat(docs): generate fish-config.md from the manual tree
Adds docs/build-manual.py (--concat) and a round-trip test in
verify-manual.py that reproduces the pre-migration fish-config.md
exactly from docs/manual/.

Fixes found by the round-trip check, applied in split-manual.py and
re-run to regenerate docs/manual/:
- NAME/SYNOPSIS/TABLE OF CONTENTS had no sidebar.order, so they sorted
  after every numbered section instead of interleaving with DESCRIPTION
  in original document order. All manual pages now get sidebar.order
  from a single position counter matching source order.
- split_h1/split_h2 used .strip() on section bodies, which also ate
  leading indentation on the first body line, corrupting the 4-space
  indented code blocks that open SYNOPSIS and TABLE OF CONTENTS.
- The source's leading pandoc metadata block (title/section/header/
  date/author) was discarded entirely by the splitter. It's now parsed
  off via manualtools.parse and stashed on index.md under a "pandoc"
  key; build-manual.py re-emits it verbatim ahead of the first heading.
2026-07-25 21:39:48 -04:00