Merged in knzm/sphinx-fix-docfields-fork (pull request #96)

make docfield translatable
This commit is contained in:
Takayuki Shimizukawa 2013-02-24 19:05:15 +09:00
commit fffde7817d
8 changed files with 153 additions and 7 deletions

View File

@ -45,7 +45,8 @@ from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import _
from sphinx.versioning import add_uids, merge_doctrees
from sphinx.transforms import DefaultSubstitutions, MoveModuleTargets, \
HandleCodeBlocks, SortIds, CitationReferences, Locale, SphinxContentsFilter
HandleCodeBlocks, SortIds, CitationReferences, Locale, \
RemoveTranslatableInline, SphinxContentsFilter
orig_role_function = roles.role
@ -90,7 +91,8 @@ class SphinxStandaloneReader(standalone.Reader):
Add our own transforms.
"""
transforms = [Locale, CitationReferences, DefaultSubstitutions,
MoveModuleTargets, HandleCodeBlocks, SortIds]
MoveModuleTargets, HandleCodeBlocks, SortIds,
RemoveTranslatableInline]
def get_transforms(self):
return standalone.Reader.get_transforms(self) + self.transforms

View File

@ -305,6 +305,24 @@ class Locale(Transform):
node['entries'] = new_entries
class RemoveTranslatableInline(Transform):
"""
Remove inline nodes used for translation as placeholders.
"""
default_priority = 999
def apply(self):
from sphinx.builders.gettext import MessageCatalogBuilder
env = self.document.settings.env
builder = env.app.builder
if isinstance(builder, MessageCatalogBuilder):
return
for inline in self.document.traverse(nodes.inline):
if 'translatable' in inline:
inline.parent.remove(inline)
inline.parent += inline.children
class SphinxContentsFilter(ContentsFilter):
"""
Used with BuildEnvironment.add_toc_from() to discard cross-file links

View File

@ -67,7 +67,7 @@ class Field(object):
fieldname += nodes.Text(' ')
fieldname += self.make_xref(self.rolename, domain,
fieldarg, nodes.Text)
fieldbody = nodes.field_body('', nodes.paragraph('', '', *content))
fieldbody = nodes.field_body('', nodes.paragraph('', '', content))
return nodes.field('', fieldname, fieldbody)
@ -255,6 +255,12 @@ class DocFieldTransformer(object):
[nodes.Text(argtype)]
fieldarg = argname
translatable_content = nodes.inline(fieldbody.rawsource,
translatable=True)
translatable_content.source = fieldbody.parent.source
translatable_content.line = fieldbody.parent.line
translatable_content += content
# grouped entries need to be collected in one entry, while others
# get one entry per field
if typedesc.is_grouped:
@ -264,10 +270,11 @@ class DocFieldTransformer(object):
groupindices[typename] = len(entries)
group = [typedesc, []]
entries.append(group)
group[1].append(typedesc.make_entry(fieldarg, content))
entry = typedesc.make_entry(fieldarg, translatable_content)
group[1].append(entry)
else:
entries.append([typedesc,
typedesc.make_entry(fieldarg, content)])
entry = typedesc.make_entry(fieldarg, translatable_content)
entries.append([typedesc, entry])
# step 2: all entries are collected, construct the new field list
new_list = nodes.field_list()

View File

@ -61,7 +61,7 @@ def extract_messages(doctree):
if not node.source:
continue # built-in message
if isinstance(node, IGNORED_NODES):
if isinstance(node, IGNORED_NODES) and 'translatable' not in node:
continue
# <field_name>orphan</field_name>
# XXX ignore all metadata (== docinfo)

View File

@ -19,3 +19,4 @@ CONTENTS
role_xref
glossary_terms
glossary_terms_inconsistency
docfields

View File

@ -0,0 +1,39 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2010, Georg Brandl & Team
# This file is distributed under the same license as the Sphinx <Tests> package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Sphinx <Tests> 0.6\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-12-16 14:11\n"
"PO-Revision-Date: 2012-12-18 06:14+0900\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "i18n with docfields"
msgstr "I18N WITH DOCFIELDS"
msgid "description of parameter param"
msgstr "DESCRIPTION OF PARAMETER param"
msgid "description of parameter foo"
msgstr "DESCRIPTION OF PARAMETER foo"
msgid "description of parameter bar"
msgstr "DESCRIPTION OF PARAMETER bar"
msgid "if the values are not valid"
msgstr "IF THE VALUES ARE NOT VALID"
msgid "if the values are out of range"
msgstr "IF THE VALUES ARE OUT OF RANGE"
msgid "a new :class:`Cls3` instance"
msgstr "A NEW :class:`Cls3` INSTANCE"

View File

@ -0,0 +1,46 @@
:tocdepth: 2
i18n with docfields
===================
.. single TypedField
.. class:: Cls1
:noindex:
:param param: description of parameter param
.. grouped TypedFields
.. class:: Cls2
:noindex:
:param foo: description of parameter foo
:param bar: description of parameter bar
.. single GroupedField
.. class:: Cls3(values)
:noindex:
:raises ValueError: if the values are out of range
.. grouped GroupedFields
.. class:: Cls4(values)
:noindex:
:raises TypeError: if the values are not valid
:raises ValueError: if the values are out of range
.. single Field
.. class:: Cls5
:noindex:
:returns: a new :class:`Cls3` instance
.. Field is never grouped

View File

@ -387,3 +387,36 @@ def test_i18n_index_entries(app):
]
for expr in expected_exprs:
assert re.search(expr, result, re.M)
@with_intl_app(buildername='text', cleanenv=True)
def test_i18n_docfields(app):
app.builder.build(['docfields'])
result = (app.outdir / 'docfields.txt').text(encoding='utf-8')
expect = (u"\nI18N WITH DOCFIELDS"
u"\n*******************\n"
u"\nclass class Cls1\n"
u"\n Parameters:"
u"\n **param** -- DESCRIPTION OF PARAMETER param\n"
u"\nclass class Cls2\n"
u"\n Parameters:"
u"\n * **foo** -- DESCRIPTION OF PARAMETER foo\n"
u"\n * **bar** -- DESCRIPTION OF PARAMETER bar\n"
u"\nclass class Cls3(values)\n"
u"\n Raises ValueError:"
u"\n IF THE VALUES ARE OUT OF RANGE\n"
u"\nclass class Cls4(values)\n"
u"\n Raises:"
u"\n * **TypeError** -- IF THE VALUES ARE NOT VALID\n"
u"\n * **ValueError** -- IF THE VALUES ARE OUT OF RANGE\n"
u"\nclass class Cls5\n"
u"\n Returns:"
u'\n A NEW "Cls3" INSTANCE\n')
assert result == expect
@with_intl_app(buildername='html', cleanenv=True)
def test_i18n_docfields_html(app):
app.builder.build(['docfields'])
result = (app.outdir / 'docfields.html').text(encoding='utf-8')
# expect no error by build