Fix #2916: numref role can also refer caption as an its linktext

This commit is contained in:
Takeshi KOMIYA 2016-09-17 14:58:43 +09:00
parent 1aafc7e2e5
commit 2b10fc0188
8 changed files with 65 additions and 10 deletions

View File

@ -119,6 +119,7 @@ Features added
* #2695: ``build_sphinx`` subcommand for setuptools handles exceptions as same
as ``sphinx-build`` does
* #326: `numref` role can also refer sections
* #2916: `numref` role can also refer caption as an its linktext
Bugs fixed
----------

View File

@ -295,14 +295,18 @@ General configuration
.. confval:: numfig_format
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'``.
``'section'`` to strings that are used for format of figure numbers.
As a special character, `%s` and `{number}` will be replaced to figure
number. `{name}` will be replaced to figure caption.
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
Support format of section. Allow to refer the caption of figures.
.. confval:: numfig_secnum_depth

View File

@ -213,7 +213,7 @@ Cross-referencing figures by figure number
.. versionadded:: 1.3
.. versionchanged:: 1.5
`numref` role can also refer sections
`numref` role can also refer sections.
.. rst:role:: numref
@ -223,7 +223,7 @@ Cross-referencing figures by figure number
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.
As a special character, `%s` will be replaced to figure number.
The format of link text is same as :confval:`numfig_format`.
If :confval:`numfig` is ``False``, figures are not numbered.
so this role inserts not a reference but labels or link text.

View File

@ -639,7 +639,12 @@ class StandardDomain(Domain):
docname, labelid, sectname, 'ref')
def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
if target in self.data['labels']:
docname, labelid, figname = self.data['labels'].get(target, ('', '', ''))
else:
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
figname = None
if not docname:
return None
@ -666,7 +671,23 @@ class StandardDomain(Domain):
else:
title = env.config.numfig_format.get(figtype, '')
newtitle = title % '.'.join(map(str, fignumber))
if figname is None and '%{name}' in title:
env.warn_node('the link has no caption: %s' % title, node)
return contnode
else:
fignum = '.'.join(map(str, fignumber))
if '{name}' in title or 'number' in title:
# new style format (cf. "Fig.%{number}")
if figname:
newtitle = title.format(name=figname, number=fignum)
else:
newtitle = title.format(number=fignum)
else:
# old style format (cf. "Fig.%s")
newtitle = title % fignum
except KeyError as exc:
env.warn_node('invalid numfig_format: %s (%r)' % (title, exc), node)
return contnode
except TypeError:
env.warn_node('invalid numfig_format: %s' % title, node)
return contnode

View File

@ -1696,10 +1696,17 @@ class LaTeXTranslator(nodes.NodeVisitor):
else:
id = node.get('refuri', '')[1:].replace('#', ':')
ref = '\\ref{%s}' % self.idescape(id)
title = node.get('title', '%s')
title = text_type(title).translate(tex_escape_map).replace('\\%s', '%s')
hyperref = '\\hyperref[%s]{%s}' % (self.idescape(id), escape_abbr(title) % ref)
if '\\{name\\}' in title or '\\{number\\}' in title:
# new style format (cf. "Fig.%{number}")
title = title.replace('\\{name\\}', '{name}').replace('\\{number\\}', '{number}')
text = escape_abbr(title).format(name='\\nameref{%s}' % self.idescape(id),
number='\\ref{%s}' % self.idescape(id))
else:
# old style format (cf. "Fig.%{number}")
text = escape_abbr(title) % ('\\ref{%s}' % self.idescape(id))
hyperref = '\\hyperref[%s]{%s}' % (self.idescape(id), text)
self.body.append(hyperref)
raise nodes.SkipNode

View File

@ -55,3 +55,5 @@ test-tocdepth
* Unnumbered section is :numref:`index`
* Invalid numfig_format 01: :numref:`invalid <fig1>`
* Invalid numfig_format 02: :numref:`Fig %s %s <fig1>`
* Fig.1 is :numref:`Fig.{number} {name} <fig1>`
* Section.1 is :numref:`Sect.{number} {name} <foo>`

View File

@ -524,6 +524,8 @@ def test_numfig_disabled(app, status, warning):
(".//li/code/span", '^Code-%s$', True),
(".//li/code/span", '^foo$', True),
(".//li/code/span", '^bar_a$', True),
(".//li/code/span", '^Fig.{number}$', True),
(".//li/code/span", '^Sect.{number}$', True),
],
'foo.html': [
(".//div[@class='figure']/p[@class='caption']/"
@ -593,6 +595,8 @@ def test_numfig_without_numbered_toctree(app, status, warning):
(".//li/a/span", '^Code-6$', True),
(".//li/code/span", '^foo$', True),
(".//li/code/span", '^bar_a$', True),
(".//li/a/span", '^Fig.9 should be Fig.1$', True),
(".//li/code/span", '^Sect.{number}$', True),
],
'foo.html': [
(".//div[@class='figure']/p[@class='caption']/"
@ -691,6 +695,8 @@ def test_numfig_with_numbered_toctree(app, status, warning):
(".//li/a/span", '^Code-2.2$', True),
(".//li/a/span", '^Section.1$', True),
(".//li/a/span", '^Section.2.1$', True),
(".//li/a/span", '^Fig.1 should be Fig.1$', True),
(".//li/a/span", '^Sect.1 Foo$', True),
],
'foo.html': [
(".//div[@class='figure']/p[@class='caption']/"
@ -793,6 +799,8 @@ def test_numfig_with_prefix(app, status, warning):
(".//li/a/span", '^Code-2.2$', True),
(".//li/a/span", '^SECTION-1$', True),
(".//li/a/span", '^SECTION-2.1$', True),
(".//li/a/span", '^Fig.1 should be Fig.1$', True),
(".//li/a/span", '^Sect.1 Foo$', True),
],
'foo.html': [
(".//div[@class='figure']/p[@class='caption']/"
@ -891,6 +899,8 @@ def test_numfig_with_secnum_depth(app, status, warning):
(".//li/a/span", '^Code-2.1.2$', True),
(".//li/a/span", '^Section.1$', True),
(".//li/a/span", '^Section.2.1$', True),
(".//li/a/span", '^Fig.1 should be Fig.1$', True),
(".//li/a/span", '^Sect.1 Foo$', True),
],
'foo.html': [
(".//div[@class='figure']/p[@class='caption']/"
@ -983,6 +993,8 @@ def test_numfig_with_singlehtml(app, status, warning):
(".//li/a/span", '^Code-2.2$', True),
(".//li/a/span", '^Section.1$', True),
(".//li/a/span", '^Section.2.1$', True),
(".//li/a/span", '^Fig.1 should be Fig.1$', True),
(".//li/a/span", '^Sect.1 Foo$', True),
(".//div[@class='figure']/p[@class='caption']/"
"span[@class='caption-number']", '^Fig. 1.1 $', True),
(".//div[@class='figure']/p[@class='caption']/"

View File

@ -153,6 +153,8 @@ def test_numref(app, status, warning):
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
assert '\\hyperref[index:fig1]{Fig.\\ref{index:fig1} \\nameref{index:fig1}}' in result
assert '\\hyperref[foo:foo]{Sect.\\ref{foo:foo} \\nameref{foo:foo}}' in result
@with_app(buildername='latex', testroot='numfig',
@ -184,6 +186,8 @@ def test_numref_with_prefix1(app, status, warning):
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
assert '\\hyperref[index:fig1]{Fig.\\ref{index:fig1} \\nameref{index:fig1}}' in result
assert '\\hyperref[foo:foo]{Sect.\\ref{foo:foo} \\nameref{foo:foo}}' in result
@with_app(buildername='latex', testroot='numfig',
@ -211,6 +215,8 @@ def test_numref_with_prefix2(app, status, warning):
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
assert '\\hyperref[index:fig1]{Fig.\\ref{index:fig1} \\nameref{index:fig1}}' in result
assert '\\hyperref[foo:foo]{Sect.\\ref{foo:foo} \\nameref{foo:foo}}' in result
@with_app(buildername='latex', testroot='numfig',
@ -232,6 +238,8 @@ def test_numref_with_language_ja(app, status, warning):
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
assert '\\hyperref[index:fig1]{Fig.\\ref{index:fig1} \\nameref{index:fig1}}' in result
assert '\\hyperref[foo:foo]{Sect.\\ref{foo:foo} \\nameref{foo:foo}}' in result
@with_app(buildername='latex')