diff --git a/CHANGES.rst b/CHANGES.rst index f0f94fda396..aada4097bc2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -68,6 +68,8 @@ Features added Patch by Jean-François B. * #13508: Initial support for :pep:`695` type aliases. Patch by Martin Matouš, Jeremy Maitin-Shepard, and Adam Turner. +* #14023: Allow ``mathjax3_config`` to be a string pointing to a JS file. + Patch by Randolf Scholz. Bugs fixed ---------- diff --git a/doc/usage/extensions/math.rst b/doc/usage/extensions/math.rst index fb41d66d8fb..d44624b070f 100644 --- a/doc/usage/extensions/math.rst +++ b/doc/usage/extensions/math.rst @@ -264,12 +264,13 @@ Sphinx but is set to automatically include it from a third-party site. or "defer" key is set. .. confval:: mathjax3_config - :type: :code-py:`dict[str, Any] | None` + :type: :code-py:`str | dict[str, Any] | None` :default: :code-py:`None` The configuration options for MathJax v3 (which is used by default). - The given dictionary is assigned to the JavaScript variable - ``window.MathJax``. + Expects a string with the relative path to a JavaScript file with the config. + Alternatively, a dictionary can be given, which is converted to a JSON object + and assigned to the JavaScript variable ``window.MathJax``. For more information, please read `Configuring MathJax`__. __ https://docs.mathjax.org/en/latest/web/configuration.html#configuration diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py index 62220cc697f..3f45bb5e675 100644 --- a/sphinx/ext/mathjax.py +++ b/sphinx/ext/mathjax.py @@ -105,9 +105,26 @@ def install_mathjax( ) body = 'MathJax.Hub.Config(%s)' % json.dumps(app.config.mathjax2_config) builder.add_js_file('', type='text/x-mathjax-config', body=body) - if app.config.mathjax3_config: - body = 'window.MathJax = %s' % json.dumps(app.config.mathjax3_config) - builder.add_js_file('', body=body) + match app.config.mathjax3_config: + case _ if not app.config.mathjax3_config: + # None, empty string or empty dict + pass + case str(config_filename): + config_filepath = app.srcdir / config_filename + if not config_filepath.exists(): + msg = f'mathjax3_config file not found: {config_filepath!s}' + raise ExtensionError(msg) + if not config_filepath.is_file() or config_filepath.suffix != '.js': + msg = f'mathjax3_config: expected a .js file, but got {config_filepath!s}' + raise ExtensionError(msg) + body = config_filepath.read_text(encoding='utf-8') + builder.add_js_file('', body=body) + case dict(config_dict): + body = f'window.MathJax = {json.dumps(config_dict)}' + builder.add_js_file('', body=body) + case _: + msg = 'mathjax3_config must be a str (filename), dict, or None' + raise ExtensionError(msg) options = {} if app.config.mathjax_options: @@ -147,7 +164,7 @@ def setup(app: Sphinx) -> ExtensionMetadata: types=frozenset({dict, NoneType}), ) app.add_config_value( - 'mathjax3_config', None, 'html', types=frozenset({dict, NoneType}) + 'mathjax3_config', None, 'html', types=frozenset({dict, str, NoneType}) ) app.connect('html-page-context', install_mathjax) diff --git a/tests/roots/test-ext-math/_static/custom_mathjax_config.js b/tests/roots/test-ext-math/_static/custom_mathjax_config.js new file mode 100644 index 00000000000..7a2bda39383 --- /dev/null +++ b/tests/roots/test-ext-math/_static/custom_mathjax_config.js @@ -0,0 +1 @@ +window.MathJax = {"extensions": ["tex2jax.js"]} \ No newline at end of file diff --git a/tests/test_extensions/test_ext_math.py b/tests/test_extensions/test_ext_math.py index 9c8e620d655..629997ea4aa 100644 --- a/tests/test_extensions/test_ext_math.py +++ b/tests/test_extensions/test_ext_math.py @@ -376,6 +376,23 @@ def test_mathjax3_config(app: SphinxTestApp) -> None: assert '' in content +@pytest.mark.sphinx( + 'html', + testroot='ext-math', + confoverrides={ + 'extensions': ['sphinx.ext.mathjax'], + 'mathjax3_config': '_static/custom_mathjax_config.js', + }, +) +def test_mathjax3_js_config(app: SphinxTestApp) -> None: + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + assert '' in content + + @pytest.mark.sphinx( 'html', testroot='ext-math',