Skip to content

Commit

Permalink
Merge pull request #10067 from tk0miya/10062_change_default_language_…
Browse files Browse the repository at this point in the history
…to_en

Close #10062: Change the default language to 'en'
  • Loading branch information
tk0miya committed Jan 12, 2022
2 parents e1fa6c7 + e4e58a4 commit c5a888f
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 70 deletions.
6 changes: 6 additions & 0 deletions CHANGES
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions doc/extdev/deprecated.rst
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions sphinx/application.py
Expand Up @@ -266,7 +266,7 @@ def _init_i18n(self) -> None:
"""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),
Expand All @@ -285,8 +285,7 @@ def _init_i18n(self) -> None:
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'))
Expand Down
11 changes: 4 additions & 7 deletions sphinx/builders/html/__init__.py
Expand Up @@ -326,7 +326,7 @@ def init_js_files(self) -> None:
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:
Expand Down Expand Up @@ -431,8 +431,6 @@ def prepare_writing(self, docnames: Set[str]) -> None:
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)
Expand Down Expand Up @@ -767,10 +765,9 @@ def create_pygments_style_file(self) -> None:

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."""
Expand Down
30 changes: 12 additions & 18 deletions sphinx/builders/latex/__init__.py
Expand Up @@ -170,9 +170,8 @@ def init_context(self) -> None:
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)
Expand Down Expand Up @@ -203,7 +202,7 @@ def update_context(self) -> None:

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'),
Expand Down Expand Up @@ -232,12 +231,11 @@ def init_multilingual(self) -> None:
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()
Expand Down Expand Up @@ -380,14 +378,10 @@ def copy_support_files(self) -> None:
# 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,
Expand Down Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion sphinx/builders/latex/util.py
Expand Up @@ -20,7 +20,7 @@ def __init__(self, language_code: str, use_polyglossia: bool = False) -> None:
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
Expand Down
2 changes: 1 addition & 1 deletion sphinx/config.py
Expand Up @@ -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', []),
Expand Down
2 changes: 1 addition & 1 deletion sphinx/environment/__init__.py
Expand Up @@ -261,7 +261,7 @@ def _update_settings(self, config: Config) -> None:
"""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)
Expand Down
16 changes: 7 additions & 9 deletions sphinx/environment/collectors/asset.py
Expand Up @@ -64,18 +64,16 @@ def process_doc(self, app: Sphinx, doctree: nodes.document) -> None:
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.
Expand Down
21 changes: 12 additions & 9 deletions sphinx/util/i18n.py
Expand Up @@ -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
Expand Down Expand Up @@ -173,9 +175,11 @@ def docname_to_domain(docname: str, compaction: Union[bool, str]) -> str:
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
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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)
Expand All @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions sphinx/writers/latex.py
Expand Up @@ -333,15 +333,15 @@ def __init__(self, document: nodes.document, builder: "LaTeXBuilder",
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 +
r'\ChNameVar{\Large\normalfont\sffamily}' + CR +
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'),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_build_latex.py
Expand Up @@ -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()
Expand Down
18 changes: 0 additions & 18 deletions tests/test_util_i18n.py
Expand Up @@ -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'
Expand All @@ -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}'
Expand Down

0 comments on commit c5a888f

Please sign in to comment.