10000 Finer grained control over domain ToC entries (#10886) · sphinx-doc/sphinx@650f63b · GitHub
[go: up one dir, main page]

Skip to content

Commit 650f63b

Browse files
authored
Finer grained control over domain ToC entries (#10886)
- Implement `:nocontentsentry:` flag - Use `:nocontentsentry:` in docs - Add domain object table of contents configuration option
1 parent 6627618 commit 650f63b

File tree

10 files changed

+61
-14
lines changed

10 files changed

+61
-14
lines changed

doc/usage/configuration.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,11 @@ General configuration
678678
:term:`object` names (for object types where a "module" of some kind is
679679
defined), e.g. for :rst:dir:`py:function` directives. Default is ``True``.
680680

681+
.. confval:: toc_object_entries
682+
683+
Create table of contents entries for domain objects (e.g. functions, classes,
684+
attributes, etc.). Default is ``True``.
685+
681686
.. confval:: toc_object_entries_show_parents
682687

683688
A string that determines how domain objects (e.g. functions, classes,

doc/usage/restructuredtext/domains.rst

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ Basic Markup
4242
Most domains provide a number of :dfn:`object description directives`, used to
4343
describe specific objects provided by modules. Each directive requires one or
4444
more signatures to provide basic information about what is being described, and
45-
the content should be the description. A domain will typically keep an
46-
internal index of all entities to aid cross-referencing. Typically it will
47-
also add entries in the shown general index.
45+
the content should be the description.
46+
47+
A domain will typically keep an internal index of all entities to aid
48+
cross-referencing.
49+
Typically it will also add entries in the shown general index.
4850
If you want to suppress the addition of an entry in the shown index, you can
4951
give the directive option flag ``:noindexentry:``.
52+
If you want to exclude the object description from the table of contents, you
53+
can give the directive option flag ``:nocontentsentry:``.
5054
If you want to typeset an object description, without even making it available
5155
for cross-referencing, you can give the directive option flag ``:noindex:``
5256
(which implies ``:noindexentry:``).
@@ -57,6 +61,10 @@ options.
5761
The directive option ``noindexentry`` in the Python, C, C++, and Javascript
5862
domains.
5963

64+
.. versionadded:: 5.2.3
65+
The directive option ``:nocontentsentry:`` in the Python, C, C++, Javascript,
66+
and reStructuredText domains.
67+
6068
An example using a Python domain directive::
6169

6270
.. py:function:: spam(eggs)
@@ -862,15 +870,19 @@ Example::
862870
This will be rendered as:
863871
864872
.. c:struct:: Data
873+
:nocontentsentry:
865874
:noindexentry:
866875
867876
.. c:union:: @data
877+
:nocontentsentry:
868878
:noindexentry:
869879
870880
.. c:var:: int a
881+
:nocontentsentry:
871882
:noindexentry:
872883
873884
.. c:var:: double b
885+
:nocontentsentry:
874886
:noindexentry:
875887
876888
Explicit ref: :c:var:`Data.@data.a`. Short-hand ref: :c:var:`Data.a`.
@@ -953,9 +965,11 @@ Inline Expressions and Types
953965
will be rendered as follows:
954966
955967
.. c:var:: int a = 42
968+
:nocontentsentry:
956969
:noindexentry:
957970
958971
.. c:function:: int f(int i)
972+
:nocontentsentry:
959973
:noindexentry:
960974
961975
An expression: :c:expr:`a * f(a)` (or as text: :c:texpr:`a * f(a)`).
@@ -1166,23 +1180,27 @@ visibility statement (``public``, ``private`` or ``protected``).
11661180
The example are rendered as follows.
11671181
11681182
.. cpp:type:: std::vector<int> MyList
1169-
:noindex:
1183+
:nocontentsentry:
1184+
:noindexentry:
11701185
11711186
A typedef-like declaration of a type.
11721187
11731188
.. cpp:type:: MyContainer::const_iterator
1174-
:noindex:
1189+
:nocontentsentry:
1190+
:noindexentry:
11751191
11761192
Declaration of a type alias with unspecified type.
11771193
11781194
.. cpp:type:: MyType = std::unordered_map<int, std::string>
1179-
:noindex:
1195+
:nocontentsentry:
1196+
:noindexentry:
11801197
11811198
Declaration of a type alias.
11821199
11831200
.. cpp:type:: template<typename T> \
11841201
MyContainer = std::vector<T>
1185-
:noindex:
1202+
:nocontentsentry:
1203+
:noindexentry:
11861204
11871205
.. rst:directive:: .. cpp:enum:: unscoped enum declaration
11881206
.. cpp:enum-struct:: scoped enum declaration
@@ -1277,7 +1295,7 @@ Options
12771295
12781296
Some directives support options:
12791297
1280-
- ``:noindexentry:``, see :ref:`basic-domain-markup`.
1298+
- ``:noindexentry:`` and ``:nocontentsentry:``, see :ref:`basic-domain-markup`.
12811299
- ``:tparam-line-spec:``, for templated declarations.
12821300
If specified, each template parameter will be rendered on a separate line.
12831301
@@ -1309,15 +1327,19 @@ Example::
13091327
This will be rendered as:
13101328
13111329
.. cpp:class:: Data
1330+
:nocontentsentry:
13121331
:noindexentry:
13131332
13141333
.. cpp:union:: @data
1334+
:nocontentsentry:
13151335
:noindexentry:
13161336
13171337
.. cpp:var:: int a
1338+
:nocontentsentry:
13181339
:noindexentry:
13191340
13201341
.. cpp:var:: double b
1342+
:nocontentsentry:
13211343
:noindexentry:
13221344
13231345
Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`.
@@ -1424,11 +1446,13 @@ introduction` instead of a template parameter list::
14241446
They are rendered as follows.
14251447

14261448
.. cpp:function:: std::Iterator{It} void advance(It &it)
1449+
:nocontentsentry:
14271450
:noindexentry:
14281451

14291452
A function template with a template parameter constrained to be an Iterator.
14301453

14311454
.. cpp:class:: std::LessThanComparable{T} MySortedContainer
1455+
:nocontentsentry:
14321456
:noindexentry:
14331457

14341458
A class template with a template parameter constrained to be
@@ -1459,9 +1483,11 @@ Inline Expressions and Types
14591483
will be rendered as follows:
14601484

14611485
.. cpp:var:: int a = 42
1486+
:nocontentsentry:
14621487
:noindexentry:
14631488

14641489
.. cpp:function:: int f(int i)
1490+
:nocontentsentry:
14651491
:noindexentry:
14661492

14671493
An expression: :cpp:expr:`a * f(a)` (or as text: :cpp:texpr:`a * f(a)`).

sphinx/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class Config:
106106
'default_role': (None, 'env', [str]),
107107
'add_function_parentheses': (True, 'env', []),
108108
'add_module_names': (True, 'env', []),
109+
'toc_object_entries': (True, 'env', [bool]),
109110
'toc_object_entries_show_parents': ('domain', 'env',
110111
ENUM('domain', 'all', 'hide')),
111112
'trim_footnote_reference_space': (False, 'env', []),

sphinx/directives/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class ObjectDescription(SphinxDirective, Generic[T]):
5151
final_argument_whitespace = True
5252
option_spec: OptionSpec = {
5353
'noindex': directives.flag,
54+
'noindexentry': directives.flag,
55+
'nocontentsentry': directives.flag,
5456
}
5557

5658
# types of doc fields that this directive handles, see sphinx.util.docfields
@@ -211,6 +213,7 @@ def run(self) -> List[Node]:
211213
node['objtype'] = node['desctype'] = self.objtype
212214
node['noindex'] = noindex = ('noindex' in self.options)
213215
node['noindexentry'] = ('noindexentry' in self.options)
216+
node['nocontentsentry'] = ('nocontentsentry' in self.options)
214217
if self.domain:
215218
node['classes'].append(self.domain)
216219
node['classes'].append(node['objtype'])
@@ -236,8 +239,12 @@ def run(self) -> List[Node]:
236239
finally:
237240
# Private attributes for ToC generation. Will be modified or removed
238241
# without notice.
239-
signode['_toc_parts'] = self._object_hierarchy_parts(signode)
240-
signode['_toc_name'] = self._toc_entry_name(signode)
242+
if self.env.app.config.toc_object_entries:
243+
signode['_toc_parts'] = self._object_hierarchy_parts(signode)
244+
signode['_toc_name'] = self._toc_entry_name(signode)
245+
else:
246+
signode['_toc_parts'] = ()
247+
signode['_toc_name'] = ''
241248
if name not in self.names:
242249
self.names.append(name)
243250
if not noindex:

sphinx/domains/c.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3142,8 +3142,8 @@ class CObject(ObjectDescription[ASTDeclaration]):
31423142
"""
31433143

31443144
option_spec: OptionSpec = {
3145-
'noindex': directives.flag,
31463145
'noindexentry': directives.flag,
3146+
'nocontentsentry': directives.flag,
31473147
}
31483148

31493149
def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None:

sphinx/domains/cpp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7186,8 +7186,8 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
71867186
]
71877187

71887188
option_spec: OptionSpec = {
7189-
'noindex': directives.flag,
71907189
'noindexentry': directives.flag,
7190+
'nocontentsentry': directives.flag,
71917191
'tparam-line-spec': directives.flag,
71927192
}
71937193

sphinx/domains/javascript.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
4040
option_spec: OptionSpec = {
4141
'noindex': directives.flag,
4242
'noindexentry': directives.flag,
43+
'nocontentsentry': directives.flag,
4344
}
4445

4546
def get_display_prefix(self) -> List[Node]:
@@ -284,7 +285,8 @@ class JSModule(SphinxDirective):
284285
optional_arguments = 0
285286
final_argument_whitespace = False
286287
option_spec: OptionSpec = {
287-
'noindex': directives.flag
288+
'noindex': directives.flag,
289+
'nocontentsentry': directives.flag,
288290
}
289291

290292
def run(self) -> List[Node]:

sphinx/domains/python.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
427427
option_spec: OptionSpec = {
428428
'noindex': directives.flag,
429429
'noindexentry': directives.flag,
430+
'nocontentsentry': directives.flag,
430431
'module': directives.unchanged,
431432
'canonical': directives.unchanged,
432433
'annotation': directives.unchanged,
@@ -1008,6 +1009,7 @@ class PyModule(SphinxDirective):
10081009
'platform': lambda x: x,
10091010
'synopsis': lambda x: x,
10101011
'noindex': directives.flag,
1012+
'nocontentsentry': directives.flag,
10111013
'deprecated': directives.flag,
10121014
}
10131015

sphinx/domains/rst.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ReSTMarkup(ObjectDescription[str]):
3131
option_spec: OptionSpec = {
3232
'noindex': directives.flag,
3333
'noindexentry': directives.flag,
34+
'nocontentsentry': directives.flag,
3435
}
3536

3637
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:

sphinx/environment/collectors/toctree.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,12 @@ def build_toc(
112112
# Skip if no name set
113113
if not sig_node.get('_toc_name', ''):
114114
continue
115+
# Skip if explicitly disabled
116+
if sig_node.parent.get('nocontentsentry'):
117+
continue
115118
# Skip entries with no ID (e.g. with :noindex: set)
116119
ids = sig_node['ids']
117-
if not ids or sig_node.parent.get('noindexentry'):
120+
if not ids:
118121
continue
119122

120123
anchorname = _make_anchor_name(ids, numentries)

0 commit comments

Comments
 (0)
0