Fixed #1771: automated .mo building doesn't work properly with template translation: sphinx-build will load sphinx.mo file to initialize template-bridge before compiling sphinx.po file.

This commit is contained in:
shimizukawa 2015-03-16 23:01:16 +09:00
parent ef3a1f7b2e
commit 30d6d72f47
5 changed files with 38 additions and 12 deletions

View File

@ -168,7 +168,9 @@ class Builder(object):
def compile_all_catalogs(self):
catalogs = i18n.get_catalogs(
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language, self.config.gettext_compact, True)
self.config.language,
gettext_compact=self.config.gettext_compact,
force_all=True)
message = 'all of %d po files' % len(catalogs)
self.compile_catalogs(catalogs, message)
@ -181,15 +183,17 @@ class Builder(object):
specified_domains = set(map(to_domain, specified_files))
catalogs = i18n.get_catalogs(
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language, self.config.gettext_compact, True)
catalogs = [f for f in catalogs if f.domain in specified_domains]
self.config.language,
domains=list(specified_domains),
gettext_compact=self.config.gettext_compact)
message = 'targets for %d po files that are specified' % len(catalogs)
self.compile_catalogs(catalogs, message)
def compile_update_catalogs(self):
catalogs = i18n.get_catalogs(
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language, self.config.gettext_compact)
self.config.language,
gettext_compact=self.config.gettext_compact)
message = 'targets for %d po files that are out of date' % len(catalogs)
self.compile_catalogs(catalogs, message)

View File

@ -208,6 +208,15 @@ def init(locale_dirs, language, catalog='sphinx'):
translator = None
# the None entry is the system's default locale path
has_translation = True
# compile mo files if po file is updated
# TODO: remove circular importing
from sphinx.util.i18n import get_catalogs
for catinfo in get_catalogs(locale_dirs, language, domains=[catalog],
force_all=False):
catinfo.write_mo(language)
# loading
for dir_ in locale_dirs:
try:
trans = gettext.translation(catalog, localedir=dir_,

View File

@ -16,6 +16,7 @@ from babel.messages.pofile import read_po
from babel.messages.mofile import write_mo
from sphinx.util.osutil import walk
from sphinx.util import SEP
LocaleFileInfoBase = namedtuple('CatalogInfo', 'base_dir,domain')
@ -50,13 +51,16 @@ class CatalogInfo(LocaleFileInfoBase):
write_mo(mo, read_po(po, locale))
def get_catalogs(locale_dirs, locale, gettext_compact=False, force_all=False):
def get_catalogs(locale_dirs, locale, domains=None,
gettext_compact=False, force_all=False):
"""
:param list locale_dirs:
list of path as `['locale_dir1', 'locale_dir2', ...]` to find
translation catalogs. Each path contains a structure such as
`<locale>/LC_MESSAGES/domain.po`.
:param str locale: a language as `'en'`
:param list domains: list of domain names to get. If empty list or None
is specified, get all domain names. default is None.
:param boolean gettext_compact:
* False: keep domains directory structure (default).
* True: domains in the sub directory will be merged into 1 file.
@ -70,6 +74,9 @@ def get_catalogs(locale_dirs, locale, gettext_compact=False, force_all=False):
catalogs = set()
for locale_dir in locale_dirs:
if not locale_dir:
continue # skip system locale directory
base_dir = path.join(locale_dir, locale, 'LC_MESSAGES')
if not path.exists(base_dir):
@ -82,6 +89,9 @@ def get_catalogs(locale_dirs, locale, gettext_compact=False, force_all=False):
domain = path.relpath(path.join(dirpath, base), base_dir)
if gettext_compact and path.sep in domain:
domain = path.split(domain)[0]
domain = domain.replace(path.sep, SEP)
if domains and domain not in domains:
continue
cat = CatalogInfo(base_dir, domain)
if force_all or cat.is_outdated():
catalogs.add(cat)

View File

@ -55,10 +55,13 @@ def test_compile_all_catalogs(app, status, warning):
@with_app(buildername='html', testroot='intl',
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
def test_compile_specific_catalogs(app, status, warning):
app.builder.compile_specific_catalogs(['admonitions'])
catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'
actual = set(find_files(catalog_dir, '.mo'))
def get_actual():
return set(find_files(catalog_dir, '.mo'))
actual_on_boot = get_actual() # sphinx.mo might be included
app.builder.compile_specific_catalogs(['admonitions'])
actual = get_actual() - actual_on_boot
assert actual == set(['admonitions.mo'])

View File

@ -77,8 +77,8 @@ def test_get_catalogs_for_xx(dir):
assert domains == set([
'test1',
'test2',
path.normpath('sub/test4'),
path.normpath('sub/test5'),
'sub/test4',
'sub/test5',
])
@ -131,8 +131,8 @@ def test_get_catalogs_for_xx_without_outdated(dir):
assert domains == set([
'test1',
'test2',
path.normpath('sub/test4'),
path.normpath('sub/test5'),
'sub/test4',
'sub/test5',
])