Merge pull request #10067 from tk0miya/10062_change_default_language_to_en

Close #10062: Change the default language to 'en'
This commit is contained in:
Takeshi KOMIYA 2022-01-12 23:56:41 +09:00 committed by GitHub
commit c5a888ffdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 59 additions and 70 deletions

View File

@ -21,12 +21,18 @@ Incompatible changes
intersphinx should resolve, or explicitly set the value of this configuration intersphinx should resolve, or explicitly set the value of this configuration
variable to an empty list. variable to an empty list.
* #9999: LaTeX: separate terms from their definitions by a CR (refs: #9985) * #9999: LaTeX: separate terms from their definitions by a CR (refs: #9985)
* #10062: Change the default language to ``'en'`` if any language is not set in
``conf.py``
Deprecated Deprecated
---------- ----------
* setuptools integration. The ``build_sphinx`` sub-command for setup.py is * setuptools integration. The ``build_sphinx`` sub-command for setup.py is
marked as deprecated to follow the policy of setuptools team. marked as deprecated to follow the policy of setuptools team.
* The ``locale`` argument of ``sphinx.util.i18n:babel_format_date()`` becomes
required
* The ``language`` argument of ``sphinx.util.i18n:format_date()`` becomes
required
* ``sphinx.writers.latex.LaTeXWriter.docclasses`` * ``sphinx.writers.latex.LaTeXWriter.docclasses``
Features added Features added

View File

@ -27,6 +27,16 @@ The following is a list of deprecated interfaces.
- 7.0 - 7.0
- N/A - N/A
* - The ``locale`` argument of ``sphinx.util.i18n:babel_format_date()``
- 5.0
- 7.0
- N/A
* - The ``language`` argument of ``sphinx.util.i18n:format_date()``
- 5.0
- 7.0
- N/A
* - ``sphinx.writers.latex.LaTeXWriter.docclasses`` * - ``sphinx.writers.latex.LaTeXWriter.docclasses``
- 5.0 - 5.0
- 7.0 - 7.0

View File

@ -266,7 +266,7 @@ class Sphinx:
"""Load translated strings from the configured localedirs if enabled in """Load translated strings from the configured localedirs if enabled in
the configuration. the configuration.
""" """
if self.config.language is None: if self.config.language == 'en':
self.translator, has_translation = locale.init([], None) self.translator, has_translation = locale.init([], None)
else: else:
logger.info(bold(__('loading translations [%s]... ') % self.config.language), logger.info(bold(__('loading translations [%s]... ') % self.config.language),
@ -285,8 +285,7 @@ class Sphinx:
locale_dirs += [path.join(package_dir, 'locale')] locale_dirs += [path.join(package_dir, 'locale')]
self.translator, has_translation = locale.init(locale_dirs, self.config.language) self.translator, has_translation = locale.init(locale_dirs, self.config.language)
if has_translation or self.config.language == 'en': if has_translation:
# "en" never needs to be translated
logger.info(__('done')) logger.info(__('done'))
else: else:
logger.info(__('not available for built-in messages')) logger.info(__('not available for built-in messages'))

View File

@ -326,7 +326,7 @@ class StandaloneHTMLBuilder(Builder):
attrs.setdefault('priority', 800) # User's JSs are loaded after extensions' attrs.setdefault('priority', 800) # User's JSs are loaded after extensions'
self.add_js_file(filename, **attrs) self.add_js_file(filename, **attrs)
if self.config.language and self._get_translations_js(): if self._get_translations_js():
self.add_js_file('translations.js') self.add_js_file('translations.js')
def add_js_file(self, filename: str, **kwargs: Any) -> None: def add_js_file(self, filename: str, **kwargs: Any) -> None:
@ -431,8 +431,6 @@ class StandaloneHTMLBuilder(Builder):
if self.search: if self.search:
from sphinx.search import IndexBuilder from sphinx.search import IndexBuilder
lang = self.config.html_search_language or self.config.language lang = self.config.html_search_language or self.config.language
if not lang:
lang = 'en'
self.indexer = IndexBuilder(self.env, lang, self.indexer = IndexBuilder(self.env, lang,
self.config.html_search_options, self.config.html_search_options,
self.config.html_search_scorer) self.config.html_search_scorer)
@ -767,7 +765,6 @@ class StandaloneHTMLBuilder(Builder):
def copy_translation_js(self) -> None: def copy_translation_js(self) -> None:
"""Copy a JavaScript file for translations.""" """Copy a JavaScript file for translations."""
if self.config.language is not None:
jsfile = self._get_translations_js() jsfile = self._get_translations_js()
if jsfile: if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js')) copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js'))

View File

@ -170,7 +170,6 @@ class LaTeXBuilder(Builder):
self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {})) self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {}))
# Add special settings for (latex_engine, language_code) # Add special settings for (latex_engine, language_code)
if self.config.language:
key = (self.config.latex_engine, self.config.language[:2]) key = (self.config.latex_engine, self.config.language[:2])
self.context.update(ADDITIONAL_SETTINGS.get(key, {})) self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
@ -203,7 +202,7 @@ class LaTeXBuilder(Builder):
def init_babel(self) -> None: def init_babel(self) -> None:
self.babel = ExtBabel(self.config.language, not self.context['babel']) self.babel = ExtBabel(self.config.language, not self.context['babel'])
if self.config.language and not self.babel.is_supported_language(): if not self.babel.is_supported_language():
# emit warning if specified language is invalid # emit warning if specified language is invalid
# (only emitting, nothing changed to processing) # (only emitting, nothing changed to processing)
logger.warning(__('no Babel option known for language %r'), logger.warning(__('no Babel option known for language %r'),
@ -232,7 +231,6 @@ class LaTeXBuilder(Builder):
self.context['classoptions'] += ',' + self.babel.get_language() self.context['classoptions'] += ',' + self.babel.get_language()
# this branch is not taken for xelatex/lualatex if default settings # this branch is not taken for xelatex/lualatex if default settings
self.context['multilingual'] = self.context['babel'] self.context['multilingual'] = self.context['babel']
if self.config.language:
self.context['shorthandoff'] = SHORTHANDOFF self.context['shorthandoff'] = SHORTHANDOFF
# Times fonts don't work with Cyrillic languages # Times fonts don't work with Cyrillic languages
@ -380,14 +378,10 @@ class LaTeXBuilder(Builder):
# configure usage of xindy (impacts Makefile and latexmkrc) # configure usage of xindy (impacts Makefile and latexmkrc)
# FIXME: convert this rather to a confval with suitable default # FIXME: convert this rather to a confval with suitable default
# according to language ? but would require extra documentation # according to language ? but would require extra documentation
if self.config.language: xindy_lang_option = XINDY_LANG_OPTIONS.get(self.config.language[:2],
xindy_lang_option = \
XINDY_LANG_OPTIONS.get(self.config.language[:2],
'-L general -C utf8 ') '-L general -C utf8 ')
xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
else:
xindy_lang_option = '-L english -C utf8 '
xindy_cyrillic = False
context = { context = {
'latex_engine': self.config.latex_engine, 'latex_engine': self.config.latex_engine,
'xindy_use': self.config.latex_use_xindy, 'xindy_use': self.config.latex_use_xindy,
@ -474,7 +468,7 @@ def default_latex_engine(config: Config) -> str:
""" Better default latex_engine settings for specific languages. """ """ Better default latex_engine settings for specific languages. """
if config.language == 'ja': if config.language == 'ja':
return 'uplatex' return 'uplatex'
elif (config.language or '').startswith('zh'): elif config.language.startswith('zh'):
return 'xelatex' return 'xelatex'
elif config.language == 'el': elif config.language == 'el':
return 'xelatex' return 'xelatex'

View File

@ -20,7 +20,7 @@ class ExtBabel(Babel):
self.language_code = language_code self.language_code = language_code
self.use_polyglossia = use_polyglossia self.use_polyglossia = use_polyglossia
self.supported = True self.supported = True
super().__init__(language_code or '') super().__init__(language_code)
def uses_cyrillic(self) -> bool: def uses_cyrillic(self) -> bool:
return self.language in self.cyrillic_languages return self.language in self.cyrillic_languages

View File

@ -100,7 +100,7 @@ class Config:
# the real default is locale-dependent # the real default is locale-dependent
'today_fmt': (None, 'env', [str]), 'today_fmt': (None, 'env', [str]),
'language': (None, 'env', [str]), 'language': ('en', 'env', [str]),
'locale_dirs': (['locales'], 'env', []), 'locale_dirs': (['locales'], 'env', []),
'figure_language_filename': ('{root}.{language}{ext}', 'env', [str]), 'figure_language_filename': ('{root}.{language}{ext}', 'env', [str]),
'gettext_allow_fuzzy_translations': (False, 'gettext', []), 'gettext_allow_fuzzy_translations': (False, 'gettext', []),

View File

@ -261,7 +261,7 @@ class BuildEnvironment:
"""Update settings by new config.""" """Update settings by new config."""
self.settings['input_encoding'] = config.source_encoding self.settings['input_encoding'] = config.source_encoding
self.settings['trim_footnote_reference_space'] = config.trim_footnote_reference_space self.settings['trim_footnote_reference_space'] = config.trim_footnote_reference_space
self.settings['language_code'] = config.language or 'en' self.settings['language_code'] = config.language
# Allow to disable by 3rd party extension (workaround) # Allow to disable by 3rd party extension (workaround)
self.settings.setdefault('smart_quotes', True) self.settings.setdefault('smart_quotes', True)

View File

@ -64,7 +64,6 @@ class ImageCollector(EnvironmentCollector):
rel_imgpath, full_imgpath = app.env.relfn2path(imguri, docname) rel_imgpath, full_imgpath = app.env.relfn2path(imguri, docname)
node['uri'] = rel_imgpath node['uri'] = rel_imgpath
if app.config.language:
# Search language-specific figures at first # Search language-specific figures at first
i18n_imguri = get_image_filename_for_language(imguri, app.env) i18n_imguri = get_image_filename_for_language(imguri, app.env)
_, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname) _, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname)
@ -72,7 +71,6 @@ class ImageCollector(EnvironmentCollector):
self.collect_candidates(app.env, full_imgpath, candidates, node) self.collect_candidates(app.env, full_imgpath, candidates, node)
else: else:
if app.config.language:
# substitute imguri by figure_language_filename # substitute imguri by figure_language_filename
# (ex. foo.png -> foo.en.png) # (ex. foo.png -> foo.en.png)
imguri = search_image_for_language(imguri, app.env) imguri = search_image_for_language(imguri, app.env)

View File

@ -10,14 +10,16 @@
import os import os
import re import re
import warnings
from datetime import datetime, timezone from datetime import datetime, timezone
from os import path from os import path
from typing import TYPE_CHECKING, Callable, Generator, List, NamedTuple, Optional, Tuple, Union from typing import TYPE_CHECKING, Callable, Generator, List, NamedTuple, Tuple, Union
import babel.dates import babel.dates
from babel.messages.mofile import write_mo from babel.messages.mofile import write_mo
from babel.messages.pofile import read_po from babel.messages.pofile import read_po
from sphinx.deprecation import RemovedInSphinx70Warning
from sphinx.errors import SphinxError from sphinx.errors import SphinxError
from sphinx.locale import __ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
@ -173,9 +175,11 @@ date_format_mappings = {
date_format_re = re.compile('(%s)' % '|'.join(date_format_mappings)) date_format_re = re.compile('(%s)' % '|'.join(date_format_mappings))
def babel_format_date(date: datetime, format: str, locale: Optional[str], def babel_format_date(date: datetime, format: str, locale: str,
formatter: Callable = babel.dates.format_date) -> str: formatter: Callable = babel.dates.format_date) -> str:
if locale is None: if locale is None:
warnings.warn('The locale argument for babel_format_date() becomes required.',
RemovedInSphinx70Warning)
locale = 'en' locale = 'en'
# Check if we have the tzinfo attribute. If not we cannot do any time # Check if we have the tzinfo attribute. If not we cannot do any time
@ -194,7 +198,7 @@ def babel_format_date(date: datetime, format: str, locale: Optional[str],
return format return format
def format_date(format: str, date: datetime = None, language: Optional[str] = None) -> str: def format_date(format: str, date: datetime = None, language: str = None) -> str:
if date is None: if date is None:
# If time is not specified, try to use $SOURCE_DATE_EPOCH variable # If time is not specified, try to use $SOURCE_DATE_EPOCH variable
# See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal # See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal
@ -204,6 +208,11 @@ def format_date(format: str, date: datetime = None, language: Optional[str] = No
else: else:
date = datetime.now(timezone.utc).astimezone() date = datetime.now(timezone.utc).astimezone()
if language is None:
warnings.warn('The language argument for format_date() becomes required.',
RemovedInSphinx70Warning)
language = 'en'
result = [] result = []
tokens = date_format_re.split(format) tokens = date_format_re.split(format)
for token in tokens: for token in tokens:
@ -229,9 +238,6 @@ def format_date(format: str, date: datetime = None, language: Optional[str] = No
def get_image_filename_for_language(filename: str, env: "BuildEnvironment") -> str: def get_image_filename_for_language(filename: str, env: "BuildEnvironment") -> str:
if not env.config.language:
return filename
filename_format = env.config.figure_language_filename filename_format = env.config.figure_language_filename
d = dict() d = dict()
d['root'], d['ext'] = path.splitext(filename) d['root'], d['ext'] = path.splitext(filename)
@ -252,9 +258,6 @@ def get_image_filename_for_language(filename: str, env: "BuildEnvironment") -> s
def search_image_for_language(filename: str, env: "BuildEnvironment") -> str: def search_image_for_language(filename: str, env: "BuildEnvironment") -> str:
if not env.config.language:
return filename
translated = get_image_filename_for_language(filename, env) translated = get_image_filename_for_language(filename, env)
_, abspath = env.relfn2path(translated) _, abspath = env.relfn2path(translated)
if path.exists(abspath): if path.exists(abspath):

View File

@ -333,7 +333,7 @@ class LaTeXTranslator(SphinxTranslator):
if self.config.numfig and self.config.math_numfig: if self.config.numfig and self.config.math_numfig:
sphinxpkgoptions.append('mathnumfig') sphinxpkgoptions.append('mathnumfig')
if (self.config.language not in {None, 'en', 'ja'} and if (self.config.language not in {'en', 'ja'} and
'fncychap' not in self.config.latex_elements): 'fncychap' not in self.config.latex_elements):
# use Sonny style if any language specified (except English) # use Sonny style if any language specified (except English)
self.elements['fncychap'] = (r'\usepackage[Sonny]{fncychap}' + CR + self.elements['fncychap'] = (r'\usepackage[Sonny]{fncychap}' + CR +
@ -341,7 +341,7 @@ class LaTeXTranslator(SphinxTranslator):
r'\ChTitleVar{\Large\normalfont\sffamily}') r'\ChTitleVar{\Large\normalfont\sffamily}')
self.babel = self.builder.babel self.babel = self.builder.babel
if self.config.language and not self.babel.is_supported_language(): if not self.babel.is_supported_language():
# emit warning if specified language is invalid # emit warning if specified language is invalid
# (only emitting, nothing changed to processing) # (only emitting, nothing changed to processing)
logger.warning(__('no Babel option known for language %r'), logger.warning(__('no Babel option known for language %r'),

View File

@ -528,7 +528,7 @@ def test_babel_with_no_language_settings(app, status, warning):
assert '\\usepackage[Bjarne]{fncychap}' in result assert '\\usepackage[Bjarne]{fncychap}' in result
assert ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n' assert ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n'
in result) in result)
assert '\\shorthandoff' not in result assert '\\shorthandoff{"}' in result
# sphinxmessages.sty # sphinxmessages.sty
result = (app.outdir / 'sphinxmessages.sty').read_text() result = (app.outdir / 'sphinxmessages.sty').read_text()

View File

@ -98,15 +98,6 @@ def test_format_date():
def test_get_filename_for_language(app): def test_get_filename_for_language(app):
app.env.temp_data['docname'] = 'index' app.env.temp_data['docname'] = 'index'
# language is None
app.env.config.language = None
assert app.env.config.language is None
assert i18n.get_image_filename_for_language('foo.png', app.env) == 'foo.png'
assert i18n.get_image_filename_for_language('foo.bar.png', app.env) == 'foo.bar.png'
assert i18n.get_image_filename_for_language('subdir/foo.png', app.env) == 'subdir/foo.png'
assert i18n.get_image_filename_for_language('../foo.png', app.env) == '../foo.png'
assert i18n.get_image_filename_for_language('foo', app.env) == 'foo'
# language is en # language is en
app.env.config.language = 'en' app.env.config.language = 'en'
assert i18n.get_image_filename_for_language('foo.png', app.env) == 'foo.en.png' assert i18n.get_image_filename_for_language('foo.png', app.env) == 'foo.en.png'
@ -115,15 +106,6 @@ def test_get_filename_for_language(app):
assert i18n.get_image_filename_for_language('../foo.png', app.env) == '../foo.en.png' assert i18n.get_image_filename_for_language('../foo.png', app.env) == '../foo.en.png'
assert i18n.get_image_filename_for_language('foo', app.env) == 'foo.en' assert i18n.get_image_filename_for_language('foo', app.env) == 'foo.en'
# modify figure_language_filename and language is None
app.env.config.language = None
app.env.config.figure_language_filename = 'images/{language}/{root}{ext}'
assert i18n.get_image_filename_for_language('foo.png', app.env) == 'foo.png'
assert i18n.get_image_filename_for_language('foo.bar.png', app.env) == 'foo.bar.png'
assert i18n.get_image_filename_for_language('subdir/foo.png', app.env) == 'subdir/foo.png'
assert i18n.get_image_filename_for_language('../foo.png', app.env) == '../foo.png'
assert i18n.get_image_filename_for_language('foo', app.env) == 'foo'
# modify figure_language_filename and language is 'en' # modify figure_language_filename and language is 'en'
app.env.config.language = 'en' app.env.config.language = 'en'
app.env.config.figure_language_filename = 'images/{language}/{root}{ext}' app.env.config.figure_language_filename = 'images/{language}/{root}{ext}'