Merge branch 'stable'

This commit is contained in:
Takeshi KOMIYA 2017-10-16 21:03:38 +09:00
commit 3369d9a03a
7 changed files with 101 additions and 32 deletions

View File

@ -96,6 +96,9 @@ Features added
* #4107: Make searchtools.js compatible with pre-Sphinx1.5 templates
* #4112: Don't override the smart_quotes setting if it was already set
* #4125: Display reference texts of original and translated passages on
i18n warning message
* #4147: Include the exception when logging PO/MO file read/write
Bugs fixed
----------
@ -106,6 +109,8 @@ Bugs fixed
* #4096: C++, don't crash when using the wrong role type. Thanks to mitya57.
* #4070, #4111: crashes when the warning message contains format strings (again)
* #4108: Search word highlighting breaks SVG images
* #3692: Unable to build HTML if writing .buildinfo failed
* #4152: HTML writer crashes if a field list is placed on top of the document
Testing
--------

View File

@ -776,12 +776,15 @@ class StandaloneHTMLBuilder(Builder):
def write_buildinfo(self):
# type: () -> None
# write build info file
with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
fp.write('# Sphinx build info version 1\n'
'# This file hashes the configuration used when building'
' these files. When it is not found, a full rebuild will'
' be done.\nconfig: %s\ntags: %s\n' %
(self.config_hash, self.tags_hash))
try:
with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
fp.write('# Sphinx build info version 1\n'
'# This file hashes the configuration used when building'
' these files. When it is not found, a full rebuild will'
' be done.\nconfig: %s\ntags: %s\n' %
(self.config_hash, self.tags_hash))
except IOError as exc:
logger.warning('Failed to write build info file: %r', exc)
def cleanup(self):
# type: () -> None

View File

@ -273,7 +273,11 @@ class Locale(SphinxTransform):
old_foot_refs = node.traverse(is_autonumber_footnote_ref)
new_foot_refs = patch.traverse(is_autonumber_footnote_ref)
if len(old_foot_refs) != len(new_foot_refs):
logger.warning('inconsistent footnote references in translated message',
old_foot_ref_rawsources = [ref.rawsource for ref in old_foot_refs]
new_foot_ref_rawsources = [ref.rawsource for ref in new_foot_refs]
logger.warning('inconsistent footnote references in translated message.' +
' original: {0}, translated: {1}'
.format(old_foot_ref_rawsources, new_foot_ref_rawsources),
location=node)
old_foot_namerefs = {} # type: Dict[unicode, List[nodes.footnote_reference]]
for r in old_foot_refs:
@ -309,7 +313,11 @@ class Locale(SphinxTransform):
old_refs = node.traverse(is_refnamed_ref)
new_refs = patch.traverse(is_refnamed_ref)
if len(old_refs) != len(new_refs):
logger.warning('inconsistent references in translated message',
old_ref_rawsources = [ref.rawsource for ref in old_refs]
new_ref_rawsources = [ref.rawsource for ref in new_refs]
logger.warning('inconsistent references in translated message.' +
' original: {0}, translated: {1}'
.format(old_ref_rawsources, new_ref_rawsources),
location=node)
old_ref_names = [r['refname'] for r in old_refs]
new_ref_names = [r['refname'] for r in new_refs]
@ -327,22 +335,46 @@ class Locale(SphinxTransform):
self.document.note_refname(new)
# refnamed footnote and citation should use original 'ids'.
# refnamed footnote should use original 'ids'.
def is_refnamed_footnote_ref(node):
# type: (nodes.Node) -> bool
footnote_ref_classes = (nodes.footnote_reference,
nodes.citation_reference)
return isinstance(node, footnote_ref_classes) and \
return isinstance(node, nodes.footnote_reference) and \
'refname' in node
old_refs = node.traverse(is_refnamed_footnote_ref)
new_refs = patch.traverse(is_refnamed_footnote_ref)
old_foot_refs = node.traverse(is_refnamed_footnote_ref)
new_foot_refs = patch.traverse(is_refnamed_footnote_ref)
refname_ids_map = {}
if len(old_refs) != len(new_refs):
logger.warning('inconsistent references in translated message',
if len(old_foot_refs) != len(new_foot_refs):
old_foot_ref_rawsources = [ref.rawsource for ref in old_foot_refs]
new_foot_ref_rawsources = [ref.rawsource for ref in new_foot_refs]
logger.warning('inconsistent footnote references in translated message.' +
' original: {0}, translated: {1}'
.format(old_foot_ref_rawsources, new_foot_ref_rawsources),
location=node)
for old in old_refs:
for old in old_foot_refs:
refname_ids_map[old["refname"]] = old["ids"]
for new in new_refs:
for new in new_foot_refs:
refname = new["refname"]
if refname in refname_ids_map:
new["ids"] = refname_ids_map[refname]
# citation should use original 'ids'.
def is_citation_ref(node):
# type: (nodes.Node) -> bool
return isinstance(node, nodes.citation_reference) and \
'refname' in node
old_cite_refs = node.traverse(is_citation_ref)
new_cite_refs = patch.traverse(is_citation_ref)
refname_ids_map = {}
if len(old_cite_refs) != len(new_cite_refs):
old_cite_ref_rawsources = [ref.rawsource for ref in old_cite_refs]
new_cite_ref_rawsources = [ref.rawsource for ref in new_cite_refs]
logger.warning('inconsistent citation references in translated message.' +
' original: {0}, translated: {1}'
.format(old_cite_ref_rawsources, new_cite_ref_rawsources),
location=node)
for old in old_cite_refs:
refname_ids_map[old["refname"]] = old["ids"]
for new in new_cite_refs:
refname = new["refname"]
if refname in refname_ids_map:
new["ids"] = refname_ids_map[refname]
@ -354,7 +386,11 @@ class Locale(SphinxTransform):
new_refs = patch.traverse(addnodes.pending_xref)
xref_reftarget_map = {}
if len(old_refs) != len(new_refs):
logger.warning('inconsistent term references in translated message',
old_ref_rawsources = [ref.rawsource for ref in old_refs]
new_ref_rawsources = [ref.rawsource for ref in new_refs]
logger.warning('inconsistent term references in translated message.' +
' original: {0}, translated: {1}'
.format(old_ref_rawsources, new_ref_rawsources),
location=node)
def get_ref_key(node):

View File

@ -89,6 +89,7 @@ class HTMLTranslator(BaseTranslator):
self.param_separator = ''
self.optional_param_level = 0
self._table_row_index = 0
self._fieldlist_row_index = 0
self.required_params_left = 0
def visit_start_of_file(self, node):

View File

@ -19,8 +19,8 @@ msgstr ""
msgid "i18n with refs inconsistency"
msgstr "I18N WITH REFS INCONSISTENCY"
msgid "[100]_ for [#]_ footnote [ref2]_."
msgstr "FOR FOOTNOTE [ref2]_."
msgid "[100]_ for [#]_ citation [ref2]_."
msgstr "FOR CITATION [ref3]_."
msgid "for reference_."
msgstr "reference_ FOR reference_."
@ -31,8 +31,8 @@ msgstr "ORPHAN REFERENCE: `I18N WITH REFS INCONSISTENCY`_."
msgid "This is a auto numbered footnote."
msgstr "THIS IS A AUTO NUMBERED FOOTNOTE."
msgid "This is a named footnote."
msgstr "THIS IS A NAMED FOOTNOTE."
msgid "This is a citation."
msgstr "THIS IS A CITATION."
msgid "This is a numbered footnote."
msgstr "THIS IS A NUMBERED FOOTNOTE."

View File

@ -3,11 +3,11 @@
i18n with refs inconsistency
=============================
* [100]_ for [#]_ footnote [ref2]_.
* [100]_ for [#]_ citation [ref2]_.
* for reference_.
* normal text.
.. [#] This is a auto numbered footnote.
.. [ref2] This is a named footnote.
.. [ref2] This is a citation.
.. [100] This is a numbered footnote.
.. _reference: http://www.example.com

View File

@ -182,23 +182,45 @@ def test_text_inconsistency_warnings(app, warning):
result = (app.outdir / 'refs_inconsistency.txt').text(encoding='utf-8')
expect = (u"I18N WITH REFS INCONSISTENCY"
u"\n****************************\n"
u"\n* FOR FOOTNOTE [ref2].\n"
u"\n* FOR CITATION [ref3].\n"
u"\n* reference FOR reference.\n"
u"\n* ORPHAN REFERENCE: I18N WITH REFS INCONSISTENCY.\n"
u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n"
u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n"
u"\n[ref2] THIS IS A CITATION.\n"
u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n")
assert result == expect
warnings = getwarning(warning)
warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \
u'WARNING: inconsistent %s in translated message\n'
u'WARNING: inconsistent %(reftype)s in translated message.' \
u' original: %(original)s, translated: %(translated)s\n'
expected_warning_expr = (
warning_fmt % 'footnote references' +
warning_fmt % 'references' +
warning_fmt % 'references')
warning_fmt % {
u'reftype': u'footnote references',
u'original': u"\[u?'\[#\]_'\]",
u'translated': u"\[\]"
} +
warning_fmt % {
u'reftype': u'footnote references',
u'original': u"\[u?'\[100\]_'\]",
u'translated': u"\[\]"
} +
warning_fmt % {
u'reftype': u'references',
u'original': u"\[u?'reference_'\]",
u'translated': u"\[u?'reference_', u?'reference_'\]"
} +
warning_fmt % {
u'reftype': u'references',
u'original': u"\[\]",
u'translated': u"\[u?'`I18N WITH REFS INCONSISTENCY`_'\]"
})
assert_re_search(expected_warning_expr, warnings)
expected_citation_warning_expr = (
u'.*/refs_inconsistency.txt:\\d+: WARNING: Citation \[ref2\] is not referenced.\n' +
u'.*/refs_inconsistency.txt:\\d+: WARNING: citation not found: ref3')
assert_re_search(expected_citation_warning_expr, warnings)
@sphinx_intl
@pytest.mark.sphinx('text')
@ -277,7 +299,9 @@ def test_text_glossary_term_inconsistencies(app, warning):
warnings = getwarning(warning)
expected_warning_expr = (
u'.*/glossary_terms_inconsistency.txt:\\d+: '
u'WARNING: inconsistent term references in translated message\n')
u'WARNING: inconsistent term references in translated message.'
u" original: \[u?':term:`Some term`', u?':term:`Some other term`'\],"
u" translated: \[u?':term:`SOME NEW TERM`'\]\n")
assert_re_search(expected_warning_expr, warnings)