feat(docs): run codespans over the man-page pipeline too

A token was typeset by whichever pipeline happened to render it: the
site marked tmux and local.fish through codespans, while the man page
and config-help marked only what the SSOT had backticked by hand. Run
the same pass in build_concat() so prose is marked identically wherever
it is rendered (549 -> 662 spans in the concat).

codespans now treats a four-space block as code. The site never meets
one -- prettify() has already turned it into a fence by then -- but the
concat keeps the indented form pandoc wants, and its contents are
verbatim: without this the table of contents alone would come out with
ov, bat, less and cat wrapped inside a code block. Section 5 is
unaffected for the same reason; its entries arrive as indented blocks
that pandoc already sets in a monospace font.

test_codespans_is_site_only asserted the opposite guarantee and was
passing only because its example, -r/--resume, sits inside one of those
newly-protected blocks. It is replaced by tests for what is now true:
indented blocks stay verbatim, prose spans reach the concat, and
section 5 carries no backticks.

The man page is left for CI to regenerate; pandoc is not needed to
build the concat.
This commit is contained in:
2026-08-31 21:56:55 -04:00
parent 2ce8bebf29
commit b01124f99d
4 changed files with 184 additions and 111 deletions
+16 -4
View File
@@ -18,8 +18,9 @@ touched, so the man page and `config-help` keep the plain-text form.
Everything here is conservative by construction: leaving a token alone is
always safe and wrapping the wrong one is not, so every rule bails out the
moment it is unsure. The regions that must never be rewritten -- fenced
blocks, existing code spans, link targets, URLs, JSX attributes,
`<FileTree>` bodies, headings -- are recognised first and passed through.
blocks, indented code blocks, existing code spans, link targets, URLs, JSX
attributes, `<FileTree>` bodies, headings -- are recognised first and
passed through.
"""
import functools
@@ -359,6 +360,14 @@ FILE_TREE_OPEN = "<FileTree"
FILE_TREE_CLOSE = "</FileTree>"
CELL_SPLIT_RE = re.compile(r"(?<!\\)\|")
# A four-space indent is this manual's code block. The site never sees one
# -- prettify() has already turned it into a fence by the time this module
# runs -- but build_concat() keeps the indented form, because that is what
# pandoc and `config-help` want, and its contents are code that must not be
# rewritten: the table of contents alone would otherwise have `ov`, `bat`,
# `less` and `cat` wrapped inside a code block.
INDENTED_CODE = " "
def _skip_line(line: str) -> bool:
"""True for a line that must be passed through untouched.
@@ -488,8 +497,9 @@ def add_code_spans(text: str, vocab: Vocabulary = EMPTY_VOCABULARY) -> str:
"""Wrap code-shaped tokens in `text` in inline code spans.
`text` is a rendered page body (no frontmatter). Fenced blocks,
`<FileTree>` bodies, headings, component markup, existing code spans,
link targets and URLs are left exactly as they are.
indented code blocks, `<FileTree>` bodies, headings, component markup,
existing code spans, link targets and URLs are left exactly as they
are.
"""
scanner = _scanner(vocab)
atom_re = _atom_re(vocab)
@@ -510,6 +520,8 @@ def add_code_spans(text: str, vocab: Vocabulary = EMPTY_VOCABULARY) -> str:
if FILE_TREE_CLOSE in line:
in_tree = False
continue
if line.startswith(INDENTED_CODE):
continue
eligible[i] = not _skip_line(line)
# Command columns are a property of a whole table, so the contiguous