File: test_tex2mathml_extern.py

package info (click to toggle)
python-docutils 0.22%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 11,448 kB
  • sloc: python: 53,302; lisp: 14,475; xml: 1,807; javascript: 1,032; makefile: 102; sh: 96
file content (156 lines) | stat: -rw-r--r-- 5,583 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python3
# :Copyright: © 2024 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
#    Copying and distribution of this file, with or without modification,
#    are permitted in any medium without royalty provided the copyright
#    notice and this notice are preserved.
#    This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause

"""Create output samples for TeX to MathML conversion.

Allows to compare the results of the various converters and Docutils' built-in
convert in web browsers.
"""

from pathlib import Path
import sys
import unittest

# Testing the conversion with external converters requires additional
# ressources (latexml, blahtexml, ttm, pandoc) and is SLOW
# (ca. 27s without testing "latexml" and 13 min with "latexml").
# Therefore, tests are skipped unless run as stand-alone module:

if __name__ != '__main__':
    raise unittest.SkipTest('run stand-alone to test external math converters')
else:
    # prepend the "docutils root" to the Python library path
    # so we import the local `docutils` package.
    sys.path.insert(0, str(Path(__file__).resolve().parents[3]))


from docutils.core import publish_parts, publish_file
from docutils.utils import relative_path

from test.test_functional import compare_output

TEST_ROOT = Path(__file__).parents[2]
DOCS = TEST_ROOT.parent / 'docs'
FUNCTIONAL = TEST_ROOT / 'functional'
EXPECTED = FUNCTIONAL / 'expected'
INPUT = FUNCTIONAL / 'input'
OUTPUT = FUNCTIONAL / 'output'


buggy_sample = r"""
There is ":math:`\lambda\omega\tau\varsigma`" to math.

======================  ========== =======
Das ist nicht lustig.   Dafür das  hier

.. math:: So \isses
======================  ========== =======


Das ist :math:`\ein` Fehler.

.. math:: \int_{-\infty} 3 \sin x} \phy \, d\gamma

.. sidebar:: nebenbemerkung

   noch was :math:`\sqrt[2]`

.. math:: \sqrt[2]

2-zeilig mit align:

.. math::
          s_i     & = 3 \\
          s_j + 3 &

"""


math_options = [('mathml', ''),
                ('mathml', 'ttm'),
                ('mathml', 'blahtexml'),
                ('mathml', 'pandoc'),
                # ('mathml', 'latexml'),  # VERY slow (up to 20 min)
                ]


class MathMLConverterTestCase(unittest.TestCase):
    """
    Functional tests of TeX to MathML converters.

    PROVISIONAL: This class tests a provisional implementation
    which is open to change without warning.
    """
    settings = {'_disable_config': True,
                'input_encoding': 'utf-8',  # skip auto-detection
                'embed_stylesheet': False,
                'warning_stream': '',
                'report_level': 2,  # warning
                # 'report_level': 3,  # error
                # 'report_level': 4,  # severe
                }

    def test_mathematics(self):
        """Test converting "mathematics.rst" from the documentation."""

        source_path = relative_path(None, DOCS/'ref'/'rst'/'mathematics.rst')

        for math_output in math_options:
            settings = {'math_output': math_output,
                        'stylesheet_path': 'minimal.css,responsive.css',
                        **self.settings}
            out_file = f'mathematics_{"_".join(math_output).strip("_")}.html'
            out_path = OUTPUT / out_file
            expected_path = EXPECTED / out_file
            output = publish_file(source_path=str(source_path),
                                  destination_path=out_path.as_posix(),
                                  writer='html5',
                                  settings_overrides=settings)
            with self.subTest(converter=math_output[1] or 'latex2mathml()'):
                compare_output(output, out_path, expected_path)

    def test_math_experiments(self):
        """Convert experimental math sample."""

        source_path = relative_path(None, INPUT/'data'/'math_experiments.rst')

        for math_output in math_options:
            settings = {'math_output': math_output, **self.settings}
            out_file = f'math_experiments_{"_".join(math_output).strip("_")}.html'  # noqa: E501
            out_path = OUTPUT / out_file
            expected_path = EXPECTED / out_file
            output = publish_file(source_path=str(source_path),
                                  destination_path=out_path.as_posix(),
                                  writer='html5',
                                  settings_overrides=settings)
            with self.subTest(converter=math_output[1] or 'latex2mathml()'):
                compare_output(output, out_path, expected_path)

    def test_buggy_math(self):
        """Test reporting conversion failure due to TeX-syntax errors."""

        for math_output in math_options:
            settings = {'math_output': math_output, **self.settings}
            out_file = f'buggy_{"_".join(math_output).strip("_")}.html'
            out_path = OUTPUT / out_file
            expected_path = EXPECTED / out_file
            preface = f'Test "math-output: {" ".join(math_output)}".\n\n'
            parts = publish_parts(preface + buggy_sample,
                                  'buggy-maths',
                                  writer='html5',
                                  settings_overrides=settings)
            Path(out_path).write_text(parts['whole'])
            with self.subTest(converter=math_output[1] or 'latex2mathml()'):
                compare_output(parts['whole'], out_path, expected_path)


if __name__ == '__main__':
    unittest.main()