##// END OF EJS Templates
adding more tests for markdown around math
Nicholas Bollweg -
Show More
@@ -1,176 +1,186 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Tests for conversions from markdown to other formats"""
2 """Tests for conversions from markdown to other formats"""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import re
7 import re
8 from copy import copy
8 from copy import copy
9
9
10 from IPython.utils.py3compat import string_types
10 from IPython.utils.py3compat import string_types
11 from IPython.testing import decorators as dec
11 from IPython.testing import decorators as dec
12
12
13 from ...tests.base import TestsBase
13 from ...tests.base import TestsBase
14 from ..markdown import markdown2latex, markdown2html, markdown2rst
14 from ..markdown import markdown2latex, markdown2html, markdown2rst
15
15
16 from jinja2 import Environment
16 from jinja2 import Environment
17
17
18 class TestMarkdown(TestsBase):
18 class TestMarkdown(TestsBase):
19
19
20 tests = [
20 tests = [
21 '*test',
21 '*test',
22 '**test',
22 '**test',
23 '*test*',
23 '*test*',
24 '_test_',
24 '_test_',
25 '__test__',
25 '__test__',
26 '__*test*__',
26 '__*test*__',
27 '**test**',
27 '**test**',
28 '#test',
28 '#test',
29 '##test',
29 '##test',
30 'test\n----',
30 'test\n----',
31 'test [link](https://google.com/)',
31 'test [link](https://google.com/)',
32 ]
32 ]
33
33
34 tokens = [
34 tokens = [
35 '*test',
35 '*test',
36 '**test',
36 '**test',
37 'test',
37 'test',
38 'test',
38 'test',
39 'test',
39 'test',
40 'test',
40 'test',
41 'test',
41 'test',
42 'test',
42 'test',
43 'test',
43 'test',
44 'test',
44 'test',
45 ('test', 'https://google.com/'),
45 ('test', 'https://google.com/'),
46 ]
46 ]
47
47
48
48
49 @dec.onlyif_cmds_exist('pandoc')
49 @dec.onlyif_cmds_exist('pandoc')
50 def test_markdown2latex(self):
50 def test_markdown2latex(self):
51 """markdown2latex test"""
51 """markdown2latex test"""
52 for index, test in enumerate(self.tests):
52 for index, test in enumerate(self.tests):
53 self._try_markdown(markdown2latex, test, self.tokens[index])
53 self._try_markdown(markdown2latex, test, self.tokens[index])
54
54
55 @dec.onlyif_cmds_exist('pandoc')
55 @dec.onlyif_cmds_exist('pandoc')
56 def test_markdown2latex_markup(self):
56 def test_markdown2latex_markup(self):
57 """markdown2latex with markup kwarg test"""
57 """markdown2latex with markup kwarg test"""
58 # This string should be passed through unaltered with pandoc's
58 # This string should be passed through unaltered with pandoc's
59 # markdown_strict reader
59 # markdown_strict reader
60 s = '1) arabic number with parenthesis'
60 s = '1) arabic number with parenthesis'
61 self.assertEqual(markdown2latex(s, markup='markdown_strict'), s)
61 self.assertEqual(markdown2latex(s, markup='markdown_strict'), s)
62 # This string should be passed through unaltered with pandoc's
62 # This string should be passed through unaltered with pandoc's
63 # markdown_strict+tex_math_dollars reader
63 # markdown_strict+tex_math_dollars reader
64 s = r'$\alpha$ latex math'
64 s = r'$\alpha$ latex math'
65 # sometimes pandoc uses $math$, sometimes it uses \(math\)
65 # sometimes pandoc uses $math$, sometimes it uses \(math\)
66 expected = re.compile(r'(\$|\\\()\\alpha(\$|\\\)) latex math')
66 expected = re.compile(r'(\$|\\\()\\alpha(\$|\\\)) latex math')
67 try:
67 try:
68 # py3
68 # py3
69 assertRegex = self.assertRegex
69 assertRegex = self.assertRegex
70 except AttributeError:
70 except AttributeError:
71 # py2
71 # py2
72 assertRegex = self.assertRegexpMatches
72 assertRegex = self.assertRegexpMatches
73 assertRegex(
73 assertRegex(
74 markdown2latex(s, markup='markdown_strict+tex_math_dollars'),
74 markdown2latex(s, markup='markdown_strict+tex_math_dollars'),
75 expected)
75 expected)
76
76
77 @dec.onlyif_cmds_exist('pandoc')
77 @dec.onlyif_cmds_exist('pandoc')
78 def test_pandoc_extra_args(self):
78 def test_pandoc_extra_args(self):
79 # pass --no-wrap
79 # pass --no-wrap
80 s = '\n'.join([
80 s = '\n'.join([
81 "#latex {{long_line | md2l('markdown', ['--no-wrap'])}}",
81 "#latex {{long_line | md2l('markdown', ['--no-wrap'])}}",
82 "#rst {{long_line | md2r(['--columns', '5'])}}",
82 "#rst {{long_line | md2r(['--columns', '5'])}}",
83 ])
83 ])
84 long_line = ' '.join(['long'] * 30)
84 long_line = ' '.join(['long'] * 30)
85 env = Environment()
85 env = Environment()
86 env.filters.update({
86 env.filters.update({
87 'md2l': markdown2latex,
87 'md2l': markdown2latex,
88 'md2r': markdown2rst,
88 'md2r': markdown2rst,
89 })
89 })
90 tpl = env.from_string(s)
90 tpl = env.from_string(s)
91 rendered = tpl.render(long_line=long_line)
91 rendered = tpl.render(long_line=long_line)
92 _, latex, rst = rendered.split('#')
92 _, latex, rst = rendered.split('#')
93
93
94 self.assertEqual(latex.strip(), 'latex %s' % long_line)
94 self.assertEqual(latex.strip(), 'latex %s' % long_line)
95 self.assertEqual(rst.strip(), 'rst %s' % long_line.replace(' ', '\n'))
95 self.assertEqual(rst.strip(), 'rst %s' % long_line.replace(' ', '\n'))
96
96
97 def test_markdown2html(self):
97 def test_markdown2html(self):
98 """markdown2html test"""
98 """markdown2html test"""
99 for index, test in enumerate(self.tests):
99 for index, test in enumerate(self.tests):
100 self._try_markdown(markdown2html, test, self.tokens[index])
100 self._try_markdown(markdown2html, test, self.tokens[index])
101
101
102 def test_markdown2html_heading_anchors(self):
102 def test_markdown2html_heading_anchors(self):
103 for md, tokens in [
103 for md, tokens in [
104 ('# test',
104 ('# test',
105 ('<h1', '>test', 'id="test"', u'&#182;</a>', "anchor-link")
105 ('<h1', '>test', 'id="test"', u'&#182;</a>', "anchor-link")
106 ),
106 ),
107 ('###test head space',
107 ('###test head space',
108 ('<h3', '>test head space', 'id="test-head-space"', u'&#182;</a>', "anchor-link")
108 ('<h3', '>test head space', 'id="test-head-space"', u'&#182;</a>', "anchor-link")
109 )
109 )
110 ]:
110 ]:
111 self._try_markdown(markdown2html, md, tokens)
111 self._try_markdown(markdown2html, md, tokens)
112
112
113 def test_markdown2html_math(self):
113 def test_markdown2html_math(self):
114 # Mathematical expressions should be passed through unaltered
114 # Mathematical expressions should be passed through unaltered
115 cases = [("\\begin{equation*}\n"
115 cases = [("\\begin{equation*}\n"
116 "\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)\n"
116 "\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)\n"
117 "\\end{equation*}"),
117 "\\end{equation*}"),
118 ("$$\n"
118 ("$$\n"
119 "a = 1 *3* 5\n"
119 "a = 1 *3* 5\n"
120 "$$"),
120 "$$"),
121 "$ a = 1 *3* 5 $",
121 "$ a = 1 *3* 5 $",
122 ]
122 ]
123 for case in cases:
123 for case in cases:
124 self.assertIn(case, markdown2html(case))
124 self.assertIn(case, markdown2html(case))
125
126 def test_markdown2html_math_mixed(self):
127 """ensure markdown between inline and inline-block math"""
128 case = """The entries of $C$ are given by the exact formula:
129 $$
130 C_{ik} = \sum_{j=1}^n A_{ij} B_{jk}
131 $$
132 but there are many ways to _implement_ this computation. $\approx 2mnp$ flops"""
133 self._try_markdown(markdown2html, case,
134 case.replace("_implement_", "<em>implement</em>"))
125
135
126 def test_markdown2html_math_paragraph(self):
136 def test_markdown2html_math_paragraph(self):
127 """these should all parse without modification"""
137 """these should all parse without modification"""
128 patterns = [
138 cases = [
129 # https://github.com/ipython/ipython/issues/6724
139 # https://github.com/ipython/ipython/issues/6724
130 """Water that is stored in $t$, $s_t$, must equal the storage content of the previous stage,
140 """Water that is stored in $t$, $s_t$, must equal the storage content of the previous stage,
131 $s_{t-1}$, plus a stochastic inflow, $I_t$, minus what is being released in $t$, $r_t$.
141 $s_{t-1}$, plus a stochastic inflow, $I_t$, minus what is being released in $t$, $r_t$.
132 With $s_0$ defined as the initial storage content in $t=1$, we have""",
142 With $s_0$ defined as the initial storage content in $t=1$, we have""",
133 # https://github.com/jupyter/nbviewer/issues/420
143 # https://github.com/jupyter/nbviewer/issues/420
134 """$C_{ik}$
144 """$C_{ik}$
135 $$
145 $$
136 C_{ik} = \sum_{j=1}
146 C_{ik} = \sum_{j=1}
137 $$
147 $$
138 $C_{ik}$""",
148 $C_{ik}$""",
139 """$m$
149 """$m$
140 $$
150 $$
141 C = \begin{pmatrix}
151 C = \begin{pmatrix}
142 0 & 0 & 0 & \cdots & 0 & 0 & -c_0 \\
152 0 & 0 & 0 & \cdots & 0 & 0 & -c_0 \\
143 0 & 0 & 0 & \cdots & 0 & 1 & -c_{m-1}
153 0 & 0 & 0 & \cdots & 0 & 1 & -c_{m-1}
144 \end{pmatrix}
154 \end{pmatrix}
145 $$
155 $$
146 $x^m$""",
156 $x^m$""",
147 """$r=\overline{1,n}$
157 """$r=\overline{1,n}$
148 $$ {\bf
158 $$ {\bf
149 b}_{i}^{r}(t)=(1-t)\,{\bf b}_{i}^{r-1}(t)+t\,{\bf b}_{i+1}^{r-1}(t),\:
159 b}_{i}^{r}(t)=(1-t)\,{\bf b}_{i}^{r-1}(t)+t\,{\bf b}_{i+1}^{r-1}(t),\:
150 i=\overline{0,n-r}, $$
160 i=\overline{0,n-r}, $$
151 i.e. the $i^{th}$"""
161 i.e. the $i^{th}$"""
152 ]
162 ]
153
163
154 for pattern in patterns:
164 for case in cases:
155 self.assertIn(pattern, markdown2html(pattern))
165 self.assertIn(case, markdown2html(case))
156
166
157 @dec.onlyif_cmds_exist('pandoc')
167 @dec.onlyif_cmds_exist('pandoc')
158 def test_markdown2rst(self):
168 def test_markdown2rst(self):
159 """markdown2rst test"""
169 """markdown2rst test"""
160
170
161 #Modify token array for rst, escape asterik
171 #Modify token array for rst, escape asterik
162 tokens = copy(self.tokens)
172 tokens = copy(self.tokens)
163 tokens[0] = r'\*test'
173 tokens[0] = r'\*test'
164 tokens[1] = r'\*\*test'
174 tokens[1] = r'\*\*test'
165
175
166 for index, test in enumerate(self.tests):
176 for index, test in enumerate(self.tests):
167 self._try_markdown(markdown2rst, test, tokens[index])
177 self._try_markdown(markdown2rst, test, tokens[index])
168
178
169
179
170 def _try_markdown(self, method, test, tokens):
180 def _try_markdown(self, method, test, tokens):
171 results = method(test)
181 results = method(test)
172 if isinstance(tokens, string_types):
182 if isinstance(tokens, string_types):
173 assert tokens in results
183 assert tokens in results
174 else:
184 else:
175 for token in tokens:
185 for token in tokens:
176 assert token in results
186 assert token in results
General Comments 0
You need to be logged in to leave comments. Login now