fix(docs): allow multi-level nesting in Starlight file trees #79

Merged
rootiest merged 1 commits from fix-starlight-file-tree into main 2026-07-27 02:05:19 +00:00
4 changed files with 89 additions and 76 deletions
+5 -2
View File
@@ -315,7 +315,7 @@ def _as_ruled_table(para: list[str]) -> str | None:
TREE_ROOT_RE = re.compile(r"^[~$][\w./{}-]*/$") TREE_ROOT_RE = re.compile(r"^[~$][\w./{}-]*/$")
TREE_BRANCH_RE = re.compile(r"^[├└]──\s*(\S+)\s*(.*)$") TREE_BRANCH_RE = re.compile(r"^([│ \t]*)[├└]──\s*(\S+)\s*(.*)$")
def _as_file_tree(para: list[str]) -> str | None: def _as_file_tree(para: list[str]) -> str | None:
@@ -329,7 +329,10 @@ def _as_file_tree(para: list[str]) -> str | None:
return None return None
branches.append(m.groups()) branches.append(m.groups())
out = ["<FileTree>", f"- {para[0].strip()}"] out = ["<FileTree>", f"- {para[0].strip()}"]
out += [f" - {name} {desc}".rstrip() for name, desc in branches] for prefix, name, desc in branches:
depth = len(prefix.replace('\t', ' ')) // 4
indent = " " * (depth + 1)
out.append(f"{indent}- {name} {desc}".rstrip())
out.append("</FileTree>") out.append("</FileTree>")
return "\n".join(out) return "\n".join(out)
+36 -35
View File
@@ -53,41 +53,42 @@ A production-grade Fish shell configuration targeting Fish 4.x. It provides:
The configuration is split across: The configuration is split across:
config.fish Main entry point; sets env vars and PATH ~/.config/fish/
conf.d/ ├── config.fish Main entry point; sets env vars and PATH
abbr.fish All abbreviations ├── conf.d/
autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish) │ ├── abbr.fish All abbreviations
cheat.fish cheat.sh tab completions ├── autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
done.fish Desktop notifications for long commands ├── cheat.fish cheat.sh tab completions
first_run.fish One-time init: Fisher bootstrap, theme, welcome ├── done.fish Desktop notifications for long commands
key_bindings.fish Custom key bindings and Vi mode │ ├── first_run.fish One-time init: Fisher bootstrap, theme, welcome
logging-events.fish C5 --on-variable event handlers; syncs logging state at startup │ ├── key_bindings.fish Custom key bindings and Vi mode
kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher ├── logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper ├── kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher
puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish) │ ├── paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux │ ├── puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit ├── tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux
sponge_privacy.fish Sponge privacy patterns; filters credentials from history │ ├── zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit
starship.fish fish_prompt with OSC 133 shell-integration markers │ ├── sponge_privacy.fish Sponge privacy patterns; filters credentials from history
tailscale.fish Tailscale CLI tab completions ├── starship.fish fish_prompt with OSC 133 shell-integration markers
theme.fish Catppuccin syntax highlight colors ├── tailscale.fish Tailscale CLI tab completions
tricks.fish PATH, bang-bang helpers, bat man pages, aliases ├── theme.fish Catppuccin syntax highlight colors
wakatime.fish WakaTime shell hook ├── tricks.fish PATH, bang-bang helpers, bat man pages, aliases
yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper │ ├── wakatime.fish WakaTime shell hook
zoxide.fish Zoxide z/zi integration; overrides cd │ ├── yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
functions/ Custom functions, one per file, autoloaded │ └── zoxide.fish Zoxide z/zi integration; overrides cd
completions/ Tab completion scripts ├── functions/ Custom functions, one per file, autoloaded
integrations/ ├── completions/ Tab completion scripts
fzf.fish FZF Catppuccin theme and key binding config ├── integrations/
scripts/ │ └── fzf.fish FZF Catppuccin theme and key binding config
clean_progress_log.py Strips paru/yay typescript animations to clean static logs ├── scripts/
agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath) │ ├── clean_progress_log.py Strips paru/yay typescript animations to clean static logs
docs/ Offline documentation and compiled man page │ └── agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath)
fish-config.md Primary source manual (terminal-readable) └── docs/ Offline documentation and compiled man page
fish-config.1 Compiled man page (auto-generated by CI) ├── fish-config.md Primary source manual (terminal-readable)
fish-config.index Section index for help config navigation ├── fish-config.1 Compiled man page (auto-generated by CI)
html/ Chunked HTML docs (auto-generated by CI) ├── fish-config.index Section index for help config navigation
wiki/ Markdown wiki (auto-generated by CI) ├── html/ Chunked HTML docs (auto-generated by CI)
└── wiki/ Markdown wiki (auto-generated by CI)
--- ---
+36 -35
View File
@@ -38,40 +38,41 @@ A production-grade Fish shell configuration targeting Fish 4.x. It provides:
The configuration is split across: The configuration is split across:
config.fish Main entry point; sets env vars and PATH ~/.config/fish/
conf.d/ ├── config.fish Main entry point; sets env vars and PATH
abbr.fish All abbreviations ├── conf.d/
autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish) │ ├── abbr.fish All abbreviations
cheat.fish cheat.sh tab completions ├── autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
done.fish Desktop notifications for long commands ├── cheat.fish cheat.sh tab completions
first_run.fish One-time init: Fisher bootstrap, theme, welcome ├── done.fish Desktop notifications for long commands
key_bindings.fish Custom key bindings and Vi mode │ ├── first_run.fish One-time init: Fisher bootstrap, theme, welcome
logging-events.fish C5 --on-variable event handlers; syncs logging state at startup │ ├── key_bindings.fish Custom key bindings and Vi mode
kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher ├── logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper ├── kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher
puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish) │ ├── paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux │ ├── puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit ├── tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux
sponge_privacy.fish Sponge privacy patterns; filters credentials from history │ ├── zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit
starship.fish fish_prompt with OSC 133 shell-integration markers │ ├── sponge_privacy.fish Sponge privacy patterns; filters credentials from history
tailscale.fish Tailscale CLI tab completions ├── starship.fish fish_prompt with OSC 133 shell-integration markers
theme.fish Catppuccin syntax highlight colors ├── tailscale.fish Tailscale CLI tab completions
tricks.fish PATH, bang-bang helpers, bat man pages, aliases ├── theme.fish Catppuccin syntax highlight colors
wakatime.fish WakaTime shell hook ├── tricks.fish PATH, bang-bang helpers, bat man pages, aliases
yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper │ ├── wakatime.fish WakaTime shell hook
zoxide.fish Zoxide z/zi integration; overrides cd │ ├── yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
functions/ Custom functions, one per file, autoloaded │ └── zoxide.fish Zoxide z/zi integration; overrides cd
completions/ Tab completion scripts ├── functions/ Custom functions, one per file, autoloaded
integrations/ ├── completions/ Tab completion scripts
fzf.fish FZF Catppuccin theme and key binding config ├── integrations/
scripts/ │ └── fzf.fish FZF Catppuccin theme and key binding config
clean_progress_log.py Strips paru/yay typescript animations to clean static logs ├── scripts/
agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath) │ ├── clean_progress_log.py Strips paru/yay typescript animations to clean static logs
docs/ Offline documentation and compiled man page │ └── agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath)
fish-config.md Primary source manual (terminal-readable) └── docs/ Offline documentation and compiled man page
fish-config.1 Compiled man page (auto-generated by CI) ├── fish-config.md Primary source manual (terminal-readable)
fish-config.index Section index for help config navigation ├── fish-config.1 Compiled man page (auto-generated by CI)
html/ Chunked HTML docs (auto-generated by CI) ├── fish-config.index Section index for help config navigation
wiki/ Markdown wiki (auto-generated by CI) ├── html/ Chunked HTML docs (auto-generated by CI)
└── wiki/ Markdown wiki (auto-generated by CI)
--- ---
+12 -4
View File
@@ -307,7 +307,7 @@ def test_site_build_produces_function_pages():
out = Path(d) out = Path(d)
sidebar = build_manual.build_site(docs / "manual", out) sidebar = build_manual.build_site(docs / "manual", out)
pages = list(out.rglob("*.md*")) pages = list(out.rglob("*.md*"))
assert (out / "index.md").exists(), "landing page missing" assert (out / "index.md").exists() or (out / "index.mdx").exists(), "landing page missing"
fn_pages = [p for p in pages if "reference" in p.parts and p.name != "index.mdx"] fn_pages = [p for p in pages if "reference" in p.parts and p.name != "index.mdx"]
assert len(fn_pages) > 80, f"expected >80 function pages, got {len(fn_pages)}" 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 not (out / "00-name.md").exists(), "site:false page was published"
@@ -665,8 +665,8 @@ def test_as_file_tree_rejects_non_trees():
assert build_manual._as_file_tree(para) is None, f"{label} was wrongly treed" assert build_manual._as_file_tree(para) is None, f"{label} was wrongly treed"
def test_as_file_tree_rejects_deeper_trees(): def test_as_file_tree_accepts_deeper_trees():
"""A tree with a second-level (indented) branch line is not detected — falls through to verbatim rendering.""" """A tree with indented branch lines becomes a Starlight <FileTree> with nested markdown lists."""
import build_manual import build_manual
para = [ para = [
@@ -675,7 +675,15 @@ def test_as_file_tree_rejects_deeper_trees():
"│ └── main.fish", "│ └── main.fish",
"└── README.md", "└── README.md",
] ]
assert build_manual._as_file_tree(para) is None out = build_manual._as_file_tree(para)
assert out == (
"<FileTree>\n"
"- ~/proj/\n"
" - src/\n"
" - main.fish\n"
" - README.md\n"
"</FileTree>"
), f"unexpected file tree output:\n{out}"
def test_customization_notes_render_as_aside(): def test_customization_notes_render_as_aside():