diff --git a/sphinx/application.py b/sphinx/application.py index c17cbb617..cee780c9c 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -29,7 +29,7 @@ from docutils.parsers.rst import convert_directive_function, \ import sphinx from sphinx import package_dir, locale from sphinx.roles import XRefRole -from sphinx.config import Config, convert_numfig_format +from sphinx.config import Config from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \ VersionRequirementError, ConfigError from sphinx.domains import ObjType @@ -236,7 +236,6 @@ class Sphinx(object): self._init_i18n() # check all configuration values for permissible types self.config.check_types(self.warn) - self._post_init_config() # set up source_parsers self._init_source_parsers() # set up the build environment @@ -271,9 +270,6 @@ class Sphinx(object): else: self.info('not available for built-in messages') - def _post_init_config(self): - convert_numfig_format(self.config) - def _init_source_parsers(self): for suffix, parser in iteritems(self._additional_source_parsers): if suffix not in self.config.source_suffix: diff --git a/sphinx/config.py b/sphinx/config.py index a5761e349..61516a1ff 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -289,12 +289,3 @@ class Config(object): def __contains__(self, name): return name in self.values - - -def convert_numfig_format(config): - """ Convert numfi_format to new one. """ - - numfig_format = {} - for figtype, fmt in iteritems(config.numfig_format): - numfig_format[figtype] = fmt.replace('%s', '{number}') - config.numfig_format = numfig_format diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index f83afdab1..b7f2597d4 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -673,18 +673,20 @@ class StandardDomain(Domain): else: title = env.config.numfig_format.get(figtype, '') - # convert old styled numfig_format to new style - title = title.replace('%s', '{number}') - - if figname is None and '{name}' in title: + 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 figname: - newtitle = title.format(name=figname, number=fignum) + 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: - newtitle = title.format(number=fignum) + # 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 diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py index 861026b55..0a3192f6a 100644 --- a/sphinx/util/texescape.py +++ b/sphinx/util/texescape.py @@ -118,17 +118,10 @@ tex_replacements = [ ('Ω', r'\(\Omega\)'), ('Ω', r'\(\Omega\)'), ] -tex_pyformats = [ - # map special chars of str.format() to escaped one - ('{', '{{'), - ('}', '}}'), -] - tex_escape_map = {} tex_replace_map = {} tex_hl_escape_map_new = {} -tex_pyformat_map = {} def init(): @@ -140,6 +133,3 @@ def init(): if a in '[]{}\\': continue tex_hl_escape_map_new[ord(a)] = b - - for a, b in tex_pyformats: - tex_pyformat_map[ord(a)] = b diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 7dd286cf7..ba2b758d8 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -291,7 +291,7 @@ class HTMLTranslator(BaseTranslator): self.builder.warn(msg) else: numbers = self.builder.fignumbers[key][figure_id] - self.body.append(prefix.format(number='.'.join(map(str, numbers))) + ' ') + self.body.append(prefix % '.'.join(map(str, numbers)) + ' ') self.body.append('') figtype = self.builder.env.domains['std'].get_figtype(node) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 0a158297b..ca0f1a7dd 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -29,7 +29,7 @@ from sphinx.util import split_into from sphinx.util.i18n import format_date from sphinx.util.nodes import clean_astext, traverse_parent from sphinx.util.template import LaTeXRenderer -from sphinx.util.texescape import tex_escape_map, tex_replace_map, tex_pyformat_map +from sphinx.util.texescape import tex_escape_map, tex_replace_map from sphinx.util.smartypants import educate_quotes_latex @@ -610,7 +610,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def generate_numfig_format(self, builder): ret = [] - figure = self.builder.config.numfig_format['figure'].split('{number}', 1) + figure = self.builder.config.numfig_format['figure'].split('%s', 1) if len(figure) == 1: ret.append('\\def\\fnum@figure{%s}\n' % escape_abbr(text_type(figure[0]).translate(tex_escape_map))) @@ -623,7 +623,7 @@ class LaTeXTranslator(nodes.NodeVisitor): escape_abbr(text_type(figure[1]).translate(tex_escape_map))) ret.append('\\makeatother\n') - table = self.builder.config.numfig_format['table'].split('{number}', 1) + table = self.builder.config.numfig_format['table'].split('%s', 1) if len(table) == 1: ret.append('\\def\\fnum@table{%s}\n' % escape_abbr(text_type(table[0]).translate(tex_escape_map))) @@ -636,7 +636,7 @@ class LaTeXTranslator(nodes.NodeVisitor): escape_abbr(text_type(table[1]).translate(tex_escape_map))) ret.append('\\makeatother\n') - codeblock = self.builder.config.numfig_format['code-block'].split('{number}', 1) + codeblock = self.builder.config.numfig_format['code-block'].split('%s', 1) if len(codeblock) == 1: pass # FIXME else: @@ -1789,11 +1789,16 @@ class LaTeXTranslator(nodes.NodeVisitor): else: id = node.get('refuri', '')[1:].replace('#', ':') - title = node.get('title', '{number}').replace('%s', '{number}') - title = text_type(title).translate(tex_escape_map).translate(tex_pyformat_map) - 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)) + title = node.get('title', '%s') + title = text_type(title).translate(tex_escape_map).replace('\\%s', '%s') + 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) diff --git a/tests/roots/test-numfig/index.rst b/tests/roots/test-numfig/index.rst index 499a1b7dc..939903839 100644 --- a/tests/roots/test-numfig/index.rst +++ b/tests/roots/test-numfig/index.rst @@ -53,5 +53,7 @@ test-tocdepth * Section.1 is :numref:`foo` * Section.2.1 is :numref:`bar_a` * Unnumbered section is :numref:`index` +* Invalid numfig_format 01: :numref:`invalid ` +* Invalid numfig_format 02: :numref:`Fig %s %s ` * Fig.1 is :numref:`Fig.{number} {name} ` * Section.1 is :numref:`Sect.{number} {name} ` diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 176590f75..d8aff88ab 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -506,6 +506,8 @@ def test_numfig_disabled(app, status, warning): 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': [ @@ -568,6 +570,8 @@ def test_numfig_without_numbered_toctree(app, status, warning): 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': [ @@ -666,6 +670,8 @@ def test_numfig_with_numbered_toctree(app, status, warning): 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': [ @@ -768,6 +774,8 @@ def test_numfig_with_prefix(app, status, warning): 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': [ @@ -866,6 +874,8 @@ def test_numfig_with_secnum_depth(app, status, warning): 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': [