From 4ca008836cd1b207991e28baa2fde6f89e8d8027 Mon Sep 17 00:00:00 2001 From: rootiest Date: Sun, 26 Jul 2026 16:06:36 -0400 Subject: [PATCH] fix(docs): recognize RST-style per-column dashed rules as tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _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. --- docs/build-manual.py | 13 ++++++++----- docs/verify-manual.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/build-manual.py b/docs/build-manual.py index 83d1168..c0fd62f 100644 --- a/docs/build-manual.py +++ b/docs/build-manual.py @@ -214,11 +214,11 @@ FILENAME_COMMENT_RE = re.compile(r"^#\s*(?:in\s+)?([\w-]+\.\w+)\s*$") CELL_SPLIT = re.compile(r"\s{2,}") -# A solid rule line under a header row — the "Component Reference" tables' +# A rule line under a header row — the "Component Reference" tables' # authoring convention (header, dashes, data rows all at the same indent, -# no ":"-terminated label). Distinct enough from CELL_SPLIT-based prose that -# it needs its own check rather than overloading _as_table's indent rule. -RULE_RE = re.compile(r"^[─\-]{10,}$") +# no ":"-terminated label). Either one solid run of dashes, or (RST-style) +# one dash run per column, gapped the same way CELL_SPLIT splits cells. +RULE_CELL_RE = re.compile(r"^[─\-]{3,}$") def _cell(text: str, code: bool) -> str: @@ -280,7 +280,10 @@ def _as_ruled_table(para: list[str]) -> str | None: else that doesn't match the header's column count is a source alignment bug, so bail out to the code-block fallback rather than guess. """ - if len(para) < 4 or not RULE_RE.match(para[1].strip()): + if len(para) < 4: + return None + rule_cells = CELL_SPLIT.split(para[1].strip()) + if not all(RULE_CELL_RE.match(cell) for cell in rule_cells): return None header = CELL_SPLIT.split(para[0].strip()) n = len(header) diff --git a/docs/verify-manual.py b/docs/verify-manual.py index 58cde59..33f14fd 100644 --- a/docs/verify-manual.py +++ b/docs/verify-manual.py @@ -437,6 +437,23 @@ def test_as_ruled_table_converts_header_rule_rows(): assert "| `spwin` | Kitty or WezTerm |" in out +def test_as_ruled_table_converts_per_column_dash_rule(): + """RST-style rule (one dash run per column, gapped like the header) tables too.""" + import build_manual + + out = build_manual._as_ruled_table( + [ + "Variable Disables", + "------------------------------ ------------------------------------", + "__fish_config_op_aliases Command shadows and flag injection", + "__fish_config_op_autoexec Startup side-effects", + ] + ) + assert out is not None, "a per-column dashed rule was rejected" + assert out.splitlines()[0] == "| Variable | Disables |" + assert "| `__fish_config_op_aliases` | Command shadows and flag injection |" in out + + def test_as_ruled_table_folds_wrapped_continuations(): """A row that splits into one cell continues the previous row's last column.""" import build_manual