Add autosectionlabel_max_depth config option

This option defines maximum section depth that labels will be
generated for by the autosectionlabel extension.

This is useful when there are a lot of sections of the similar
structure, for example:

 Releases
 ========
 Release 1
 ---------
 Changes
 ^^^^^^^

 Date
 ^^^^

 ...

 Release N
 ---------
 Changes
 ^^^^^^^

 Date
 ^^^^

This way there'll be warnings about duplicate labels. Setting
autosectionlabel_max_depth allows to skip sections deeper than
'Releases' in the example above.

By default it's None, so things will not change and labels will
be generated for all sections unless configured otherwise.
This commit is contained in:
Roman Bogorodskiy
2017-11-26 18:02:36 +04:00
parent 466241d43a
commit 6bbfa9ac45
3 changed files with 51 additions and 2 deletions

View File

@@ -16,10 +16,22 @@ from sphinx.util.nodes import clean_astext
logger = logging.getLogger(__name__)
def node_get_depth(node):
i = 0
cur_node = node
while cur_node.parent != node.document:
cur_node = cur_node.parent
i += 1
return i
def register_sections_as_label(app, document):
labels = app.env.domaindata['std']['labels']
anonlabels = app.env.domaindata['std']['anonlabels']
for node in document.traverse(nodes.section):
if (app.config.autosectionlabel_max_depth and
node_get_depth(node) > app.config.autosectionlabel_max_depth):
continue
labelid = node['ids'][0]
docname = app.env.docname
if app.config.autosectionlabel_prefix_document:
@@ -39,4 +51,5 @@ def register_sections_as_label(app, document):
def setup(app):
app.add_config_value('autosectionlabel_prefix_document', False, 'env')
app.add_config_value('autosectionlabel_max_depth', None, 'env')
app.connect('doctree-read', register_sections_as_label)

View File

@@ -15,6 +15,11 @@ For Windows users
For UNIX users
--------------
Linux
^^^^^
FreeBSD
^^^^^^^
References
==========
@@ -23,3 +28,5 @@ References
* :ref:`Installation`
* :ref:`For Windows users`
* :ref:`For UNIX users`
* :ref:`Linux`
* :ref:`FreeBSD`

View File

@@ -15,7 +15,7 @@ import pytest
@pytest.mark.sphinx('html', testroot='ext-autosectionlabel')
def test_autosectionlabel_html(app, status, warning):
def test_autosectionlabel_html(app, status, warning, skipped_labels=False):
app.builder.build_all()
content = (app.outdir / 'index.html').text()
@@ -35,8 +35,37 @@ def test_autosectionlabel_html(app, status, warning):
'<span class="std std-ref">For UNIX users</span></a></li>')
assert re.search(html, content, re.S)
if skipped_labels is None:
return
if not skipped_labels:
html = ('<li><a class="reference internal" href="#linux">'
'<span class="std std-ref">Linux</span></a></li>')
assert re.search(html, content, re.S)
html = ('<li><a class="reference internal" href="#freebsd">'
'<span class="std std-ref">FreeBSD</span></a></li>')
assert re.search(html, content, re.S)
else:
html = '<li><span class="xref std std-ref">Linux</span></li>'
assert re.search(html, content, re.S)
html = '<li><span class="xref std std-ref">FreeBSD</span></li>'
assert re.search(html, content, re.S)
assert 'WARNING: undefined label: linux' in warning.getvalue()
assert 'WARNING: undefined label: freebsd' in warning.getvalue()
# Re-use test definition from above, just change the test root directory
@pytest.mark.sphinx('html', testroot='ext-autosectionlabel-prefix-document')
def test_autosectionlabel_prefix_document_html(app, status, warning):
return test_autosectionlabel_html(app, status, warning)
return test_autosectionlabel_html(app, status, warning,
skipped_labels=None)
@pytest.mark.sphinx('html', testroot='ext-autosectionlabel',
confoverrides={'autosectionlabel_max_depth': 2})
def test_autosectionlabel_max_depth(app, status, warning):
return test_autosectionlabel_html(app, status, warning,
skipped_labels=True)