diff --git a/sphinx/application.py b/sphinx/application.py index b39996106..32d6384ed 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -145,16 +145,16 @@ class Sphinx(object): if self.confdir: # confdir is optional self.confdir = abspath(self.confdir) if not path.isfile(path.join(self.confdir, 'conf.py')): - raise ApplicationError("config directory doesn't contain a " - "conf.py file (%s)" % confdir) + raise ApplicationError(__("config directory doesn't contain a " + "conf.py file (%s)") % confdir) if not path.isdir(self.srcdir): - raise ApplicationError('Cannot find source directory (%s)' % + raise ApplicationError(__('Cannot find source directory (%s)') % self.srcdir) if self.srcdir == self.outdir: - raise ApplicationError('Source directory and destination ' - 'directory cannot be identical') + raise ApplicationError(__('Source directory and destination ' + 'directory cannot be identical')) self.parallel = parallel @@ -180,7 +180,7 @@ class Sphinx(object): self.messagelog = deque(maxlen=10) # type: deque # say hello to the world - logger.info(bold('Running Sphinx v%s' % sphinx.__display_version__)) + logger.info(bold(__('Running Sphinx v%s') % sphinx.__display_version__)) # status code for command-line application self.statuscode = 0 @@ -222,7 +222,7 @@ class Sphinx(object): self.preload_builder(buildername) if not path.isdir(outdir): - logger.info('making output directory...') + logger.info(__('making output directory...')) ensuredir(outdir) # the config file itself can be an extension @@ -261,7 +261,7 @@ class Sphinx(object): the configuration. """ if self.config.language is not None: - logger.info(bold('loading translations [%s]... ' % self.config.language), + logger.info(bold(__('loading translations [%s]... ') % self.config.language), nonl=True) user_locale_dirs = [ path.join(self.srcdir, x) for x in self.config.locale_dirs] @@ -279,7 +279,7 @@ class Sphinx(object): # "en" never needs to be translated logger.info(__('done')) else: - logger.info('not available for built-in messages') + logger.info(__('not available for built-in messages')) def _init_env(self, freshenv): # type: (bool) -> None @@ -343,7 +343,7 @@ class Sphinx(object): __('succeeded') or __('finished with problems')) if self._warncount: logger.info(bold(__('build %s, %s warning.', - 'build %s, %s warnings.', self._warncount) % + 'build %s, %s warnings.', self._warncount) % (status, self._warncount))) else: logger.info(bold(__('build %s.') % status)) @@ -1152,7 +1152,7 @@ class Sphinx(object): allowed = getattr(ext, attrname, None) if allowed is None: logger.warning(message, ext.name) - logger.warning('doing serial %s', typ) + logger.warning(__('doing serial %s'), typ) return False elif not allowed: return False diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index 71825b2c7..3dcc117ea 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -19,6 +19,7 @@ from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.environment import BuildEnvironment from sphinx.environment.adapters.asset import ImageAdapter from sphinx.errors import SphinxError +from sphinx.locale import __ from sphinx.util import i18n, import_object, logging, status_iterator from sphinx.util.build_phase import BuildPhase from sphinx.util.console import bold # type: ignore @@ -214,7 +215,7 @@ class Builder(object): if candidate: break else: - logger.warning('no matching candidate for image URI %r', + logger.warning(__('no matching candidate for image URI %r'), images.get_original_image_uri(node['uri']), location=node) continue @@ -237,8 +238,8 @@ class Builder(object): # type: (CatalogInfo) -> unicode return path.relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP) - logger.info(bold('building [mo]: ') + message) - for catalog in status_iterator(catalogs, 'writing output... ', "darkgreen", + logger.info(bold(__('building [mo]: ')) + message) + for catalog in status_iterator(catalogs, __('writing output... '), "darkgreen", len(catalogs), self.app.verbosity, stringify_func=cat2relpath): catalog.write_mo(self.config.language) @@ -251,7 +252,7 @@ class Builder(object): charset=self.config.source_encoding, gettext_compact=self.config.gettext_compact, force_all=True) - message = 'all of %d po files' % len(catalogs) + message = __('all of %d po files') % len(catalogs) self.compile_catalogs(catalogs, message) def compile_specific_catalogs(self, specified_files): @@ -272,7 +273,7 @@ class Builder(object): domains=list(specified_domains), charset=self.config.source_encoding, gettext_compact=self.config.gettext_compact) - message = 'targets for %d po files that are specified' % len(catalogs) + message = __('targets for %d po files that are specified') % len(catalogs) self.compile_catalogs(catalogs, message) def compile_update_catalogs(self): @@ -282,7 +283,7 @@ class Builder(object): self.config.language, charset=self.config.source_encoding, gettext_compact=self.config.gettext_compact) - message = 'targets for %d po files that are out of date' % len(catalogs) + message = __('targets for %d po files that are out of date') % len(catalogs) self.compile_catalogs(catalogs, message) # build methods @@ -290,7 +291,7 @@ class Builder(object): def build_all(self): # type: () -> None """Build all source files.""" - self.build(None, summary='all source files', method='all') + self.build(None, summary=__('all source files'), method='all') def build_specific(self, filenames): # type: (List[unicode]) -> None @@ -304,13 +305,13 @@ class Builder(object): for filename in filenames: filename = path.normpath(path.abspath(filename)) if not filename.startswith(self.srcdir): - logger.warning('file %r given on command line is not under the ' - 'source directory, ignoring', filename) + logger.warning(__('file %r given on command line is not under the ' + 'source directory, ignoring'), filename) continue if not (path.isfile(filename) or any(path.isfile(filename + suffix) for suffix in suffixes)): - logger.warning('file %r given on command line does not exist, ' - 'ignoring', filename) + logger.warning(__('file %r given on command line does not exist, ' + 'ignoring'), filename) continue filename = filename[dirlen:] for suffix in suffixes: @@ -320,8 +321,7 @@ class Builder(object): filename = filename.replace(path.sep, SEP) to_write.append(filename) self.build(to_write, method='specific', - summary='%d source files given on command ' - 'line' % len(to_write)) + summary=__('%d source files given on command line') % len(to_write)) def build_update(self): # type: () -> None @@ -332,8 +332,8 @@ class Builder(object): else: to_build = list(to_build) self.build(to_build, - summary='targets for %d source files that are ' - 'out of date' % len(to_build)) + summary=__('targets for %d source files that are out of date') % + len(to_build)) def build(self, docnames, summary=None, method='update'): # type: (Iterable[unicode], unicode, unicode) -> None @@ -342,37 +342,37 @@ class Builder(object): First updates the environment, and then calls :meth:`write`. """ if summary: - logger.info(bold('building [%s]' % self.name) + ': ' + summary) + logger.info(bold(__('building [%s]') % self.name) + ': ' + summary) # while reading, collect all warnings from docutils with logging.pending_warnings(): updated_docnames = set(self.read()) doccount = len(updated_docnames) - logger.info(bold('looking for now-outdated files... '), nonl=1) + logger.info(bold(__('looking for now-outdated files... ')), nonl=1) for docname in self.env.check_dependents(self.app, updated_docnames): updated_docnames.add(docname) outdated = len(updated_docnames) - doccount if outdated: - logger.info('%d found', outdated) + logger.info(__('%d found'), outdated) else: - logger.info('none found') + logger.info(__('none found')) if updated_docnames: # save the environment from sphinx.application import ENV_PICKLE_FILENAME - logger.info(bold('pickling environment... '), nonl=True) + logger.info(bold(__('pickling environment... ')), nonl=True) self.env.topickle(path.join(self.doctreedir, ENV_PICKLE_FILENAME)) - logger.info('done') + logger.info(__('done')) # global actions self.app.phase = BuildPhase.CONSISTENCY_CHECK - logger.info(bold('checking consistency... '), nonl=True) + logger.info(bold(__('checking consistency... ')), nonl=True) self.env.check_consistency() - logger.info('done') + logger.info(__('done')) else: if method == 'update' and not docnames: - logger.info(bold('no targets are out of date.')) + logger.info(bold(__('no targets are out of date.'))) return self.app.phase = BuildPhase.RESOLVING @@ -515,7 +515,7 @@ class Builder(object): docnames = set(build_docnames) | set(updated_docnames) else: docnames = set(build_docnames) - logger.debug('docnames to write: %s', ', '.join(sorted(docnames))) + logger.debug(__('docnames to write: %s'), ', '.join(sorted(docnames))) # add all toctree-containing files that may have changed for docname in list(docnames): @@ -524,9 +524,9 @@ class Builder(object): docnames.add(tocdocname) docnames.add(self.config.master_doc) - logger.info(bold('preparing documents... '), nonl=True) + logger.info(bold(__('preparing documents... ')), nonl=True) self.prepare_writing(docnames) - logger.info('done') + logger.info(__('done')) if self.parallel_ok: # number of subprocesses is parallel-1 because the main process @@ -539,7 +539,7 @@ class Builder(object): def _write_serial(self, docnames): # type: (Sequence[unicode]) -> None with logging.pending_warnings(): - for docname in status_iterator(docnames, 'writing output... ', "darkgreen", + for docname in status_iterator(docnames, __('writing output... '), "darkgreen", len(docnames), self.app.verbosity): self.app.phase = BuildPhase.RESOLVING doctree = self.env.get_and_resolve_doctree(docname, self) @@ -567,7 +567,7 @@ class Builder(object): chunks = make_chunks(docnames, nproc) self.app.phase = BuildPhase.RESOLVING - for chunk in status_iterator(chunks, 'writing output... ', "darkgreen", + for chunk in status_iterator(chunks, __('writing output... '), "darkgreen", len(chunks), self.app.verbosity): arg = [] for i, docname in enumerate(chunk): @@ -577,7 +577,7 @@ class Builder(object): tasks.add_task(write_process, arg) # make sure all threads have finished - logger.info(bold('waiting for workers...')) + logger.info(bold(__('waiting for workers...'))) tasks.join() def prepare_writing(self, docnames): diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index 880326100..39c288cf5 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -21,6 +21,7 @@ from docutils.utils import smartquotes from sphinx import addnodes from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder +from sphinx.locale import __ from sphinx.util import logging from sphinx.util import status_iterator from sphinx.util.fileutil import copy_asset_file @@ -401,13 +402,13 @@ class EpubBuilder(StandaloneHTMLBuilder): img = Image.open(path.join(self.srcdir, src)) except IOError: if not self.is_vector_graphics(src): - logger.warning('cannot read image file %r: copying it instead', + logger.warning(__('cannot read image file %r: copying it instead'), path.join(self.srcdir, src)) try: copyfile(path.join(self.srcdir, src), path.join(self.outdir, self.imagedir, dest)) except (IOError, OSError) as err: - logger.warning('cannot copy image file %r: %s', + logger.warning(__('cannot copy image file %r: %s'), path.join(self.srcdir, src), err) continue if self.config.epub_fix_images: @@ -423,7 +424,7 @@ class EpubBuilder(StandaloneHTMLBuilder): try: img.save(path.join(self.outdir, self.imagedir, dest)) except (IOError, OSError) as err: - logger.warning('cannot write image file %r: %s', + logger.warning(__('cannot write image file %r: %s'), path.join(self.srcdir, src), err) def copy_image_files(self): @@ -434,7 +435,7 @@ class EpubBuilder(StandaloneHTMLBuilder): if self.images: if self.config.epub_fix_images or self.config.epub_max_image_width: if not Image: - logger.warning('PIL not found - copying image files') + logger.warning(__('PIL not found - copying image files')) super(EpubBuilder, self).copy_image_files() else: self.copy_image_files_pil() @@ -464,14 +465,14 @@ class EpubBuilder(StandaloneHTMLBuilder): def build_mimetype(self, outdir, outname): # type: (unicode, unicode) -> None """Write the metainfo file mimetype.""" - logger.info('writing %s file...', outname) + logger.info(__('writing %s file...'), outname) copy_asset_file(path.join(self.template_dir, 'mimetype'), path.join(outdir, outname)) def build_container(self, outdir, outname): # type: (unicode, unicode) -> None """Write the metainfo file META-INF/container.xml.""" - logger.info('writing %s file...', outname) + logger.info(__('writing %s file...'), outname) filename = path.join(outdir, outname) ensuredir(path.dirname(filename)) copy_asset_file(path.join(self.template_dir, 'container.xml'), filename) @@ -501,7 +502,7 @@ class EpubBuilder(StandaloneHTMLBuilder): """Write the metainfo file content.opf It contains bibliographic data, a file list and the spine (the reading order). """ - logger.info('writing %s file...', outname) + logger.info(__('writing %s file...'), outname) metadata = self.content_metadata() # files @@ -527,7 +528,7 @@ class EpubBuilder(StandaloneHTMLBuilder): # we always have JS and potentially OpenSearch files, don't # always warn about them if ext not in ('.js', '.xml'): - logger.warning('unknown mimetype for %s, ignoring', filename, + logger.warning(__('unknown mimetype for %s, ignoring'), filename, type='epub', subtype='unknown_project_files') continue filename = filename.replace(os.sep, '/') @@ -680,7 +681,7 @@ class EpubBuilder(StandaloneHTMLBuilder): def build_toc(self, outdir, outname): # type: (unicode, unicode) -> None """Write the metainfo file toc.ncx.""" - logger.info('writing %s file...', outname) + logger.info(__('writing %s file...'), outname) if self.config.epub_tocscope == 'default': doctree = self.env.get_and_resolve_doctree(self.config.master_doc, @@ -705,7 +706,7 @@ class EpubBuilder(StandaloneHTMLBuilder): It is a zip file with the mimetype file stored uncompressed as the first entry. """ - logger.info('writing %s file...', outname) + logger.info(__('writing %s file...'), outname) epub_filename = path.join(outdir, outname) with ZipFile(epub_filename, 'w', ZIP_DEFLATED) as epub: # type: ignore epub.write(path.join(outdir, 'mimetype'), 'mimetype', ZIP_STORED) # type: ignore diff --git a/sphinx/builders/applehelp.py b/sphinx/builders/applehelp.py index d850581a8..3e289effc 100644 --- a/sphinx/builders/applehelp.py +++ b/sphinx/builders/applehelp.py @@ -21,6 +21,7 @@ from typing import TYPE_CHECKING from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.config import string_classes from sphinx.errors import SphinxError +from sphinx.locale import __ from sphinx.util import logging from sphinx.util.console import bold # type: ignore from sphinx.util.fileutil import copy_asset @@ -60,11 +61,11 @@ access_page_template = '''\ class AppleHelpIndexerFailed(SphinxError): - category = 'Help indexer failed' + category = __('Help indexer failed') class AppleHelpCodeSigningFailed(SphinxError): - category = 'Code signing failed' + category = __('Code signing failed') class AppleHelpBuilder(StandaloneHTMLBuilder): @@ -73,10 +74,10 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): on the ``hiutil`` command line tool. """ name = 'applehelp' - epilog = ('The help book is in %(outdir)s.\n' - 'Note that won\'t be able to view it unless you put it in ' - '~/Library/Documentation/Help or install it in your application ' - 'bundle.') + epilog = __('The help book is in %(outdir)s.\n' + 'Note that won\'t be able to view it unless you put it in ' + '~/Library/Documentation/Help or install it in your application ' + 'bundle.') # don't copy the reST source copysource = False @@ -100,8 +101,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): self.link_suffix = '.html' if self.config.applehelp_bundle_id is None: - raise SphinxError('You must set applehelp_bundle_id before ' - 'building Apple Help output') + raise SphinxError(__('You must set applehelp_bundle_id before ' + 'building Apple Help output')) self.bundle_path = path.join(self.outdir, self.config.applehelp_bundle_name + @@ -124,13 +125,13 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): target_dir = self.outdir if path.isdir(source_dir): - logger.info(bold('copying localized files... '), nonl=True) + logger.info(bold(__('copying localized files... ')), nonl=True) excluded = Matcher(self.config.exclude_patterns + ['**/.*']) copy_asset(source_dir, target_dir, excluded, context=self.globalcontext, renderer=self.templates) - logger.info('done') + logger.info(__('done')) def build_helpbook(self): # type: () -> None @@ -171,36 +172,36 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): if self.config.applehelp_remote_url is not None: info_plist['HPDBookRemoteURL'] = self.config.applehelp_remote_url - logger.info(bold('writing Info.plist... '), nonl=True) + logger.info(bold(__('writing Info.plist... ')), nonl=True) with open(path.join(contents_dir, 'Info.plist'), 'wb') as f: write_plist(info_plist, f) - logger.info('done') + logger.info(__('done')) # Copy the icon, if one is supplied if self.config.applehelp_icon: - logger.info(bold('copying icon... '), nonl=True) + logger.info(bold(__('copying icon... ')), nonl=True) try: copyfile(path.join(self.srcdir, self.config.applehelp_icon), path.join(resources_dir, info_plist['HPDBookIconPath'])) - logger.info('done') + logger.info(__('done')) except Exception as err: - logger.warning('cannot copy icon file %r: %s', + logger.warning(__('cannot copy icon file %r: %s'), path.join(self.srcdir, self.config.applehelp_icon), err) del info_plist['HPDBookIconPath'] # Build the access page - logger.info(bold('building access page...'), nonl=True) + logger.info(bold(__('building access page...')), nonl=True) with codecs.open(path.join(language_dir, '_access.html'), 'w') as f: # type: ignore f.write(access_page_template % { 'toc': htmlescape(toc, quote=True), 'title': htmlescape(self.config.applehelp_title) }) - logger.info('done') + logger.info(__('done')) # Generate the help index - logger.info(bold('generating help index... '), nonl=True) + logger.info(bold(__('generating help index... ')), nonl=True) args = [ self.config.applehelp_indexer_path, @@ -222,9 +223,9 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): args += ['-l', self.config.applehelp_locale] if self.config.applehelp_disable_external_tools: - logger.info('skipping') + logger.info(__('skipping')) - logger.warning('you will need to index this help book with:\n %s', + logger.warning(__('you will need to index this help book with:\n %s'), ' '.join([pipes.quote(arg) for arg in args])) else: try: @@ -237,13 +238,13 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): if p.returncode != 0: raise AppleHelpIndexerFailed(output) else: - logger.info('done') + logger.info(__('done')) except OSError: - raise AppleHelpIndexerFailed('Command not found: %s' % args[0]) + raise AppleHelpIndexerFailed(__('Command not found: %s') % args[0]) # If we've been asked to, sign the bundle if self.config.applehelp_codesign_identity: - logger.info(bold('signing help book... '), nonl=True) + logger.info(bold(__('signing help book... ')), nonl=True) args = [ self.config.applehelp_codesign_path, @@ -256,8 +257,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): args.append(self.bundle_path) if self.config.applehelp_disable_external_tools: - logger.info('skipping') - logger.warning('you will need to sign this help book with:\n %s', + logger.info(__('skipping')) + logger.warning(__('you will need to sign this help book with:\n %s'), ' '.join([pipes.quote(arg) for arg in args])) else: try: @@ -270,9 +271,9 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): if p.returncode != 0: raise AppleHelpCodeSigningFailed(output) else: - logger.info('done') + logger.info(__('done')) except OSError: - raise AppleHelpCodeSigningFailed('Command not found: %s' % args[0]) + raise AppleHelpCodeSigningFailed(__('Command not found: %s') % args[0]) def setup(app): diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index eb7bb1554..fe88b5aaf 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -17,7 +17,7 @@ from six import iteritems from sphinx import package_dir from sphinx.builders import Builder -from sphinx.locale import _ +from sphinx.locale import _, __ from sphinx.theming import HTMLThemeFactory from sphinx.util import logging from sphinx.util.console import bold # type: ignore @@ -38,7 +38,7 @@ class ChangesBuilder(Builder): Write a summary with all versionadded/changed directives. """ name = 'changes' - epilog = 'The overview file is in %(outdir)s.' + epilog = __('The overview file is in %(outdir)s.') def init(self): # type: () -> None @@ -64,7 +64,7 @@ class ChangesBuilder(Builder): apichanges = [] # type: List[Tuple[unicode, unicode, int]] otherchanges = {} # type: Dict[Tuple[unicode, unicode], List[Tuple[unicode, unicode, int]]] # NOQA if version not in self.env.versionchanges: - logger.info(bold('no changes in version %s.' % version)) + logger.info(bold(__('no changes in version %s.') % version)) return logger.info(bold('writing summary file...')) for type, docname, lineno, module, descname, content in \ @@ -129,14 +129,14 @@ class ChangesBuilder(Builder): break return line - logger.info(bold('copying source files...')) + logger.info(bold(__('copying source files...'))) for docname in self.env.all_docs: with codecs.open(self.env.doc2path(docname), 'r', # type: ignore self.env.config.source_encoding) as f: try: lines = f.readlines() except UnicodeDecodeError: - logger.warning('could not read %r for changelog creation', docname) + logger.warning(__('could not read %r for changelog creation'), docname) continue targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html' ensuredir(path.dirname(targetfn)) diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py index 4e204eabb..f1511b564 100644 --- a/sphinx/builders/devhelp.py +++ b/sphinx/builders/devhelp.py @@ -22,6 +22,7 @@ from docutils import nodes from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.environment.adapters.indexentries import IndexEntries +from sphinx.locale import __ from sphinx.util import logging from sphinx.util.osutil import make_filename @@ -43,10 +44,10 @@ class DevhelpBuilder(StandaloneHTMLBuilder): Builder that also outputs GNOME Devhelp file. """ name = 'devhelp' - epilog = ('To view the help file:\n' - '$ mkdir -p $HOME/.local/share/devhelp/%(project)s\n' - '$ ln -s %(outdir)s $HOME/.local/share/devhelp/%(project)s\n' - '$ devhelp') + epilog = __('To view the help file:\n' + '$ mkdir -p $HOME/.local/share/devhelp/%(project)s\n' + '$ ln -s %(outdir)s $HOME/.local/share/devhelp/%(project)s\n' + '$ devhelp') # don't copy the reST source copysource = False @@ -69,7 +70,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder): def build_devhelp(self, outdir, outname): # type: (unicode, unicode) -> None - logger.info('dumping devhelp index...') + logger.info(__('dumping devhelp index...')) # Basic info root = etree.Element('book', diff --git a/sphinx/builders/dummy.py b/sphinx/builders/dummy.py index e0f2a3dab..cc23c6e2b 100644 --- a/sphinx/builders/dummy.py +++ b/sphinx/builders/dummy.py @@ -12,6 +12,7 @@ from typing import TYPE_CHECKING from sphinx.builders import Builder +from sphinx.locale import __ if TYPE_CHECKING: from typing import Any, Dict, Set # NOQA @@ -21,7 +22,7 @@ if TYPE_CHECKING: class DummyBuilder(Builder): name = 'dummy' - epilog = 'The dummy builder generates no files.' + epilog = __('The dummy builder generates no files.') allow_parallel = True diff --git a/sphinx/builders/epub3.py b/sphinx/builders/epub3.py index 53deb0ee5..995f5a6dc 100644 --- a/sphinx/builders/epub3.py +++ b/sphinx/builders/epub3.py @@ -17,6 +17,7 @@ from typing import TYPE_CHECKING from sphinx import package_dir from sphinx.builders import _epub_base from sphinx.config import string_classes, ENUM +from sphinx.locale import __ from sphinx.util import logging, xmlname_checker from sphinx.util.fileutil import copy_asset_file from sphinx.util.i18n import format_date @@ -63,7 +64,7 @@ class Epub3Builder(_epub_base.EpubBuilder): an epub file. """ name = 'epub' - epilog = 'The ePub file is in %(outdir)s.' + epilog = __('The ePub file is in %(outdir)s.') supported_remote_images = False template_dir = path.join(package_dir, 'templates', 'epub3') @@ -88,37 +89,37 @@ class Epub3Builder(_epub_base.EpubBuilder): # type: () -> None # lang attribute, dc:language if not self.app.config.epub_language: - logger.warning('conf value "epub_language" (or "language") ' - 'should not be empty for EPUB3') + logger.warning(__('conf value "epub_language" (or "language") ' + 'should not be empty for EPUB3')) # unique-identifier attribute if not xmlname_checker().match(self.app.config.epub_uid): - logger.warning('conf value "epub_uid" should be XML NAME for EPUB3') + logger.warning(__('conf value "epub_uid" should be XML NAME for EPUB3')) # dc:title if not self.app.config.epub_title: - logger.warning('conf value "epub_title" (or "html_title") ' - 'should not be empty for EPUB3') + logger.warning(__('conf value "epub_title" (or "html_title") ' + 'should not be empty for EPUB3')) # dc:creator if not self.app.config.epub_author: - logger.warning('conf value "epub_author" should not be empty for EPUB3') + logger.warning(__('conf value "epub_author" should not be empty for EPUB3')) # dc:contributor if not self.app.config.epub_contributor: - logger.warning('conf value "epub_contributor" should not be empty for EPUB3') + logger.warning(__('conf value "epub_contributor" should not be empty for EPUB3')) # dc:description if not self.app.config.epub_description: - logger.warning('conf value "epub_description" should not be empty for EPUB3') + logger.warning(__('conf value "epub_description" should not be empty for EPUB3')) # dc:publisher if not self.app.config.epub_publisher: - logger.warning('conf value "epub_publisher" should not be empty for EPUB3') + logger.warning(__('conf value "epub_publisher" should not be empty for EPUB3')) # dc:rights if not self.app.config.epub_copyright: - logger.warning('conf value "epub_copyright" (or "copyright")' - 'should not be empty for EPUB3') + logger.warning(__('conf value "epub_copyright" (or "copyright")' + 'should not be empty for EPUB3')) # dc:identifier if not self.app.config.epub_identifier: - logger.warning('conf value "epub_identifier" should not be empty for EPUB3') + logger.warning(__('conf value "epub_identifier" should not be empty for EPUB3')) # meta ibooks:version if not self.app.config.version: - logger.warning('conf value "version" should not be empty for EPUB3') + logger.warning(__('conf value "version" should not be empty for EPUB3')) def content_metadata(self): # type: () -> Dict @@ -204,7 +205,7 @@ class Epub3Builder(_epub_base.EpubBuilder): def build_navigation_doc(self, outdir, outname): # type: (unicode, unicode) -> None """Write the metainfo file nav.xhtml.""" - logger.info('writing %s file...', outname) + logger.info(__('writing %s file...'), outname) if self.config.epub_tocscope == 'default': doctree = self.env.get_and_resolve_doctree( diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index f7a2c988f..584463b4f 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -23,6 +23,7 @@ from six import iteritems, StringIO from sphinx.builders import Builder from sphinx.domains.python import pairindextypes +from sphinx.locale import __ from sphinx.util import split_index_msg, logging, status_iterator from sphinx.util.console import bold # type: ignore from sphinx.util.i18n import find_catalog @@ -215,7 +216,7 @@ class MessageCatalogBuilder(I18nBuilder): Builds gettext-style message catalogs (.pot files). """ name = 'gettext' - epilog = 'The message catalogs are in %(outdir)s.' + epilog = __('The message catalogs are in %(outdir)s.') def init(self): # type: () -> None @@ -239,12 +240,12 @@ class MessageCatalogBuilder(I18nBuilder): # type: () -> None files = list(self._collect_templates()) files.sort() - logger.info(bold('building [%s]: ' % self.name), nonl=1) - logger.info('targets for %d template files', len(files)) + logger.info(bold(__('building [%s]: ') % self.name), nonl=1) + logger.info(__('targets for %d template files'), len(files)) extract_translations = self.templates.environment.extract_translations - for template in status_iterator(files, 'reading templates... ', "purple", # type: ignore # NOQA + for template in status_iterator(files, __('reading templates... '), "purple", # type: ignore # NOQA len(files), self.app.verbosity): with open(template, 'r', encoding='utf-8') as f: # type: ignore context = f.read() @@ -268,7 +269,7 @@ class MessageCatalogBuilder(I18nBuilder): timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'), ) for textdomain, catalog in status_iterator(iteritems(self.catalogs), # type: ignore - "writing message catalogs... ", + __("writing message catalogs... "), "darkgreen", len(self.catalogs), self.app.verbosity, lambda textdomain__: textdomain__[0]): diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index b8c43d08c..017f58620 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -37,7 +37,7 @@ from sphinx.environment.adapters.asset import ImageAdapter from sphinx.environment.adapters.indexentries import IndexEntries from sphinx.environment.adapters.toctree import TocTree from sphinx.highlighting import PygmentsBridge -from sphinx.locale import _ +from sphinx.locale import _, __ from sphinx.search import js_index from sphinx.theming import HTMLThemeFactory from sphinx.util import jsonimpl, logging, status_iterator @@ -174,7 +174,7 @@ class BuildInfo(object): build_info.tags_hash = lines[3].split()[1].strip() return build_info except Exception as exc: - raise ValueError('build info file is broken: %r' % exc) + raise ValueError(__('build info file is broken: %r') % exc) def __init__(self, config=None, tags=None, config_categories=[]): # type: (Config, Tags, List[unicode]) -> None @@ -213,7 +213,7 @@ class StandaloneHTMLBuilder(Builder): """ name = 'html' format = 'html' - epilog = 'The HTML pages are in %(outdir)s.' + epilog = __('The HTML pages are in %(outdir)s.') copysource = True allow_parallel = True @@ -346,7 +346,7 @@ class StandaloneHTMLBuilder(Builder): yield docname return except ValueError as exc: - logger.warning('Failed to read build info file: %r', exc) + logger.warning(__('Failed to read build info file: %r'), exc) except IOError: # ignore errors on reading pass @@ -458,7 +458,7 @@ class StandaloneHTMLBuilder(Builder): path.basename(self.config.html_favicon) or '' if not isinstance(self.config.html_use_opensearch, string_types): - logger.warning('html_use_opensearch config value must now be a string') + logger.warning(__('html_use_opensearch config value must now be a string')) self.relations = self.env.collect_relations() @@ -635,7 +635,7 @@ class StandaloneHTMLBuilder(Builder): def gen_indices(self): # type: () -> None - logger.info(bold('generating indices...'), nonl=1) + logger.info(bold(__('generating indices...')), nonl=1) # the global general index if self.use_index: @@ -653,7 +653,7 @@ class StandaloneHTMLBuilder(Builder): for pagename, context, template in pagelist: self.handle_page(pagename, context, template) - logger.info(bold('writing additional pages...'), nonl=1) + logger.info(bold(__('writing additional pages...')), nonl=1) # additional pages from conf.py for pagename, template in self.config.html_additional_pages.items(): @@ -719,7 +719,7 @@ class StandaloneHTMLBuilder(Builder): if self.images: stringify_func = ImageAdapter(self.app.env).get_original_image_uri ensuredir(path.join(self.outdir, self.imagedir)) - for src in status_iterator(self.images, 'copying images... ', "brown", + for src in status_iterator(self.images, __('copying images... '), "brown", len(self.images), self.app.verbosity, stringify_func=stringify_func): dest = self.images[src] @@ -727,7 +727,7 @@ class StandaloneHTMLBuilder(Builder): copyfile(path.join(self.srcdir, src), path.join(self.outdir, self.imagedir, dest)) except Exception as err: - logger.warning('cannot copy image file %r: %s', + logger.warning(__('cannot copy image file %r: %s'), path.join(self.srcdir, src), err) def copy_download_files(self): @@ -738,7 +738,7 @@ class StandaloneHTMLBuilder(Builder): # copy downloadable files if self.env.dlfiles: ensuredir(path.join(self.outdir, '_downloads')) - for src in status_iterator(self.env.dlfiles, 'copying downloadable files... ', + for src in status_iterator(self.env.dlfiles, __('copying downloadable files... '), "brown", len(self.env.dlfiles), self.app.verbosity, stringify_func=to_relpath): dest = self.env.dlfiles[src][1] @@ -746,13 +746,13 @@ class StandaloneHTMLBuilder(Builder): copyfile(path.join(self.srcdir, src), path.join(self.outdir, '_downloads', dest)) except Exception as err: - logger.warning('cannot copy downloadable file %r: %s', + logger.warning(__('cannot copy downloadable file %r: %s'), path.join(self.srcdir, src), err) def copy_static_files(self): # type: () -> None # copy static files - logger.info(bold('copying static files... '), nonl=True) + logger.info(bold(__('copying static files... ')), nonl=True) ensuredir(path.join(self.outdir, '_static')) # first, create pygments style file with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f: @@ -787,7 +787,7 @@ class StandaloneHTMLBuilder(Builder): for static_path in self.config.html_static_path: entry = path.join(self.confdir, static_path) if not path.exists(entry): - logger.warning('html_static_path entry %r does not exist', entry) + logger.warning(__('html_static_path entry %r does not exist'), entry) continue copy_asset(entry, path.join(self.outdir, '_static'), excluded, context=ctx, renderer=self.templates) @@ -796,7 +796,7 @@ class StandaloneHTMLBuilder(Builder): logobase = path.basename(self.config.html_logo) logotarget = path.join(self.outdir, '_static', logobase) if not path.isfile(path.join(self.confdir, self.config.html_logo)): - logger.warning('logo file %r does not exist', self.config.html_logo) + logger.warning(__('logo file %r does not exist'), self.config.html_logo) elif not path.isfile(logotarget): copyfile(path.join(self.confdir, self.config.html_logo), logotarget) @@ -804,7 +804,7 @@ class StandaloneHTMLBuilder(Builder): iconbase = path.basename(self.config.html_favicon) icontarget = path.join(self.outdir, '_static', iconbase) if not path.isfile(path.join(self.confdir, self.config.html_favicon)): - logger.warning('favicon file %r does not exist', self.config.html_favicon) + logger.warning(__('favicon file %r does not exist'), self.config.html_favicon) elif not path.isfile(icontarget): copyfile(path.join(self.confdir, self.config.html_favicon), icontarget) @@ -813,17 +813,17 @@ class StandaloneHTMLBuilder(Builder): def copy_extra_files(self): # type: () -> None # copy html_extra_path files - logger.info(bold('copying extra files... '), nonl=True) + logger.info(bold(__('copying extra files... ')), nonl=True) excluded = Matcher(self.config.exclude_patterns) for extra_path in self.config.html_extra_path: entry = path.join(self.confdir, extra_path) if not path.exists(entry): - logger.warning('html_extra_path entry %r does not exist', entry) + logger.warning(__('html_extra_path entry %r does not exist'), entry) continue copy_asset(entry, self.outdir, excluded) - logger.info('done') + logger.info(__('done')) def write_buildinfo(self): # type: () -> None @@ -831,7 +831,7 @@ class StandaloneHTMLBuilder(Builder): with open(path.join(self.outdir, '.buildinfo'), 'w') as fp: self.build_info.dump(fp) except IOError as exc: - logger.warning('Failed to write build info file: %r', exc) + logger.warning(__('Failed to write build info file: %r'), exc) def cleanup(self): # type: () -> None @@ -878,9 +878,9 @@ class StandaloneHTMLBuilder(Builder): self.indexer.load(f, self.indexer_format) except (IOError, OSError, ValueError): if keep: - logger.warning('search index couldn\'t be loaded, but not all ' - 'documents will be built: the index will be ' - 'incomplete.') + logger.warning(__('search index couldn\'t be loaded, but not all ' + 'documents will be built: the index will be ' + 'incomplete.')) # delete all entries for files that will be rebuilt self.indexer.prune(keep) @@ -932,8 +932,8 @@ class StandaloneHTMLBuilder(Builder): if has_wildcard(pattern): # warn if both patterns contain wildcards if has_wildcard(matched): - logger.warning('page %s matches two patterns in ' - 'html_sidebars: %r and %r', + logger.warning(__('page %s matches two patterns in ' + 'html_sidebars: %r and %r'), pagename, matched, pattern) # else the already matched pattern is more specific # than the present one, because it contains no wildcard @@ -1018,9 +1018,9 @@ class StandaloneHTMLBuilder(Builder): try: output = self.templates.render(templatename, ctx) except UnicodeError: - logger.warning("a Unicode error occurred when rendering the page %s. " - "Please make sure all config values that contain " - "non-ASCII content are Unicode strings.", pagename) + logger.warning(__("a Unicode error occurred when rendering the page %s. " + "Please make sure all config values that contain " + "non-ASCII content are Unicode strings."), pagename) return if not outfilename: @@ -1031,7 +1031,7 @@ class StandaloneHTMLBuilder(Builder): with codecs.open(outfilename, 'w', ctx['encoding'], 'xmlcharrefreplace') as f: # type: ignore # NOQA f.write(output) except (IOError, OSError) as err: - logger.warning("error writing file %s: %s", outfilename, err) + logger.warning(__("error writing file %s: %s"), outfilename, err) if self.copysource and ctx.get('sourcename'): # copy the source file for the "show source" link source_name = path.join(self.outdir, '_sources', @@ -1051,14 +1051,14 @@ class StandaloneHTMLBuilder(Builder): def dump_inventory(self): # type: () -> None - logger.info(bold('dumping object inventory... '), nonl=True) + logger.info(bold(__('dumping object inventory... ')), nonl=True) InventoryFile.dump(path.join(self.outdir, INVENTORY_FILENAME), self.env, self) - logger.info('done') + logger.info(__('done')) def dump_search_index(self): # type: () -> None logger.info( - bold('dumping search index in %s ... ' % self.indexer.label()), + bold(__('dumping search index in %s ... ') % self.indexer.label()), nonl=True) self.indexer.prune(self.env.all_docs) searchindexfn = path.join(self.outdir, self.searchindex_filename) @@ -1071,7 +1071,7 @@ class StandaloneHTMLBuilder(Builder): with f: self.indexer.dump(f, self.indexer_format) movefile(searchindexfn + '.tmp', searchindexfn) - logger.info('done') + logger.info(__('done')) class DirectoryHTMLBuilder(StandaloneHTMLBuilder): @@ -1113,7 +1113,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder): HTML page. """ name = 'singlehtml' - epilog = 'The HTML page is in %(outdir)s.' + epilog = __('The HTML page is in %(outdir)s.') copysource = False @@ -1243,24 +1243,24 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder): # type: (Any) -> None docnames = self.env.all_docs - logger.info(bold('preparing documents... '), nonl=True) + logger.info(bold(__('preparing documents... ')), nonl=True) self.prepare_writing(docnames) - logger.info('done') + logger.info(__('done')) - logger.info(bold('assembling single document... '), nonl=True) + logger.info(bold(__('assembling single document... ')), nonl=True) doctree = self.assemble_doctree() self.env.toc_secnumbers = self.assemble_toc_secnumbers() self.env.toc_fignumbers = self.assemble_toc_fignumbers() logger.info('') - logger.info(bold('writing... '), nonl=True) + logger.info(bold(__('writing... ')), nonl=True) self.write_doc_serialized(self.config.master_doc, doctree) self.write_doc(self.config.master_doc, doctree) - logger.info('done') + logger.info(__('done')) def finish(self): # type: () -> None # no indices or search pages are supported - logger.info(bold('writing additional files...'), nonl=1) + logger.info(bold(__('writing additional files...')), nonl=1) # additional pages from conf.py for pagename, template in self.config.html_additional_pages.items(): @@ -1377,7 +1377,7 @@ class PickleHTMLBuilder(SerializingHTMLBuilder): A Builder that dumps the generated HTML into pickle files. """ name = 'pickle' - epilog = 'You can now process the pickle files in %(outdir)s.' + epilog = __('You can now process the pickle files in %(outdir)s.') implementation = pickle implementation_dumps_unicode = False @@ -1398,7 +1398,7 @@ class JSONHTMLBuilder(SerializingHTMLBuilder): A builder that dumps the generated HTML into JSON files. """ name = 'json' - epilog = 'You can now process the JSON files in %(outdir)s.' + epilog = __('You can now process the JSON files in %(outdir)s.') implementation = jsonimpl implementation_dumps_unicode = True diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py index a518582b4..8f7cd7734 100644 --- a/sphinx/builders/htmlhelp.py +++ b/sphinx/builders/htmlhelp.py @@ -21,6 +21,7 @@ from docutils import nodes from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.environment.adapters.indexentries import IndexEntries +from sphinx.locale import __ from sphinx.util import logging from sphinx.util.osutil import make_filename from sphinx.util.pycompat import htmlescape @@ -174,8 +175,8 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): index files. Adapted from the original Doc/tools/prechm.py. """ name = 'htmlhelp' - epilog = ('You can now run HTML Help Workshop with the .htp file in ' - '%(outdir)s.') + epilog = __('You can now run HTML Help Workshop with the .htp file in ' + '%(outdir)s.') # don't copy the reST source copysource = False @@ -228,12 +229,12 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): def build_hhx(self, outdir, outname): # type: (unicode, unicode) -> None - logger.info('dumping stopword list...') + logger.info(__('dumping stopword list...')) with self.open_file(outdir, outname + '.stp') as f: for word in sorted(stopwords): print(word, file=f) - logger.info('writing project file...') + logger.info(__('writing project file...')) with self.open_file(outdir, outname + '.hhp') as f: f.write(project_template % { 'outname': outname, @@ -254,7 +255,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): print(path.join(root, fn)[olen:].replace(os.sep, '\\'), file=f) - logger.info('writing TOC file...') + logger.info(__('writing TOC file...')) with self.open_file(outdir, outname + '.hhc') as f: f.write(contents_header) # special books @@ -296,7 +297,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): write_toc(node) f.write(contents_footer) - logger.info('writing index file...') + logger.info(__('writing index file...')) index = IndexEntries(self.env).create_index(self) with self.open_file(outdir, outname + '.hhk') as f: f.write('