##// END OF EJS Templates
Better color options and added scale
Oscar Gustafsson -
Show More
@@ -1,203 +1,220 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for handling LaTeX."""
2 """Tools for handling LaTeX."""
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 from io import BytesIO, open
7 from io import BytesIO, open
8 import os
8 import os
9 import tempfile
9 import tempfile
10 import shutil
10 import shutil
11 import subprocess
11 import subprocess
12 from base64 import encodebytes
12 from base64 import encodebytes
13 from textwrap import wrap as splitstring
13
14
14 from IPython.utils.process import find_cmd, FindCmdError
15 from IPython.utils.process import find_cmd, FindCmdError
15 from traitlets.config import get_config
16 from traitlets.config import get_config
16 from traitlets.config.configurable import SingletonConfigurable
17 from traitlets.config.configurable import SingletonConfigurable
17 from traitlets import List, Bool, Unicode
18 from traitlets import List, Bool, Unicode
18 from IPython.utils.py3compat import cast_unicode
19 from IPython.utils.py3compat import cast_unicode
19
20
20
21
21 class LaTeXTool(SingletonConfigurable):
22 class LaTeXTool(SingletonConfigurable):
22 """An object to store configuration of the LaTeX tool."""
23 """An object to store configuration of the LaTeX tool."""
23 def _config_default(self):
24 def _config_default(self):
24 return get_config()
25 return get_config()
25
26
26 backends = List(
27 backends = List(
27 Unicode(), ["matplotlib", "dvipng"],
28 Unicode(), ["matplotlib", "dvipng"],
28 help="Preferred backend to draw LaTeX math equations. "
29 help="Preferred backend to draw LaTeX math equations. "
29 "Backends in the list are checked one by one and the first "
30 "Backends in the list are checked one by one and the first "
30 "usable one is used. Note that `matplotlib` backend "
31 "usable one is used. Note that `matplotlib` backend "
31 "is usable only for inline style equations. To draw "
32 "is usable only for inline style equations. To draw "
32 "display style equations, `dvipng` backend must be specified. ",
33 "display style equations, `dvipng` backend must be specified. ",
33 # It is a List instead of Enum, to make configuration more
34 # It is a List instead of Enum, to make configuration more
34 # flexible. For example, to use matplotlib mainly but dvipng
35 # flexible. For example, to use matplotlib mainly but dvipng
35 # for display style, the default ["matplotlib", "dvipng"] can
36 # for display style, the default ["matplotlib", "dvipng"] can
36 # be used. To NOT use dvipng so that other repr such as
37 # be used. To NOT use dvipng so that other repr such as
37 # unicode pretty printing is used, you can use ["matplotlib"].
38 # unicode pretty printing is used, you can use ["matplotlib"].
38 ).tag(config=True)
39 ).tag(config=True)
39
40
40 use_breqn = Bool(
41 use_breqn = Bool(
41 True,
42 True,
42 help="Use breqn.sty to automatically break long equations. "
43 help="Use breqn.sty to automatically break long equations. "
43 "This configuration takes effect only for dvipng backend.",
44 "This configuration takes effect only for dvipng backend.",
44 ).tag(config=True)
45 ).tag(config=True)
45
46
46 packages = List(
47 packages = List(
47 ['amsmath', 'amsthm', 'amssymb', 'bm'],
48 ['amsmath', 'amsthm', 'amssymb', 'bm'],
48 help="A list of packages to use for dvipng backend. "
49 help="A list of packages to use for dvipng backend. "
49 "'breqn' will be automatically appended when use_breqn=True.",
50 "'breqn' will be automatically appended when use_breqn=True.",
50 ).tag(config=True)
51 ).tag(config=True)
51
52
52 preamble = Unicode(
53 preamble = Unicode(
53 help="Additional preamble to use when generating LaTeX source "
54 help="Additional preamble to use when generating LaTeX source "
54 "for dvipng backend.",
55 "for dvipng backend.",
55 ).tag(config=True)
56 ).tag(config=True)
56
57
57
58
58 def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black'):
59 def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black',
60 scale=1.0):
59 """Render a LaTeX string to PNG.
61 """Render a LaTeX string to PNG.
60
62
61 Parameters
63 Parameters
62 ----------
64 ----------
63 s : str
65 s : str
64 The raw string containing valid inline LaTeX.
66 The raw string containing valid inline LaTeX.
65 encode : bool, optional
67 encode : bool, optional
66 Should the PNG data base64 encoded to make it JSON'able.
68 Should the PNG data base64 encoded to make it JSON'able.
67 backend : {matplotlib, dvipng}
69 backend : {matplotlib, dvipng}
68 Backend for producing PNG data.
70 Backend for producing PNG data.
69 wrap : bool
71 wrap : bool
70 If true, Automatically wrap `s` as a LaTeX equation.
72 If true, Automatically wrap `s` as a LaTeX equation.
71 color : string
73 color : string
72 Foreground color name among dvipsnames.
74 Foreground color name among dvipsnames, e.g. 'Maroon' or on hex RGB
75 format, e.g. '#AA20FA'.
76 scale : float
77 Scale factor for the resulting PNG.
73
78
74 None is returned when the backend cannot be used.
79 None is returned when the backend cannot be used.
75
80
76 """
81 """
77 s = cast_unicode(s)
82 s = cast_unicode(s)
78 allowed_backends = LaTeXTool.instance().backends
83 allowed_backends = LaTeXTool.instance().backends
79 if backend is None:
84 if backend is None:
80 backend = allowed_backends[0]
85 backend = allowed_backends[0]
81 if backend not in allowed_backends:
86 if backend not in allowed_backends:
82 return None
87 return None
83 if backend == 'matplotlib':
88 if backend == 'matplotlib':
84 f = latex_to_png_mpl
89 f = latex_to_png_mpl
85 elif backend == 'dvipng':
90 elif backend == 'dvipng':
86 f = latex_to_png_dvipng
91 f = latex_to_png_dvipng
92 if color.startswith('#'):
93 # Convert hex RGB color to LaTeX RGB color.
94 if len(color) == 7:
95 try:
96 color = "RGB {}".format(" ".join([str(int(x, 16)) for x in
97 splitstring(color[1:], 2)]))
98 except ValueError:
99 raise ValueError('Invalid color specification {}.'.format(color))
100 else:
101 raise ValueError('Invalid color specification {}.'.format(color))
87 else:
102 else:
88 raise ValueError('No such backend {0}'.format(backend))
103 raise ValueError('No such backend {0}'.format(backend))
89 bin_data = f(s, wrap, color)
104 bin_data = f(s, wrap, color, scale)
90 if encode and bin_data:
105 if encode and bin_data:
91 bin_data = encodebytes(bin_data)
106 bin_data = encodebytes(bin_data)
92 return bin_data
107 return bin_data
93
108
94
109
95 def latex_to_png_mpl(s, wrap, color='Black'):
110 def latex_to_png_mpl(s, wrap, color='Black', scale=1.0):
96 try:
111 try:
97 from matplotlib import mathtext
112 from matplotlib import mathtext
98 from pyparsing import ParseFatalException
113 from pyparsing import ParseFatalException
99 except ImportError:
114 except ImportError:
100 return None
115 return None
101
116
102 # mpl mathtext doesn't support display math, force inline
117 # mpl mathtext doesn't support display math, force inline
103 s = s.replace('$$', '$')
118 s = s.replace('$$', '$')
104 if wrap:
119 if wrap:
105 s = u'${0}$'.format(s)
120 s = u'${0}$'.format(s)
106
121
107 try:
122 try:
108 mt = mathtext.MathTextParser('bitmap')
123 mt = mathtext.MathTextParser('bitmap')
109 f = BytesIO()
124 f = BytesIO()
110 mt.to_png(f, s, fontsize=12, color=color)
125 dpi = 120*scale
126 mt.to_png(f, s, fontsize=12, dpi=dpi, color=color)
111 return f.getvalue()
127 return f.getvalue()
112 except (ValueError, RuntimeError, ParseFatalException):
128 except (ValueError, RuntimeError, ParseFatalException):
113 return None
129 return None
114
130
115
131
116 def latex_to_png_dvipng(s, wrap, color='Black'):
132 def latex_to_png_dvipng(s, wrap, color='Black', scale=1.0):
117 try:
133 try:
118 find_cmd('latex')
134 find_cmd('latex')
119 find_cmd('dvipng')
135 find_cmd('dvipng')
120 except FindCmdError:
136 except FindCmdError:
121 return None
137 return None
122 try:
138 try:
123 workdir = tempfile.mkdtemp()
139 workdir = tempfile.mkdtemp()
124 tmpfile = os.path.join(workdir, "tmp.tex")
140 tmpfile = os.path.join(workdir, "tmp.tex")
125 dvifile = os.path.join(workdir, "tmp.dvi")
141 dvifile = os.path.join(workdir, "tmp.dvi")
126 outfile = os.path.join(workdir, "tmp.png")
142 outfile = os.path.join(workdir, "tmp.png")
127
143
128 with open(tmpfile, "w", encoding='utf8') as f:
144 with open(tmpfile, "w", encoding='utf8') as f:
129 f.writelines(genelatex(s, wrap))
145 f.writelines(genelatex(s, wrap))
130
146
131 with open(os.devnull, 'wb') as devnull:
147 with open(os.devnull, 'wb') as devnull:
132 subprocess.check_call(
148 subprocess.check_call(
133 ["latex", "-halt-on-error", "-interaction", "batchmode", tmpfile],
149 ["latex", "-halt-on-error", "-interaction", "batchmode", tmpfile],
134 cwd=workdir, stdout=devnull, stderr=devnull)
150 cwd=workdir, stdout=devnull, stderr=devnull)
135
151
152 resolution = round(150*scale)
136 subprocess.check_call(
153 subprocess.check_call(
137 ["dvipng", "-T", "tight", "-x", "1500", "-z", "9",
154 ["dvipng", "-T", "tight", "-D", str(resolution), "-z", "9",
138 "-bg", "transparent", "-o", outfile, dvifile, "-fg", color],
155 "-bg", "transparent", "-o", outfile, dvifile, "-fg", color],
139 cwd=workdir, stdout=devnull, stderr=devnull)
156 cwd=workdir, stdout=devnull, stderr=devnull)
140
157
141 with open(outfile, "rb") as f:
158 with open(outfile, "rb") as f:
142 return f.read()
159 return f.read()
143 except subprocess.CalledProcessError:
160 except subprocess.CalledProcessError:
144 return None
161 return None
145 finally:
162 finally:
146 shutil.rmtree(workdir)
163 shutil.rmtree(workdir)
147
164
148
165
149 def kpsewhich(filename):
166 def kpsewhich(filename):
150 """Invoke kpsewhich command with an argument `filename`."""
167 """Invoke kpsewhich command with an argument `filename`."""
151 try:
168 try:
152 find_cmd("kpsewhich")
169 find_cmd("kpsewhich")
153 proc = subprocess.Popen(
170 proc = subprocess.Popen(
154 ["kpsewhich", filename],
171 ["kpsewhich", filename],
155 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
172 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
156 (stdout, stderr) = proc.communicate()
173 (stdout, stderr) = proc.communicate()
157 return stdout.strip().decode('utf8', 'replace')
174 return stdout.strip().decode('utf8', 'replace')
158 except FindCmdError:
175 except FindCmdError:
159 pass
176 pass
160
177
161
178
162 def genelatex(body, wrap):
179 def genelatex(body, wrap):
163 """Generate LaTeX document for dvipng backend."""
180 """Generate LaTeX document for dvipng backend."""
164 lt = LaTeXTool.instance()
181 lt = LaTeXTool.instance()
165 breqn = wrap and lt.use_breqn and kpsewhich("breqn.sty")
182 breqn = wrap and lt.use_breqn and kpsewhich("breqn.sty")
166 yield r'\documentclass{article}'
183 yield r'\documentclass{article}'
167 packages = lt.packages
184 packages = lt.packages
168 if breqn:
185 if breqn:
169 packages = packages + ['breqn']
186 packages = packages + ['breqn']
170 for pack in packages:
187 for pack in packages:
171 yield r'\usepackage{{{0}}}'.format(pack)
188 yield r'\usepackage{{{0}}}'.format(pack)
172 yield r'\pagestyle{empty}'
189 yield r'\pagestyle{empty}'
173 if lt.preamble:
190 if lt.preamble:
174 yield lt.preamble
191 yield lt.preamble
175 yield r'\begin{document}'
192 yield r'\begin{document}'
176 if breqn:
193 if breqn:
177 yield r'\begin{dmath*}'
194 yield r'\begin{dmath*}'
178 yield body
195 yield body
179 yield r'\end{dmath*}'
196 yield r'\end{dmath*}'
180 elif wrap:
197 elif wrap:
181 yield u'$${0}$$'.format(body)
198 yield u'$${0}$$'.format(body)
182 else:
199 else:
183 yield body
200 yield body
184 yield u'\\end{document}'
201 yield u'\\end{document}'
185
202
186
203
187 _data_uri_template_png = u"""<img src="data:image/png;base64,%s" alt=%s />"""
204 _data_uri_template_png = u"""<img src="data:image/png;base64,%s" alt=%s />"""
188
205
189 def latex_to_html(s, alt='image'):
206 def latex_to_html(s, alt='image'):
190 """Render LaTeX to HTML with embedded PNG data using data URIs.
207 """Render LaTeX to HTML with embedded PNG data using data URIs.
191
208
192 Parameters
209 Parameters
193 ----------
210 ----------
194 s : str
211 s : str
195 The raw string containing valid inline LateX.
212 The raw string containing valid inline LateX.
196 alt : str
213 alt : str
197 The alt text to use for the HTML.
214 The alt text to use for the HTML.
198 """
215 """
199 base64_data = latex_to_png(s, encode=True).decode('ascii')
216 base64_data = latex_to_png(s, encode=True).decode('ascii')
200 if base64_data:
217 if base64_data:
201 return _data_uri_template_png % (base64_data, alt)
218 return _data_uri_template_png % (base64_data, alt)
202
219
203
220
@@ -1,157 +1,181 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.utils.path.py"""
2 """Tests for IPython.utils.path.py"""
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 from unittest.mock import patch
6 from unittest.mock import patch
7 import nose.tools as nt
7 import nose.tools as nt
8
8
9 from IPython.lib import latextools
9 from IPython.lib import latextools
10 from IPython.testing.decorators import onlyif_cmds_exist, skipif_not_matplotlib
10 from IPython.testing.decorators import onlyif_cmds_exist, skipif_not_matplotlib
11 from IPython.utils.process import FindCmdError
11 from IPython.utils.process import FindCmdError
12
12
13
13
14 def test_latex_to_png_dvipng_fails_when_no_cmd():
14 def test_latex_to_png_dvipng_fails_when_no_cmd():
15 """
15 """
16 `latex_to_png_dvipng` should return None when there is no required command
16 `latex_to_png_dvipng` should return None when there is no required command
17 """
17 """
18 for command in ['latex', 'dvipng']:
18 for command in ['latex', 'dvipng']:
19 yield (check_latex_to_png_dvipng_fails_when_no_cmd, command)
19 yield (check_latex_to_png_dvipng_fails_when_no_cmd, command)
20
20
21
21
22 def check_latex_to_png_dvipng_fails_when_no_cmd(command):
22 def check_latex_to_png_dvipng_fails_when_no_cmd(command):
23 def mock_find_cmd(arg):
23 def mock_find_cmd(arg):
24 if arg == command:
24 if arg == command:
25 raise FindCmdError
25 raise FindCmdError
26
26
27 with patch.object(latextools, "find_cmd", mock_find_cmd):
27 with patch.object(latextools, "find_cmd", mock_find_cmd):
28 nt.assert_equal(latextools.latex_to_png_dvipng("whatever", True),
28 nt.assert_equal(latextools.latex_to_png_dvipng("whatever", True),
29 None)
29 None)
30
30
31
31
32 @onlyif_cmds_exist('latex', 'dvipng')
32 @onlyif_cmds_exist('latex', 'dvipng')
33 def test_latex_to_png_dvipng_runs():
33 def test_latex_to_png_dvipng_runs():
34 """
34 """
35 Test that latex_to_png_dvipng just runs without error.
35 Test that latex_to_png_dvipng just runs without error.
36 """
36 """
37 def mock_kpsewhich(filename):
37 def mock_kpsewhich(filename):
38 nt.assert_equal(filename, "breqn.sty")
38 nt.assert_equal(filename, "breqn.sty")
39 return None
39 return None
40
40
41 for (s, wrap) in [(u"$$x^2$$", False), (u"x^2", True)]:
41 for (s, wrap) in [(u"$$x^2$$", False), (u"x^2", True)]:
42 yield (latextools.latex_to_png_dvipng, s, wrap)
42 yield (latextools.latex_to_png_dvipng, s, wrap)
43
43
44 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
44 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
45 yield (latextools.latex_to_png_dvipng, s, wrap)
45 yield (latextools.latex_to_png_dvipng, s, wrap)
46
46
47 @skipif_not_matplotlib
47 @skipif_not_matplotlib
48 def test_latex_to_png_mpl_runs():
48 def test_latex_to_png_mpl_runs():
49 """
49 """
50 Test that latex_to_png_mpl just runs without error.
50 Test that latex_to_png_mpl just runs without error.
51 """
51 """
52 def mock_kpsewhich(filename):
52 def mock_kpsewhich(filename):
53 nt.assert_equal(filename, "breqn.sty")
53 nt.assert_equal(filename, "breqn.sty")
54 return None
54 return None
55
55
56 for (s, wrap) in [("$x^2$", False), ("x^2", True)]:
56 for (s, wrap) in [("$x^2$", False), ("x^2", True)]:
57 yield (latextools.latex_to_png_mpl, s, wrap)
57 yield (latextools.latex_to_png_mpl, s, wrap)
58
58
59 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
59 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
60 yield (latextools.latex_to_png_mpl, s, wrap)
60 yield (latextools.latex_to_png_mpl, s, wrap)
61
61
62 @skipif_not_matplotlib
62 @skipif_not_matplotlib
63 def test_latex_to_html():
63 def test_latex_to_html():
64 img = latextools.latex_to_html("$x^2$")
64 img = latextools.latex_to_html("$x^2$")
65 nt.assert_in("data:image/png;base64,iVBOR", img)
65 nt.assert_in("data:image/png;base64,iVBOR", img)
66
66
67
67
68 def test_genelatex_no_wrap():
68 def test_genelatex_no_wrap():
69 """
69 """
70 Test genelatex with wrap=False.
70 Test genelatex with wrap=False.
71 """
71 """
72 def mock_kpsewhich(filename):
72 def mock_kpsewhich(filename):
73 assert False, ("kpsewhich should not be called "
73 assert False, ("kpsewhich should not be called "
74 "(called with {0})".format(filename))
74 "(called with {0})".format(filename))
75
75
76 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
76 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
77 nt.assert_equal(
77 nt.assert_equal(
78 '\n'.join(latextools.genelatex("body text", False)),
78 '\n'.join(latextools.genelatex("body text", False)),
79 r'''\documentclass{article}
79 r'''\documentclass{article}
80 \usepackage{amsmath}
80 \usepackage{amsmath}
81 \usepackage{amsthm}
81 \usepackage{amsthm}
82 \usepackage{amssymb}
82 \usepackage{amssymb}
83 \usepackage{bm}
83 \usepackage{bm}
84 \pagestyle{empty}
84 \pagestyle{empty}
85 \begin{document}
85 \begin{document}
86 body text
86 body text
87 \end{document}''')
87 \end{document}''')
88
88
89
89
90 def test_genelatex_wrap_with_breqn():
90 def test_genelatex_wrap_with_breqn():
91 """
91 """
92 Test genelatex with wrap=True for the case breqn.sty is installed.
92 Test genelatex with wrap=True for the case breqn.sty is installed.
93 """
93 """
94 def mock_kpsewhich(filename):
94 def mock_kpsewhich(filename):
95 nt.assert_equal(filename, "breqn.sty")
95 nt.assert_equal(filename, "breqn.sty")
96 return "path/to/breqn.sty"
96 return "path/to/breqn.sty"
97
97
98 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
98 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
99 nt.assert_equal(
99 nt.assert_equal(
100 '\n'.join(latextools.genelatex("x^2", True)),
100 '\n'.join(latextools.genelatex("x^2", True)),
101 r'''\documentclass{article}
101 r'''\documentclass{article}
102 \usepackage{amsmath}
102 \usepackage{amsmath}
103 \usepackage{amsthm}
103 \usepackage{amsthm}
104 \usepackage{amssymb}
104 \usepackage{amssymb}
105 \usepackage{bm}
105 \usepackage{bm}
106 \usepackage{breqn}
106 \usepackage{breqn}
107 \pagestyle{empty}
107 \pagestyle{empty}
108 \begin{document}
108 \begin{document}
109 \begin{dmath*}
109 \begin{dmath*}
110 x^2
110 x^2
111 \end{dmath*}
111 \end{dmath*}
112 \end{document}''')
112 \end{document}''')
113
113
114
114
115 def test_genelatex_wrap_without_breqn():
115 def test_genelatex_wrap_without_breqn():
116 """
116 """
117 Test genelatex with wrap=True for the case breqn.sty is not installed.
117 Test genelatex with wrap=True for the case breqn.sty is not installed.
118 """
118 """
119 def mock_kpsewhich(filename):
119 def mock_kpsewhich(filename):
120 nt.assert_equal(filename, "breqn.sty")
120 nt.assert_equal(filename, "breqn.sty")
121 return None
121 return None
122
122
123 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
123 with patch.object(latextools, "kpsewhich", mock_kpsewhich):
124 nt.assert_equal(
124 nt.assert_equal(
125 '\n'.join(latextools.genelatex("x^2", True)),
125 '\n'.join(latextools.genelatex("x^2", True)),
126 r'''\documentclass{article}
126 r'''\documentclass{article}
127 \usepackage{amsmath}
127 \usepackage{amsmath}
128 \usepackage{amsthm}
128 \usepackage{amsthm}
129 \usepackage{amssymb}
129 \usepackage{amssymb}
130 \usepackage{bm}
130 \usepackage{bm}
131 \pagestyle{empty}
131 \pagestyle{empty}
132 \begin{document}
132 \begin{document}
133 $$x^2$$
133 $$x^2$$
134 \end{document}''')
134 \end{document}''')
135
135
136
136
137 @skipif_not_matplotlib
138 @onlyif_cmds_exist('latex', 'dvipng')
137 def test_latex_to_png_color():
139 def test_latex_to_png_color():
138 """
140 """
139 Test color settings for latex_to_png.
141 Test color settings for latex_to_png.
140 """
142 """
141 latex_string = "$x^2$"
143 latex_string = "$x^2$"
142 default_value = latextools.latex_to_png(latex_string, wrap=False)
144 default_value = latextools.latex_to_png(latex_string, wrap=False)
145 default_hexblack = latextools.latex_to_png(latex_string, wrap=False,
146 color='#000000')
143 dvipng_default = latextools.latex_to_png_dvipng(latex_string, False)
147 dvipng_default = latextools.latex_to_png_dvipng(latex_string, False)
144 dvipng_black = latextools.latex_to_png_dvipng(latex_string, False, 'Black')
148 dvipng_black = latextools.latex_to_png_dvipng(latex_string, False, 'Black')
145 nt.assert_equal(dvipng_default, dvipng_black)
149 nt.assert_equal(dvipng_default, dvipng_black)
146 mpl_default = latextools.latex_to_png_mpl(latex_string, False)
150 mpl_default = latextools.latex_to_png_mpl(latex_string, False)
147 mpl_black = latextools.latex_to_png_mpl(latex_string, False, 'Black')
151 mpl_black = latextools.latex_to_png_mpl(latex_string, False, 'Black')
148 nt.assert_equal(mpl_default, mpl_black)
152 nt.assert_equal(mpl_default, mpl_black)
149 nt.assert_in(default_value, [dvipng_black, mpl_black])
153 nt.assert_in(default_value, [dvipng_black, mpl_black])
154 nt.assert_in(default_hexblack, [dvipng_black, mpl_black])
150
155
151 # Test that dvips name colors can be used without error
156 # Test that dvips name colors can be used without error
152 dvipng_maroon = latextools.latex_to_png_dvipng(latex_string, False, 'Maroon')
157 dvipng_maroon = latextools.latex_to_png_dvipng(latex_string, False,
158 'Maroon')
153 # And that it doesn't return the black one
159 # And that it doesn't return the black one
154 nt.assert_not_equal(dvipng_black, dvipng_maroon)
160 nt.assert_not_equal(dvipng_black, dvipng_maroon)
155
161
156 mpl_maroon = latextools.latex_to_png_mpl(latex_string, False, 'Maroon')
162 mpl_maroon = latextools.latex_to_png_mpl(latex_string, False, 'Maroon')
157 nt.assert_not_equal(mpl_black, mpl_maroon)
163 nt.assert_not_equal(mpl_black, mpl_maroon)
164 mpl_white = latextools.latex_to_png_mpl(latex_string, False, 'White')
165 mpl_hexwhite = latextools.latex_to_png_mpl(latex_string, False, '#FFFFFF')
166 nt.assert_equal(mpl_white, mpl_hexwhite)
167
168 mpl_white_scale = latextools.latex_to_png_mpl(latex_string, False,
169 'White', 1.2)
170 nt.assert_not_equal(mpl_white, mpl_white_scale)
171
172
173 def test_latex_to_png_invalid_hex_colors():
174 """
175 Test that invalid hex colors provided to dvipng gives an exception.
176 """
177 latex_string = "$x^2$"
178 nt.assert_raises(ValueError, lambda: latextools.latex_to_png(latex_string,
179 backend='dvipng', color="#f00bar"))
180 nt.assert_raises(ValueError, lambda: latextools.latex_to_png(latex_string,
181 backend='dvipng', color="#f00"))
General Comments 0
You need to be logged in to leave comments. Login now