##// END OF EJS Templates
Copyright fix on sympyprinting.py and latextools.py...
Takafumi Arakaki -
Show More
@@ -1,151 +1,151 b''
1 1 """
2 2 A print function that pretty prints sympy Basic objects.
3 3
4 4 :moduleauthor: Brian Granger
5 5
6 6 Usage
7 7 =====
8 8
9 9 Once the extension is loaded, Sympy Basic objects are automatically
10 10 pretty-printed.
11 11
12 12 """
13 13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 from IPython.lib.latextools import latex_to_png
25 25 from IPython.testing import decorators as dec
26 26 # use @dec.skipif_not_sympy to skip tests requiring sympy
27 27
28 28 try:
29 29 from sympy import pretty, latex
30 30 except ImportError:
31 31 pass
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Definitions of special display functions for use with IPython
35 35 #-----------------------------------------------------------------------------
36 36
37 37 def print_basic_unicode(o, p, cycle):
38 38 """A function to pretty print sympy Basic objects."""
39 39 if cycle:
40 40 return p.text('Basic(...)')
41 41 out = pretty(o, use_unicode=True)
42 42 if '\n' in out:
43 43 p.text(u'\n')
44 44 p.text(out)
45 45
46 46
47 47 def print_png(o):
48 48 """
49 49 A function to display sympy expression using inline style LaTeX in PNG.
50 50 """
51 51 s = latex(o, mode='inline')
52 52 # mathtext does not understand certain latex flags, so we try to replace
53 53 # them with suitable subs.
54 54 s = s.replace('\\operatorname','')
55 55 s = s.replace('\\overline', '\\bar')
56 56 png = latex_to_png(s)
57 57 return png
58 58
59 59
60 60 def print_display_png(o):
61 61 """
62 62 A function to display sympy expression using display style LaTeX in PNG.
63 63 """
64 64 s = latex(o, mode='plain')
65 65 s = s.strip('$')
66 66 # As matplotlib does not support display style, dvipng backend is
67 67 # used here.
68 68 png = latex_to_png('$$%s$$' % s, backend='dvipng')
69 69 return png
70 70
71 71
72 72 def can_print_latex(o):
73 73 """
74 74 Return True if type o can be printed with LaTeX.
75 75
76 76 If o is a container type, this is True if and only if every element of o
77 77 can be printed with LaTeX.
78 78 """
79 79 import sympy
80 80 if isinstance(o, (list, tuple, set, frozenset)):
81 81 return all(can_print_latex(i) for i in o)
82 82 elif isinstance(o, dict):
83 83 return all((isinstance(i, basestring) or can_print_latex(i)) and can_print_latex(o[i]) for i in o)
84 84 elif isinstance(o,(sympy.Basic, sympy.matrices.Matrix, int, long, float)):
85 85 return True
86 86 return False
87 87
88 88 def print_latex(o):
89 89 """A function to generate the latex representation of sympy
90 90 expressions."""
91 91 if can_print_latex(o):
92 92 s = latex(o, mode='plain')
93 93 s = s.replace('\\dag','\\dagger')
94 94 s = s.strip('$')
95 95 return '$$%s$$' % s
96 96 # Fallback to the string printer
97 97 return None
98 98
99 99 _loaded = False
100 100
101 101 def load_ipython_extension(ip):
102 102 """Load the extension in IPython."""
103 103 import sympy
104 104 global _loaded
105 105 if not _loaded:
106 106 plaintext_formatter = ip.display_formatter.formatters['text/plain']
107 107
108 108 for cls in (object, str):
109 109 plaintext_formatter.for_type(cls, print_basic_unicode)
110 110
111 111 printable_containers = [list, tuple]
112 112
113 113 # set and frozen set were broken with SymPy's latex() function, but
114 114 # was fixed in the 0.7.1-git development version. See
115 115 # http://code.google.com/p/sympy/issues/detail?id=3062.
116 116 if sympy.__version__ > '0.7.1':
117 117 printable_containers += [set, frozenset]
118 118 else:
119 119 plaintext_formatter.for_type(cls, print_basic_unicode)
120 120
121 121 plaintext_formatter.for_type_by_name(
122 122 'sympy.core.basic', 'Basic', print_basic_unicode
123 123 )
124 124 plaintext_formatter.for_type_by_name(
125 125 'sympy.matrices.matrices', 'Matrix', print_basic_unicode
126 126 )
127 127
128 128 png_formatter = ip.display_formatter.formatters['image/png']
129 129
130 130 png_formatter.for_type_by_name(
131 131 'sympy.core.basic', 'Basic', print_png
132 132 )
133 133 png_formatter.for_type_by_name(
134 134 'sympy.matrices.matrices', 'Matrix', print_display_png
135 135 )
136 136 for cls in [dict, int, long, float] + printable_containers:
137 137 png_formatter.for_type(cls, print_png)
138 138
139 139 latex_formatter = ip.display_formatter.formatters['text/latex']
140 140 latex_formatter.for_type_by_name(
141 141 'sympy.core.basic', 'Basic', print_latex
142 142 )
143 143 latex_formatter.for_type_by_name(
144 144 'sympy.matrices.matrices', 'Matrix', print_latex
145 145 )
146 146
147 147 for cls in printable_containers:
148 148 # Use LaTeX only if every element is printable by latex
149 149 latex_formatter.for_type(cls, print_latex)
150 150
151 151 _loaded = True
@@ -1,174 +1,174 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 # Copyright (C) 2010-2011, IPython Development Team.
9 # Copyright (C) 2010 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 22 import os
23 23 import tempfile
24 24 import shutil
25 25 import subprocess
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Tools
29 29 #-----------------------------------------------------------------------------
30 30
31 31
32 32 def latex_to_png(s, encode=False, backend='mpl'):
33 33 """Render a LaTeX string to PNG.
34 34
35 35 Parameters
36 36 ----------
37 37 s : str
38 38 The raw string containing valid inline LaTeX.
39 39 encode : bool, optional
40 40 Should the PNG data bebase64 encoded to make it JSON'able.
41 41 backend : {mpl, dvipng}
42 42 Backend for producing PNG data.
43 43
44 44 None is returned when the backend cannot be used.
45 45
46 46 """
47 47 if backend == 'mpl':
48 48 f = latex_to_png_mpl
49 49 elif backend == 'dvipng':
50 50 f = latex_to_png_dvipng
51 51 else:
52 52 raise ValueError('No such backend {0}'.format(backend))
53 53 bin_data = f(s)
54 54 if encode and bin_data:
55 55 bin_data = encodestring(bin_data)
56 56 return bin_data
57 57
58 58
59 59 def latex_to_png_mpl(s):
60 60 try:
61 61 from matplotlib import mathtext
62 62 except ImportError:
63 63 return None
64 64
65 65 mt = mathtext.MathTextParser('bitmap')
66 66 f = StringIO()
67 67 mt.to_png(f, s, fontsize=12)
68 68 return f.getvalue()
69 69
70 70
71 71 def latex_to_png_dvipng(s):
72 72 try:
73 73 workdir = tempfile.mkdtemp()
74 74 tmpfile = os.path.join(workdir, "tmp.tex")
75 75 dvifile = os.path.join(workdir, "tmp.dvi")
76 76 outfile = os.path.join(workdir, "tmp.png")
77 77
78 78 with open(tmpfile, "w") as f:
79 79 f.write(_latex_header)
80 80 f.write(s)
81 81 f.write(_latex_footer)
82 82
83 83 subprocess.check_call(
84 84 ["latex", "-halt-on-errror", tmpfile], cwd=workdir)
85 85
86 86 subprocess.check_call(
87 87 ["dvipng", "-T", "tight", "-x", "1500", "-z", "9",
88 88 "-bg", "transparent", "-o", outfile, dvifile], cwd=workdir)
89 89
90 90 with open(outfile) as f:
91 91 bin_data = f.read()
92 92 except subprocess.CalledProcessError:
93 93 bin_data = None
94 94 finally:
95 95 shutil.rmtree(workdir)
96 96 return bin_data
97 97
98 98
99 99 _latex_header = r'''
100 100 \documentclass{article}
101 101 \usepackage{amsmath}
102 102 \usepackage{amsthm}
103 103 \usepackage{amssymb}
104 104 \usepackage{bm}
105 105 \pagestyle{empty}
106 106 \begin{document}
107 107 '''
108 108
109 109 _latex_footer = r'\end{document}'
110 110
111 111
112 112 _data_uri_template_png = """<img src="data:image/png;base64,%s" alt=%s />"""
113 113
114 114 def latex_to_html(s, alt='image'):
115 115 """Render LaTeX to HTML with embedded PNG data using data URIs.
116 116
117 117 Parameters
118 118 ----------
119 119 s : str
120 120 The raw string containing valid inline LateX.
121 121 alt : str
122 122 The alt text to use for the HTML.
123 123 """
124 124 base64_data = latex_to_png(s, encode=True)
125 125 if base64_data:
126 126 return _data_uri_template_png % (base64_data, alt)
127 127
128 128
129 129 # From matplotlib, thanks to mdboom. Once this is in matplotlib releases, we
130 130 # will remove.
131 131 def math_to_image(s, filename_or_obj, prop=None, dpi=None, format=None):
132 132 """
133 133 Given a math expression, renders it in a closely-clipped bounding
134 134 box to an image file.
135 135
136 136 *s*
137 137 A math expression. The math portion should be enclosed in
138 138 dollar signs.
139 139
140 140 *filename_or_obj*
141 141 A filepath or writable file-like object to write the image data
142 142 to.
143 143
144 144 *prop*
145 145 If provided, a FontProperties() object describing the size and
146 146 style of the text.
147 147
148 148 *dpi*
149 149 Override the output dpi, otherwise use the default associated
150 150 with the output format.
151 151
152 152 *format*
153 153 The output format, eg. 'svg', 'pdf', 'ps' or 'png'. If not
154 154 provided, will be deduced from the filename.
155 155 """
156 156 from matplotlib import figure
157 157 # backend_agg supports all of the core output formats
158 158 from matplotlib.backends import backend_agg
159 159 from matplotlib.font_manager import FontProperties
160 160 from matplotlib.mathtext import MathTextParser
161 161
162 162 if prop is None:
163 163 prop = FontProperties()
164 164
165 165 parser = MathTextParser('path')
166 166 width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop)
167 167
168 168 fig = figure.Figure(figsize=(width / 72.0, height / 72.0))
169 169 fig.text(0, depth/height, s, fontproperties=prop)
170 170 backend_agg.FigureCanvasAgg(fig)
171 171 fig.savefig(filename_or_obj, dpi=dpi, format=format)
172 172
173 173 return depth
174 174
General Comments 0
You need to be logged in to leave comments. Login now