##// END OF EJS Templates
More improvements to the display system....
Brian Granger -
Show More
@@ -0,0 +1,62 b''
1 # -*- coding: utf-8 -*-
2 """Tools for handling LaTeX.
3
4 Authors:
5
6 * Brian Granger
7 """
8 #-----------------------------------------------------------------------------
9 # Copyright (c) 2010, IPython Development Team.
10 #
11 # Distributed under the terms of the Modified BSD License.
12 #
13 # The full license is in the file COPYING.txt, distributed with this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
19
20 from StringIO import StringIO
21 from base64 import encodestring
22
23 #-----------------------------------------------------------------------------
24 # Tools
25 #-----------------------------------------------------------------------------
26
27
28 def latex_to_png(s, encode=True):
29 """Render a LaTeX string to PNG using matplotlib.mathtext.
30
31 Parameters
32 ----------
33 s : str
34 The raw string containing valid inline LaTeX.
35 encode : bool, optional
36 Should the PNG data bebase64 encoded to make it JSON'able.
37 """
38 from matplotlib import mathtext
39
40 mt = mathtext.MathTextParser('bitmap')
41 f = StringIO()
42 mt.to_png(f, s, fontsize=12)
43 bin_data = f.getvalue()
44 if encode:
45 bin_data = encodestring(bin_data)
46 return bin_data
47
48 _data_uri_template_png = """<img src="data:image/png;base64,%s" alt=%s />"""
49
50 def latex_to_html(s, alt='image'):
51 """Render LaTeX to HTML with embedded PNG data using data URIs.
52
53 Parameters
54 ----------
55 s : str
56 The raw string containing valid inline LateX.
57 alt : str
58 The alt text to use for the HTML.
59 """
60 base64_data = latex_to_png(s, encode=True)
61 return _data_uri_template_png % (base64_data, alt)
62
@@ -48,6 +48,17 b' def display(obj, include=None, exclude=None):'
48 48 publish('IPython.core.display.display', format_dict)
49 49
50 50
51 def display_pretty(obj):
52 """Display the pretty (default) representation of an object.
53
54 Parameters
55 ----------
56 obj : object
57 The Python object to display.
58 """
59 display(obj, include=['text/plain'])
60
61
51 62 def display_html(obj):
52 63 """Display the HTML representation of an object.
53 64
@@ -15,6 +15,10 b' Authors:'
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
18 22 # Stdlib imports
19 23 import abc
20 24 # We must use StringIO, as cStringIO doesn't handle unicode properly.
@@ -259,6 +263,23 b' class BaseFormatter(Configurable):'
259 263 self.deferred_printers[key] = func
260 264 return oldfunc
261 265
266 def _in_deferred_types(self, cls):
267 """
268 Check if the given class is specified in the deferred type registry.
269
270 Returns the printer from the registry if it exists, and None if the
271 class is not in the registry. Successful matches will be moved to the
272 regular type registry for future use.
273 """
274 mod = getattr(cls, '__module__', None)
275 name = getattr(cls, '__name__', None)
276 key = (mod, name)
277 printer = None
278 if key in self.deferred_printers:
279 # Move the printer over to the regular registry.
280 printer = self.deferred_printers.pop(key)
281 self.type_printers[cls] = printer
282 return printer
262 283
263 284 class PlainTextFormatter(BaseFormatter):
264 285 """The default pretty-printer.
@@ -14,7 +14,9 b' Authors:'
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 from sympy import pretty
17 from IPython.lib.latextools import latex_to_png
18
19 from sympy import pretty, latex
18 20
19 21 #-----------------------------------------------------------------------------
20 22 # Definitions of magic functions for use with IPython
@@ -30,6 +32,12 b' def print_basic_unicode(o, p, cycle):'
30 32 p.text(out)
31 33
32 34
35 def print_png(o):
36 """A funciton to display sympy expression using LaTex -> PNG."""
37 s = latex(o)
38 png = latex_to_png(s, encode=True)
39 return png
40
33 41 _loaded = False
34 42
35 43
@@ -41,5 +49,9 b' def load_ipython_extension(ip):'
41 49 plaintext_formatter.for_type_by_name(
42 50 'sympy.core.basic', 'Basic', print_basic_unicode
43 51 )
52 png_formatter = ip.display_formatter.formatters['image/png']
53 png_formatter.for_type_by_name(
54 'sympy.core.basic', 'Basic', print_png
55 )
44 56 _loaded = True
45 57
@@ -210,6 +210,8 b' class IPythonWidget(FrontendWidget):'
210 210 elif data.has_key('text/plain'):
211 211 text = data['text/plain']
212 212 self._append_plain_text(text)
213 # This newline seems to be needed for text and html output.
214 self._append_plain_text(u'\n')
213 215
214 216 def _started_channels(self):
215 217 """ Reimplemented to make a history request.
@@ -1,6 +1,7 b''
1 1 # System library imports
2 2 import os
3 3 import re
4 from base64 import decodestring
4 5 from PyQt4 import QtCore, QtGui
5 6
6 7 # Local imports
@@ -74,6 +75,13 b' class RichIPythonWidget(IPythonWidget):'
74 75 # TODO: try/except this call.
75 76 self._append_svg(data['image/svg+xml'])
76 77 self._append_html(self.output_sep2)
78 elif data.has_key('image/png'):
79 self._append_plain_text(self.output_sep)
80 self._append_html(self._make_out_prompt(prompt_number))
81 # TODO: try/except these calls
82 png = decodestring(data['image/png'])
83 self._append_png(png)
84 self._append_html(self.output_sep2)
77 85 else:
78 86 # Default back to the plain text representation.
79 87 return super(RichIPythonWidget, self)._handle_pyout(msg)
@@ -91,6 +99,12 b' class RichIPythonWidget(IPythonWidget):'
91 99 svg = data['image/svg+xml']
92 100 # TODO: try/except this call.
93 101 self._append_svg(svg)
102 elif data.has_key('image/png'):
103 # TODO: try/except these calls
104 # PNG data is base64 encoded as it passes over the network
105 # in a JSON structure so we decode it.
106 png = decodestring(data['image/png'])
107 self._append_png(png)
94 108 else:
95 109 # Default back to the plain text representation.
96 110 return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -135,6 +149,21 b' class RichIPythonWidget(IPythonWidget):'
135 149 cursor.insertImage(format)
136 150 cursor.insertBlock()
137 151
152 def _append_png(self, png):
153 """ Append raw svg data to the widget.
154 """
155 try:
156 image = QtGui.QImage()
157 image.loadFromData(png, 'PNG')
158 except ValueError:
159 self._append_plain_text('Received invalid plot data.')
160 else:
161 format = self._add_image(image)
162 cursor = self._get_end_cursor()
163 cursor.insertBlock()
164 cursor.insertImage(format)
165 cursor.insertBlock()
166
138 167 def _add_image(self, image):
139 168 """ Adds the specified QImage to the document and returns a
140 169 QTextImageFormat that references it.
General Comments 0
You need to be logged in to leave comments. Login now