Skip to content

Commit

Permalink
Add a new confval directive to document settings and configuratio…
Browse files Browse the repository at this point in the history
…n values (#12536)
  • Loading branch information
AA-Turner authored Jul 10, 2024
1 parent 05d1d8a commit a4de250
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Features added
Patch by Bénédikt Tran and Adam Turner.
* #12524: Add a ``class`` option to the :rst:dir:`toctree` directive.
Patch by Tim Hoffmann.
* #12536: Add the :rst:dir:`confval` directive.
Patch by Adam Turner.

Bugs fixed
----------
Expand Down
6 changes: 0 additions & 6 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,6 @@ def setup(app: Sphinx) -> None:
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
app.connect('source-read', linkify_issues_in_changelog)
app.connect('build-finished', build_redirects)
app.add_object_type(
'confval',
'confval',
objname='configuration value',
indextemplate='pair: %s; configuration value',
)
fdesc = GroupedField('parameter', label='Parameters', names=['param'], can_collapse=True)
app.add_object_type(
'event', 'event', 'pair: %s; event', parse_event, doc_field_types=[fdesc]
Expand Down
38 changes: 38 additions & 0 deletions doc/usage/domains/standard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,44 @@ There is a set of directives allowing documenting command-line programs:

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

.. rst:directive:: .. confval:: name
Describes a configuration value or setting that the documented
code or program uses or defines.
Referenceable by :rst:role:`confval`.

.. rst:directive:option:: type
:type: text
Describes the type of the configuration value.
This is optional, and if specified will be interpreted as reStructuredText.
.. rst:directive:option:: default
:type: text
Describes the default value of the configuration value.
This is optional, and if specified will be interpreted as reStructuredText.
Example:

.. code-block:: rst
.. confval:: the_answer
:type: ``int`` (a *number*)
:default: **42**
This is a setting that controls the value of the answer.
will be rendered as follows:

.. confval:: the_answer
:no-contents-entry:
:no-index-entry:
:type: ``int`` (a *number*)
:default: **42**

This is a setting that controls the value of the answer.

.. rst:directive:: .. envvar:: name
Describes an environment variable that the documented code or program uses
Expand Down
7 changes: 7 additions & 0 deletions doc/usage/referencing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ Cross-referencing other items of interest
The following roles do possibly create a cross-reference, but do not refer to
objects:

.. rst:role:: confval
A configuration value or setting.
Index entries are generated.
Also generates a link to the matching :rst:dir:`confval` directive,
if it exists.

.. rst:role:: envvar
An environment variable. Index entries are generated. Also generates a link
Expand Down
73 changes: 73 additions & 0 deletions sphinx/domains/std/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,76 @@ def result_nodes(self, document: nodes.document, env: BuildEnvironment, node: El
return [indexnode, targetnode, node], []


class ConfigurationValue(ObjectDescription[str]):
index_template: str = _('%s; configuration value')
option_spec: ClassVar[OptionSpec] = {
'no-index': directives.flag,
'no-index-entry': directives.flag,
'no-contents-entry': directives.flag,
'no-typesetting': directives.flag,
'type': directives.unchanged_required,
'default': directives.unchanged_required,
}

def handle_signature(self, sig: str, sig_node: desc_signature) -> str:
sig_node.clear()
sig_node += addnodes.desc_name(sig, sig)
name = ws_re.sub(' ', sig)
sig_node['fullname'] = name
return name

def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]:
return (sig_node['fullname'],)

def _toc_entry_name(self, sig_node: desc_signature) -> str:
if not sig_node.get('_toc_parts'):
return ''
name, = sig_node['_toc_parts']
return name

def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
node_id = make_id(self.env, self.state.document, self.objtype, name)
signode['ids'].append(node_id)
self.state.document.note_explicit_target(signode)
index_entry = self.index_template % name
self.indexnode['entries'].append(('pair', index_entry, node_id, '', None))
self.env.domains['std'].note_object(self.objtype, name, node_id, location=signode)

def transform_content(self, content_node: addnodes.desc_content) -> None:
"""Insert *type* and *default* as a field list."""
field_list = nodes.field_list()
if 'type' in self.options:
field, msgs = self.format_type(self.options['type'])
field_list.append(field)
field_list += msgs
if 'default' in self.options:
field, msgs = self.format_default(self.options['default'])
field_list.append(field)
field_list += msgs
if len(field_list.children) > 0:
content_node.insert(0, field_list)

def format_type(self, type_: str) -> tuple[nodes.field, list[system_message]]:
"""Formats the ``:type:`` option."""
parsed, msgs = self.parse_inline(type_, lineno=self.lineno)
field = nodes.field(
'',
nodes.field_name('', _('Type')),
nodes.field_body('', *parsed),
)
return field, msgs

def format_default(self, default: str) -> tuple[nodes.field, list[system_message]]:
"""Formats the ``:default:`` option."""
parsed, msgs = self.parse_inline(default, lineno=self.lineno)
field = nodes.field(
'',
nodes.field_name('', _('Default')),
nodes.field_body('', *parsed),
)
return field, msgs


class Target(SphinxDirective):
"""
Generic target for user-defined cross-reference types.
Expand Down Expand Up @@ -527,6 +597,7 @@ class StandardDomain(Domain):
'token': ObjType(_('grammar token'), 'token', searchprio=-1),
'label': ObjType(_('reference label'), 'ref', 'keyword',
searchprio=-1),
'confval': ObjType('configuration value', 'confval'),
'envvar': ObjType(_('environment variable'), 'envvar'),
'cmdoption': ObjType(_('program option'), 'option'),
'doc': ObjType(_('document'), 'doc', searchprio=-1),
Expand All @@ -536,12 +607,14 @@ class StandardDomain(Domain):
'program': Program,
'cmdoption': Cmdoption, # old name for backwards compatibility
'option': Cmdoption,
'confval': ConfigurationValue,
'envvar': EnvVar,
'glossary': Glossary,
'productionlist': ProductionList,
}
roles: dict[str, RoleFunction | XRefRole] = {
'option': OptionXRefRole(warn_dangling=True),
'confval': XRefRole(warn_dangling=True),
'envvar': EnvVarXRefRole(),
# links to tokens in grammar productions
'token': TokenXRefRole(),
Expand Down

0 comments on commit a4de250

Please sign in to comment.