##// END OF EJS Templates
Add dvipng backend to latex_to_png
Takafumi Arakaki -
Show More
@@ -1,110 +1,167 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for handling LaTeX.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (C) 2010-2011, IPython Development Team.
10 10 #
11 11 # Distributed under the terms of the Modified BSD License.
12 12 #
13 13 # The full license is in the file COPYING.txt, distributed with this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from StringIO import StringIO
21 21 from base64 import encodestring
22 import os
23 import tempfile
24 import shutil
25 import subprocess
22 26
23 27 #-----------------------------------------------------------------------------
24 28 # Tools
25 29 #-----------------------------------------------------------------------------
26 30
27 31
28 def latex_to_png(s, encode=False):
29 """Render a LaTeX string to PNG using matplotlib.mathtext.
32 def latex_to_png(s, encode=False, backend='mpl'):
33 """Render a LaTeX string to PNG.
30 34
31 35 Parameters
32 36 ----------
33 37 s : str
34 38 The raw string containing valid inline LaTeX.
35 39 encode : bool, optional
36 40 Should the PNG data bebase64 encoded to make it JSON'able.
41 backend : {mpl, dvipng}
42 Backend for producing PNG data.
43
37 44 """
45 if backend == 'mpl':
46 f = latex_to_png_mpl
47 elif backend == 'dvipng':
48 f = latex_to_png_dvipng
49 else:
50 raise ValueError('No such backend {0}'.format(backend))
51 bin_data = f(s)
52 if encode:
53 bin_data = encodestring(bin_data)
54 return bin_data
55
56
57 def latex_to_png_mpl(s):
38 58 from matplotlib import mathtext
39 59
40 60 mt = mathtext.MathTextParser('bitmap')
41 61 f = StringIO()
42 62 mt.to_png(f, s, fontsize=12)
43 bin_data = f.getvalue()
44 if encode:
45 bin_data = encodestring(bin_data)
63 return f.getvalue()
64
65
66 def latex_to_png_dvipng(s):
67 try:
68 workdir = tempfile.mkdtemp()
69 tmpfile = os.path.join(workdir, "tmp.tex")
70 dvifile = os.path.join(workdir, "tmp.dvi")
71 outfile = os.path.join(workdir, "tmp.png")
72
73 with open(tmpfile, "w") as f:
74 f.write(_latex_header)
75 f.write(s)
76 f.write(_latex_footer)
77
78 subprocess.check_call(
79 ["latex", "-halt-on-errror", tmpfile], cwd=workdir)
80
81 subprocess.check_call(
82 ["dvipng", "-T", "tight", "-x", "1500", "-z", "9",
83 "-bg", "transparent", "-o", outfile, dvifile], cwd=workdir)
84
85 with open(outfile) as f:
86 bin_data = f.read()
87 finally:
88 shutil.rmtree(workdir)
46 89 return bin_data
47 90
48 91
92
93 _latex_header = r'''
94 \documentclass{article}
95 \usepackage{amsmath}
96 \usepackage{amsthm}
97 \usepackage{amssymb}
98 \usepackage{bm}
99 \pagestyle{empty}
100 \begin{document}
101 '''
102
103 _latex_footer = r'\end{document}'
104
105
49 106 _data_uri_template_png = """<img src="data:image/png;base64,%s" alt=%s />"""
50 107
51 108 def latex_to_html(s, alt='image'):
52 109 """Render LaTeX to HTML with embedded PNG data using data URIs.
53 110
54 111 Parameters
55 112 ----------
56 113 s : str
57 114 The raw string containing valid inline LateX.
58 115 alt : str
59 116 The alt text to use for the HTML.
60 117 """
61 118 base64_data = latex_to_png(s, encode=True)
62 119 return _data_uri_template_png % (base64_data, alt)
63 120
64 121
65 122 # From matplotlib, thanks to mdboom. Once this is in matplotlib releases, we
66 123 # will remove.
67 124 def math_to_image(s, filename_or_obj, prop=None, dpi=None, format=None):
68 125 """
69 126 Given a math expression, renders it in a closely-clipped bounding
70 127 box to an image file.
71 128
72 129 *s*
73 130 A math expression. The math portion should be enclosed in
74 131 dollar signs.
75 132
76 133 *filename_or_obj*
77 134 A filepath or writable file-like object to write the image data
78 135 to.
79 136
80 137 *prop*
81 138 If provided, a FontProperties() object describing the size and
82 139 style of the text.
83 140
84 141 *dpi*
85 142 Override the output dpi, otherwise use the default associated
86 143 with the output format.
87 144
88 145 *format*
89 146 The output format, eg. 'svg', 'pdf', 'ps' or 'png'. If not
90 147 provided, will be deduced from the filename.
91 148 """
92 149 from matplotlib import figure
93 150 # backend_agg supports all of the core output formats
94 151 from matplotlib.backends import backend_agg
95 152 from matplotlib.font_manager import FontProperties
96 153 from matplotlib.mathtext import MathTextParser
97 154
98 155 if prop is None:
99 156 prop = FontProperties()
100 157
101 158 parser = MathTextParser('path')
102 159 width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop)
103 160
104 161 fig = figure.Figure(figsize=(width / 72.0, height / 72.0))
105 162 fig.text(0, depth/height, s, fontproperties=prop)
106 163 backend_agg.FigureCanvasAgg(fig)
107 164 fig.savefig(filename_or_obj, dpi=dpi, format=format)
108 165
109 166 return depth
110 167
General Comments 0
You need to be logged in to leave comments. Login now