summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--doc/extdev/appapi.rst3
-rw-r--r--sphinx/application.py10
-rw-r--r--sphinx/builders/html/__init__.py8
-rw-r--r--sphinx/domains/math.py7
-rw-r--r--sphinx/ext/mathjax.py27
-rw-r--r--tests/roots/test-ext-math/index.rst1
-rw-r--r--tests/roots/test-ext-math/nomath.rst0
-rw-r--r--tests/test_ext_math.py13
9 files changed, 55 insertions, 18 deletions
diff --git a/CHANGES b/CHANGES
index 253fcd8c2..36d191821 100644
--- a/CHANGES
+++ b/CHANGES
@@ -22,8 +22,12 @@ Features added
* #8619: html: kbd role generates customizable HTML tags for compound keys
* #8634: html: Allow to change the order of JS/CSS via ``priority`` parameter
for :meth:`Sphinx.add_js_file()` and :meth:`Sphinx.add_css_file()`
+* #6241: html: Allow to add JS/CSS files to the specific page when an extension
+ calls ``app.add_js_file()`` or ``app.add_css_file()`` on
+ :event:`html-page-context` event
* #8649: imgconverter: Skip availability check if builder supports the image
type
+* #6241: mathjax: Include mathjax.js only on the document using equations
* #8132: Add :confval:`project_copyright` as an alias of :confval:`copyright`
Bugs fixed
diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst
index 9f2c10676..a42e9184a 100644
--- a/doc/extdev/appapi.rst
+++ b/doc/extdev/appapi.rst
@@ -369,6 +369,9 @@ Here is a more detailed list of these events.
You can return a string from the handler, it will then replace
``'page.html'`` as the HTML template for this page.
+ .. note:: You can install JS/CSS files for the specific page via
+ :meth:`Sphinx.add_js_file` and :meth:`Sphinx.add_css_file` since v3.5.0.
+
.. versionadded:: 0.4
.. versionchanged:: 1.3
diff --git a/sphinx/application.py b/sphinx/application.py
index 2252705c0..54a2603aa 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -958,6 +958,9 @@ class Sphinx:
* - 800
- default priority for :confval:`html_js_files`
+ A JavaScript file can be added to the specific HTML page when on extension
+ calls this method on :event:`html-page-context` event.
+
.. versionadded:: 0.5
.. versionchanged:: 1.8
@@ -965,7 +968,7 @@ class Sphinx:
And it allows keyword arguments as attributes of script tag.
.. versionchanged:: 3.5
- Take priority argument.
+ Take priority argument. Allow to add a JavaScript file to the specific page.
"""
self.registry.add_js_file(filename, priority=priority, **kwargs)
if hasattr(self.builder, 'add_js_file'):
@@ -1004,6 +1007,9 @@ class Sphinx:
* - 800
- default priority for :confval:`html_css_files`
+ A CSS file can be added to the specific HTML page when on extension calls
+ this method on :event:`html-page-context` event.
+
.. versionadded:: 1.0
.. versionchanged:: 1.6
@@ -1018,7 +1024,7 @@ class Sphinx:
And it allows keyword arguments as attributes of link tag.
.. versionchanged:: 3.5
- Take priority argument.
+ Take priority argument. Allow to add a CSS file to the specific page.
"""
logger.debug('[app] adding stylesheet: %r', filename)
self.registry.add_css_files(filename, priority=priority, **kwargs)
diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py
index 84efa0cc0..4bb7ee510 100644
--- a/sphinx/builders/html/__init__.py
+++ b/sphinx/builders/html/__init__.py
@@ -466,6 +466,10 @@ class StandaloneHTMLBuilder(Builder):
rellinks.append((indexname, indexcls.localname,
'', indexcls.shortname))
+ # back up script_files and css_files to allow adding JS/CSS files to a specific page.
+ self._script_files = list(self.script_files)
+ self._css_files = list(self.css_files)
+
if self.config.html_style is not None:
stylename = self.config.html_style
elif self.theme:
@@ -1016,6 +1020,10 @@ class StandaloneHTMLBuilder(Builder):
self.add_sidebars(pagename, ctx)
ctx.update(addctx)
+ # revert script_files and css_files
+ self.script_files[:] = self._script_files
+ self.css_files[:] = self.css_files
+
self.update_page_context(pagename, templatename, ctx, event_arg)
newtmpl = self.app.emit_firstresult('html-page-context', pagename,
templatename, ctx, event_arg)
diff --git a/sphinx/domains/math.py b/sphinx/domains/math.py
index 6bd93e7b5..248a7a2a6 100644
--- a/sphinx/domains/math.py
+++ b/sphinx/domains/math.py
@@ -157,8 +157,11 @@ class MathDomain(Domain):
targets = [eq for eq in self.equations.values() if eq[0] == docname]
return len(targets) + 1
- def has_equations(self) -> bool:
- return any(self.data['has_equations'].values())
+ def has_equations(self, docname: str = None) -> bool:
+ if docname:
+ return self.data['has_equations'].get(docname, False)
+ else:
+ return any(self.data['has_equations'].values())
def setup(app: "Sphinx") -> Dict[str, Any]:
diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py
index e4318f35d..ff8ef3718 100644
--- a/sphinx/ext/mathjax.py
+++ b/sphinx/ext/mathjax.py
@@ -17,14 +17,17 @@ from docutils import nodes
import sphinx
from sphinx.application import Sphinx
-from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.domains.math import MathDomain
-from sphinx.environment import BuildEnvironment
from sphinx.errors import ExtensionError
from sphinx.locale import _
from sphinx.util.math import get_node_equation_number
from sphinx.writers.html import HTMLTranslator
+# more information for mathjax secure url is here:
+# https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
+MATHJAX_URL = ('https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?'
+ 'config=TeX-AMS-MML_HTMLorMML')
+
def html_visit_math(self: HTMLTranslator, node: nodes.math) -> None:
self.body.append(self.starttag(node, 'span', '', CLASS='math notranslate nohighlight'))
@@ -66,25 +69,25 @@ def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None
raise nodes.SkipNode
-def install_mathjax(app: Sphinx, env: BuildEnvironment) -> None:
+def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict,
+ event_arg: Any) -> None:
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
return
if not app.config.mathjax_path:
raise ExtensionError('mathjax_path config value must be set for the '
'mathjax extension to work')
- builder = cast(StandaloneHTMLBuilder, app.builder)
- domain = cast(MathDomain, env.get_domain('math'))
- if domain.has_equations():
+ domain = cast(MathDomain, app.env.get_domain('math'))
+ if domain.has_equations(pagename):
# Enable mathjax only if equations exists
options = {'async': 'async'}
if app.config.mathjax_options:
options.update(app.config.mathjax_options)
- builder.add_js_file(app.config.mathjax_path, **options)
+ app.add_js_file(app.config.mathjax_path, **options) # type: ignore
if app.config.mathjax_config:
body = "MathJax.Hub.Config(%s)" % json.dumps(app.config.mathjax_config)
- builder.add_js_file(None, type="text/x-mathjax-config", body=body)
+ app.add_js_file(None, type="text/x-mathjax-config", body=body)
def setup(app: Sphinx) -> Dict[str, Any]:
@@ -92,15 +95,11 @@ def setup(app: Sphinx) -> Dict[str, Any]:
(html_visit_math, None),
(html_visit_displaymath, None))
- # more information for mathjax secure url is here:
- # 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.7/latest.js?'
- 'config=TeX-AMS-MML_HTMLorMML', 'html')
+ app.add_config_value('mathjax_path', MATHJAX_URL, '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.add_config_value('mathjax_config', None, 'html')
- app.connect('env-updated', install_mathjax)
+ app.connect('html-page-context', install_mathjax)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
diff --git a/tests/roots/test-ext-math/index.rst b/tests/roots/test-ext-math/index.rst
index 4237b73ff..221284aeb 100644
--- a/tests/roots/test-ext-math/index.rst
+++ b/tests/roots/test-ext-math/index.rst
@@ -6,6 +6,7 @@ Test Math
math
page
+ nomath
.. math:: a^2+b^2=c^2
diff --git a/tests/roots/test-ext-math/nomath.rst b/tests/roots/test-ext-math/nomath.rst
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/roots/test-ext-math/nomath.rst
diff --git a/tests/test_ext_math.py b/tests/test_ext_math.py
index 28c2c35a5..10c8c4866 100644
--- a/tests/test_ext_math.py
+++ b/tests/test_ext_math.py
@@ -15,6 +15,7 @@ import warnings
import pytest
from docutils import nodes
+from sphinx.ext.mathjax import MATHJAX_URL
from sphinx.testing.util import assert_node
@@ -224,6 +225,18 @@ def test_mathjax_config(app, status, warning):
'</script>' in content)
+@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.mathjax']})
+def test_mathjax_is_installed_only_if_document_having_math(app, status, warning):
+ app.builder.build_all()
+
+ content = (app.outdir / 'index.html').read_text()
+ assert MATHJAX_URL in content
+
+ content = (app.outdir / 'nomath.html').read_text()
+ assert MATHJAX_URL not in content
+
+
@pytest.mark.sphinx('html', testroot='basic',
confoverrides={'extensions': ['sphinx.ext.mathjax']})
def test_mathjax_is_not_installed_if_no_equations(app, status, warning):