mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Use a new "lazy" gettext function instead of using dummy _() to help text extraction.
This commit is contained in:
@@ -172,32 +172,18 @@ class Builder(object):
|
||||
Load translated strings from the configured localedirs if
|
||||
enabled in the configuration.
|
||||
"""
|
||||
self.translator = None
|
||||
if self.config.language is not None:
|
||||
self.info(bold('loading translations [%s]... ' %
|
||||
self.config.language), nonl=True)
|
||||
# the None entry is the system's default locale path
|
||||
locale_dirs = [None, path.join(package_dir, 'locale')] + \
|
||||
[path.join(self.srcdir, x) for x in self.config.locale_dirs]
|
||||
for dir_ in locale_dirs:
|
||||
try:
|
||||
trans = gettext.translation('sphinx', localedir=dir_,
|
||||
languages=[self.config.language])
|
||||
if self.translator is None:
|
||||
self.translator = trans
|
||||
else:
|
||||
self.translator._catalog.update(trans.catalog)
|
||||
except Exception:
|
||||
# Language couldn't be found in the specified path
|
||||
pass
|
||||
if self.translator is not None:
|
||||
self.translator, has_translation = locale.init(locale_dirs,
|
||||
self.config.language)
|
||||
if self.config.language is not None:
|
||||
if has_translation:
|
||||
self.info('done')
|
||||
else:
|
||||
self.info('locale not available')
|
||||
if self.translator is None:
|
||||
self.translator = gettext.NullTranslations()
|
||||
self.translator.install(unicode=True)
|
||||
locale.init() # translate common labels
|
||||
|
||||
def load_env(self):
|
||||
"""Set up the build environment."""
|
||||
|
||||
@@ -113,6 +113,10 @@ class Config(object):
|
||||
latex_docclass = ({}, None),
|
||||
# now deprecated - use latex_elements
|
||||
latex_preamble = ('', None),
|
||||
|
||||
# text options
|
||||
text_sectionchars = ('*=-~"+`', 'text'),
|
||||
text_windows_newlines = (False, 'text'),
|
||||
)
|
||||
|
||||
def __init__(self, dirname, filename, overrides, tags):
|
||||
|
||||
@@ -15,6 +15,7 @@ from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains import Domain, domains
|
||||
from sphinx.locale import l_
|
||||
from sphinx.util import ws_re
|
||||
from sphinx.util.compat import Directive, directive_dwim
|
||||
|
||||
@@ -84,8 +85,6 @@ class DescDirective(Directive):
|
||||
'module': directives.unchanged,
|
||||
}
|
||||
|
||||
_ = lambda x: x # make gettext extraction in constants possible
|
||||
|
||||
doc_fields_with_arg = {
|
||||
'param': '%param',
|
||||
'parameter': '%param',
|
||||
@@ -95,23 +94,23 @@ class DescDirective(Directive):
|
||||
'kwarg': '%param',
|
||||
'kwparam': '%param',
|
||||
'type': '%type',
|
||||
'raises': _('Raises'),
|
||||
'raise': 'Raises',
|
||||
'exception': 'Raises',
|
||||
'except': 'Raises',
|
||||
'var': _('Variable'),
|
||||
'ivar': 'Variable',
|
||||
'cvar': 'Variable',
|
||||
'returns': _('Returns'),
|
||||
'return': 'Returns',
|
||||
'raises': l_('Raises'),
|
||||
'raise': l_('Raises'),
|
||||
'exception': l_('Raises'),
|
||||
'except': l_('Raises'),
|
||||
'var': l_('Variable'),
|
||||
'ivar': l_('Variable'),
|
||||
'cvar': l_('Variable'),
|
||||
'returns': l_('Returns'),
|
||||
'return': l_('Returns'),
|
||||
}
|
||||
|
||||
doc_fields_with_linked_arg = ('raises', 'raise', 'exception', 'except')
|
||||
|
||||
doc_fields_without_arg = {
|
||||
'returns': 'Returns',
|
||||
'return': 'Returns',
|
||||
'rtype': _('Return type'),
|
||||
'returns': l_('Returns'),
|
||||
'return': l_('Returns'),
|
||||
'rtype': l_('Return type'),
|
||||
}
|
||||
|
||||
def handle_doc_fields(self, node):
|
||||
@@ -132,7 +131,7 @@ class DescDirective(Directive):
|
||||
fname, fbody = field
|
||||
try:
|
||||
typ, obj = fname.astext().split(None, 1)
|
||||
typdesc = _(self.doc_fields_with_arg[typ])
|
||||
typdesc = self.doc_fields_with_arg[typ]
|
||||
if _is_only_paragraph(fbody):
|
||||
children = fbody.children[0].children
|
||||
else:
|
||||
@@ -176,7 +175,7 @@ class DescDirective(Directive):
|
||||
except (KeyError, ValueError):
|
||||
fnametext = fname.astext()
|
||||
try:
|
||||
typ = _(self.doc_fields_without_arg[fnametext])
|
||||
typ = self.doc_fields_without_arg[fnametext]
|
||||
except KeyError:
|
||||
# at least capitalize the field name
|
||||
typ = fnametext.capitalize()
|
||||
@@ -499,14 +498,14 @@ class ClassmemberDesc(PythonDesc):
|
||||
clsname, methname = name.rsplit('.', 1)
|
||||
except ValueError:
|
||||
if modname:
|
||||
return '%s() (in module %s)' % (name, modname)
|
||||
return _('%s() (in module %s)') % (name, modname)
|
||||
else:
|
||||
return '%s()' % name
|
||||
if modname:
|
||||
return '%s() (%s.%s class method)' % (methname, modname,
|
||||
clsname)
|
||||
return _('%s() (%s.%s class method)') % (methname, modname,
|
||||
clsname)
|
||||
else:
|
||||
return '%s() (%s class method)' % (methname, clsname)
|
||||
return _('%s() (%s class method)') % (methname, clsname)
|
||||
elif self.desctype == 'attribute':
|
||||
try:
|
||||
clsname, attrname = name.rsplit('.', 1)
|
||||
@@ -692,7 +691,7 @@ class GenericDesc(DescDirective):
|
||||
signode['ids'].append(targetname)
|
||||
self.state.document.note_explicit_target(signode)
|
||||
if indextemplate:
|
||||
indexentry = _(indextemplate) % (name,)
|
||||
indexentry = indextemplate % (name,)
|
||||
indextype = 'single'
|
||||
colon = indexentry.find(':')
|
||||
if colon != -1:
|
||||
@@ -757,17 +756,13 @@ class DefaultDomain(Directive):
|
||||
# Note: the target directive is not registered here, it is used by the
|
||||
# application when registering additional xref types.
|
||||
|
||||
_ = lambda x: x
|
||||
|
||||
# Generic cross-reference types; they can be registered in the application;
|
||||
# the directives are either desc_directive or target_directive.
|
||||
additional_xref_types = {
|
||||
# directive name: (role name, index text, function to parse the desc node)
|
||||
'envvar': ('envvar', _('environment variable; %s'), None),
|
||||
'envvar': ('envvar', l_('environment variable; %s'), None),
|
||||
}
|
||||
|
||||
del _
|
||||
|
||||
|
||||
directives.register_directive('default-domain', directive_dwim(DefaultDomain))
|
||||
directives.register_directive('describe', directive_dwim(DescDirective))
|
||||
|
||||
@@ -8,41 +8,179 @@
|
||||
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
import gettext
|
||||
import UserString
|
||||
|
||||
from sphinx import package_dir
|
||||
|
||||
|
||||
class _TranslationProxy(UserString.UserString, object):
|
||||
"""Class for proxy strings from gettext translations. This is a helper
|
||||
for the lazy_* functions from this module.
|
||||
|
||||
The proxy implementation attempts to be as complete as possible, so that
|
||||
the lazy objects should mostly work as expected, for example for sorting.
|
||||
|
||||
This inherits from UserString because some docutils versions use UserString
|
||||
for their Text nodes, which then checks its argument for being either a
|
||||
basestring or UserString, otherwise calls str() -- not unicode() -- on it.
|
||||
This also inherits from object to make the __new__ method work.
|
||||
"""
|
||||
__slots__ = ('_func', '_args')
|
||||
|
||||
def __new__(cls, func, *args):
|
||||
if not args:
|
||||
# not called with "function" and "arguments", but a plain string
|
||||
return unicode(func)
|
||||
return object.__new__(cls)
|
||||
|
||||
def __init__(self, func, *args):
|
||||
self._func = func
|
||||
self._args = args
|
||||
|
||||
data = property(lambda x: x._func(*x._args))
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self.data
|
||||
|
||||
def __nonzero__(self):
|
||||
return bool(self.data)
|
||||
|
||||
def __dir__(self):
|
||||
return dir(unicode)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.data)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.data)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.data)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.data)
|
||||
|
||||
def __add__(self, other):
|
||||
return self.data + other
|
||||
|
||||
def __radd__(self, other):
|
||||
return other + self.data
|
||||
|
||||
def __mod__(self, other):
|
||||
return self.data % other
|
||||
|
||||
def __rmod__(self, other):
|
||||
return other % self.data
|
||||
|
||||
def __mul__(self, other):
|
||||
return self.data * other
|
||||
|
||||
def __rmul__(self, other):
|
||||
return other * self.data
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.data < other
|
||||
|
||||
def __le__(self, other):
|
||||
return self.data <= other
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.data == other
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.data != other
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.data > other
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.data >= other
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == '__members__':
|
||||
return self.__dir__()
|
||||
return getattr(self.data, name)
|
||||
|
||||
def __getstate__(self):
|
||||
return self._func, self._args
|
||||
|
||||
def __setstate__(self, tup):
|
||||
self._func, self._args = tup
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.data[key]
|
||||
|
||||
def __copy__(self):
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
try:
|
||||
return 'i' + repr(unicode(self.data))
|
||||
except:
|
||||
return '<%s broken>' % self.__class__.__name__
|
||||
|
||||
def mygettext(string):
|
||||
"""Used instead of _ when creating TranslationProxies, because _ is not bound
|
||||
yet at that time."""
|
||||
return _(string)
|
||||
|
||||
def lazy_gettext(string):
|
||||
"""A lazy version of `gettext`."""
|
||||
#if isinstance(string, _TranslationProxy):
|
||||
# return string
|
||||
return _TranslationProxy(mygettext, string)
|
||||
|
||||
l_ = lazy_gettext
|
||||
|
||||
_ = lambda x: x
|
||||
|
||||
admonitionlabels = {
|
||||
'attention': _('Attention'),
|
||||
'caution': _('Caution'),
|
||||
'danger': _('Danger'),
|
||||
'error': _('Error'),
|
||||
'hint': _('Hint'),
|
||||
'important': _('Important'),
|
||||
'note': _('Note'),
|
||||
'seealso': _('See Also'),
|
||||
'tip': _('Tip'),
|
||||
'warning': _('Warning'),
|
||||
'attention': l_('Attention'),
|
||||
'caution': l_('Caution'),
|
||||
'danger': l_('Danger'),
|
||||
'error': l_('Error'),
|
||||
'hint': l_('Hint'),
|
||||
'important': l_('Important'),
|
||||
'note': l_('Note'),
|
||||
'seealso': l_('See Also'),
|
||||
'tip': l_('Tip'),
|
||||
'warning': l_('Warning'),
|
||||
}
|
||||
|
||||
versionlabels = {
|
||||
'versionadded': _('New in version %s'),
|
||||
'versionchanged': _('Changed in version %s'),
|
||||
'deprecated': _('Deprecated since version %s'),
|
||||
'versionadded': l_('New in version %s'),
|
||||
'versionchanged': l_('Changed in version %s'),
|
||||
'deprecated': l_('Deprecated since version %s'),
|
||||
}
|
||||
|
||||
pairindextypes = {
|
||||
'module': _('module'),
|
||||
'keyword': _('keyword'),
|
||||
'operator': _('operator'),
|
||||
'object': _('object'),
|
||||
'exception': _('exception'),
|
||||
'statement': _('statement'),
|
||||
'builtin': _('built-in function'),
|
||||
'module': l_('module'),
|
||||
'keyword': l_('keyword'),
|
||||
'operator': l_('operator'),
|
||||
'object': l_('object'),
|
||||
'exception': l_('exception'),
|
||||
'statement': l_('statement'),
|
||||
'builtin': l_('built-in function'),
|
||||
}
|
||||
|
||||
del _
|
||||
|
||||
def init():
|
||||
for dct in (admonitionlabels, versionlabels, pairindextypes):
|
||||
for key in dct:
|
||||
dct[key] = _(dct[key])
|
||||
def init(locale_dirs, language):
|
||||
# the None entry is the system's default locale path
|
||||
translator = None
|
||||
has_translation = True
|
||||
for dir_ in locale_dirs:
|
||||
try:
|
||||
trans = gettext.translation('sphinx', localedir=dir_,
|
||||
languages=[language])
|
||||
if translator is None:
|
||||
translator = trans
|
||||
else:
|
||||
translator._catalog.update(trans.catalog)
|
||||
except Exception:
|
||||
# Language couldn't be found in the specified path
|
||||
pass
|
||||
if translator is None:
|
||||
translator = gettext.NullTranslations()
|
||||
has_translation = False
|
||||
translator.install(unicode=True)
|
||||
return translator, has_translation
|
||||
|
||||
Reference in New Issue
Block a user