Close #10062: Change the default language to 'en'

Change the default language to `'en'` if any language is not set in
`conf.py`.
This commit is contained in:
Takeshi KOMIYA 2022-01-09 01:02:32 +09:00
parent b90a52c93c
commit e4e58a4f27
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
variable to an empty list.
* #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
----------
* setuptools integration. The ``build_sphinx`` sub-command for setup.py is
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``
Features added

View File

@ -27,6 +27,16 @@ The following is a list of deprecated interfaces.
- 7.0
- 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``
- 5.0
- 7.0

View File

@ -266,7 +266,7 @@ class Sphinx:
"""Load translated strings from the configured localedirs if enabled in
the configuration.
"""
if self.config.language is None:
if self.config.language == 'en':
self.translator, has_translation = locale.init([], None)
else:
logger.info(bold(__('loading translations [%s]... ') % self.config.language),
@ -285,8 +285,7 @@ class Sphinx:
locale_dirs += [path.join(package_dir, 'locale')]
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
if has_translation or self.config.language == 'en':
# "en" never needs to be translated
if has_translation:
logger.info(__('done'))
else:
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'
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')
def add_js_file(self, filename: str, **kwargs: Any) -> None:
@ -431,8 +431,6 @@ class StandaloneHTMLBuilder(Builder):
if self.search:
from sphinx.search import IndexBuilder
lang = self.config.html_search_language or self.config.language
if not lang:
lang = 'en'
self.indexer = IndexBuilder(self.env, lang,
self.config.html_search_options,
self.config.html_search_scorer)
@ -767,10 +765,9 @@ class StandaloneHTMLBuilder(Builder):
def copy_translation_js(self) -> None:
"""Copy a JavaScript file for translations."""
if self.config.language is not None:
jsfile = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js'))
jsfile = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js'))
def copy_stemmer_js(self) -> None:
"""Copy a JavaScript file for stemmer."""

View File

@ -170,9 +170,8 @@ class LaTeXBuilder(Builder):
self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {}))
# Add special settings for (latex_engine, language_code)
if self.config.language:
key = (self.config.latex_engine, self.config.language[:2])
self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
key = (self.config.latex_engine, self.config.language[:2])
self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
# Apply user settings to context
self.context.update(self.config.latex_elements)
@ -203,7 +202,7 @@ class LaTeXBuilder(Builder):
def init_babel(self) -> None:
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
# (only emitting, nothing changed to processing)
logger.warning(__('no Babel option known for language %r'),
@ -232,12 +231,11 @@ class LaTeXBuilder(Builder):
self.context['classoptions'] += ',' + self.babel.get_language()
# this branch is not taken for xelatex/lualatex if default settings
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
if self.babel.uses_cyrillic() and 'fontpkg' not in self.config.latex_elements:
self.context['fontpkg'] = ''
# Times fonts don't work with Cyrillic languages
if self.babel.uses_cyrillic() and 'fontpkg' not in self.config.latex_elements:
self.context['fontpkg'] = ''
elif self.context['polyglossia']:
self.context['classoptions'] += ',' + self.babel.get_language()
options = self.babel.get_mainlanguage_options()
@ -380,14 +378,10 @@ class LaTeXBuilder(Builder):
# configure usage of xindy (impacts Makefile and latexmkrc)
# FIXME: convert this rather to a confval with suitable default
# according to language ? but would require extra documentation
if self.config.language:
xindy_lang_option = \
XINDY_LANG_OPTIONS.get(self.config.language[:2],
'-L general -C utf8 ')
xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
else:
xindy_lang_option = '-L english -C utf8 '
xindy_cyrillic = False
xindy_lang_option = XINDY_LANG_OPTIONS.get(self.config.language[:2],
'-L general -C utf8 ')
xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
context = {
'latex_engine': self.config.latex_engine,
'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. """
if config.language == 'ja':
return 'uplatex'
elif (config.language or '').startswith('zh'):
elif config.language.startswith('zh'):
return 'xelatex'
elif config.language == 'el':
return 'xelatex'

View File

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

View File

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

View File

@ -261,7 +261,7 @@ class BuildEnvironment:
"""Update settings by new config."""
self.settings['input_encoding'] = config.source_encoding
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)
self.settings.setdefault('smart_quotes', True)

View File

@ -64,18 +64,16 @@ class ImageCollector(EnvironmentCollector):
rel_imgpath, full_imgpath = app.env.relfn2path(imguri, docname)
node['uri'] = rel_imgpath
if app.config.language:
# Search language-specific figures at first
i18n_imguri = get_image_filename_for_language(imguri, app.env)
_, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname)
self.collect_candidates(app.env, full_i18n_imgpath, candidates, node)
# Search language-specific figures at first
i18n_imguri = get_image_filename_for_language(imguri, app.env)
_, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname)
self.collect_candidates(app.env, full_i18n_imgpath, candidates, node)
self.collect_candidates(app.env, full_imgpath, candidates, node)
else:
if app.config.language:
# substitute imguri by figure_language_filename
# (ex. foo.png -> foo.en.png)
imguri = search_image_for_language(imguri, app.env)
# substitute imguri by figure_language_filename
# (ex. foo.png -> foo.en.png)
imguri = search_image_for_language(imguri, app.env)
# Update `node['uri']` to a relative path from srcdir
# from a relative path from current document.

View File

@ -10,14 +10,16 @@
import os
import re
import warnings
from datetime import datetime, timezone
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
from babel.messages.mofile import write_mo
from babel.messages.pofile import read_po
from sphinx.deprecation import RemovedInSphinx70Warning
from sphinx.errors import SphinxError
from sphinx.locale import __
from sphinx.util import logging
@ -173,9 +175,11 @@ 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:
if locale is None:
warnings.warn('The locale argument for babel_format_date() becomes required.',
RemovedInSphinx70Warning)
locale = 'en'
# 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
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 time is not specified, try to use $SOURCE_DATE_EPOCH variable
# See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal
@ -204,6 +208,11 @@ def format_date(format: str, date: datetime = None, language: Optional[str] = No
else:
date = datetime.now(timezone.utc).astimezone()
if language is None:
warnings.warn('The language argument for format_date() becomes required.',
RemovedInSphinx70Warning)
language = 'en'
result = []
tokens = date_format_re.split(format)
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:
if not env.config.language:
return filename
filename_format = env.config.figure_language_filename
d = dict()
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:
if not env.config.language:
return filename
translated = get_image_filename_for_language(filename, env)
_, abspath = env.relfn2path(translated)
if path.exists(abspath):

View File

@ -333,7 +333,7 @@ class LaTeXTranslator(SphinxTranslator):
if self.config.numfig and self.config.math_numfig:
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):
# use Sonny style if any language specified (except English)
self.elements['fncychap'] = (r'\usepackage[Sonny]{fncychap}' + CR +
@ -341,7 +341,7 @@ class LaTeXTranslator(SphinxTranslator):
r'\ChTitleVar{\Large\normalfont\sffamily}')
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
# (only emitting, nothing changed to processing)
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 ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n'
in result)
assert '\\shorthandoff' not in result
assert '\\shorthandoff{"}' in result
# sphinxmessages.sty
result = (app.outdir / 'sphinxmessages.sty').read_text()

View File

@ -98,15 +98,6 @@ def test_format_date():
def test_get_filename_for_language(app):
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
app.env.config.language = 'en'
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', 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'
app.env.config.language = 'en'
app.env.config.figure_language_filename = 'images/{language}/{root}{ext}'