Add `config-inited` event

This commit is contained in:
Takeshi KOMIYA 2016-11-17 12:42:43 +09:00
parent 5a606ee96a
commit 9569c6dbff
8 changed files with 41 additions and 37 deletions

View File

@ -29,7 +29,7 @@ from docutils.parsers.rst import convert_directive_function, \
import sphinx import sphinx
from sphinx import package_dir, locale from sphinx import package_dir, locale
from sphinx.roles import XRefRole from sphinx.roles import XRefRole
from sphinx.config import Config from sphinx.config import Config, convert_numfig_format
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \ from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
VersionRequirementError, ConfigError VersionRequirementError, ConfigError
from sphinx.domains import ObjType from sphinx.domains import ObjType
@ -236,6 +236,7 @@ class Sphinx(object):
self._init_i18n() self._init_i18n()
# check all configuration values for permissible types # check all configuration values for permissible types
self.config.check_types(self.warn) self.config.check_types(self.warn)
self._post_init_config()
# set up source_parsers # set up source_parsers
self._init_source_parsers() self._init_source_parsers()
# set up the build environment # set up the build environment
@ -270,6 +271,9 @@ class Sphinx(object):
else: else:
self.info('not available for built-in messages') self.info('not available for built-in messages')
def _post_init_config(self):
convert_numfig_format(self.config)
def _init_source_parsers(self): def _init_source_parsers(self):
for suffix, parser in iteritems(self._additional_source_parsers): for suffix, parser in iteritems(self._additional_source_parsers):
if suffix not in self.config.source_suffix: if suffix not in self.config.source_suffix:

View File

@ -286,3 +286,12 @@ class Config(object):
def __contains__(self, name): def __contains__(self, name):
return name in self.values 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

View File

@ -673,20 +673,18 @@ class StandardDomain(Domain):
else: else:
title = env.config.numfig_format.get(figtype, '') title = env.config.numfig_format.get(figtype, '')
if figname is None and '%{name}' in title: # convert old styled numfig_format to new style
title = title.replace('%s', '{number}')
if figname is None and '{name}' in title:
env.warn_node('the link has no caption: %s' % title, node) env.warn_node('the link has no caption: %s' % title, node)
return contnode return contnode
else: else:
fignum = '.'.join(map(str, fignumber)) fignum = '.'.join(map(str, fignumber))
if '{name}' in title or 'number' in title:
# new style format (cf. "Fig.%{number}")
if figname: if figname:
newtitle = title.format(name=figname, number=fignum) newtitle = title.format(name=figname, number=fignum)
else: else:
newtitle = title.format(number=fignum) newtitle = title.format(number=fignum)
else:
# old style format (cf. "Fig.%s")
newtitle = title % fignum
except KeyError as exc: except KeyError as exc:
env.warn_node('invalid numfig_format: %s (%r)' % (title, exc), node) env.warn_node('invalid numfig_format: %s (%r)' % (title, exc), node)
return contnode return contnode

View File

@ -118,10 +118,17 @@ tex_replacements = [
('Ω', r'\(\Omega\)'), ('Ω', r'\(\Omega\)'),
('', r'\(\Omega\)'), ('', r'\(\Omega\)'),
] ]
tex_pyformats = [
# map special chars of str.format() to escaped one
('{', '{{'),
('}', '}}'),
]
tex_escape_map = {} tex_escape_map = {}
tex_replace_map = {} tex_replace_map = {}
tex_hl_escape_map_new = {} tex_hl_escape_map_new = {}
tex_pyformat_map = {}
def init(): def init():
@ -133,3 +140,6 @@ def init():
if a in '[]{}\\': if a in '[]{}\\':
continue continue
tex_hl_escape_map_new[ord(a)] = b tex_hl_escape_map_new[ord(a)] = b
for a, b in tex_pyformats:
tex_pyformat_map[ord(a)] = b

View File

@ -291,7 +291,7 @@ class HTMLTranslator(BaseTranslator):
self.builder.warn(msg) self.builder.warn(msg)
else: else:
numbers = self.builder.fignumbers[key][figure_id] numbers = self.builder.fignumbers[key][figure_id]
self.body.append(prefix % '.'.join(map(str, numbers)) + ' ') self.body.append(prefix.format(number='.'.join(map(str, numbers))) + ' ')
self.body.append('</span>') self.body.append('</span>')
figtype = self.builder.env.domains['std'].get_figtype(node) figtype = self.builder.env.domains['std'].get_figtype(node)

View File

@ -29,7 +29,7 @@ from sphinx.util import split_into
from sphinx.util.i18n import format_date from sphinx.util.i18n import format_date
from sphinx.util.nodes import clean_astext, traverse_parent from sphinx.util.nodes import clean_astext, traverse_parent
from sphinx.util.template import LaTeXRenderer from sphinx.util.template import LaTeXRenderer
from sphinx.util.texescape import tex_escape_map, tex_replace_map from sphinx.util.texescape import tex_escape_map, tex_replace_map, tex_pyformat_map
from sphinx.util.smartypants import educate_quotes_latex from sphinx.util.smartypants import educate_quotes_latex
@ -610,7 +610,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
def generate_numfig_format(self, builder): def generate_numfig_format(self, builder):
ret = [] ret = []
figure = self.builder.config.numfig_format['figure'].split('%s', 1) figure = self.builder.config.numfig_format['figure'].split('{number}', 1)
if len(figure) == 1: if len(figure) == 1:
ret.append('\\def\\fnum@figure{%s}\n' % ret.append('\\def\\fnum@figure{%s}\n' %
escape_abbr(text_type(figure[0]).translate(tex_escape_map))) 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))) escape_abbr(text_type(figure[1]).translate(tex_escape_map)))
ret.append('\\makeatother\n') ret.append('\\makeatother\n')
table = self.builder.config.numfig_format['table'].split('%s', 1) table = self.builder.config.numfig_format['table'].split('{number}', 1)
if len(table) == 1: if len(table) == 1:
ret.append('\\def\\fnum@table{%s}\n' % ret.append('\\def\\fnum@table{%s}\n' %
escape_abbr(text_type(table[0]).translate(tex_escape_map))) 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))) escape_abbr(text_type(table[1]).translate(tex_escape_map)))
ret.append('\\makeatother\n') ret.append('\\makeatother\n')
codeblock = self.builder.config.numfig_format['code-block'].split('%s', 1) codeblock = self.builder.config.numfig_format['code-block'].split('{number}', 1)
if len(codeblock) == 1: if len(codeblock) == 1:
pass # FIXME pass # FIXME
else: else:
@ -1789,16 +1789,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
else: else:
id = node.get('refuri', '')[1:].replace('#', ':') id = node.get('refuri', '')[1:].replace('#', ':')
title = node.get('title', '%s') title = node.get('title', '{number}').replace('%s', '{number}')
title = text_type(title).translate(tex_escape_map).replace('\\%s', '%s') title = text_type(title).translate(tex_escape_map).translate(tex_pyformat_map)
if '\\{name\\}' in title or '\\{number\\}' in title: title = title.replace('\\{{name\\}}', '{name}').replace('\\{{number\\}}', '{number}')
# 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), text = escape_abbr(title).format(name='\\nameref{%s}' % self.idescape(id),
number='\\ref{%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) hyperref = '\\hyperref[%s]{%s}' % (self.idescape(id), text)
self.body.append(hyperref) self.body.append(hyperref)

View File

@ -53,7 +53,5 @@ test-tocdepth
* Section.1 is :numref:`foo` * Section.1 is :numref:`foo`
* Section.2.1 is :numref:`bar_a` * Section.2.1 is :numref:`bar_a`
* Unnumbered section is :numref:`index` * 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>` * Fig.1 is :numref:`Fig.{number} {name} <fig1>`
* Section.1 is :numref:`Sect.{number} {name} <foo>` * Section.1 is :numref:`Sect.{number} {name} <foo>`

View File

@ -506,8 +506,6 @@ def test_numfig_disabled(app, status, warning):
warnings = warning.getvalue() warnings = warning.getvalue()
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' in warnings 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: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 = { expects = {
'index.html': [ 'index.html': [
@ -570,8 +568,6 @@ def test_numfig_without_numbered_toctree(app, status, warning):
warnings = warning.getvalue() warnings = warning.getvalue()
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings 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: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 = { expects = {
'index.html': [ 'index.html': [
@ -670,8 +666,6 @@ def test_numfig_with_numbered_toctree(app, status, warning):
warnings = warning.getvalue() warnings = warning.getvalue()
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings 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: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 = { expects = {
'index.html': [ 'index.html': [
@ -774,8 +768,6 @@ def test_numfig_with_prefix(app, status, warning):
warnings = warning.getvalue() warnings = warning.getvalue()
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings 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: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 = { expects = {
'index.html': [ 'index.html': [
@ -874,8 +866,6 @@ def test_numfig_with_secnum_depth(app, status, warning):
warnings = warning.getvalue() warnings = warning.getvalue()
assert 'index.rst:47: WARNING: numfig is disabled. :numref: is ignored.' not in warnings 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: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 = { expects = {
'index.html': [ 'index.html': [