mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #326: numref
role can also refer sections
This commit is contained in:
parent
98886d3e07
commit
1aafc7e2e5
1
CHANGES
1
CHANGES
@ -118,6 +118,7 @@ Features added
|
||||
* #2926: EPUB3 builder supports vertical mode (``epub3_writing_mode`` option)
|
||||
* #2695: ``build_sphinx`` subcommand for setuptools handles exceptions as same
|
||||
as ``sphinx-build`` does
|
||||
* #326: `numref` role can also refer sections
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -294,13 +294,16 @@ General configuration
|
||||
|
||||
.. confval:: numfig_format
|
||||
|
||||
A dictionary mapping ``'figure'``, ``'table'`` and ``'code-block'`` to
|
||||
strings that are used for format of figure numbers. Default is to use
|
||||
``'Fig. %s'`` for ``'figure'``, ``'Table %s'`` for ``'table'`` and
|
||||
``'Listing %s'`` for ``'code-block'``.
|
||||
A dictionary mapping ``'figure'``, ``'table'``, ``'code-block'`` and
|
||||
``'section'`` to strings that are used for format of figure numbers. Default
|
||||
is to use ``'Fig. %s'`` for ``'figure'``, ``'Table %s'`` for ``'table'``,
|
||||
``'Listing %s'`` for ``'code-block'`` and ``'Section'`` for ``'section'``.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
Support format of section
|
||||
|
||||
.. confval:: numfig_secnum_depth
|
||||
|
||||
The scope of figure numbers, that is, the numfig feature numbers figures
|
||||
|
@ -212,11 +212,14 @@ Cross-referencing figures by figure number
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
`numref` role can also refer sections
|
||||
|
||||
.. rst:role:: numref
|
||||
|
||||
Link to the specified figures, tables and code-blocks; the standard reST
|
||||
labels are used. When you use this role, it will insert a reference to the
|
||||
figure with link text by its figure number like "Fig. 1.1".
|
||||
Link to the specified figures, tables, code-blocks and sections; the standard
|
||||
reST labels are used. When you use this role, it will insert a reference to
|
||||
the figure with link text by its figure number like "Fig. 1.1".
|
||||
|
||||
If an explicit link text is given (like usual: ``:numref:`Image of Sphinx (Fig.
|
||||
%s) <my-figure>```), the link caption will be the title of the reference.
|
||||
|
@ -104,7 +104,8 @@ class Config(object):
|
||||
nitpick_ignore = ([], None),
|
||||
numfig = (False, 'env'),
|
||||
numfig_secnum_depth = (1, 'env'),
|
||||
numfig_format = ({'figure': l_('Fig. %s'),
|
||||
numfig_format = ({'section': l_('Section %s'),
|
||||
'figure': l_('Fig. %s'),
|
||||
'table': l_('Table %s'),
|
||||
'code-block': l_('Listing %s')},
|
||||
'env'),
|
||||
|
@ -653,11 +653,10 @@ class StandardDomain(Domain):
|
||||
return None
|
||||
|
||||
try:
|
||||
figure_id = target_node['ids'][0]
|
||||
fignumber = env.toc_fignumbers[docname][figtype][figure_id]
|
||||
except (KeyError, IndexError):
|
||||
# target_node is found, but fignumber is not assigned.
|
||||
# Maybe it is defined in orphaned document.
|
||||
fignumber = self.get_fignumber(env, builder, figtype, docname, target_node)
|
||||
if fignumber is None:
|
||||
return contnode
|
||||
except ValueError:
|
||||
env.warn_node("no number is assigned for %s: %s" % (figtype, labelid), node)
|
||||
return contnode
|
||||
|
||||
@ -670,7 +669,7 @@ class StandardDomain(Domain):
|
||||
newtitle = title % '.'.join(map(str, fignumber))
|
||||
except TypeError:
|
||||
env.warn_node('invalid numfig_format: %s' % title, node)
|
||||
return None
|
||||
return contnode
|
||||
|
||||
return self.build_reference_node(fromdocname, builder,
|
||||
docname, labelid, newtitle, 'numref',
|
||||
@ -804,7 +803,9 @@ class StandardDomain(Domain):
|
||||
def has_child(node, cls):
|
||||
return any(isinstance(child, cls) for child in node)
|
||||
|
||||
if isinstance(node, nodes.container):
|
||||
if isinstance(node, nodes.section):
|
||||
return 'section'
|
||||
elif isinstance(node, nodes.container):
|
||||
if node.get('literal_block') and has_child(node, nodes.literal_block):
|
||||
return 'code-block'
|
||||
else:
|
||||
@ -813,6 +814,28 @@ class StandardDomain(Domain):
|
||||
figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
|
||||
return figtype
|
||||
|
||||
def get_fignumber(self, env, builder, figtype, docname, target_node):
|
||||
if figtype == 'section':
|
||||
if builder.name == 'latex':
|
||||
return tuple()
|
||||
elif docname not in env.toc_secnumbers:
|
||||
raise ValueError # no number assigned
|
||||
else:
|
||||
anchorname = '#' + target_node['ids'][0]
|
||||
if anchorname not in env.toc_secnumbers[docname]:
|
||||
# try first heading which has no anchor
|
||||
return env.toc_secnumbers[docname].get('')
|
||||
else:
|
||||
return env.toc_secnumbers[docname].get(anchorname)
|
||||
else:
|
||||
try:
|
||||
figure_id = target_node['ids'][0]
|
||||
return env.toc_fignumbers[docname][figtype][figure_id]
|
||||
except (KeyError, IndexError):
|
||||
# target_node is found, but fignumber is not assigned.
|
||||
# Maybe it is defined in orphaned document.
|
||||
raise ValueError
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_domain(StandardDomain)
|
||||
|
@ -1,7 +1,11 @@
|
||||
.. _bar:
|
||||
|
||||
===
|
||||
Bar
|
||||
===
|
||||
|
||||
.. _bar_a:
|
||||
|
||||
Bar A
|
||||
=====
|
||||
|
||||
@ -37,9 +41,13 @@ Bar A
|
||||
|
||||
print('hello world')
|
||||
|
||||
.. _bar_b:
|
||||
|
||||
Bar B
|
||||
=====
|
||||
|
||||
.. _bar_b1:
|
||||
|
||||
Bar B1
|
||||
------
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _baz_a:
|
||||
|
||||
Baz A
|
||||
-----
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _foo:
|
||||
|
||||
===
|
||||
Foo
|
||||
===
|
||||
@ -16,6 +18,8 @@ Foo
|
||||
|
||||
print('hello world')
|
||||
|
||||
.. _foo_a:
|
||||
|
||||
Foo A
|
||||
=====
|
||||
|
||||
@ -47,12 +51,18 @@ Foo A
|
||||
|
||||
print('hello world')
|
||||
|
||||
.. _foo_a1:
|
||||
|
||||
Foo A1
|
||||
------
|
||||
|
||||
.. _foo_b:
|
||||
|
||||
Foo B
|
||||
=====
|
||||
|
||||
.. _foo_b1:
|
||||
|
||||
Foo B1
|
||||
------
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _index:
|
||||
|
||||
test-tocdepth
|
||||
=============
|
||||
|
||||
@ -48,5 +50,8 @@ test-tocdepth
|
||||
* Table.2.2 is :numref:`Table:%s <table22>`
|
||||
* List.1 is :numref:`CODE_1`
|
||||
* List.2.2 is :numref:`Code-%s <CODE22>`
|
||||
* Section.1 is :numref:`foo`
|
||||
* Section.2.1 is :numref:`bar_a`
|
||||
* Unnumbered section is :numref:`index`
|
||||
* Invalid numfig_format 01: :numref:`invalid <fig1>`
|
||||
* Invalid numfig_format 02: :numref:`Fig %s %s <fig1>`
|
||||
|
@ -503,10 +503,11 @@ def test_tocdepth_singlehtml(app, status, warning):
|
||||
def test_numfig_disabled(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
|
||||
in warning.getvalue())
|
||||
assert 'index.rst:51: WARNING: invalid numfig_format: invalid' not in warning.getvalue()
|
||||
assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' not in warning.getvalue()
|
||||
warnings = warning.getvalue()
|
||||
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' in warnings
|
||||
assert 'index.rst:55: WARNING: no number is assigned for section: index' not in warnings
|
||||
assert 'index.rst:56: WARNING: invalid numfig_format: invalid' not in warnings
|
||||
assert 'index.rst:57: WARNING: invalid numfig_format: Fig %s %s' not in warnings
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
@ -521,6 +522,8 @@ def test_numfig_disabled(app, status, warning):
|
||||
(".//li/code/span", '^Table:%s$', True),
|
||||
(".//li/code/span", '^CODE_1$', True),
|
||||
(".//li/code/span", '^Code-%s$', True),
|
||||
(".//li/code/span", '^foo$', True),
|
||||
(".//li/code/span", '^bar_a$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
@ -562,10 +565,11 @@ def test_numfig_without_numbered_toctree(app, status, warning):
|
||||
(app.srcdir / 'index.rst').write_text(index, encoding='utf-8')
|
||||
app.builder.build_all()
|
||||
|
||||
assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
|
||||
not in warning.getvalue())
|
||||
assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
|
||||
assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
|
||||
warnings = warning.getvalue()
|
||||
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings
|
||||
assert 'index.rst:55: WARNING: no number is assigned for section: index' in warnings
|
||||
assert 'index.rst:56: WARNING: invalid numfig_format: invalid' in warnings
|
||||
assert 'index.rst:57: WARNING: invalid numfig_format: Fig %s %s' in warnings
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
@ -587,6 +591,8 @@ def test_numfig_without_numbered_toctree(app, status, warning):
|
||||
(".//li/a/span", '^Table:6$', True),
|
||||
(".//li/a/span", '^Listing 9$', True),
|
||||
(".//li/a/span", '^Code-6$', True),
|
||||
(".//li/code/span", '^foo$', True),
|
||||
(".//li/code/span", '^bar_a$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
@ -657,10 +663,11 @@ def test_numfig_without_numbered_toctree(app, status, warning):
|
||||
def test_numfig_with_numbered_toctree(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
|
||||
not in warning.getvalue())
|
||||
assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
|
||||
assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
|
||||
warnings = warning.getvalue()
|
||||
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings
|
||||
assert 'index.rst:55: WARNING: no number is assigned for section: index' in warnings
|
||||
assert 'index.rst:56: WARNING: invalid numfig_format: invalid' in warnings
|
||||
assert 'index.rst:57: WARNING: invalid numfig_format: Fig %s %s' in warnings
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
@ -682,6 +689,8 @@ def test_numfig_with_numbered_toctree(app, status, warning):
|
||||
(".//li/a/span", '^Table:2.2$', True),
|
||||
(".//li/a/span", '^Listing 1$', True),
|
||||
(".//li/a/span", '^Code-2.2$', True),
|
||||
(".//li/a/span", '^Section.1$', True),
|
||||
(".//li/a/span", '^Section.2.1$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
@ -751,14 +760,16 @@ def test_numfig_with_numbered_toctree(app, status, warning):
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s',
|
||||
'table': 'Tab_%s',
|
||||
'code-block': 'Code-%s'}})
|
||||
'code-block': 'Code-%s',
|
||||
'section': 'SECTION-%s'}})
|
||||
def test_numfig_with_prefix(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
|
||||
not in warning.getvalue())
|
||||
assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
|
||||
assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
|
||||
warnings = warning.getvalue()
|
||||
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings
|
||||
assert 'index.rst:55: WARNING: no number is assigned for section: index' in warnings
|
||||
assert 'index.rst:56: WARNING: invalid numfig_format: invalid' in warnings
|
||||
assert 'index.rst:57: WARNING: invalid numfig_format: Fig %s %s' in warnings
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
@ -780,6 +791,8 @@ def test_numfig_with_prefix(app, status, warning):
|
||||
(".//li/a/span", '^Table:2.2$', True),
|
||||
(".//li/a/span", '^Code-1$', True),
|
||||
(".//li/a/span", '^Code-2.2$', True),
|
||||
(".//li/a/span", '^SECTION-1$', True),
|
||||
(".//li/a/span", '^SECTION-2.1$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
@ -850,10 +863,11 @@ def test_numfig_with_prefix(app, status, warning):
|
||||
def test_numfig_with_secnum_depth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
|
||||
not in warning.getvalue())
|
||||
assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
|
||||
assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
|
||||
warnings = warning.getvalue()
|
||||
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings
|
||||
assert 'index.rst:55: WARNING: no number is assigned for section: index' in warnings
|
||||
assert 'index.rst:56: WARNING: invalid numfig_format: invalid' in warnings
|
||||
assert 'index.rst:57: WARNING: invalid numfig_format: Fig %s %s' in warnings
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
@ -875,6 +889,8 @@ def test_numfig_with_secnum_depth(app, status, warning):
|
||||
(".//li/a/span", '^Table:2.1.2$', True),
|
||||
(".//li/a/span", '^Listing 1$', True),
|
||||
(".//li/a/span", '^Code-2.1.2$', True),
|
||||
(".//li/a/span", '^Section.1$', True),
|
||||
(".//li/a/span", '^Section.2.1$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
@ -965,6 +981,8 @@ def test_numfig_with_singlehtml(app, status, warning):
|
||||
(".//li/a/span", '^Table:2.2$', True),
|
||||
(".//li/a/span", '^Listing 1$', True),
|
||||
(".//li/a/span", '^Code-2.2$', True),
|
||||
(".//li/a/span", '^Section.1$', True),
|
||||
(".//li/a/span", '^Section.2.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
"span[@class='caption-number']", '^Fig. 1.1 $', True),
|
||||
(".//div[@class='figure']/p[@class='caption']/"
|
||||
|
@ -151,13 +151,16 @@ def test_numref(app, status, warning):
|
||||
assert '\\hyperref[baz:table22]{Table:\\ref{baz:table22}}' in result
|
||||
assert '\\hyperref[index:code-1]{Listing \\ref{index:code-1}}' in result
|
||||
assert '\\hyperref[baz:code22]{Code-\\ref{baz:code22}}' in result
|
||||
assert '\\hyperref[foo:foo]{Section \\ref{foo:foo}}' in result
|
||||
assert '\\hyperref[bar:bar-a]{Section \\ref{bar:bar-a}}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s',
|
||||
'table': 'Tab_%s',
|
||||
'code-block': 'Code-%s'}})
|
||||
'code-block': 'Code-%s',
|
||||
'section': 'SECTION-%s'}})
|
||||
def test_numref_with_prefix1(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@ -179,13 +182,16 @@ def test_numref_with_prefix1(app, status, warning):
|
||||
assert '\\hyperref[baz:table22]{Table:\\ref{baz:table22}}' in result
|
||||
assert '\\hyperref[index:code-1]{Code-\\ref{index:code-1}}' in result
|
||||
assert '\\hyperref[baz:code22]{Code-\\ref{baz:code22}}' in result
|
||||
assert '\\hyperref[foo:foo]{SECTION-\\ref{foo:foo}}' in result
|
||||
assert '\\hyperref[bar:bar-a]{SECTION-\\ref{bar:bar-a}}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s.',
|
||||
'table': 'Tab_%s:',
|
||||
'code-block': 'Code-%s | '}})
|
||||
'code-block': 'Code-%s | ',
|
||||
'section': 'SECTION_%s_'}})
|
||||
def test_numref_with_prefix2(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@ -203,6 +209,8 @@ def test_numref_with_prefix2(app, status, warning):
|
||||
assert '\\hyperref[baz:table22]{Table:\\ref{baz:table22}}' in result
|
||||
assert '\\hyperref[index:code-1]{Code-\\ref{index:code-1} \\textbar{} }' in result
|
||||
assert '\\hyperref[baz:code22]{Code-\\ref{baz:code22}}' in result
|
||||
assert '\\hyperref[foo:foo]{SECTION\\_\\ref{foo:foo}\\_}' in result
|
||||
assert '\\hyperref[bar:bar-a]{SECTION\\_\\ref{bar:bar-a}\\_}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
@ -222,6 +230,8 @@ def test_numref_with_language_ja(app, status, warning):
|
||||
assert '\\hyperref[baz:table22]{Table:\\ref{baz:table22}}' in result
|
||||
assert '\\hyperref[index:code-1]{LIST \\ref{index:code-1}}' in result
|
||||
assert '\\hyperref[baz:code22]{Code-\\ref{baz:code22}}' in result
|
||||
assert '\\hyperref[foo:foo]{Section \\ref{foo:foo}}' in result
|
||||
assert '\\hyperref[bar:bar-a]{Section \\ref{bar:bar-a}}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
|
Loading…
Reference in New Issue
Block a user