##// END OF EJS Templates
Better color options and added scale
Oscar Gustafsson -
Show More
@@ -10,6 +10,7 b' 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
@@ -55,7 +56,8 b' class LaTeXTool(SingletonConfigurable):'
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
@@ -69,7 +71,10 b" def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black'):"
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
@@ -84,15 +89,25 b" def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black'):"
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
@@ -107,13 +122,14 b" def latex_to_png_mpl(s, wrap, color='Black'):"
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')
@@ -133,8 +149,9 b" def latex_to_png_dvipng(s, wrap, color='Black'):"
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
@@ -134,12 +134,16 b' $$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)
@@ -147,11 +151,31 b' def test_latex_to_png_color():'
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