summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2009-07-03 13:34:08 +0200
committerGeorg Brandl <georg@python.org>2009-07-03 13:34:08 +0200
commitc8e8b1bfd4d76f13b51cd86b48cb32ccbe7559e0 (patch)
tree6d2a736922487d83b6a850e26a190e2ada1e9933
parent1f18db60a49e0fc6552bcfd11fe4b2be5153c68a (diff)
downloadsphinx-git-c8e8b1bfd4d76f13b51cd86b48cb32ccbe7559e0.tar.gz
Use a new "lazy" gettext function instead of using dummy _() to help text extraction.
-rw-r--r--sphinx/builders/__init__.py22
-rw-r--r--sphinx/config.py4
-rw-r--r--sphinx/directives/desc.py47
-rw-r--r--sphinx/locale/__init__.py190
4 files changed, 193 insertions, 70 deletions
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index a8fc8871c..348e2e8fd 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -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."""
diff --git a/sphinx/config.py b/sphinx/config.py
index 912f3eb2e..dbe569fb7 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -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):
diff --git a/sphinx/directives/desc.py b/sphinx/directives/desc.py
index 47c640b5e..666397c39 100644
--- a/sphinx/directives/desc.py
+++ b/sphinx/directives/desc.py
@@ -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))
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py
index 36fabc615..a9abc9cb9 100644
--- a/sphinx/locale/__init__.py
+++ b/sphinx/locale/__init__.py
@@ -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