From 7eac4ccab2a36556222be3b43edadcd4e2ddc4e9 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 05:47:43 -0600 Subject: [PATCH 01/21] feat(nodes): Add linkable arguments with wrapper and headerlink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add _generate_argument_id() to create unique IDs from argument names by stripping dashes and joining with hyphens (e.g., "-L" -> "L", ["-v", "--verbose"] -> "v-verbose"). Modify visit_argparse_argument_html() to: - Wrap dt+dd in
- Add for direct linking Modify depart_argparse_argument_html() to: - Wrap default values in for styled display - Close the wrapper div --- docs/_ext/sphinx_argparse_neo/nodes.py | 70 +++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/docs/_ext/sphinx_argparse_neo/nodes.py b/docs/_ext/sphinx_argparse_neo/nodes.py index 55039db639..f34f864f9c 100644 --- a/docs/_ext/sphinx_argparse_neo/nodes.py +++ b/docs/_ext/sphinx_argparse_neo/nodes.py @@ -26,6 +26,48 @@ from sphinx_argparse_neo.utils import strip_ansi # noqa: E402 +def _generate_argument_id(names: list[str], id_prefix: str = "") -> str: + """Generate unique ID for an argument based on its names. + + Creates a slug-style ID suitable for HTML anchors by: + 1. Stripping leading dashes from option names + 2. Joining multiple names with hyphens + 3. Prepending optional prefix for namespace isolation + + Parameters + ---------- + names : list[str] + List of argument names (e.g., ["-L", "--socket-name"]). + id_prefix : str + Optional prefix for uniqueness (e.g., "shell" -> "shell-L-socket-name"). + + Returns + ------- + str + A slug-style ID suitable for HTML anchors. + + Examples + -------- + >>> _generate_argument_id(["-L"]) + 'L' + >>> _generate_argument_id(["--help"]) + 'help' + >>> _generate_argument_id(["-v", "--verbose"]) + 'v-verbose' + >>> _generate_argument_id(["-L"], "shell") + 'shell-L' + >>> _generate_argument_id(["filename"]) + 'filename' + >>> _generate_argument_id([]) + '' + """ + clean_names = [name.lstrip("-") for name in names if name.lstrip("-")] + if not clean_names: + return "" + name_part = "-".join(clean_names) + return f"{id_prefix}-{name_part}" if id_prefix else name_part + + def _token_to_css_class(token_type: t.Any) -> str: """Map a Pygments token type to its CSS class abbreviation. @@ -419,6 +461,9 @@ def visit_argparse_argument_html( - Positional arguments get class 'nl' (Name.Label) - Metavars get class 'nv' (Name.Variable) + The argument is wrapped in a container div with a unique ID for linking. + A headerlink anchor (¶) is added for direct navigation. + Parameters ---------- self : HTML5Translator @@ -428,11 +473,28 @@ def visit_argparse_argument_html( """ names: list[str] = node.get("names", []) metavar = node.get("metavar") + id_prefix: str = node.get("id_prefix", "") + + # Generate unique ID for this argument + arg_id = _generate_argument_id(names, id_prefix) + + # Open wrapper div with ID for linking + if arg_id: + self.body.append(f'
\n') + else: + self.body.append('
\n') # Build the argument signature with syntax highlighting highlighted_sig = _highlight_argument_names(names, metavar, self.encode) - self.body.append(f'
{highlighted_sig}
\n') + # Add headerlink anchor inside dt for navigation + headerlink = "" + if arg_id: + headerlink = f'' + + self.body.append( + f'
{highlighted_sig}{headerlink}
\n' + ) self.body.append('
') # Add help text @@ -447,6 +509,7 @@ def depart_argparse_argument_html( """Depart argparse_argument node - close argument entry. Adds default, choices, and type information if present. + Default values are wrapped in ```` for styled display. Parameters ---------- @@ -460,7 +523,8 @@ def depart_argparse_argument_html( default = node.get("default_string") if default is not None: - metadata.append(f"Default: {self.encode(default)}") + # Wrap default value in nv span for yellow/italic styling + metadata.append(f'Default: {self.encode(default)}') choices = node.get("choices") if choices: @@ -480,6 +544,8 @@ def depart_argparse_argument_html( self.body.append(f'

{meta_str}

') self.body.append("
\n") + # Close wrapper div + self.body.append("
\n") def visit_argparse_subcommands_html( From 5c7f1d08c674a7abff0640377cbfd036a3769e59 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 05:47:52 -0600 Subject: [PATCH 02/21] feat(renderer): Thread id_prefix to argument nodes Add id_prefix parameter to render_argument(), render_group(), and render_mutex_group() methods. Update render_group_section() to pass the prefix through to child methods. This enables unique argument IDs per subcommand (e.g., "load-L" vs "shell-L") when multiple argparse directives exist on the same page. --- docs/_ext/sphinx_argparse_neo/renderer.py | 32 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/_ext/sphinx_argparse_neo/renderer.py b/docs/_ext/sphinx_argparse_neo/renderer.py index 69272b5896..f6c313f9f1 100644 --- a/docs/_ext/sphinx_argparse_neo/renderer.py +++ b/docs/_ext/sphinx_argparse_neo/renderer.py @@ -358,13 +358,18 @@ def render_group_section( section += nodes.title(title, title) # Create the styled group container (with empty title - section provides it) - group_node = self.render_group(group, include_title=False) + # Pass id_prefix to render_group so arguments get unique IDs + group_node = self.render_group(group, include_title=False, id_prefix=id_prefix) section += group_node return section def render_group( - self, group: ArgumentGroup, include_title: bool = True + self, + group: ArgumentGroup, + include_title: bool = True, + *, + id_prefix: str = "", ) -> argparse_group: """Render an argument group. @@ -376,6 +381,10 @@ def render_group( Whether to include the title in the group node. When False, the title is assumed to come from a parent section node. Default is True for backwards compatibility. + id_prefix : str + Optional prefix for argument IDs (e.g., "shell" -> "shell-h"). + Used to ensure unique IDs when multiple argparse directives exist + on the same page. Returns ------- @@ -397,23 +406,29 @@ def render_group( # Add individual arguments for arg in group.arguments: - arg_node = self.render_argument(arg) + arg_node = self.render_argument(arg, id_prefix=id_prefix) group_node.append(arg_node) # Add mutually exclusive groups for mutex in group.mutually_exclusive: - mutex_nodes = self.render_mutex_group(mutex) + mutex_nodes = self.render_mutex_group(mutex, id_prefix=id_prefix) group_node.extend(mutex_nodes) return group_node - def render_argument(self, arg: ArgumentInfo) -> argparse_argument: + def render_argument( + self, arg: ArgumentInfo, *, id_prefix: str = "" + ) -> argparse_argument: """Render a single argument. Parameters ---------- arg : ArgumentInfo The argument to render. + id_prefix : str + Optional prefix for the argument ID (e.g., "shell" -> "shell-L"). + Used to ensure unique IDs when multiple argparse directives exist + on the same page. Returns ------- @@ -425,6 +440,7 @@ def render_argument(self, arg: ArgumentInfo) -> argparse_argument: arg_node["help"] = arg.help arg_node["metavar"] = arg.metavar arg_node["required"] = arg.required + arg_node["id_prefix"] = id_prefix if self.config.show_defaults: arg_node["default_string"] = arg.default_string @@ -438,7 +454,7 @@ def render_argument(self, arg: ArgumentInfo) -> argparse_argument: return arg_node def render_mutex_group( - self, mutex: MutuallyExclusiveGroup + self, mutex: MutuallyExclusiveGroup, *, id_prefix: str = "" ) -> list[argparse_argument]: """Render a mutually exclusive group. @@ -446,6 +462,8 @@ def render_mutex_group( ---------- mutex : MutuallyExclusiveGroup The mutually exclusive group. + id_prefix : str + Optional prefix for argument IDs (e.g., "shell" -> "shell-h"). Returns ------- @@ -454,7 +472,7 @@ def render_mutex_group( """ result: list[argparse_argument] = [] for arg in mutex.arguments: - arg_node = self.render_argument(arg) + arg_node = self.render_argument(arg, id_prefix=id_prefix) # Mark as part of mutex group arg_node["mutex"] = True arg_node["mutex_required"] = mutex.required From 4a942cdc3164369cfba6c570b4c4de504b099fd2 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 05:47:59 -0600 Subject: [PATCH 03/21] style(css): Add argument wrapper and headerlink styles - Background for .argparse-argument-name (like code.literal) - scroll-margin-top for .argparse-argument-wrapper - Headerlink visibility (hidden by default, visible on hover) - :target highlight when navigating via URL fragment - .nv styling in .argparse-argument-meta for default values --- docs/_static/css/argparse-highlight.css | 59 +++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index dce008dc36..867288e6dd 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -272,3 +272,62 @@ pre.argparse-usage { color: #C678DD; font-weight: bold; } + +/* ========================================================================== + Argument Wrapper and Linking Styles + ========================================================================== */ + +/* + * Background styling for argument names - subtle background like code.literal + * This provides visual weight and hierarchy for argument definitions. + */ +.argparse-argument-name { + background: var(--color-inline-code-background); + border-radius: .2em; + padding: .1em .3em; + font-family: var(--font-stack--monospace); +} + +/* + * Wrapper for linking - enables scroll-margin for fixed header navigation + * and :target pseudo-class for highlighting when linked. + */ +.argparse-argument-wrapper { + scroll-margin-top: 2.5rem; +} + +/* + * Headerlink anchor (¶) - hidden until hover + * Follows Sphinx documentation convention for linkable headings. + */ +.argparse-argument-name .headerlink { + visibility: hidden; + margin-left: .5rem; + color: var(--color-foreground-secondary); + text-decoration: none; +} + +.argparse-argument-name:hover .headerlink { + visibility: visible; +} + +.argparse-argument-name .headerlink:hover { + color: var(--color-foreground-primary); +} + +/* + * Highlight when targeted via URL fragment + * Uses Furo's highlight-on-target color for consistency. + */ +.argparse-argument-wrapper:target .argparse-argument-name { + background-color: var(--color-highlight-on-target); +} + +/* + * Default value styling in metadata + * Uses .nv (Name.Variable) class for yellow/italic styling consistent with metavars. + */ +.argparse-argument-meta .nv { + color: #E5C07B; + font-style: italic; +} From c9ec5ac7688252634768ffaca297c71c2505bc1b Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 05:48:05 -0600 Subject: [PATCH 04/21] test(nodes): Add tests for ID generation and HTML rendering Add tests for _generate_argument_id() covering: - Short/long options, positional arguments - Multiple names, empty names, prefix handling Add parametrized HTML rendering tests using NamedTuple: - MockTranslator and render_argument_to_html() helper - Verify wrapper div, headerlink, styled defaults - Test balanced div tags and ID patterns --- .../_ext/sphinx_argparse_neo/test_nodes.py | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) diff --git a/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py b/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py index c473c9974c..5ce2f0284f 100644 --- a/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py +++ b/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py @@ -2,8 +2,13 @@ from __future__ import annotations +import re +import typing as t + +import pytest from docutils import nodes from sphinx_argparse_neo.nodes import ( + _generate_argument_id, argparse_argument, argparse_group, argparse_program, @@ -257,3 +262,264 @@ def test_full_node_tree() -> None: assert isinstance(program.children[1], argparse_group) assert isinstance(program.children[2], argparse_group) assert isinstance(program.children[3], argparse_subcommands) + + +# --- ID generation tests --- + + +def test_generate_argument_id_short_option() -> None: + """Test ID generation for short option.""" + assert _generate_argument_id(["-L"]) == "L" + + +def test_generate_argument_id_long_option() -> None: + """Test ID generation for long option.""" + assert _generate_argument_id(["--help"]) == "help" + + +def test_generate_argument_id_multiple_names() -> None: + """Test ID generation for argument with multiple names.""" + assert _generate_argument_id(["-v", "--verbose"]) == "v-verbose" + + +def test_generate_argument_id_with_prefix() -> None: + """Test ID generation with prefix for namespace isolation.""" + assert _generate_argument_id(["-L"], "shell") == "shell-L" + assert _generate_argument_id(["--help"], "load") == "load-help" + + +def test_generate_argument_id_positional() -> None: + """Test ID generation for positional argument.""" + assert _generate_argument_id(["filename"]) == "filename" + + +def test_generate_argument_id_empty() -> None: + """Test ID generation with empty names list.""" + assert _generate_argument_id([]) == "" + + +def test_generate_argument_id_prefix_no_names() -> None: + """Test that prefix alone doesn't create ID when no names.""" + assert _generate_argument_id([], "shell") == "" + + +# --- HTML rendering tests using NamedTuple for parametrization --- + + +class ArgumentHTMLCase(t.NamedTuple): + """Test case for argument HTML rendering.""" + + test_id: str + names: list[str] + metavar: str | None + help_text: str | None + default: str | None + id_prefix: str + expected_patterns: list[str] # Regex patterns to match + + +ARGUMENT_HTML_CASES = [ + ArgumentHTMLCase( + test_id="short_option_with_metavar", + names=["-L"], + metavar="socket-name", + help_text="pass-through for tmux -L", + default="None", + id_prefix="shell", + expected_patterns=[ + r'
', + r'
', + r'-L', + r'socket-name', + r'', + r'Default: None', + r"
", + ], + ), + ArgumentHTMLCase( + test_id="long_option", + names=["--help"], + metavar=None, + help_text="show help", + default=None, + id_prefix="", + expected_patterns=[ + r'--help', + r'id="help"', + r'href="#help"', + ], + ), + ArgumentHTMLCase( + test_id="positional_argument", + names=["filename"], + metavar=None, + help_text="input file", + default=None, + id_prefix="", + expected_patterns=[ + r'filename', + r'id="filename"', + ], + ), + ArgumentHTMLCase( + test_id="multiple_names", + names=["-v", "--verbose"], + metavar=None, + help_text="Enable verbose mode", + default=None, + id_prefix="load", + expected_patterns=[ + r'id="load-v-verbose"', + r'-v', + r'--verbose', + r'href="#load-v-verbose"', + ], + ), +] + + +class MockTranslator: + """Mock HTML5Translator for testing HTML generation.""" + + def __init__(self) -> None: + """Initialize mock translator.""" + self.body: list[str] = [] + + def encode(self, text: str) -> str: + """HTML encode text.""" + return str(text).replace("&", "&").replace("<", "<").replace(">", ">") + + +def render_argument_to_html( + names: list[str], + metavar: str | None, + help_text: str | None, + default: str | None, + id_prefix: str, +) -> str: + """Render an argument node to HTML string for testing. + + Parameters + ---------- + names + Argument names (e.g., ["-v", "--verbose"]). + metavar + Optional metavar (e.g., "FILE"). + help_text + Help text for the argument. + default + Default value string. + id_prefix + Prefix for the argument ID. + + Returns + ------- + str + HTML string from the mock translator's body. + """ + from sphinx_argparse_neo.nodes import ( + depart_argparse_argument_html, + visit_argparse_argument_html, + ) + + node = argparse_argument() + node["names"] = names + node["metavar"] = metavar + node["help"] = help_text + node["default_string"] = default + node["id_prefix"] = id_prefix + + translator = MockTranslator() + visit_argparse_argument_html(translator, node) # type: ignore[arg-type] + depart_argparse_argument_html(translator, node) # type: ignore[arg-type] + + return "".join(translator.body) + + +@pytest.mark.parametrize( + "case", + ARGUMENT_HTML_CASES, + ids=lambda c: c.test_id, +) +def test_argument_html_rendering(case: ArgumentHTMLCase) -> None: + """Test HTML output for argument nodes.""" + html = render_argument_to_html( + names=case.names, + metavar=case.metavar, + help_text=case.help_text, + default=case.default, + id_prefix=case.id_prefix, + ) + + for pattern in case.expected_patterns: + assert re.search(pattern, html), f"Pattern not found: {pattern}\nHTML: {html}" + + +def test_argument_wrapper_has_id() -> None: + """Verify wrapper div has correct ID attribute.""" + html = render_argument_to_html( + names=["-f", "--file"], + metavar="PATH", + help_text="Input file", + default=None, + id_prefix="convert", + ) + + assert 'id="convert-f-file"' in html + assert '
None: + """Verify headerlink anchor exists with correct href.""" + html = render_argument_to_html( + names=["--output"], + metavar="FILE", + help_text="Output file", + default=None, + id_prefix="freeze", + ) + + assert '' in html + + +def test_default_value_styled() -> None: + """Verify default value is wrapped in nv span.""" + html = render_argument_to_html( + names=["--format"], + metavar=None, + help_text="Output format", + default="json", + id_prefix="", + ) + + assert 'Default: json' in html + + +def test_wrapper_div_closed() -> None: + """Verify wrapper div is properly closed.""" + html = render_argument_to_html( + names=["-v"], + metavar=None, + help_text="Verbose", + default=None, + id_prefix="", + ) + + # Count opening and closing div tags + open_divs = html.count("") + assert open_divs == close_divs, f"Unbalanced divs in HTML: {html}" + + +def test_argument_no_id_prefix() -> None: + """Test argument rendering without ID prefix.""" + html = render_argument_to_html( + names=["--debug"], + metavar=None, + help_text="Enable debug mode", + default=None, + id_prefix="", + ) + + assert 'id="debug"' in html + assert 'href="#debug"' in html From 6be7fcc9b86acab24f393387824b67a96c8cce6d Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 05:58:40 -0600 Subject: [PATCH 05/21] style(css): Add light mode overrides for argument backgrounds - Set --color-inline-code-background to #eeeeee in light mode - Use color-mix with 50% white for .argparse-argument-name in light mode --- docs/_static/css/argparse-highlight.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 867288e6dd..98bcb0c0ef 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -277,9 +277,18 @@ pre.argparse-usage { Argument Wrapper and Linking Styles ========================================================================== */ +/* + * Light mode overrides + * Furo's default inline code background is too dark in light mode. + */ +body:not([data-theme="dark"]) { + --color-inline-code-background: #eeeeee; +} + /* * Background styling for argument names - subtle background like code.literal * This provides visual weight and hierarchy for argument definitions. + * Light mode uses a lighter tint (50% white mix) for better contrast. */ .argparse-argument-name { background: var(--color-inline-code-background); @@ -288,6 +297,10 @@ pre.argparse-usage { font-family: var(--font-stack--monospace); } +body:not([data-theme="dark"]) .argparse-argument-name { + background: color-mix(in srgb, var(--color-inline-code-background), white 50%); +} + /* * Wrapper for linking - enables scroll-margin for fixed header navigation * and :target pseudo-class for highlighting when linked. From 40eddab4d4e958526ff82d8c392894254a654556 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 05:59:42 -0600 Subject: [PATCH 06/21] style(css): Add width fit-content to argument wrapper --- docs/_static/css/argparse-highlight.css | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 98bcb0c0ef..98bae303e3 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -307,6 +307,7 @@ body:not([data-theme="dark"]) .argparse-argument-name { */ .argparse-argument-wrapper { scroll-margin-top: 2.5rem; + width: fit-content; } /* From 01162109daa63661923a6050717ea967496d13a3 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:10:22 -0600 Subject: [PATCH 07/21] style(css): Refine argument name styling with monokai background - Use monokai background (#272822) for both light and dark modes - Add dark mode media query for prefers-color-scheme support - Adjust padding to .325rem .6rem and border-radius to .2rem - Add width: fit-content to .argparse-argument-name - Set headerlink color to #9ca0a5 in light mode for dark background - Remove color-mix override (same background for both modes now) --- docs/_static/css/argparse-highlight.css | 28 +++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 98bae303e3..486f062cac 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -279,26 +279,32 @@ pre.argparse-usage { /* * Light mode overrides - * Furo's default inline code background is too dark in light mode. + * Use monokai background (#272822) to match code blocks. */ body:not([data-theme="dark"]) { - --color-inline-code-background: #eeeeee; + --color-inline-code-background: #272822; +} + +/* + * Dark mode overrides (respects prefers-color-scheme) + * Use monokai background (#272822) to match code blocks. + */ +@media (prefers-color-scheme: dark) { + body:not([data-theme="light"]) { + --color-inline-code-background: #272822; + } } /* * Background styling for argument names - subtle background like code.literal * This provides visual weight and hierarchy for argument definitions. - * Light mode uses a lighter tint (50% white mix) for better contrast. */ .argparse-argument-name { background: var(--color-inline-code-background); - border-radius: .2em; - padding: .1em .3em; + border-radius: .2rem; + padding: .325rem .6rem; font-family: var(--font-stack--monospace); -} - -body:not([data-theme="dark"]) .argparse-argument-name { - background: color-mix(in srgb, var(--color-inline-code-background), white 50%); + width: fit-content; } /* @@ -321,6 +327,10 @@ body:not([data-theme="dark"]) .argparse-argument-name { text-decoration: none; } +body:not([data-theme="dark"]) .argparse-argument-name .headerlink { + color: #9ca0a5; +} + .argparse-argument-name:hover .headerlink { visibility: visible; } From e7706ef569c1f007907d7dad4d4a3e0fb0ff6638 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:14:12 -0600 Subject: [PATCH 08/21] style(css): Add light mode headerlink hover color - Use :hover:not(:visited) for headerlink hover states - Set light mode hover color to #cfd0d0 --- docs/_static/css/argparse-highlight.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 486f062cac..7574f2a91f 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -335,10 +335,14 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { visibility: visible; } -.argparse-argument-name .headerlink:hover { +.argparse-argument-name .headerlink:hover:not(:visited) { color: var(--color-foreground-primary); } +body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:visited) { + color: #cfd0d0; +} + /* * Highlight when targeted via URL fragment * Uses Furo's highlight-on-target color for consistency. From 3eae0ddba6bf8450cfd6c964b7993c079ee570a4 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:19:09 -0600 Subject: [PATCH 09/21] style(css): Style default values as inline code in argument meta Add background, border-radius, padding, and font-family to .argparse-argument-meta .nv to match inline code appearance. --- docs/_static/css/argparse-highlight.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 7574f2a91f..3dc0cbeeec 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -353,9 +353,13 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis /* * Default value styling in metadata - * Uses .nv (Name.Variable) class for yellow/italic styling consistent with metavars. + * Styled like inline code with monokai background. */ .argparse-argument-meta .nv { + background: var(--color-inline-code-background); + border-radius: .2rem; + padding: .325rem .6rem; + font-family: var(--font-stack--monospace); color: #E5C07B; font-style: italic; } From 9a3feb667cf221d70ef1849a9a5bfb95a0d92053 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:22:10 -0600 Subject: [PATCH 10/21] style(css): Use custom --argparse-code-background variable Replace overrides of Furo's --color-inline-code-background with a custom --argparse-code-background variable (#272822 monokai) to avoid affecting other inline code styling on the site. --- docs/_static/css/argparse-highlight.css | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 3dc0cbeeec..c9d3aea961 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -278,21 +278,11 @@ pre.argparse-usage { ========================================================================== */ /* - * Light mode overrides - * Use monokai background (#272822) to match code blocks. + * Argparse-specific code background (monokai #272822) + * Uses a custom variable to avoid affecting Furo's --color-inline-code-background. */ -body:not([data-theme="dark"]) { - --color-inline-code-background: #272822; -} - -/* - * Dark mode overrides (respects prefers-color-scheme) - * Use monokai background (#272822) to match code blocks. - */ -@media (prefers-color-scheme: dark) { - body:not([data-theme="light"]) { - --color-inline-code-background: #272822; - } +:root { + --argparse-code-background: #272822; } /* @@ -300,7 +290,7 @@ body:not([data-theme="dark"]) { * This provides visual weight and hierarchy for argument definitions. */ .argparse-argument-name { - background: var(--color-inline-code-background); + background: var(--argparse-code-background); border-radius: .2rem; padding: .325rem .6rem; font-family: var(--font-stack--monospace); @@ -356,7 +346,7 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis * Styled like inline code with monokai background. */ .argparse-argument-meta .nv { - background: var(--color-inline-code-background); + background: var(--argparse-code-background); border-radius: .2rem; padding: .325rem .6rem; font-family: var(--font-stack--monospace); From fe4a03d3b7e16104a1d5a31b89e2c5781b6d683d Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:26:49 -0600 Subject: [PATCH 11/21] style(css): Adjust argument styling and fix mypy warnings - Increase .argparse-argument-name padding to .485rem .875rem - Add .argparse-argument-help with padding-block-start for spacing - Remove unused type: ignore comments in test_nodes.py --- docs/_static/css/argparse-highlight.css | 10 +++++++++- tests/docs/_ext/sphinx_argparse_neo/test_nodes.py | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index c9d3aea961..bb2dce1a8c 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -292,7 +292,7 @@ pre.argparse-usage { .argparse-argument-name { background: var(--argparse-code-background); border-radius: .2rem; - padding: .325rem .6rem; + padding: .485rem .875rem; font-family: var(--font-stack--monospace); width: fit-content; } @@ -353,3 +353,11 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis color: #E5C07B; font-style: italic; } + +/* + * Help text description + * Adds spacing above for visual separation from argument name. + */ +.argparse-argument-help { + padding-block-start: 0.5rem; +} diff --git a/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py b/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py index 5ce2f0284f..e30306b6a7 100644 --- a/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py +++ b/tests/docs/_ext/sphinx_argparse_neo/test_nodes.py @@ -430,8 +430,8 @@ def render_argument_to_html( node["id_prefix"] = id_prefix translator = MockTranslator() - visit_argparse_argument_html(translator, node) # type: ignore[arg-type] - depart_argparse_argument_html(translator, node) # type: ignore[arg-type] + visit_argparse_argument_html(translator, node) + depart_argparse_argument_html(translator, node) return "".join(translator.body) From 24a86d3eac7c5a21c17c153c02865bd7112cbbca Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:28:32 -0600 Subject: [PATCH 12/21] style(css): Show headerlink when argument is targeted via URL fragment --- docs/_static/css/argparse-highlight.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index bb2dce1a8c..dfbafa18e3 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -341,6 +341,10 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis background-color: var(--color-highlight-on-target); } +.argparse-argument-wrapper:target .argparse-argument-name .headerlink { + visibility: visible; +} + /* * Default value styling in metadata * Styled like inline code with monokai background. From 358b3e8210934e5fe13c34ba185279b9d603e415 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:34:43 -0600 Subject: [PATCH 13/21] style(css): Consolidate duplicate selectors and use CSS variable - Extract shared font-family into combined .cli-* selector rule - Merge .cli-option-long and .cli-option-short (identical color) - Combine hover and :target headerlink visibility rules - Replace hardcoded #272822 with var(--argparse-code-background) --- docs/_static/css/argparse-highlight.css | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index dfbafa18e3..272e7d92da 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -22,18 +22,22 @@ ========================================================================== */ /* - * CLI Options - * - * Long options (--verbose) and short options (-h) both use teal color. + * Shared monospace font for all CLI inline roles */ -.cli-option { +.cli-option, +.cli-metavar, +.cli-command, +.cli-default, +.cli-choice { font-family: var(--font-stack--monospace); } -.cli-option-long { - color: #56B6C2; -} - +/* + * CLI Options + * + * Long options (--verbose) and short options (-h) both use teal color. + */ +.cli-option-long, .cli-option-short { color: #56B6C2; } @@ -45,7 +49,6 @@ * Yellow/amber to indicate "replace me" - distinct from flags (teal). */ .cli-metavar { - font-family: var(--font-stack--monospace); color: #E5C07B; font-style: italic; } @@ -57,7 +60,6 @@ * Green (same as choices) - they're enumerated command options. */ .cli-command { - font-family: var(--font-stack--monospace); color: #98C379; font-weight: bold; } @@ -69,7 +71,6 @@ * Subtle styling to not distract from options. */ .cli-default { - font-family: var(--font-stack--monospace); color: #CCCED4; font-style: italic; } @@ -81,7 +82,6 @@ * Green color to show they are valid literal values. */ .cli-choice { - font-family: var(--font-stack--monospace); color: #98C379; } @@ -195,7 +195,7 @@ /* Usage block container - match Pygments monokai background and code block styling */ pre.argparse-usage { - background: #272822; /* Monokai - same as .highlight */ + background: var(--argparse-code-background); padding: .625rem .875rem; line-height: 1.5; border-radius: .2rem; @@ -321,7 +321,11 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { color: #9ca0a5; } -.argparse-argument-name:hover .headerlink { +/* + * Show headerlink on hover or when targeted via URL fragment + */ +.argparse-argument-name:hover .headerlink, +.argparse-argument-wrapper:target .argparse-argument-name .headerlink { visibility: visible; } @@ -341,10 +345,6 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis background-color: var(--color-highlight-on-target); } -.argparse-argument-wrapper:target .argparse-argument-name .headerlink { - visibility: visible; -} - /* * Default value styling in metadata * Styled like inline code with monokai background. From d89198d841b8b53319a3a0c93e9ebd20e8b22496 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:38:15 -0600 Subject: [PATCH 14/21] style(css): Position headerlink outside argument name element MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use absolute positioning to place the ¶ link outside the dt element to the right, rather than inline. Hover trigger moved to the wrapper element so the link appears when hovering anywhere on the argument block. --- docs/_static/css/argparse-highlight.css | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 272e7d92da..3c3cf19d85 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -295,6 +295,7 @@ pre.argparse-usage { padding: .485rem .875rem; font-family: var(--font-stack--monospace); width: fit-content; + position: relative; } /* @@ -308,11 +309,15 @@ pre.argparse-usage { /* * Headerlink anchor (¶) - hidden until hover + * Positioned outside the dt element to the right. * Follows Sphinx documentation convention for linkable headings. */ .argparse-argument-name .headerlink { visibility: hidden; - margin-left: .5rem; + position: absolute; + right: -1.5rem; + top: 50%; + transform: translateY(-50%); color: var(--color-foreground-secondary); text-decoration: none; } @@ -324,8 +329,8 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { /* * Show headerlink on hover or when targeted via URL fragment */ -.argparse-argument-name:hover .headerlink, -.argparse-argument-wrapper:target .argparse-argument-name .headerlink { +.argparse-argument-wrapper:hover .headerlink, +.argparse-argument-wrapper:target .headerlink { visibility: visible; } From f5c85919f390fc1dc381331c78e423e25e72fd27 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:39:38 -0600 Subject: [PATCH 15/21] style(css): Remove unnecessary width: fit-content from wrapper --- docs/_static/css/argparse-highlight.css | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 3c3cf19d85..abccd97228 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -304,7 +304,6 @@ pre.argparse-usage { */ .argparse-argument-wrapper { scroll-margin-top: 2.5rem; - width: fit-content; } /* From 4a7cbb035a1ef30aa1bbafe5cd5da2ad831b3dab Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:42:34 -0600 Subject: [PATCH 16/21] style(css): Reduce default value badge size with smaller font and padding --- docs/_static/css/argparse-highlight.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index abccd97228..21dcda6f12 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -356,8 +356,9 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis .argparse-argument-meta .nv { background: var(--argparse-code-background); border-radius: .2rem; - padding: .325rem .6rem; + padding: .1405rem .3rem; font-family: var(--font-stack--monospace); + font-size: var(--font-size--small); color: #E5C07B; font-style: italic; } From c97be8a2cd39d792f3a72f3db2112e85cba4aab0 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:42:58 -0600 Subject: [PATCH 17/21] style(css): Remove italic from default value badge --- docs/_static/css/argparse-highlight.css | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 21dcda6f12..49a45b0edf 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -360,7 +360,6 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:vis font-family: var(--font-stack--monospace); font-size: var(--font-size--small); color: #E5C07B; - font-style: italic; } /* From 1802705e7f3a5d838229c1d87c96a3ab73f42aa5 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:46:34 -0600 Subject: [PATCH 18/21] style(css): Consolidate .cli-command and .cli-choice green color --- docs/_static/css/argparse-highlight.css | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 49a45b0edf..62d6768c5a 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -54,13 +54,18 @@ } /* - * CLI Commands + * CLI Commands and Choices * - * Subcommand names like sync, add, list. - * Green (same as choices) - they're enumerated command options. + * Both use green to indicate valid enumerated values. + * Commands: subcommand names like sync, add, list + * Choices: enumeration values like json, yaml, table */ -.cli-command { +.cli-command, +.cli-choice { color: #98C379; +} + +.cli-command { font-weight: bold; } @@ -75,16 +80,6 @@ font-style: italic; } -/* - * CLI Choice Values - * - * Choice enumeration values like json, yaml, table. - * Green color to show they are valid literal values. - */ -.cli-choice { - color: #98C379; -} - /* ========================================================================== Argparse Code Block Highlighting ========================================================================== */ From 2133a0df7d35494143173b0b3958b7fac0b25c95 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:47:32 -0600 Subject: [PATCH 19/21] style(css): Consolidate light mode headerlink selectors with nesting --- docs/_static/css/argparse-highlight.css | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index 62d6768c5a..ab33d339e2 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -316,10 +316,6 @@ pre.argparse-usage { text-decoration: none; } -body:not([data-theme="dark"]) .argparse-argument-name .headerlink { - color: #9ca0a5; -} - /* * Show headerlink on hover or when targeted via URL fragment */ @@ -332,8 +328,15 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { color: var(--color-foreground-primary); } -body:not([data-theme="dark"]) .argparse-argument-name .headerlink:hover:not(:visited) { - color: #cfd0d0; +/* + * Light mode headerlink color overrides + */ +body:not([data-theme="dark"]) .argparse-argument-name .headerlink { + color: #9ca0a5; + + &:hover:not(:visited) { + color: #cfd0d0; + } } /* From 643e215816fcc8a6ae4b2b074a21d16b1b981891 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 06:48:20 -0600 Subject: [PATCH 20/21] style(css): Format with biome (tabs, lowercase hex, leading zeros) --- docs/_static/css/argparse-highlight.css | 170 ++++++++++++------------ docs/_static/css/custom.css | 19 +-- 2 files changed, 95 insertions(+), 94 deletions(-) diff --git a/docs/_static/css/argparse-highlight.css b/docs/_static/css/argparse-highlight.css index ab33d339e2..a0a77ec795 100644 --- a/docs/_static/css/argparse-highlight.css +++ b/docs/_static/css/argparse-highlight.css @@ -29,7 +29,7 @@ .cli-command, .cli-default, .cli-choice { - font-family: var(--font-stack--monospace); + font-family: var(--font-stack--monospace); } /* @@ -39,7 +39,7 @@ */ .cli-option-long, .cli-option-short { - color: #56B6C2; + color: #56b6c2; } /* @@ -49,8 +49,8 @@ * Yellow/amber to indicate "replace me" - distinct from flags (teal). */ .cli-metavar { - color: #E5C07B; - font-style: italic; + color: #e5c07b; + font-style: italic; } /* @@ -62,11 +62,11 @@ */ .cli-command, .cli-choice { - color: #98C379; + color: #98c379; } .cli-command { - font-weight: bold; + font-weight: bold; } /* @@ -76,8 +76,8 @@ * Subtle styling to not distract from options. */ .cli-default { - color: #CCCED4; - font-style: italic; + color: #ccced4; + font-style: italic; } /* ========================================================================== @@ -93,55 +93,55 @@ .highlight-argparse .gh, .highlight-argparse-usage .gh, .highlight-argparse-help .gh { - color: #61AFEF; - font-weight: bold; + color: #61afef; + font-weight: bold; } /* Section headers like "positional arguments:", "options:" - neutral bright */ .highlight-argparse .gs, .highlight-argparse-help .gs { - color: #E5E5E5; - font-weight: bold; + color: #e5e5e5; + font-weight: bold; } /* Long options --foo - teal */ .highlight-argparse .nt, .highlight-argparse-usage .nt, .highlight-argparse-help .nt { - color: #56B6C2; - font-weight: normal; + color: #56b6c2; + font-weight: normal; } /* Short options -h - teal (same as long) */ .highlight-argparse .na, .highlight-argparse-usage .na, .highlight-argparse-help .na { - color: #56B6C2; - font-weight: normal; + color: #56b6c2; + font-weight: normal; } /* Metavar placeholders FILE, PATH - yellow/amber italic */ .highlight-argparse .nv, .highlight-argparse-usage .nv, .highlight-argparse-help .nv { - color: #E5C07B; - font-style: italic; + color: #e5c07b; + font-style: italic; } /* Command/program names - purple bold */ .highlight-argparse .nl, .highlight-argparse-usage .nl, .highlight-argparse-help .nl { - color: #C678DD; - font-weight: bold; + color: #c678dd; + font-weight: bold; } /* Subcommands - bold green */ .highlight-argparse .nf, .highlight-argparse-usage .nf, .highlight-argparse-help .nf { - color: #98C379; - font-weight: bold; + color: #98c379; + font-weight: bold; } /* Choice values - green */ @@ -151,22 +151,22 @@ .highlight-argparse .nc, .highlight-argparse-usage .nc, .highlight-argparse-help .nc { - color: #98C379; + color: #98c379; } /* Punctuation [], {}, () - neutral gray */ .highlight-argparse .p, .highlight-argparse-usage .p, .highlight-argparse-help .p { - color: #CCCED4; + color: #ccced4; } /* Operators like | - neutral gray */ .highlight-argparse .o, .highlight-argparse-usage .o, .highlight-argparse-help .o { - color: #CCCED4; - font-weight: normal; + color: #ccced4; + font-weight: normal; } /* ========================================================================== @@ -190,56 +190,56 @@ /* Usage block container - match Pygments monokai background and code block styling */ pre.argparse-usage { - background: var(--argparse-code-background); - padding: .625rem .875rem; - line-height: 1.5; - border-radius: .2rem; - scrollbar-color: var(--color-foreground-border) transparent; - scrollbar-width: thin; + background: var(--argparse-code-background); + padding: 0.625rem 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; + scrollbar-color: var(--color-foreground-border) transparent; + scrollbar-width: thin; } .argparse-usage .gh { - color: #61AFEF; - font-weight: bold; + color: #61afef; + font-weight: bold; } .argparse-usage .nt { - color: #56B6C2; - font-weight: normal; + color: #56b6c2; + font-weight: normal; } .argparse-usage .na { - color: #56B6C2; - font-weight: normal; + color: #56b6c2; + font-weight: normal; } .argparse-usage .nv { - color: #E5C07B; - font-style: italic; + color: #e5c07b; + font-style: italic; } .argparse-usage .nl { - color: #C678DD; - font-weight: bold; + color: #c678dd; + font-weight: bold; } .argparse-usage .nf { - color: #98C379; - font-weight: bold; + color: #98c379; + font-weight: bold; } .argparse-usage .no, .argparse-usage .nc { - color: #98C379; + color: #98c379; } .argparse-usage .o { - color: #CCCED4; - font-weight: normal; + color: #ccced4; + font-weight: normal; } .argparse-usage .p { - color: #CCCED4; + color: #ccced4; } /* @@ -249,23 +249,23 @@ pre.argparse-usage { * semantic spans for options and metavars. */ .argparse-argument-name .nt { - color: #56B6C2; - font-weight: normal; + color: #56b6c2; + font-weight: normal; } .argparse-argument-name .na { - color: #56B6C2; - font-weight: normal; + color: #56b6c2; + font-weight: normal; } .argparse-argument-name .nv { - color: #E5C07B; - font-style: italic; + color: #e5c07b; + font-style: italic; } .argparse-argument-name .nl { - color: #C678DD; - font-weight: bold; + color: #c678dd; + font-weight: bold; } /* ========================================================================== @@ -277,7 +277,7 @@ pre.argparse-usage { * Uses a custom variable to avoid affecting Furo's --color-inline-code-background. */ :root { - --argparse-code-background: #272822; + --argparse-code-background: #272822; } /* @@ -285,12 +285,12 @@ pre.argparse-usage { * This provides visual weight and hierarchy for argument definitions. */ .argparse-argument-name { - background: var(--argparse-code-background); - border-radius: .2rem; - padding: .485rem .875rem; - font-family: var(--font-stack--monospace); - width: fit-content; - position: relative; + background: var(--argparse-code-background); + border-radius: 0.2rem; + padding: 0.485rem 0.875rem; + font-family: var(--font-stack--monospace); + width: fit-content; + position: relative; } /* @@ -298,7 +298,7 @@ pre.argparse-usage { * and :target pseudo-class for highlighting when linked. */ .argparse-argument-wrapper { - scroll-margin-top: 2.5rem; + scroll-margin-top: 2.5rem; } /* @@ -307,13 +307,13 @@ pre.argparse-usage { * Follows Sphinx documentation convention for linkable headings. */ .argparse-argument-name .headerlink { - visibility: hidden; - position: absolute; - right: -1.5rem; - top: 50%; - transform: translateY(-50%); - color: var(--color-foreground-secondary); - text-decoration: none; + visibility: hidden; + position: absolute; + right: -1.5rem; + top: 50%; + transform: translateY(-50%); + color: var(--color-foreground-secondary); + text-decoration: none; } /* @@ -321,22 +321,22 @@ pre.argparse-usage { */ .argparse-argument-wrapper:hover .headerlink, .argparse-argument-wrapper:target .headerlink { - visibility: visible; + visibility: visible; } .argparse-argument-name .headerlink:hover:not(:visited) { - color: var(--color-foreground-primary); + color: var(--color-foreground-primary); } /* * Light mode headerlink color overrides */ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { - color: #9ca0a5; + color: #9ca0a5; - &:hover:not(:visited) { - color: #cfd0d0; - } + &:hover:not(:visited) { + color: #cfd0d0; + } } /* @@ -344,7 +344,7 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { * Uses Furo's highlight-on-target color for consistency. */ .argparse-argument-wrapper:target .argparse-argument-name { - background-color: var(--color-highlight-on-target); + background-color: var(--color-highlight-on-target); } /* @@ -352,12 +352,12 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { * Styled like inline code with monokai background. */ .argparse-argument-meta .nv { - background: var(--argparse-code-background); - border-radius: .2rem; - padding: .1405rem .3rem; - font-family: var(--font-stack--monospace); - font-size: var(--font-size--small); - color: #E5C07B; + background: var(--argparse-code-background); + border-radius: 0.2rem; + padding: 0.1405rem 0.3rem; + font-family: var(--font-stack--monospace); + font-size: var(--font-size--small); + color: #e5c07b; } /* @@ -365,5 +365,5 @@ body:not([data-theme="dark"]) .argparse-argument-name .headerlink { * Adds spacing above for visual separation from argument name. */ .argparse-argument-help { - padding-block-start: 0.5rem; + padding-block-start: 0.5rem; } diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index b420cee944..00a15fdc22 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,20 +1,21 @@ .sidebar-tree p.indented-block { - padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0 - var(--sidebar-item-spacing-horizontal); - margin-bottom: 0; + padding: var(--sidebar-item-spacing-vertical) + var(--sidebar-item-spacing-horizontal) 0 + var(--sidebar-item-spacing-horizontal); + margin-bottom: 0; } .sidebar-tree p.indented-block span.indent { - margin-left: var(--sidebar-item-spacing-horizontal); - display: block; + margin-left: var(--sidebar-item-spacing-horizontal); + display: block; } .sidebar-tree p.indented-block .project-name { - font-size: var(--sidebar-item-font-size); - font-weight: bold; - margin-right: calc(var(--sidebar-item-spacing-horizontal) / 2.5); + font-size: var(--sidebar-item-font-size); + font-weight: bold; + margin-right: calc(var(--sidebar-item-spacing-horizontal) / 2.5); } .sidebar-tree .active { - font-weight: bold; + font-weight: bold; } From 4f22db0a3bfe59e89acf2185ea91228db308031b Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 25 Jan 2026 07:30:23 -0600 Subject: [PATCH 21/21] docs(CHANGES): Add user-focused notes for linkable CLI arguments (#1010) Document the new linkable arguments feature with headerlinks, visual styling improvements, and default value badges --- CHANGES | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGES b/CHANGES index d615dc0c7a..c65567baef 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,17 @@ $ pipx install --suffix=@next 'tmuxp' --pip-args '\--pre' --force _Notes on the upcoming release will go here._ +### Documentation + +#### Linkable CLI arguments and options (#1010) + +CLI documentation now supports direct linking to specific arguments: + +- **Linkable options**: Each `--option` and positional argument has a permanent URL anchor (e.g., `cli/load.html#-d`) +- **Headerlinks**: Hover over any argument to reveal a ¶ link for easy sharing +- **Visual styling**: Argument names displayed with syntax-highlighted backgrounds for better readability +- **Default value badges**: Default values shown as styled inline code (e.g., `auto`) + ## tmuxp 1.64.0 (2026-01-24) ### Documentation