mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #2189: previous sibling link has broken if previous doc is under nested toctree
This commit is contained in:
parent
222a51e0cf
commit
8a763feb6b
@ -1950,63 +1950,31 @@ class BuildEnvironment:
|
||||
for (key_, group) in groupby(newlist, keyfunc2)]
|
||||
|
||||
def collect_relations(self):
|
||||
traversed = set()
|
||||
|
||||
def traverse_toctree(parent, docname):
|
||||
# traverse toctree by pre-order
|
||||
yield parent, docname
|
||||
traversed.add(docname)
|
||||
|
||||
for child in (self.toctree_includes.get(docname) or []):
|
||||
for subparent, subdocname in traverse_toctree(docname, child):
|
||||
if subdocname not in traversed:
|
||||
yield subparent, subdocname
|
||||
traversed.add(subdocname)
|
||||
|
||||
relations = {}
|
||||
getinc = self.toctree_includes.get
|
||||
docnames = traverse_toctree(None, self.config.master_doc)
|
||||
prevdoc = None
|
||||
parent, docname = docnames.next()
|
||||
for nextparent, nextdoc in docnames:
|
||||
relations[docname] = [parent, prevdoc, nextdoc]
|
||||
prevdoc = docname
|
||||
docname = nextdoc
|
||||
parent = nextparent
|
||||
|
||||
def collect(parents, parents_set, docname, previous, next):
|
||||
# circular relationship?
|
||||
if docname in parents_set:
|
||||
# we will warn about this in resolve_toctree()
|
||||
return
|
||||
if docname in relations:
|
||||
return
|
||||
includes = getinc(docname)
|
||||
# previous
|
||||
if not previous:
|
||||
# if no previous sibling, go to parent
|
||||
previous = parents[0][0]
|
||||
else:
|
||||
# else, go to previous sibling, or if it has children, to
|
||||
# the last of its children, or if that has children, to the
|
||||
# last of those, and so forth
|
||||
while 1:
|
||||
previncs = getinc(previous)
|
||||
if previncs:
|
||||
previous = previncs[-1]
|
||||
else:
|
||||
break
|
||||
# next
|
||||
if includes:
|
||||
# if it has children, go to first of them
|
||||
next = includes[0]
|
||||
elif next:
|
||||
# else, if next sibling, go to it
|
||||
pass
|
||||
else:
|
||||
# else, go to the next sibling of the parent, if present,
|
||||
# else the grandparent's sibling, if present, and so forth
|
||||
for parname, parindex in parents:
|
||||
parincs = getinc(parname)
|
||||
if parincs:
|
||||
for parinc in parincs[parindex + 1:]:
|
||||
if parinc in relations or parinc == docname:
|
||||
pass
|
||||
else:
|
||||
next = parinc
|
||||
break
|
||||
relations[docname] = [parent, prevdoc, None]
|
||||
|
||||
if next:
|
||||
break
|
||||
# else it will stay None
|
||||
# same for children
|
||||
if includes:
|
||||
for subindex, args in enumerate(zip(includes,
|
||||
[None] + includes,
|
||||
includes[1:] + [None])):
|
||||
collect([(docname, subindex)] + parents,
|
||||
parents_set.union([docname]), *args)
|
||||
relations[docname] = [parents[0][0], previous, next]
|
||||
collect([(None, 0)], set(), self.config.master_doc, None, None)
|
||||
return relations
|
||||
|
||||
def check_consistency(self):
|
||||
|
4
tests/roots/test-toctree-glob/bar/bar_4/index.rst
Normal file
4
tests/roots/test-toctree-glob/bar/bar_4/index.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Bar-4
|
||||
=====
|
||||
|
||||
bar
|
@ -5,3 +5,4 @@ Bar
|
||||
:glob:
|
||||
|
||||
*
|
||||
bar_4/index
|
||||
|
@ -8,3 +8,4 @@ test-toctree-glob
|
||||
bar/index
|
||||
bar/*
|
||||
baz
|
||||
qux/index
|
||||
|
4
tests/roots/test-toctree-glob/quux.rst
Normal file
4
tests/roots/test-toctree-glob/quux.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Quux
|
||||
====
|
||||
|
||||
quux
|
8
tests/roots/test-toctree-glob/qux/index.rst
Normal file
8
tests/roots/test-toctree-glob/qux/index.rst
Normal file
@ -0,0 +1,8 @@
|
||||
Qux
|
||||
===
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:hidden:
|
||||
|
||||
*
|
4
tests/roots/test-toctree-glob/qux/qux_1.rst
Normal file
4
tests/roots/test-toctree-glob/qux/qux_1.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Qux-1
|
||||
=====
|
||||
|
||||
qux
|
4
tests/roots/test-toctree-glob/qux/qux_2.rst
Normal file
4
tests/roots/test-toctree-glob/qux/qux_2.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Qux-1
|
||||
=====
|
||||
|
||||
qux
|
@ -20,5 +20,10 @@ def test_relations(app, status, warning):
|
||||
assert app.builder.relations['bar/index'] == ['index', 'foo', 'bar/bar_1']
|
||||
assert app.builder.relations['bar/bar_1'] == ['bar/index', 'bar/index', 'bar/bar_2']
|
||||
assert app.builder.relations['bar/bar_2'] == ['bar/index', 'bar/bar_1', 'bar/bar_3']
|
||||
assert app.builder.relations['bar/bar_3'] == ['bar/index', 'bar/bar_2', 'baz']
|
||||
assert app.builder.relations['baz'] == ['index', 'bar/bar_3', None]
|
||||
assert app.builder.relations['bar/bar_3'] == ['bar/index', 'bar/bar_2', 'bar/bar_4/index']
|
||||
assert app.builder.relations['bar/bar_4/index'] == ['bar/index', 'bar/bar_3', 'baz']
|
||||
assert app.builder.relations['baz'] == ['index', 'bar/bar_4/index', 'qux/index']
|
||||
assert app.builder.relations['qux/index'] == ['index', 'baz', 'qux/qux_1']
|
||||
assert app.builder.relations['qux/qux_1'] == ['qux/index', 'qux/index', 'qux/qux_2']
|
||||
assert app.builder.relations['qux/qux_2'] == ['qux/index', 'qux/qux_1', None]
|
||||
assert 'quux' not in app.builder.relations
|
||||
|
Loading…
Reference in New Issue
Block a user