Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow reserved pages in toctree #2849

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion doc/usage/restructuredtext/directives.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ tables of contents. The ``toctree`` directive is the central element.

The special entry name ``self`` stands for the document containing the
toctree directive. This is useful if you want to generate a "sitemap" from
the toctree.
the toctree. The special document names ``genindex``, ``modindex``, and
``search`` can also be used.
Comment on lines +153 to +154
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps expand this, as the special names can also be used indirectly, as you illustrate in the test.


You can use the ``reversed`` flag option to reverse the order of the entries
in the list. This can be useful when using the ``glob`` flag option to
Expand Down Expand Up @@ -220,6 +221,9 @@ tables of contents. The ``toctree`` directive is the central element.
.. versionchanged:: 1.3
Added "caption" and "name" option.

.. versionchanged:: 4.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.. versionchanged:: 4.5
.. versionchanged:: 5.1

If you re-target the PR to 5.x

Added support for "genindex", "modindex", and "search" references.

Special names
^^^^^^^^^^^^^

Expand Down
2 changes: 1 addition & 1 deletion sphinx/directives/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def parse_content(self, toctree: addnodes.toctree) -> List[Node]:
break
# absolutize filenames
docname = docname_join(self.env.docname, docname)
if url_re.match(ref) or ref == 'self':
if url_re.match(ref) or ref in ('self', 'genindex', 'modindex', 'search'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if this 4-tuple was factored out somewhere as it is used more than once, but there aren't any great locations that come to mind.

toctree['entries'].append((title, ref))
elif docname not in self.env.found_docs:
if excluded(self.env.doc2path(docname, None)):
Expand Down
12 changes: 8 additions & 4 deletions sphinx/environment/adapters/toctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,16 @@ def _entries_from_toctree(toctreenode: addnodes.toctree, parents: List[str],
para = addnodes.compact_paragraph('', '', reference)
item = nodes.list_item('', para)
toc = nodes.bullet_list('', item)
elif ref == 'self':
elif ref in ('self', 'genindex', 'modindex', 'search'):
# 'self' refers to the document from which this
# toctree originates
ref = toctreenode['parent']
if not title:
title = clean_astext(self.env.titles[ref])
if ref == 'self':
ref = toctreenode['parent']
title = title or clean_astext(self.env.titles[ref])
else:
reflabel = self.env.domains['std'].data['labels'][ref]
ref = reflabel[0]
title = title or reflabel[2]
reference = nodes.reference('', '', internal=True,
refuri=ref,
anchorname='',
Expand Down
5 changes: 3 additions & 2 deletions sphinx/environment/collectors/toctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def _walk_toctree(toctreenode: addnodes.toctree, depth: int) -> None:
if depth == 0:
return
for (_title, ref) in toctreenode['entries']:
if url_re.match(ref) or ref == 'self':
if url_re.match(ref) or ref in ('self', 'genindex', 'modindex', 'search'):
# don't mess with those
continue
elif ref in assigned:
Expand Down Expand Up @@ -262,7 +262,8 @@ def _walk_doctree(docname: str, doctree: Element, secnum: Tuple[int, ...]) -> No
_walk_doctree(docname, subnode, secnum)
elif isinstance(subnode, addnodes.toctree):
for _title, subdocname in subnode['entries']:
if url_re.match(subdocname) or subdocname == 'self':
if url_re.match(subdocname) or \
subdocname in ('self', 'genindex', 'modindex', 'search'):
# don't mess with those
continue

Expand Down
3 changes: 3 additions & 0 deletions tests/roots/test-toctree/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Contents:
bar
http://sphinx-doc.org/
self
genindex
Modules <modindex>
search

.. only:: html

Expand Down
4 changes: 2 additions & 2 deletions tests/test_build_epub.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def navinfo(elem):
content.get('src'), label.text)

navpoints = toc.findall("./ncx:navMap/ncx:navPoint")
assert len(navpoints) == 4
assert len(navpoints) == 7
assert navinfo(navpoints[0]) == ('navPoint1', '1', 'index.xhtml',
"Welcome to Sphinx Tests’s documentation!")
assert navpoints[0].findall("./ncx:navPoint") == []
Expand All @@ -205,7 +205,7 @@ def navinfo(elem):

nav = EPUBElementTree.fromstring((app.outdir / 'nav.xhtml').read_bytes())
toc = nav.findall("./xhtml:body/xhtml:nav/xhtml:ol/xhtml:li")
assert len(toc) == 4
assert len(toc) == 7
assert navinfo(toc[0]) == ('index.xhtml',
"Welcome to Sphinx Tests’s documentation!")
assert toc[0].findall("./xhtml:ol") == []
Expand Down
23 changes: 18 additions & 5 deletions tests/test_environment_toctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def test_process_doc(app):
caption="Table of Contents", glob=False, hidden=False,
titlesonly=False, maxdepth=2, numbered=999,
entries=[(None, 'foo'), (None, 'bar'), (None, 'http://sphinx-doc.org/'),
(None, 'self')],
(None, 'self'), (None, 'genindex'), ('Modules', 'modindex'),
(None, 'search')],
includefiles=['foo', 'bar'])

# only branch
Expand Down Expand Up @@ -222,7 +223,10 @@ def test_get_toctree_for(app):
[list_item, compact_paragraph, reference, "bar"],
[list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
[list_item, compact_paragraph, reference,
"Welcome to Sphinx Tests’s documentation!"]))
"Welcome to Sphinx Tests’s documentation!"],
[list_item, compact_paragraph, reference, "Index"],
[list_item, compact_paragraph, reference, "Modules"],
[list_item, compact_paragraph, reference, "Search Page"]))
assert_node(toctree[1][0][1],
([list_item, compact_paragraph, reference, "quux"],
[list_item, compact_paragraph, reference, "foo.1"],
Expand Down Expand Up @@ -261,7 +265,10 @@ def test_get_toctree_for_collapse(app):
[list_item, compact_paragraph, reference, "bar"],
[list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
[list_item, compact_paragraph, reference,
"Welcome to Sphinx Tests’s documentation!"]))
"Welcome to Sphinx Tests’s documentation!"],
[list_item, compact_paragraph, reference, "Index"],
[list_item, compact_paragraph, reference, "Modules"],
[list_item, compact_paragraph, reference, "Search Page"]))
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
Expand Down Expand Up @@ -294,7 +301,10 @@ def test_get_toctree_for_maxdepth(app):
[list_item, compact_paragraph, reference, "bar"],
[list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
[list_item, compact_paragraph, reference,
"Welcome to Sphinx Tests’s documentation!"]))
"Welcome to Sphinx Tests’s documentation!"],
[list_item, compact_paragraph, reference, "Index"],
[list_item, compact_paragraph, reference, "Modules"],
[list_item, compact_paragraph, reference, "Search Page"]))
assert_node(toctree[1][0][1],
([list_item, compact_paragraph, reference, "quux"],
[list_item, ([compact_paragraph, reference, "foo.1"],
Expand Down Expand Up @@ -339,7 +349,10 @@ def test_get_toctree_for_includehidden(app):
[list_item, compact_paragraph, reference, "bar"],
[list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
[list_item, compact_paragraph, reference,
"Welcome to Sphinx Tests’s documentation!"]))
"Welcome to Sphinx Tests’s documentation!"],
[list_item, compact_paragraph, reference, "Index"],
[list_item, compact_paragraph, reference, "Modules"],
[list_item, compact_paragraph, reference, "Search Page"]))
assert_node(toctree[1][0][1],
([list_item, compact_paragraph, reference, "quux"],
[list_item, compact_paragraph, reference, "foo.1"],
Expand Down