diff --git a/CHANGES b/CHANGES
index 1bf3f113c..ada67e572 100644
--- a/CHANGES
+++ b/CHANGES
@@ -34,9 +34,10 @@ Incompatible changes
* #1857: latex: :confval:`latex_show_pagerefs` does not add pagerefs for
citations
* #4648: latex: Now "rubric" elements are rendered as unnumbered section title
-* #4983: html: The URL for the productionlist has been changed
+* #4983: html: The anchor for productionlist tokens has been changed
* Modifying a template variable ``script_files`` in templates is allowed now.
Please use ``app.add_js_file()`` instead.
+* #5072: Save environment object also with only new documents
* #5035: qthelp builder allows dashes in :confval:`qthelp_namespace`
Deprecated
@@ -138,6 +139,9 @@ Features added
* html: Output ``canonical_url`` metadata if :confval:`html_baseurl` set (refs:
#4193)
* #5029: autosummary: expose ``inherited_members`` to template
+* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
+ for mathjax
+* #4362: latex: Don't overwrite .tex file if document not changed
Bugs fixed
----------
@@ -156,6 +160,11 @@ Features removed
* ``sphinx.ext.pngmath`` extension
+Documentation
+-------------
+
+* #5083: Fix wrong make.bat option for internationalization.
+
Release 1.7.6 (in development)
==============================
@@ -187,6 +196,8 @@ Bugs fixed
* #5019: autodoc: crashed by Form Feed Character
* #5032: autodoc: loses the first staticmethod parameter for old styled classes
* #5036: quickstart: Typing Ctrl-U clears the whole of line
+* #5066: html: "relations" sidebar is not shown by default
+* #5091: latex: curly braces in index entries are not handled correctly
Testing
--------
diff --git a/EXAMPLES b/EXAMPLES
index ee9d4a128..94aade9bc 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -195,6 +195,7 @@ Documentation using sphinx_rtd_theme
* Julia: https://julia.readthedocs.io/
* Jupyter Notebook: https://jupyter-notebook.readthedocs.io/
* Lasagne: https://lasagne.readthedocs.io/
+* latexindent.pl: https://latexindentpl.readthedocs.io/
* Linguistica: https://linguistica-uchicago.github.io/lxa5/
* Linux kernel: https://www.kernel.org/doc/html/latest/index.html
* MathJax: https://docs.mathjax.org/
diff --git a/doc/Makefile b/doc/Makefile
index 293ccca2e..4d2067071 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,9 +1,10 @@
# Makefile for Sphinx documentation
#
+PYTHON ?= python
# You can set these variables from the command line.
SPHINXOPTS =
-SPHINXBUILD = python3 ../sphinx/cmd/build.py
+SPHINXBUILD = $(PYTHON) ../sphinx/cmd/build.py
SPHINXPROJ = sphinx
SOURCEDIR = .
BUILDDIR = _build
diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html
index e1747c762..94174ce90 100644
--- a/doc/_templates/indexsidebar.html
+++ b/doc/_templates/indexsidebar.html
@@ -3,19 +3,9 @@
{%trans%}project{%endtrans%}
Download
-{% if version.endswith('+') %}
-{%trans%}This documentation is for version {{ version }} , which is
- not released yet.{%endtrans%}
-{%trans%}You can use it from the
- Git repo or look for
- released versions in the Python
- Package Index .{%endtrans%}
-{% else %}
-{%trans%}Current version: {{ version }} {%endtrans%}
-{%trans%}Get Sphinx from the Python Package
-Index , or install it with:{%endtrans%}
+{%trans%}Current version: {%endtrans%}
+{%trans%}Install Sphinx with:{%endtrans%}
pip install -U Sphinx
-{% endif %}
{%trans%}Questions? Suggestions?{%endtrans%}
diff --git a/doc/_themes/sphinx13/static/sphinx13.css b/doc/_themes/sphinx13/static/sphinx13.css
index eff18df3c..c2afc2a7c 100644
--- a/doc/_themes/sphinx13/static/sphinx13.css
+++ b/doc/_themes/sphinx13/static/sphinx13.css
@@ -140,6 +140,10 @@ div.sphinxsidebar .logo img {
vertical-align: middle;
}
+div.sphinxsidebar .download a img {
+ vertical-align: middle;
+}
+
div.subscribeformwrapper {
display: block;
overflow: auto;
diff --git a/doc/ext/math.rst b/doc/ext/math.rst
index c00713a3d..c299b7bee 100644
--- a/doc/ext/math.rst
+++ b/doc/ext/math.rst
@@ -260,6 +260,16 @@ Sphinx.
You can also give a full ``https://`` URL different from the CDN URL.
+.. confval:: mathjax_options
+
+ The options to script tag for mathjax. For example, you can set integrity
+ option with following setting::
+
+ mathjax_options = {
+ 'integrity': 'sha384-......',
+ }
+
+ The default is empty (``{}``).
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
------------------------------------------------------
diff --git a/doc/intl.rst b/doc/intl.rst
index 43f620bd0..129665dde 100644
--- a/doc/intl.rst
+++ b/doc/intl.rst
@@ -123,14 +123,14 @@ This section describe an easy way to translate with sphinx-intl.
.. code-block:: console
- > set SPHINXOPTS=-D language='de'
+ > set SPHINXOPTS=-D language=de
> .\make.bat html
command line (for PowerShell):
.. code-block:: console
- > Set-Item env:SPHINXOPTS "-D language='de'"
+ > Set-Item env:SPHINXOPTS "-D language=de"
> .\make.bat html
diff --git a/doc/make.bat b/doc/make.bat
index 0a4bd77b9..1e6dc991e 100644
--- a/doc/make.bat
+++ b/doc/make.bat
@@ -3,7 +3,7 @@
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=python ../sphinx-build.py
+ set SPHINXBUILD=python ../sphinx/cmd/build.py
)
set SOURCEDIR=.
set BUILDDIR=_build
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index 7cfacbd3c..e446ca94a 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -372,14 +372,14 @@ class Builder(object):
else:
logger.info(__('none found'))
- if updated_docnames:
- # save the environment
- from sphinx.application import ENV_PICKLE_FILENAME
- logger.info(bold(__('pickling environment... ')), nonl=True)
- with open(path.join(self.doctreedir, ENV_PICKLE_FILENAME), 'wb') as f:
- pickle.dump(self.env, f, pickle.HIGHEST_PROTOCOL)
- logger.info(__('done'))
+ # save the environment
+ from sphinx.application import ENV_PICKLE_FILENAME
+ logger.info(bold(__('pickling environment... ')), nonl=True)
+ with open(path.join(self.doctreedir, ENV_PICKLE_FILENAME), 'wb') as f:
+ pickle.dump(self.env, f, pickle.HIGHEST_PROTOCOL)
+ logger.info(__('done'))
+ if updated_docnames:
# global actions
self.app.phase = BuildPhase.CONSISTENCY_CHECK
logger.info(bold(__('checking consistency... ')), nonl=True)
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index b98d4104a..62e0a28d7 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -1014,19 +1014,27 @@ class StandaloneHTMLBuilder(Builder):
def has_wildcard(pattern):
# type: (unicode) -> bool
return any(char in pattern for char in '*?[')
- sidebars = self.theme.get_config('theme', 'sidebars', None)
+ sidebars = None
matched = None
customsidebar = None
# default sidebars settings for selected theme
- theme_default_sidebars = self.theme.get_config('theme', 'sidebars', None)
- if theme_default_sidebars:
- sidebars = [name.strip() for name in theme_default_sidebars.split(',')]
- elif self.theme.name == 'alabaster':
+ if self.theme.name == 'alabaster':
# provide default settings for alabaster (for compatibility)
# Note: this will be removed before Sphinx-2.0
- sidebars = ['about.html', 'navigation.html', 'relation.html',
- 'searchbox.html', 'donate.html']
+ try:
+ # get default sidebars settings from alabaster (if defined)
+ theme_default_sidebars = self.theme.config.get('theme', 'sidebars')
+ if theme_default_sidebars:
+ sidebars = [name.strip() for name in theme_default_sidebars.split(',')]
+ except Exception:
+ # fallback to better default settings
+ sidebars = ['about.html', 'navigation.html', 'relations.html',
+ 'searchbox.html', 'donate.html']
+ else:
+ theme_default_sidebars = self.theme.get_config('theme', 'sidebars', None)
+ if theme_default_sidebars:
+ sidebars = [name.strip() for name in theme_default_sidebars.split(',')]
# user sidebar settings
for pattern, patsidebars in iteritems(self.config.html_sidebars):
diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py
index 32e813241..382914731 100644
--- a/sphinx/builders/latex/__init__.py
+++ b/sphinx/builders/latex/__init__.py
@@ -13,7 +13,6 @@ import os
from os import path
from docutils.frontend import OptionParser
-from docutils.io import FileOutput
from six import text_type
from sphinx import package_dir, addnodes, highlighting
@@ -31,7 +30,7 @@ from sphinx.locale import _, __
from sphinx.transforms import SphinxTransformer
from sphinx.util import texescape, logging, status_iterator
from sphinx.util.console import bold, darkgreen # type: ignore
-from sphinx.util.docutils import new_document
+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
@@ -134,9 +133,8 @@ class LaTeXBuilder(Builder):
toctree_only = False
if len(entry) > 5:
toctree_only = entry[5]
- destination = FileOutput(
- destination_path=path.join(self.outdir, targetname),
- encoding='utf-8')
+ destination = SphinxFileOutput(destination_path=path.join(self.outdir, targetname),
+ encoding='utf-8', overwrite_if_changed=True)
logger.info(__("processing %s..."), targetname, nonl=1)
toctrees = self.env.get_doctree(docname).traverse(addnodes.toctree)
if toctrees:
diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py
index 8aeafefc7..0d73f3d3d 100644
--- a/sphinx/ext/mathjax.py
+++ b/sphinx/ext/mathjax.py
@@ -74,6 +74,8 @@ def builder_inited(app):
'mathjax extension to work')
if app.builder.format == 'html':
options = {'async': 'async'}
+ if app.config.mathjax_options:
+ options.update(app.config.mathjax_options)
app.builder.add_js_file(app.config.mathjax_path, **options) # type: ignore
@@ -88,7 +90,8 @@ def setup(app):
# https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
app.add_config_value('mathjax_path',
'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?'
- 'config=TeX-AMS-MML_HTMLorMML', False)
+ 'config=TeX-AMS-MML_HTMLorMML', 'html')
+ app.add_config_value('mathjax_options', {}, 'html')
app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
app.connect('builder-inited', builder_inited)
diff --git a/sphinx/themes/basic/search.html b/sphinx/themes/basic/search.html
index 6264d0414..57030d83a 100644
--- a/sphinx/themes/basic/search.html
+++ b/sphinx/themes/basic/search.html
@@ -9,10 +9,10 @@
#}
{%- extends "layout.html" %}
{% set title = _('Search') %}
-{%- macro script() %}
+{%- block scripts %}
{{ super() }}
-{%- endmacro %}
+{%- endblock %}
{% block extrahead %}
-{%- endmacro %}
+{%- endblock %}
{# put the sidebar before the body #}
{% block sidebar1 %}{{ sidebar() }}{% endblock %}
diff --git a/sphinx/themes/classic/layout.html b/sphinx/themes/classic/layout.html
index 3ba9ad57f..8042e3f7e 100644
--- a/sphinx/themes/classic/layout.html
+++ b/sphinx/themes/classic/layout.html
@@ -10,8 +10,8 @@
{%- extends "basic/layout.html" %}
{% if theme_collapsiblesidebar|tobool %}
-{%- macro script() %}
+{%- block scripts %}
{{ super() }}
-{%- endmacro %}
+{%- endblock %}
{% endif %}
diff --git a/sphinx/themes/scrolls/layout.html b/sphinx/themes/scrolls/layout.html
index 1b58a6d46..7bb7b19e3 100644
--- a/sphinx/themes/scrolls/layout.html
+++ b/sphinx/themes/scrolls/layout.html
@@ -13,10 +13,10 @@
{{ super() }}
{%- endblock %}
-{%- macro script() %}
+{%- block scripts %}
{{ super() }}
-{%- endmacro %}
+{%- endblock %}
{# do not display relbars #}
{% block relbar1 %}{% endblock %}
{% block relbar2 %}{% endblock %}
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py
index d96ab843c..547d74c17 100644
--- a/sphinx/util/docutils.py
+++ b/sphinx/util/docutils.py
@@ -10,6 +10,7 @@
"""
from __future__ import absolute_import
+import codecs
import os
import re
import types
@@ -21,6 +22,7 @@ from os import path
import docutils
from docutils import nodes
+from docutils.io import FileOutput
from docutils.parsers.rst import Directive, directives, roles, convert_directive_function
from docutils.statemachine import StateMachine
from docutils.utils import Reporter
@@ -300,6 +302,26 @@ def switch_source_input(state, content):
state.memo.reporter.get_source_and_line = get_source_and_line
+class SphinxFileOutput(FileOutput):
+ """Better FileOutput class for Sphinx."""
+
+ def __init__(self, **kwargs):
+ # type: (Any) -> None
+ self.overwrite_if_changed = kwargs.pop('overwrite_if_changed', False)
+ FileOutput.__init__(self, **kwargs)
+
+ def write(self, data):
+ # type: (unicode) -> unicode
+ if (self.destination_path and self.autoclose and 'b' not in self.mode and
+ self.overwrite_if_changed and os.path.exists(self.destination_path)):
+ with codecs.open(self.destination_path, encoding=self.encoding) as f:
+ # skip writing: content not changed
+ if f.read() == data:
+ return data
+
+ return FileOutput.write(self, data)
+
+
class SphinxDirective(Directive):
"""A base class for Sphinx directives.
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index db58780f1..e4fdf3ca1 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -1894,8 +1894,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
# type: (nodes.Node, Pattern) -> None
def escape(value):
value = self.encode(value)
- value = value.replace(r'\{', r'\sphinxleftcurlybrace')
- value = value.replace(r'\}', r'\sphinxrightcurlybrace')
+ value = value.replace(r'\{', r'{\sphinxleftcurlybrace}')
+ value = value.replace(r'\}', r'{\sphinxrightcurlybrace}')
return value
if not node.get('inline', True):
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index 50e323a23..68017a80d 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -1245,21 +1245,50 @@ def test_html_remote_images(app, status, warning):
@pytest.mark.sphinx('html', testroot='basic')
def test_html_sidebar(app, status, warning):
+ ctx = {}
+
+ # default for alabaster
app.builder.build_all()
result = (app.outdir / 'index.html').text(encoding='utf8')
- assert '' in result
+ assert ('