From c668500a4b37e5cf3c7015bda8a558ededbcebfe Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Thu, 2 Jul 2020 17:26:40 +0200 Subject: [PATCH] Add :noindexentry: option Fixes sphinx-doc/sphinx#7052 --- CHANGES | 3 +++ doc/usage/restructuredtext/domains.rst | 20 ++++++++++++++++--- sphinx/domains/c.py | 11 +++++------ sphinx/domains/cpp.py | 3 ++- sphinx/domains/javascript.py | 12 +++++++++--- sphinx/domains/python.py | 27 ++++++++++++++------------ 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/CHANGES b/CHANGES index 2fb8890ccb2..a5b98f87082 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,9 @@ Features added * #7888: napoleon: Add aliases Warn and Raise. * C, added :rst:dir:`c:alias` directive for inserting copies of existing declarations. +* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains. + Update the documentation to better reflect the relationship between this option + and the ``:noindex:`` option. Bugs fixed ---------- diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index 285e5b826f5..311b03d666c 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -42,9 +42,22 @@ Basic Markup Most domains provide a number of :dfn:`object description directives`, used to describe specific objects provided by modules. Each directive requires one or more signatures to provide basic information about what is being described, and -the content should be the description. The basic version makes entries in the -general index; if no index entry is desired, you can give the directive option -flag ``:noindex:``. An example using a Python domain directive:: +the content should be the description. A domain will typically keep an +internal index of all entites to aid cross-referencing. Typically it will +also add entries in the shown general index. +If you want to suppress the addition of an entry in the shown index, you can +give the directive option flag ``:noindexentry:``. +If you want to typeset an object description, without even making it available +for cross-referencing, you can give the directive option flag ``:noindex:`` +(which implies ``:noindexentry:``). +Though, note that not every directive en every domain may support these +options. + +.. versionadded:: 3.2 + The directive option ``noindexentry`` in the Python, C, C++, and Javascript + domains. + +An example using a Python domain directive:: .. py:function:: spam(eggs) ham(eggs) @@ -1073,6 +1086,7 @@ Options Some directives support options: +- ``:noindexentry:``, see :ref:`basic-domain-markup`. - ``:tparam-line-spec:``, for templated declarations. If specified, each template parameter will be rendered on a separate line. diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 8a0b8a1054b..10ced026d3b 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -16,6 +16,7 @@ from docutils import nodes from docutils.nodes import Element, Node, TextElement, system_message +from docutils.parsers.rst import directives from sphinx import addnodes from sphinx.addnodes import pending_xref @@ -3023,10 +3024,7 @@ class CObject(ObjectDescription): ] option_spec = { - # have a dummy option to ensure proper errors on options, - # otherwise the option is taken as a continuation of the - # argument - 'dummy': None + 'noindexentry': directives.flag, } def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None: @@ -3098,8 +3096,9 @@ def add_target_and_index(self, ast: ASTDeclaration, sig: str, if name not in domain.objects: domain.objects[name] = (domain.env.docname, newestId, self.objtype) - indexText = self.get_index_text(name) - self.indexnode['entries'].append(('single', indexText, newestId, '', None)) + if 'noindexentry' not in self.options: + indexText = self.get_index_text(name) + self.indexnode['entries'].append(('single', indexText, newestId, '', None)) @property def object_type(self) -> str: diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 310691d4956..c840423aade 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -6625,6 +6625,7 @@ class CPPObject(ObjectDescription): ] option_spec = { + 'noindexentry': directives.flag, 'tparam-line-spec': directives.flag, } @@ -6701,7 +6702,7 @@ def add_target_and_index(self, ast: ASTDeclaration, sig: str, if decl.objectType == 'concept': isInConcept = True break - if not isInConcept: + if not isInConcept and 'noindexentry' not in self.options: strippedName = name for prefix in self.env.config.cpp_index_common_prefix: if name.startswith(prefix): diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index d510d790342..6c75f8dd79a 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -49,6 +49,11 @@ class JSObject(ObjectDescription): #: based on directive nesting allow_nesting = False + option_spec = { + 'noindex': directives.flag, + 'noindexentry': directives.flag, + } + def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]: """Breaks down construct signatures @@ -120,9 +125,10 @@ def add_target_and_index(self, name_obj: Tuple[str, str], sig: str, domain = cast(JavaScriptDomain, self.env.get_domain('js')) domain.note_object(fullname, self.objtype, node_id, location=signode) - indextext = self.get_index_text(mod_name, name_obj) - if indextext: - self.indexnode['entries'].append(('single', indextext, node_id, '', None)) + if 'noindexentry' not in self.options: + indextext = self.get_index_text(mod_name, name_obj) + if indextext: + self.indexnode['entries'].append(('single', indextext, node_id, '', None)) def get_index_text(self, objectname: str, name_obj: Tuple[str, str]) -> str: name, obj = name_obj diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 5ea8d5d3da1..4ca60624849 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -317,6 +317,7 @@ class PyObject(ObjectDescription): """ option_spec = { 'noindex': directives.flag, + 'noindexentry': directives.flag, 'module': directives.unchanged, 'annotation': directives.unchanged, } @@ -459,9 +460,10 @@ def add_target_and_index(self, name_cls: Tuple[str, str], sig: str, domain = cast(PythonDomain, self.env.get_domain('py')) domain.note_object(fullname, self.objtype, node_id, location=signode) - indextext = self.get_index_text(modname, name_cls) - if indextext: - self.indexnode['entries'].append(('single', indextext, node_id, '', None)) + if 'noindexentry' not in self.options: + indextext = self.get_index_text(modname, name_cls) + if indextext: + self.indexnode['entries'].append(('single', indextext, node_id, '', None)) def before_content(self) -> None: """Handle object nesting before content @@ -576,16 +578,17 @@ def needs_arglist(self) -> bool: def add_target_and_index(self, name_cls: Tuple[str, str], sig: str, signode: desc_signature) -> None: super().add_target_and_index(name_cls, sig, signode) - modname = self.options.get('module', self.env.ref_context.get('py:module')) - node_id = signode['ids'][0] + if 'noindexentry' not in self.options: + modname = self.options.get('module', self.env.ref_context.get('py:module')) + node_id = signode['ids'][0] - name, cls = name_cls - if modname: - text = _('%s() (in module %s)') % (name, modname) - self.indexnode['entries'].append(('single', text, node_id, '', None)) - else: - text = '%s; %s()' % (pairindextypes['builtin'], name) - self.indexnode['entries'].append(('pair', text, node_id, '', None)) + name, cls = name_cls + if modname: + text = _('%s() (in module %s)') % (name, modname) + self.indexnode['entries'].append(('single', text, node_id, '', None)) + else: + text = '%s; %s()' % (pairindextypes['builtin'], name) + self.indexnode['entries'].append(('pair', text, node_id, '', None)) def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str: # add index in own add_target_and_index() instead.