##// END OF EJS Templates
Better color options and added scale
Oscar Gustafsson -
Show More
@@ -10,6 +10,7 b' import tempfile'
10 10 import shutil
11 11 import subprocess
12 12 from base64 import encodebytes
13 from textwrap import wrap as splitstring
13 14
14 15 from IPython.utils.process import find_cmd, FindCmdError
15 16 from traitlets.config import get_config
@@ -55,7 +56,8 b' class LaTeXTool(SingletonConfigurable):'
55 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 61 """Render a LaTeX string to PNG.
60 62
61 63 Parameters
@@ -69,7 +71,10 b" def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black'):"
69 71 wrap : bool
70 72 If true, Automatically wrap `s` as a LaTeX equation.
71 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 79 None is returned when the backend cannot be used.
75 80
@@ -84,15 +89,25 b" def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black'):"
84 89 f = latex_to_png_mpl
85 90 elif backend == 'dvipng':
86 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 102 else:
88 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 105 if encode and bin_data:
91 106 bin_data = encodebytes(bin_data)
92 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 111 try:
97 112 from matplotlib import mathtext
98 113 from pyparsing import ParseFatalException
@@ -107,13 +122,14 b" def latex_to_png_mpl(s, wrap, color='Black'):"
107 122 try:
108 123 mt = mathtext.MathTextParser('bitmap')
109 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 127 return f.getvalue()
112 128 except (ValueError, RuntimeError, ParseFatalException):
113 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 133 try:
118 134 find_cmd('latex')
119 135 find_cmd('dvipng')
@@ -133,8 +149,9 b" def latex_to_png_dvipng(s, wrap, color='Black'):"
133 149 ["latex", "-halt-on-error", "-interaction", "batchmode", tmpfile],
134 150 cwd=workdir, stdout=devnull, stderr=devnull)
135 151
152 resolution = round(150*scale)
136 153 subprocess.check_call(
137 ["dvipng", "-T", "tight", "-x", "1500", "-z", "9",
154 ["dvipng", "-T", "tight", "-D", str(resolution), "-z", "9",
138 155 "-bg", "transparent", "-o", outfile, dvifile, "-fg", color],
139 156 cwd=workdir, stdout=devnull, stderr=devnull)
140 157
@@ -134,12 +134,16 b' $$x^2$$'
134 134 \end{document}''')
135 135
136 136
137 @skipif_not_matplotlib
138 @onlyif_cmds_exist('latex', 'dvipng')
137 139 def test_latex_to_png_color():
138 140 """
139 141 Test color settings for latex_to_png.
140 142 """
141 143 latex_string = "$x^2$"
142 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 147 dvipng_default = latextools.latex_to_png_dvipng(latex_string, False)
144 148 dvipng_black = latextools.latex_to_png_dvipng(latex_string, False, 'Black')
145 149 nt.assert_equal(dvipng_default, dvipng_black)
@@ -147,11 +151,31 b' def test_latex_to_png_color():'
147 151 mpl_black = latextools.latex_to_png_mpl(latex_string, False, 'Black')
148 152 nt.assert_equal(mpl_default, mpl_black)
149 153 nt.assert_in(default_value, [dvipng_black, mpl_black])
154 nt.assert_in(default_hexblack, [dvipng_black, mpl_black])
150 155
151 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 159 # And that it doesn't return the black one
154 160 nt.assert_not_equal(dvipng_black, dvipng_maroon)
155 161
156 162 mpl_maroon = latextools.latex_to_png_mpl(latex_string, False, 'Maroon')
157 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