mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
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:
parent
b90a52c93c
commit
e4e58a4f27
6
CHANGES
6
CHANGES
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'))
|
||||
|
@ -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."""
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
|
@ -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', []),
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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):
|
||||
|
@ -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'),
|
||||
|
@ -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()
|
||||
|
@ -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}'
|
||||
|
Loading…
Reference in New Issue
Block a user