"""Test math extensions.""" import re import shutil import subprocess import warnings import pytest from docutils import nodes from sphinx.ext.mathjax import MATHJAX_URL from sphinx.testing.util import assert_node def has_binary(binary): try: subprocess.check_output([binary]) except FileNotFoundError: return False except OSError: pass return True @pytest.mark.skipif(not has_binary('dvipng'), reason='Requires dvipng" binary') @pytest.mark.sphinx('html', testroot='ext-math-simple', confoverrides={'extensions': ['sphinx.ext.imgmath']}) def test_imgmath_png(app, status, warning): app.build(force_all=True) if "LaTeX command 'latex' cannot be run" in warning.getvalue(): msg = 'LaTeX command "latex" is not available' raise pytest.skip.Exception(msg) if "dvipng command 'dvipng' cannot be run" in warning.getvalue(): msg = 'dvipng command "dvipng" is not available' raise pytest.skip.Exception(msg) content = (app.outdir / 'index.html').read_text(encoding='utf8') shutil.rmtree(app.outdir) html = (r'
\s*

\s*\s*

\s*
') assert re.search(html, content, re.DOTALL) @pytest.mark.skipif(not has_binary('dvisvgm'), reason='Requires dvisvgm" binary') @pytest.mark.sphinx('html', testroot='ext-math-simple', confoverrides={'extensions': ['sphinx.ext.imgmath'], 'imgmath_image_format': 'svg'}) def test_imgmath_svg(app, status, warning): app.build(force_all=True) if "LaTeX command 'latex' cannot be run" in warning.getvalue(): msg = 'LaTeX command "latex" is not available' raise pytest.skip.Exception(msg) if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue(): msg = 'dvisvgm command "dvisvgm" is not available' raise pytest.skip.Exception(msg) content = (app.outdir / 'index.html').read_text(encoding='utf8') shutil.rmtree(app.outdir) html = (r'
\s*

\s*\s*

\s*
') assert re.search(html, content, re.DOTALL) @pytest.mark.skipif(not has_binary('dvisvgm'), reason='Requires dvisvgm" binary') @pytest.mark.sphinx('html', testroot='ext-math-simple', confoverrides={'extensions': ['sphinx.ext.imgmath'], 'imgmath_image_format': 'svg', 'imgmath_embed': True}) def test_imgmath_svg_embed(app, status, warning): app.build(force_all=True) if "LaTeX command 'latex' cannot be run" in warning.getvalue(): msg = 'LaTeX command "latex" is not available' raise pytest.skip.Exception(msg) if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue(): msg = 'dvisvgm command "dvisvgm" is not available' raise pytest.skip.Exception(msg) content = (app.outdir / 'index.html').read_text(encoding='utf8') shutil.rmtree(app.outdir) html = r'' '' in content) @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_mathjax_align(app, status, warning): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') shutil.rmtree(app.outdir) html = (r'
\s*' r'\\\[ \\begin\{align\}\\begin\{aligned\}S \&= \\pi r\^2\\\\' r'V \&= \\frac\{4\}\{3\} \\pi r\^3\\end\{aligned\}\\end\{align\} \\\]
') assert re.search(html, content, re.DOTALL) @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'math_number_all': True, 'extensions': ['sphinx.ext.mathjax']}) def test_math_number_all_mathjax(app, status, warning): app.build() content = (app.outdir / 'index.html').read_text(encoding='utf8') html = (r'
\s*' r'\(1\)\xb6\\\[a\^2\+b\^2=c\^2\\\]
') assert re.search(html, content, re.DOTALL) @pytest.mark.sphinx('latex', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_math_number_all_latex(app, status, warning): app.build() content = (app.outdir / 'python.tex').read_text(encoding='utf8') macro = (r'\\begin{equation\*}\s*' r'\\begin{split}a\^2\+b\^2=c\^2\\end{split}\s*' r'\\end{equation\*}') assert re.search(macro, content, re.DOTALL) macro = r'Inline \\\(E=mc\^2\\\)' assert re.search(macro, content, re.DOTALL) macro = (r'\\begin{equation\*}\s*' r'\\begin{split}e\^{i\\pi}\+1=0\\end{split}\s+' r'\\end{equation\*}') assert re.search(macro, content, re.DOTALL) macro = (r'\\begin{align\*}\\!\\begin{aligned}\s*' r'S &= \\pi r\^2\\\\\s*' r'V &= \\frac\{4}\{3} \\pi r\^3\\\\\s*' r'\\end{aligned}\\end{align\*}') assert re.search(macro, content, re.DOTALL) macro = r'Referencing equation \\eqref{equation:math:foo}.' assert re.search(macro, content, re.DOTALL) @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax'], 'math_eqref_format': 'Eq.{number}'}) def test_math_eqref_format_html(app, status, warning): app.build(force_all=True) content = (app.outdir / 'math.html').read_text(encoding='utf8') html = ('

Referencing equation Eq.1 and Eq.1.

') assert html in content @pytest.mark.sphinx('latex', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax'], 'math_eqref_format': 'Eq.{number}'}) def test_math_eqref_format_latex(app, status, warning): app.build(force_all=True) content = (app.outdir / 'python.tex').read_text(encoding='utf8') macro = (r'Referencing equation Eq.\\ref{equation:math:foo} and ' r'Eq.\\ref{equation:math:foo}.') assert re.search(macro, content, re.DOTALL) @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax'], 'numfig': True, 'math_numfig': True}) def test_mathjax_numfig_html(app, status, warning): app.build(force_all=True) content = (app.outdir / 'math.html').read_text(encoding='utf8') html = ('
\n' '(1.2)') assert html in content html = ('

Referencing equation (1.1) and ' '(1.1).

') assert html in content @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.imgmath'], 'numfig': True, 'numfig_secnum_depth': 0, 'math_numfig': True}) def test_imgmath_numfig_html(app, status, warning): app.build(force_all=True) content = (app.outdir / 'page.html').read_text(encoding='utf8') html = '(3)Referencing equations (1) and ' '(3).

') assert html in content @pytest.mark.sphinx('dummy', testroot='ext-math-compat') def test_math_compat(app, status, warning): with warnings.catch_warnings(record=True): app.build(force_all=True) doctree = app.env.get_and_resolve_doctree('index', app.builder) assert_node(doctree, [nodes.document, nodes.section, (nodes.title, [nodes.section, (nodes.title, nodes.paragraph)], nodes.section)]) assert_node(doctree[0][1][1], ('Inline: ', [nodes.math, "E=mc^2"], '\nInline my math: ', [nodes.math, "E = mc^2"])) assert_node(doctree[0][2], ([nodes.title, "block"], [nodes.math_block, "a^2+b^2=c^2\n\n"], [nodes.paragraph, "Second math"], [nodes.math_block, "e^{i\\pi}+1=0\n\n"], [nodes.paragraph, "Multi math equations"], [nodes.math_block, "E = mc^2"])) @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax'], 'mathjax3_config': {'extensions': ['tex2jax.js']}}) def test_mathjax3_config(app, status, warning): 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', confoverrides={'extensions': ['sphinx.ext.mathjax'], 'mathjax2_config': {'extensions': ['tex2jax.js']}}) def test_mathjax2_config(app, status, warning): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert ('' in content) @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax'], 'mathjax_options': {'async': 'async'}, 'mathjax3_config': {'extensions': ['tex2jax.js']}}) def test_mathjax_options_async_for_mathjax3(app, status, warning): 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', confoverrides={ 'extensions': ['sphinx.ext.mathjax'], 'mathjax_path': 'MathJax.js?config=scipy-mathjax', }, ) def test_mathjax_path_config(app): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert '' 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.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert MATHJAX_URL in content content = (app.outdir / 'nomath.html').read_text(encoding='utf8') 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): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert 'MathJax.js' not in content @pytest.mark.sphinx('html', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_mathjax_is_installed_if_no_equations_when_forced(app, status, warning): app.set_html_assets_policy('always') app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert MATHJAX_URL in content content = (app.outdir / 'nomath.html').read_text(encoding='utf8') assert MATHJAX_URL in content @pytest.mark.sphinx('html', testroot='ext-math-include', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_mathjax_is_installed_if_included_file_has_equations(app): app.build(force_all=True) # no real equations at the rst level, but includes "included" content = (app.outdir / 'index.html').read_text(encoding='utf8') assert MATHJAX_URL in content # no real equations at the rst level, but includes "math.rst" content = (app.outdir / 'included.html').read_text(encoding='utf8') assert MATHJAX_URL in content content = (app.outdir / 'math.html').read_text(encoding='utf8') assert MATHJAX_URL in content @pytest.mark.sphinx('singlehtml', testroot='ext-math', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_mathjax_is_installed_only_if_document_having_math_singlehtml(app): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert MATHJAX_URL in content @pytest.mark.sphinx('singlehtml', testroot='basic', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_mathjax_is_not_installed_if_no_equations_singlehtml(app): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert 'MathJax.js' not in content @pytest.mark.sphinx('singlehtml', testroot='ext-math-include', confoverrides={'extensions': ['sphinx.ext.mathjax']}) def test_mathjax_is_installed_if_included_file_has_equations_singlehtml(app): app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert MATHJAX_URL in content