diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index bbbcce0dc..0b31a8bcf 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -34,7 +34,9 @@ from sphinx.util.docutils import SphinxFileOutput, new_document from sphinx.util.fileutil import copy_asset_file from sphinx.util.nodes import inline_all_toctrees from sphinx.util.osutil import SEP, make_filename -from sphinx.writers.latex import DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator +from sphinx.writers.latex import ( + ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator +) if False: # For type annotation @@ -126,11 +128,14 @@ class LaTeXBuilder(Builder): def init(self): # type: () -> None + self.context = {} # type: Dict[unicode, Any] self.docnames = [] # type: Iterable[unicode] self.document_data = [] # type: List[Tuple[unicode, unicode, unicode, unicode, unicode, bool]] # NOQA self.usepackages = self.app.registry.latex_packages texescape.init() + self.init_context() + def get_outdated_docs(self): # type: () -> Union[unicode, List[unicode]] return 'all documents' # for now @@ -167,6 +172,31 @@ class LaTeXBuilder(Builder): docname = docname[:-5] self.titles.append((docname, entry[2])) + def init_context(self): + # type: () -> None + self.context = DEFAULT_SETTINGS.copy() + + # Add special settings for latex_engine + self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {})) + + # for xelatex+French, don't use polyglossia by default + if self.config.latex_engine == 'xelatex': + if self.config.language: + if self.config.language[:2] == 'fr': + self.context['polyglossia'] = '' + self.context['babel'] = r'\usepackage{babel}' + + # Apply user settings to context + self.context.update(self.config.latex_elements) + self.context['release'] = self.config.release + self.context['use_xindy'] = self.config.latex_use_xindy + + # for compatibilities + self.context['indexname'] = _('Index') + if self.config.release: + # Show the release label only if release value exists + self.context['releasename'] = _('Release') + def write_stylesheet(self): # type: () -> None highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style) @@ -210,6 +240,8 @@ class LaTeXBuilder(Builder): doctree['tocdepth'] = tocdepth self.apply_transforms(doctree) self.post_process_images(doctree) + self.update_doc_context(title, author) + logger.info(__("writing... "), nonl=1) doctree.settings = docsettings doctree.settings.author = author @@ -231,6 +263,11 @@ class LaTeXBuilder(Builder): return contentsname + def update_doc_context(self, title, author): + # type: (unicode, unicode) -> None + self.context['title'] = title + self.context['author'] = author + def assemble_doctree(self, indexfile, toctree_only, appendices): # type: (unicode, bool, List[unicode]) -> nodes.Node from docutils import nodes # NOQA diff --git a/sphinx/templates/latex/latex.tex_t b/sphinx/templates/latex/latex.tex_t index d219f8525..41c1e71b5 100644 --- a/sphinx/templates/latex/latex.tex_t +++ b/sphinx/templates/latex/latex.tex_t @@ -47,11 +47,15 @@ \release{<%= release %>} \author{<%= author %>} \newcommand{\sphinxlogo}{<%= logo %>} -\renewcommand{\releasename}{<%= releasename %>} +<%- if releasename or release %> +\renewcommand{\releasename}{<%= releasename or _('Release') %>} +<%- else %> +\renewcommand{\releasename}{} +<%- endif %> <%= makeindex %> <%= body %> <%= atendofbody %> <%= indices %> -\renewcommand{\indexname}{<%= indexname %>} +\renewcommand{\indexname}{<%= _('Index') %>} <%= printindex %> \end{document} diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 1cd5d1d7e..7fc7a811b 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -487,33 +487,10 @@ class LaTeXTranslator(nodes.NodeVisitor): self.first_param = 0 # sort out some elements - self.elements = DEFAULT_SETTINGS.copy() - self.elements.update(ADDITIONAL_SETTINGS.get(builder.config.latex_engine, {})) - # for xelatex+French, don't use polyglossia - if self.elements['latex_engine'] == 'xelatex': - if builder.config.language: - if builder.config.language[:2] == 'fr': - self.elements.update({ - 'polyglossia': '', - 'babel': '\\usepackage{babel}', - }) - # allow the user to override them all - self.elements.update(builder.config.latex_elements) + self.elements = builder.context.copy() # but some have other interface in config file - self.elements.update({ - 'wrapperclass': self.format_docclass(document.settings.docclass), - # if empty, the title is set to the first section title - 'title': document.settings.title, # treat as a raw LaTeX code - 'release': self.encode(builder.config.release), - 'author': document.settings.author, # treat as a raw LaTeX code - 'indexname': _('Index'), - 'use_xindy': builder.config.latex_use_xindy, - }) - if not self.elements['releasename'] and self.elements['release']: - self.elements.update({ - 'releasename': _('Release'), - }) + self.elements['wrapperclass'] = self.format_docclass(document.settings.docclass) # we assume LaTeX class provides \chapter command except in case # of non-Japanese 'howto' case diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 8075bf8d0..cad85272d 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -112,6 +112,7 @@ def skip_if_stylefiles_notfound(testfunc): def test_build_latex_doc(app, status, warning, engine, docclass): app.config.latex_engine = engine app.config.latex_documents[0] = app.config.latex_documents[0][:4] + (docclass,) + app.builder.init_context() LaTeXTranslator.ignore_missing_images = True app.builder.build_all() diff --git a/tests/test_markup.py b/tests/test_markup.py index 802202639..0f401306b 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -18,6 +18,7 @@ from docutils.parsers.rst import Parser as RstParser from docutils.transforms.universal import SmartQuotes from sphinx import addnodes +from sphinx.builders.latex import LaTeXBuilder from sphinx.testing.util import assert_node from sphinx.util import texescape from sphinx.util.docutils import sphinx_domains @@ -87,6 +88,9 @@ def verify_re_html(app, parse): def verify_re_latex(app, parse): def verify(rst, latex_expected): document = parse(rst) + app.builder = LaTeXBuilder(app) + app.builder.set_environment(app.env) + app.builder.init_context() latex_translator = ForgivingLaTeXTranslator(document, app.builder) latex_translator.first_document = -1 # don't write \begin{document} document.walkabout(latex_translator)