Skip to content

Commit

Permalink
Add option_emphasise_placeholders config value.
Browse files Browse the repository at this point in the history
Support parsing of "variable part" for option directives similarly
to samp roles.

Fixes: #9965.

Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Signed-off-by: Martin Liska <mliska@suse.cz>
  • Loading branch information
marxin and AA-Turner committed May 25, 2022
1 parent 4c664ae commit 786130c
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 4 deletions.
9 changes: 9 additions & 0 deletions doc/usage/configuration.rst
Expand Up @@ -706,6 +706,15 @@ General configuration

.. versionadded:: 3.0

.. confval:: option_emphasise_placeholders

Default is ``False``.
When enabled, emphasise placeholders in ``.. option:`` directives.
To display literal braces, escape with a backslash (``\{``). For example,
``option_emphasise_placeholders=True`` and ``.. option:: -foption={TYPE}`` would
render with ``TYPE`` emphasised.

.. versionadded:: 5.1

.. _intl-options:

Expand Down
3 changes: 3 additions & 0 deletions doc/usage/restructuredtext/domains.rst
Expand Up @@ -1750,6 +1750,9 @@ There is a set of directives allowing documenting command-line programs:
referenceable by :rst:role:`option` (in the example case, you'd use something
like ``:option:`dest_dir```, ``:option:`-m```, or ``:option:`--module```).

Use :confval:`option_emphasise_placeholders` for parsing of
"variable part" of a literal text (similarly to the ``samp`` role).

``cmdoption`` directive is a deprecated alias for the ``option`` directive.

.. rst:directive:: .. envvar:: name
Expand Down
1 change: 1 addition & 0 deletions sphinx/config.py
Expand Up @@ -140,6 +140,7 @@ class Config:
'smartquotes_excludes': ({'languages': ['ja'],
'builders': ['man', 'text']},
'env', []),
'option_emphasise_placeholders': (False, 'env', []),
}

def __init__(self, config: Dict[str, Any] = {}, overrides: Dict[str, Any] = {}) -> None:
Expand Down
36 changes: 32 additions & 4 deletions sphinx/domains/std.py
Expand Up @@ -15,7 +15,7 @@
from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, ObjType
from sphinx.locale import _, __
from sphinx.roles import XRefRole
from sphinx.roles import EmphasizedLiteral, XRefRole
from sphinx.util import docname_join, logging, ws_re
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import clean_astext, make_id, make_refnode
Expand All @@ -34,6 +34,8 @@
# RE for grammar tokens
token_re = re.compile(r'`((~?\w*:)?\w+)`', re.U)

samp_role = EmphasizedLiteral()


class GenericObject(ObjectDescription[str]):
"""
Expand Down Expand Up @@ -170,15 +172,41 @@ def handle_signature(self, sig: str, signode: desc_signature) -> str:
location=signode)
continue
optname, args = m.groups()
if optname.endswith('[') and args.endswith(']'):
if optname[-1] == '[' and args[-1] == ']':
# optional value surrounded by brackets (ex. foo[=bar])
optname = optname[:-1]
args = '[' + args

if count:
signode += addnodes.desc_addname(', ', ', ')
if self.env.config.option_emphasise_placeholders:
signode += addnodes.desc_sig_punctuation(',', ',')
signode += addnodes.desc_sig_space()
else:
signode += addnodes.desc_addname(', ', ', ')
signode += addnodes.desc_name(optname, optname)
signode += addnodes.desc_addname(args, args)
if self.env.config.option_emphasise_placeholders:
add_end_bracket = False
if not args:
continue
if args[0] == '[' and args[-1] == ']':
add_end_bracket = True
signode += addnodes.desc_sig_punctuation('[', '[')
args = args[1:-1]
if args[0] == ' ':
signode += addnodes.desc_sig_space()
args = args.strip()
if args[0] == '=':
signode += addnodes.desc_sig_punctuation('=', '=')
args = args[1:]
for part in samp_role.parse(args):
if isinstance(part, nodes.Text):
signode += nodes.Text(part.astext())
else:
signode += part
if add_end_bracket:
signode += addnodes.desc_sig_punctuation(']', ']')
else:
signode += addnodes.desc_addname(args, args)
if not count:
firstname = optname
signode['allnames'] = [optname]
Expand Down
9 changes: 9 additions & 0 deletions tests/roots/test-root/objects.txt
Expand Up @@ -194,6 +194,15 @@ Link to :option:`perl +p`, :option:`--ObjC++`, :option:`--plugin.option`, :optio

Link to :option:`hg commit` and :option:`git commit -p`.

.. option:: --abi={TYPE}

.. option:: --test={WHERE}-{COUNT}

.. option:: --wrap=\{\{value\}\}

.. option:: -allowable_client {client_name}

Foo bar.

User markup
===========
Expand Down
22 changes: 22 additions & 0 deletions tests/test_build_html.py
Expand Up @@ -1735,3 +1735,25 @@ def test_html_code_role(app):
assert ('<div class="highlight-python notranslate">' +
'<div class="highlight"><pre><span></span>' +
common_content) in content


@pytest.mark.sphinx('html', testroot='root',
confoverrides={'option_emphasise_placeholders': True})
def test_option_emphasise_placeholders(app, status, warning):
app.build()
content = (app.outdir / 'objects.html').read_text()
assert '<em><span class="pre">TYPE</span></em>' in content
assert '{TYPE}' not in content
assert ('<em><span class="pre">WHERE</span></em>'
'<span class="pre">-</span>'
'<em><span class="pre">COUNT</span></em>' in content)
assert '<span class="pre">{{value}}</span>' in content


@pytest.mark.sphinx('html', testroot='root')
def test_option_emphasise_placeholders_default(app, status, warning):
app.build()
content = (app.outdir / 'objects.html').read_text()
assert '<span class="pre">={TYPE}</span>' in content
assert '<span class="pre">={WHERE}-{COUNT}</span></span>' in content
assert '<span class="pre">{client_name}</span>' in content

0 comments on commit 786130c

Please sign in to comment.