From 66da82993bd4bdb1fa9d92526c073d1ca43d2f26 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 29 Sep 2022 19:20:02 +0100 Subject: [PATCH 1/5] Use `:nocontentsentry:` --- doc/usage/restructuredtext/domains.rst | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index 397416a8907..b9c0032de8b 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -862,16 +862,16 @@ Example:: This will be rendered as: .. c:struct:: Data - :noindexentry: + :nocontentsentry: .. c:union:: @data - :noindexentry: + :nocontentsentry: .. c:var:: int a - :noindexentry: + :nocontentsentry: .. c:var:: double b - :noindexentry: + :nocontentsentry: Explicit ref: :c:var:`Data.@data.a`. Short-hand ref: :c:var:`Data.a`. @@ -953,10 +953,10 @@ Inline Expressions and Types will be rendered as follows: .. c:var:: int a = 42 - :noindexentry: + :nocontentsentry: .. c:function:: int f(int i) - :noindexentry: + :nocontentsentry: An expression: :c:expr:`a * f(a)` (or as text: :c:texpr:`a * f(a)`). @@ -1309,16 +1309,16 @@ Example:: This will be rendered as: .. cpp:class:: Data - :noindexentry: + :nocontentsentry: .. cpp:union:: @data - :noindexentry: + :nocontentsentry: .. cpp:var:: int a - :noindexentry: + :nocontentsentry: .. cpp:var:: double b - :noindexentry: + :nocontentsentry: Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`. @@ -1424,12 +1424,12 @@ introduction` instead of a template parameter list:: They are rendered as follows. .. cpp:function:: std::Iterator{It} void advance(It &it) - :noindexentry: + :nocontentsentry: A function template with a template parameter constrained to be an Iterator. .. cpp:class:: std::LessThanComparable{T} MySortedContainer - :noindexentry: + :nocontentsentry: A class template with a template parameter constrained to be LessThanComparable. @@ -1459,10 +1459,10 @@ Inline Expressions and Types will be rendered as follows: .. cpp:var:: int a = 42 - :noindexentry: + :nocontentsentry: .. cpp:function:: int f(int i) - :noindexentry: + :nocontentsentry: An expression: :cpp:expr:`a * f(a)` (or as text: :cpp:texpr:`a * f(a)`). From 3fbe4ac74c37a359f7329650b262a233ca769752 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 29 Sep 2022 19:24:04 +0100 Subject: [PATCH 2/5] Implement `nocontentsentry` flag --- doc/usage/restructuredtext/domains.rst | 44 ++++++++++++++---------- sphinx/directives/__init__.py | 3 ++ sphinx/domains/c.py | 2 +- sphinx/domains/cpp.py | 2 +- sphinx/domains/javascript.py | 4 ++- sphinx/domains/python.py | 2 ++ sphinx/domains/rst.py | 2 +- sphinx/environment/collectors/toctree.py | 5 ++- 8 files changed, 41 insertions(+), 23 deletions(-) diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index b9c0032de8b..1c78ec008d0 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -42,11 +42,15 @@ 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. A domain will typically keep an -internal index of all entities to aid cross-referencing. Typically it will -also add entries in the shown general index. +the content should be the description. + +A domain will typically keep an internal index of all entities 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 exclude the object description from the table of contents, you +can give the directive option flag ``:nocontentsentry:``. 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:``). @@ -57,6 +61,10 @@ options. The directive option ``noindexentry`` in the Python, C, C++, and Javascript domains. +.. versionadded:: 5.2.3 + The directive option ``:nocontentsentry:`` in the Python, C, C++, Javascript, + and reStructuredText domains. + An example using a Python domain directive:: .. py:function:: spam(eggs) @@ -523,7 +531,7 @@ For functions with optional parameters that don't have default values argument support), you can use brackets to specify the optional parts: .. py:function:: compile(source[, filename[, symbol]]) - :noindex: + :nocontentsentry: It is customary to put the opening bracket before the comma. @@ -580,7 +588,7 @@ explained by an example:: This will render like this: .. py:function:: send_message(sender, recipient, message_body, [priority=1]) - :noindex: + :nocontentsentry: Send a message to a recipient @@ -1166,23 +1174,23 @@ visibility statement (``public``, ``private`` or ``protected``). The example are rendered as follows. .. cpp:type:: std::vector MyList - :noindex: + :nocontentsentry: A typedef-like declaration of a type. .. cpp:type:: MyContainer::const_iterator - :noindex: + :nocontentsentry: Declaration of a type alias with unspecified type. .. cpp:type:: MyType = std::unordered_map - :noindex: + :nocontentsentry: Declaration of a type alias. .. cpp:type:: template \ MyContainer = std::vector - :noindex: + :nocontentsentry: .. rst:directive:: .. cpp:enum:: unscoped enum declaration .. cpp:enum-struct:: scoped enum declaration @@ -1277,7 +1285,7 @@ Options Some directives support options: -- ``:noindexentry:``, see :ref:`basic-domain-markup`. +- ``:noindexentry:`` and ``:nocontentsentry:``, see :ref:`basic-domain-markup`. - ``:tparam-line-spec:``, for templated declarations. If specified, each template parameter will be rendered on a separate line. @@ -1878,7 +1886,7 @@ The JavaScript domain (name **js**) provides the following directives: This is rendered as: .. js:function:: $.getJSON(href, callback[, errback]) - :noindex: + :nocontentsentry: :param string href: An URI to the location of the resource. :param callback: Gets called with the object. @@ -1908,7 +1916,7 @@ The JavaScript domain (name **js**) provides the following directives: This is rendered as: .. js:class:: MyAnimal(name[, age]) - :noindex: + :nocontentsentry: :param string name: The name of the animal :param number age: an optional age for the animal @@ -1955,12 +1963,12 @@ The reStructuredText domain (name **rst**) provides the following directives: will be rendered as: .. rst:directive:: foo - :noindex: + :nocontentsentry: Foo description. .. rst:directive:: .. bar:: baz - :noindex: + :nocontentsentry: Bar description. @@ -1979,13 +1987,13 @@ The reStructuredText domain (name **rst**) provides the following directives: will be rendered as: .. rst:directive:: toctree - :noindex: + :nocontentsentry: .. rst:directive:option:: caption: caption of ToC - :noindex: + :nocontentsentry: .. rst:directive:option:: glob - :noindex: + :nocontentsentry: .. rubric:: options @@ -2014,7 +2022,7 @@ The reStructuredText domain (name **rst**) provides the following directives: will be rendered as: .. rst:role:: foo - :noindex: + :nocontentsentry: Foo description. diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index b6838a6fd7a..2c8bdcdc51a 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -51,6 +51,8 @@ class ObjectDescription(SphinxDirective, Generic[T]): final_argument_whitespace = True option_spec: OptionSpec = { 'noindex': directives.flag, + 'noindexentry': directives.flag, + 'nocontentsentry': directives.flag, } # types of doc fields that this directive handles, see sphinx.util.docfields @@ -211,6 +213,7 @@ def run(self) -> List[Node]: node['objtype'] = node['desctype'] = self.objtype node['noindex'] = noindex = ('noindex' in self.options) node['noindexentry'] = ('noindexentry' in self.options) + node['nocontentsentry'] = ('nocontentsentry' in self.options) if self.domain: node['classes'].append(self.domain) node['classes'].append(node['objtype']) diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 61e3c4e1774..e12eabfdc3b 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -3142,8 +3142,8 @@ class CObject(ObjectDescription[ASTDeclaration]): """ option_spec: OptionSpec = { - 'noindex': directives.flag, 'noindexentry': directives.flag, + 'nocontentsentry': directives.flag, } def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None: diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index b448449b707..b509b34893e 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -7186,8 +7186,8 @@ class CPPObject(ObjectDescription[ASTDeclaration]): ] option_spec: OptionSpec = { - 'noindex': directives.flag, 'noindexentry': directives.flag, + 'nocontentsentry': directives.flag, 'tparam-line-spec': directives.flag, } diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index b78dfd30e0e..391cebf3391 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -40,6 +40,7 @@ class JSObject(ObjectDescription[Tuple[str, str]]): option_spec: OptionSpec = { 'noindex': directives.flag, 'noindexentry': directives.flag, + 'nocontentsentry': directives.flag, } def get_display_prefix(self) -> List[Node]: @@ -284,7 +285,8 @@ class JSModule(SphinxDirective): optional_arguments = 0 final_argument_whitespace = False option_spec: OptionSpec = { - 'noindex': directives.flag + 'noindex': directives.flag, + 'nocontentsentry': directives.flag, } def run(self) -> List[Node]: diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index bd507a21c85..8e0e3cca9fb 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -427,6 +427,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]): option_spec: OptionSpec = { 'noindex': directives.flag, 'noindexentry': directives.flag, + 'nocontentsentry': directives.flag, 'module': directives.unchanged, 'canonical': directives.unchanged, 'annotation': directives.unchanged, @@ -1008,6 +1009,7 @@ class PyModule(SphinxDirective): 'platform': lambda x: x, 'synopsis': lambda x: x, 'noindex': directives.flag, + 'nocontentsentry': directives.flag, 'deprecated': directives.flag, } diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index fc7f2e551bf..a8d5057eb9e 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -29,8 +29,8 @@ class ReSTMarkup(ObjectDescription[str]): Description of generic reST markup. """ option_spec: OptionSpec = { - 'noindex': directives.flag, 'noindexentry': directives.flag, + 'nocontentsentry': directives.flag, } def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None: diff --git a/sphinx/environment/collectors/toctree.py b/sphinx/environment/collectors/toctree.py index 68c730504ae..d923f097cf0 100644 --- a/sphinx/environment/collectors/toctree.py +++ b/sphinx/environment/collectors/toctree.py @@ -112,9 +112,12 @@ def build_toc( # Skip if no name set if not sig_node.get('_toc_name', ''): continue + # Skip if explicitly disabled + if sig_node.parent.get('nocontentsentry'): + continue # Skip entries with no ID (e.g. with :noindex: set) ids = sig_node['ids'] - if not ids or sig_node.parent.get('noindexentry'): + if not ids: continue anchorname = _make_anchor_name(ids, numentries) From 1d404d4a195981f0e47d175aa072d68aedbbd43d Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 29 Sep 2022 19:38:19 +0100 Subject: [PATCH 3/5] Add domain object table of contents configuration option --- doc/usage/configuration.rst | 5 +++++ sphinx/config.py | 1 + sphinx/directives/__init__.py | 8 ++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 5866b0e2977..906827ff32e 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -678,6 +678,11 @@ General configuration :term:`object` names (for object types where a "module" of some kind is defined), e.g. for :rst:dir:`py:function` directives. Default is ``True``. +.. confval:: toc_object_entries + + Create table of contents entries for domain objects (e.g. functions, classes, + attributes, etc.). Default is ``True``. + .. confval:: toc_object_entries_show_parents A string that determines how domain objects (e.g. functions, classes, diff --git a/sphinx/config.py b/sphinx/config.py index 45df6bb0057..2906a328578 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -106,6 +106,7 @@ class Config: 'default_role': (None, 'env', [str]), 'add_function_parentheses': (True, 'env', []), 'add_module_names': (True, 'env', []), + 'toc_object_entries': (True, 'env', [bool]), 'toc_object_entries_show_parents': ('domain', 'env', ENUM('domain', 'all', 'hide')), 'trim_footnote_reference_space': (False, 'env', []), diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index 2c8bdcdc51a..e59cb1295d8 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -239,8 +239,12 @@ def run(self) -> List[Node]: finally: # Private attributes for ToC generation. Will be modified or removed # without notice. - signode['_toc_parts'] = self._object_hierarchy_parts(signode) - signode['_toc_name'] = self._toc_entry_name(signode) + if self.env.app.config.toc_object_entries: + signode['_toc_parts'] = self._object_hierarchy_parts(signode) + signode['_toc_name'] = self._toc_entry_name(signode) + else: + signode['_toc_parts'] = () + signode['_toc_name'] = '' if name not in self.names: self.names.append(name) if not noindex: From bdb4e205c537a39c51ce43acd7cf7ed53eb040ba Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 29 Sep 2022 22:56:21 +0100 Subject: [PATCH 4/5] Revert to noindex --- doc/usage/restructuredtext/domains.rst | 42 +++++++++++++++++--------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index 1c78ec008d0..ff5688446e1 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -531,7 +531,7 @@ For functions with optional parameters that don't have default values argument support), you can use brackets to specify the optional parts: .. py:function:: compile(source[, filename[, symbol]]) - :nocontentsentry: + :noindex: It is customary to put the opening bracket before the comma. @@ -588,7 +588,7 @@ explained by an example:: This will render like this: .. py:function:: send_message(sender, recipient, message_body, [priority=1]) - :nocontentsentry: + :noindex: Send a message to a recipient @@ -871,15 +871,19 @@ This will be rendered as: .. c:struct:: Data :nocontentsentry: + :noindexentry: .. c:union:: @data :nocontentsentry: + :noindexentry: .. c:var:: int a :nocontentsentry: + :noindexentry: .. c:var:: double b :nocontentsentry: + :noindexentry: Explicit ref: :c:var:`Data.@data.a`. Short-hand ref: :c:var:`Data.a`. @@ -962,9 +966,11 @@ Inline Expressions and Types .. c:var:: int a = 42 :nocontentsentry: + :noindexentry: .. c:function:: int f(int i) :nocontentsentry: + :noindexentry: An expression: :c:expr:`a * f(a)` (or as text: :c:texpr:`a * f(a)`). @@ -1174,23 +1180,23 @@ visibility statement (``public``, ``private`` or ``protected``). The example are rendered as follows. .. cpp:type:: std::vector MyList - :nocontentsentry: + :noindex: A typedef-like declaration of a type. .. cpp:type:: MyContainer::const_iterator - :nocontentsentry: + :noindex: Declaration of a type alias with unspecified type. .. cpp:type:: MyType = std::unordered_map - :nocontentsentry: + :noindex: Declaration of a type alias. .. cpp:type:: template \ MyContainer = std::vector - :nocontentsentry: + :noindex: .. rst:directive:: .. cpp:enum:: unscoped enum declaration .. cpp:enum-struct:: scoped enum declaration @@ -1318,15 +1324,19 @@ This will be rendered as: .. cpp:class:: Data :nocontentsentry: + :noindexentry: .. cpp:union:: @data :nocontentsentry: + :noindexentry: .. cpp:var:: int a :nocontentsentry: + :noindexentry: .. cpp:var:: double b :nocontentsentry: + :noindexentry: Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`. @@ -1433,11 +1443,13 @@ They are rendered as follows. .. cpp:function:: std::Iterator{It} void advance(It &it) :nocontentsentry: + :noindexentry: A function template with a template parameter constrained to be an Iterator. .. cpp:class:: std::LessThanComparable{T} MySortedContainer :nocontentsentry: + :noindexentry: A class template with a template parameter constrained to be LessThanComparable. @@ -1468,9 +1480,11 @@ Inline Expressions and Types .. cpp:var:: int a = 42 :nocontentsentry: + :noindexentry: .. cpp:function:: int f(int i) :nocontentsentry: + :noindexentry: An expression: :cpp:expr:`a * f(a)` (or as text: :cpp:texpr:`a * f(a)`). @@ -1886,7 +1900,7 @@ The JavaScript domain (name **js**) provides the following directives: This is rendered as: .. js:function:: $.getJSON(href, callback[, errback]) - :nocontentsentry: + :noindex: :param string href: An URI to the location of the resource. :param callback: Gets called with the object. @@ -1916,7 +1930,7 @@ The JavaScript domain (name **js**) provides the following directives: This is rendered as: .. js:class:: MyAnimal(name[, age]) - :nocontentsentry: + :noindex: :param string name: The name of the animal :param number age: an optional age for the animal @@ -1963,12 +1977,12 @@ The reStructuredText domain (name **rst**) provides the following directives: will be rendered as: .. rst:directive:: foo - :nocontentsentry: + :noindex: Foo description. .. rst:directive:: .. bar:: baz - :nocontentsentry: + :noindex: Bar description. @@ -1987,13 +2001,13 @@ The reStructuredText domain (name **rst**) provides the following directives: will be rendered as: .. rst:directive:: toctree - :nocontentsentry: + :noindex: .. rst:directive:option:: caption: caption of ToC - :nocontentsentry: + :noindex: .. rst:directive:option:: glob - :nocontentsentry: + :noindex: .. rubric:: options @@ -2022,7 +2036,7 @@ The reStructuredText domain (name **rst**) provides the following directives: will be rendered as: .. rst:role:: foo - :nocontentsentry: + :noindex: Foo description. From e0aa330c967aa8db4eccbe973bb0b9e8bbd00a29 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 29 Sep 2022 23:34:10 +0100 Subject: [PATCH 5/5] Fix --- doc/usage/restructuredtext/domains.rst | 12 ++++++++---- sphinx/domains/rst.py | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index ff5688446e1..cf9867779e7 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -1180,23 +1180,27 @@ visibility statement (``public``, ``private`` or ``protected``). The example are rendered as follows. .. cpp:type:: std::vector MyList - :noindex: + :nocontentsentry: + :noindexentry: A typedef-like declaration of a type. .. cpp:type:: MyContainer::const_iterator - :noindex: + :nocontentsentry: + :noindexentry: Declaration of a type alias with unspecified type. .. cpp:type:: MyType = std::unordered_map - :noindex: + :nocontentsentry: + :noindexentry: Declaration of a type alias. .. cpp:type:: template \ MyContainer = std::vector - :noindex: + :nocontentsentry: + :noindexentry: .. rst:directive:: .. cpp:enum:: unscoped enum declaration .. cpp:enum-struct:: scoped enum declaration diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index a8d5057eb9e..8f49fcaa008 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -29,6 +29,7 @@ class ReSTMarkup(ObjectDescription[str]): Description of generic reST markup. """ option_spec: OptionSpec = { + 'noindex': directives.flag, 'noindexentry': directives.flag, 'nocontentsentry': directives.flag, }