From 0a91adb64d70ff9ab3bf59f5f2a57f22225f80e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Li=C5=A1ka?= Date: Sun, 2 Oct 2022 16:50:53 +0200 Subject: [PATCH] Extend cross referencing options with values (#10883) This change means that text following `=`, `[=`, or ` ` is ignored when searching for a corresponding option directive to an option cross reference role. These are commonly used options, for example `--profile=path`, `--profile[=path]` or `--profile path`. Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- doc/usage/restructuredtext/domains.rst | 3 ++- sphinx/domains/std.py | 15 +++++++++++---- tests/roots/test-root/objects.txt | 3 ++- tests/test_build_html.py | 3 +++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index f2f07927d48..cc0713b9fd1 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -1803,7 +1803,8 @@ There is a set of directives allowing documenting command-line programs: .. versionchanged:: 5.3 - One can cross-reference including an option value: ``:option:`--module=foobar```. + One can cross-reference including an option value: ``:option:`--module=foobar```, + ,``:option:`--module[=foobar]``` or ``:option:`--module foobar```. Use :confval:`option_emphasise_placeholders` for parsing of "variable part" of a literal text (similarly to the :rst:role:`samp` role). diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index ef13e156e42..6154a6ac1cc 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -943,10 +943,17 @@ def _resolve_option_xref(self, env: "BuildEnvironment", fromdocname: str, progname = node.get('std:program') target = target.strip() docname, labelid = self.progoptions.get((progname, target), ('', '')) - # for :option:`-foo=bar` search for -foo option directive - if not docname and '=' in target: - target2 = target[:target.find('=')] - docname, labelid = self.progoptions.get((progname, target2), ('', '')) + if not docname: + # Support also reference that contain an option value: + # * :option:`-foo=bar` + # * :option:`-foo[=bar]` + # * :option:`-foo bar` + for needle in {'=', '[=', ' '}: + if needle in target: + stem, _, _ = target.partition(needle) + docname, labelid = self.progoptions.get((progname, stem), ('', '')) + if docname: + break if not docname: commands = [] while ws_re.search(target): diff --git a/tests/roots/test-root/objects.txt b/tests/roots/test-root/objects.txt index fa9e475e565..170c026e760 100644 --- a/tests/roots/test-root/objects.txt +++ b/tests/roots/test-root/objects.txt @@ -214,7 +214,8 @@ Test repeated option directive. My secret API. -Reference the first option :option:`-mapi=secret`. +Reference the first option :option:`-mapi=secret`, :option:`-mapi[=xxx]` +or :option:`-mapi with_space`. User markup diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 453225e18ee..138f8a9c129 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -1771,6 +1771,9 @@ def test_option_reference_with_value(app, status, warning): assert ('-mapi' '' in content + assert ('' + '-mapi[=xxx]') in content + assert '-mapi with_space' in content @pytest.mark.sphinx('html', testroot='theming')