##// END OF EJS Templates
remove publish_foo functions
MinRK -
Show More
@@ -1,598 +1,591 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Top-level display functions for displaying object in different formats.
2 """Top-level display functions for displaying object in different formats.
3
3
4 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2013 The IPython Development Team
10 # Copyright (C) 2013 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 from __future__ import print_function
20 from __future__ import print_function
21
21
22 import os
22 import os
23
23
24 from .displaypub import (
25 publish_pretty, publish_html,
26 publish_latex, publish_svg,
27 publish_png, publish_json,
28 publish_javascript, publish_jpeg
29 )
30
31 from IPython.utils.py3compat import string_types
24 from IPython.utils.py3compat import string_types
32
25
33 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
34 # utility functions
27 # utility functions
35 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
36
29
37 def _safe_exists(path):
30 def _safe_exists(path):
38 """Check path, but don't let exceptions raise"""
31 """Check path, but don't let exceptions raise"""
39 try:
32 try:
40 return os.path.exists(path)
33 return os.path.exists(path)
41 except Exception:
34 except Exception:
42 return False
35 return False
43
36
44 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
45 # Main functions
38 # Main functions
46 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
47
40
48 def display(*objs, **kwargs):
41 def display(*objs, **kwargs):
49 """Display a Python object in all frontends.
42 """Display a Python object in all frontends.
50
43
51 By default all representations will be computed and sent to the frontends.
44 By default all representations will be computed and sent to the frontends.
52 Frontends can decide which representation is used and how.
45 Frontends can decide which representation is used and how.
53
46
54 Parameters
47 Parameters
55 ----------
48 ----------
56 objs : tuple of objects
49 objs : tuple of objects
57 The Python objects to display.
50 The Python objects to display.
58 include : list or tuple, optional
51 include : list or tuple, optional
59 A list of format type strings (MIME types) to include in the
52 A list of format type strings (MIME types) to include in the
60 format data dict. If this is set *only* the format types included
53 format data dict. If this is set *only* the format types included
61 in this list will be computed.
54 in this list will be computed.
62 exclude : list or tuple, optional
55 exclude : list or tuple, optional
63 A list of format type strings (MIME types) to exclude in the format
56 A list of format type strings (MIME types) to exclude in the format
64 data dict. If this is set all format types will be computed,
57 data dict. If this is set all format types will be computed,
65 except for those included in this argument.
58 except for those included in this argument.
66 """
59 """
67 include = kwargs.get('include')
60 include = kwargs.get('include')
68 exclude = kwargs.get('exclude')
61 exclude = kwargs.get('exclude')
69
62
70 from IPython.core.interactiveshell import InteractiveShell
63 from IPython.core.interactiveshell import InteractiveShell
71 inst = InteractiveShell.instance()
64 inst = InteractiveShell.instance()
72 format = inst.display_formatter.format
65 format = inst.display_formatter.format
73 publish = inst.display_pub.publish
66 publish = inst.display_pub.publish
74
67
75 for obj in objs:
68 for obj in objs:
76 format_dict, md_dict = format(obj, include=include, exclude=exclude)
69 format_dict, md_dict = format(obj, include=include, exclude=exclude)
77 publish('IPython.core.display.display', format_dict, md_dict)
70 publish('IPython.core.display.display', format_dict, md_dict)
78
71
79
72
80 def display_pretty(*objs, **kwargs):
73 def display_pretty(*objs, **kwargs):
81 """Display the pretty (default) representation of an object.
74 """Display the pretty (default) representation of an object.
82
75
83 Parameters
76 Parameters
84 ----------
77 ----------
85 objs : tuple of objects
78 objs : tuple of objects
86 The Python objects to display, or if raw=True raw text data to
79 The Python objects to display, or if raw=True raw text data to
87 display.
80 display.
88 raw : bool
81 raw : bool
89 Are the data objects raw data or Python objects that need to be
82 Are the data objects raw data or Python objects that need to be
90 formatted before display? [default: False]
83 formatted before display? [default: False]
91 """
84 """
92 raw = kwargs.pop('raw',False)
85 raw = kwargs.pop('raw',False)
93 if raw:
86 if raw:
94 for obj in objs:
87 for obj in objs:
95 publish_pretty(obj)
88 publish_pretty(obj)
96 else:
89 else:
97 display(*objs, include=['text/plain'])
90 display(*objs, include=['text/plain'])
98
91
99
92
100 def display_html(*objs, **kwargs):
93 def display_html(*objs, **kwargs):
101 """Display the HTML representation of an object.
94 """Display the HTML representation of an object.
102
95
103 Parameters
96 Parameters
104 ----------
97 ----------
105 objs : tuple of objects
98 objs : tuple of objects
106 The Python objects to display, or if raw=True raw HTML data to
99 The Python objects to display, or if raw=True raw HTML data to
107 display.
100 display.
108 raw : bool
101 raw : bool
109 Are the data objects raw data or Python objects that need to be
102 Are the data objects raw data or Python objects that need to be
110 formatted before display? [default: False]
103 formatted before display? [default: False]
111 """
104 """
112 raw = kwargs.pop('raw',False)
105 raw = kwargs.pop('raw',False)
113 if raw:
106 if raw:
114 for obj in objs:
107 for obj in objs:
115 publish_html(obj)
108 publish_html(obj)
116 else:
109 else:
117 display(*objs, include=['text/plain','text/html'])
110 display(*objs, include=['text/plain','text/html'])
118
111
119
112
120 def display_svg(*objs, **kwargs):
113 def display_svg(*objs, **kwargs):
121 """Display the SVG representation of an object.
114 """Display the SVG representation of an object.
122
115
123 Parameters
116 Parameters
124 ----------
117 ----------
125 objs : tuple of objects
118 objs : tuple of objects
126 The Python objects to display, or if raw=True raw svg data to
119 The Python objects to display, or if raw=True raw svg data to
127 display.
120 display.
128 raw : bool
121 raw : bool
129 Are the data objects raw data or Python objects that need to be
122 Are the data objects raw data or Python objects that need to be
130 formatted before display? [default: False]
123 formatted before display? [default: False]
131 """
124 """
132 raw = kwargs.pop('raw',False)
125 raw = kwargs.pop('raw',False)
133 if raw:
126 if raw:
134 for obj in objs:
127 for obj in objs:
135 publish_svg(obj)
128 publish_svg(obj)
136 else:
129 else:
137 display(*objs, include=['text/plain','image/svg+xml'])
130 display(*objs, include=['text/plain','image/svg+xml'])
138
131
139
132
140 def display_png(*objs, **kwargs):
133 def display_png(*objs, **kwargs):
141 """Display the PNG representation of an object.
134 """Display the PNG representation of an object.
142
135
143 Parameters
136 Parameters
144 ----------
137 ----------
145 objs : tuple of objects
138 objs : tuple of objects
146 The Python objects to display, or if raw=True raw png data to
139 The Python objects to display, or if raw=True raw png data to
147 display.
140 display.
148 raw : bool
141 raw : bool
149 Are the data objects raw data or Python objects that need to be
142 Are the data objects raw data or Python objects that need to be
150 formatted before display? [default: False]
143 formatted before display? [default: False]
151 """
144 """
152 raw = kwargs.pop('raw',False)
145 raw = kwargs.pop('raw',False)
153 if raw:
146 if raw:
154 for obj in objs:
147 for obj in objs:
155 publish_png(obj)
148 publish_png(obj)
156 else:
149 else:
157 display(*objs, include=['text/plain','image/png'])
150 display(*objs, include=['text/plain','image/png'])
158
151
159
152
160 def display_jpeg(*objs, **kwargs):
153 def display_jpeg(*objs, **kwargs):
161 """Display the JPEG representation of an object.
154 """Display the JPEG representation of an object.
162
155
163 Parameters
156 Parameters
164 ----------
157 ----------
165 objs : tuple of objects
158 objs : tuple of objects
166 The Python objects to display, or if raw=True raw JPEG data to
159 The Python objects to display, or if raw=True raw JPEG data to
167 display.
160 display.
168 raw : bool
161 raw : bool
169 Are the data objects raw data or Python objects that need to be
162 Are the data objects raw data or Python objects that need to be
170 formatted before display? [default: False]
163 formatted before display? [default: False]
171 """
164 """
172 raw = kwargs.pop('raw',False)
165 raw = kwargs.pop('raw',False)
173 if raw:
166 if raw:
174 for obj in objs:
167 for obj in objs:
175 publish_jpeg(obj)
168 publish_jpeg(obj)
176 else:
169 else:
177 display(*objs, include=['text/plain','image/jpeg'])
170 display(*objs, include=['text/plain','image/jpeg'])
178
171
179
172
180 def display_latex(*objs, **kwargs):
173 def display_latex(*objs, **kwargs):
181 """Display the LaTeX representation of an object.
174 """Display the LaTeX representation of an object.
182
175
183 Parameters
176 Parameters
184 ----------
177 ----------
185 objs : tuple of objects
178 objs : tuple of objects
186 The Python objects to display, or if raw=True raw latex data to
179 The Python objects to display, or if raw=True raw latex data to
187 display.
180 display.
188 raw : bool
181 raw : bool
189 Are the data objects raw data or Python objects that need to be
182 Are the data objects raw data or Python objects that need to be
190 formatted before display? [default: False]
183 formatted before display? [default: False]
191 """
184 """
192 raw = kwargs.pop('raw',False)
185 raw = kwargs.pop('raw',False)
193 if raw:
186 if raw:
194 for obj in objs:
187 for obj in objs:
195 publish_latex(obj)
188 publish_latex(obj)
196 else:
189 else:
197 display(*objs, include=['text/plain','text/latex'])
190 display(*objs, include=['text/plain','text/latex'])
198
191
199
192
200 def display_json(*objs, **kwargs):
193 def display_json(*objs, **kwargs):
201 """Display the JSON representation of an object.
194 """Display the JSON representation of an object.
202
195
203 Note that not many frontends support displaying JSON.
196 Note that not many frontends support displaying JSON.
204
197
205 Parameters
198 Parameters
206 ----------
199 ----------
207 objs : tuple of objects
200 objs : tuple of objects
208 The Python objects to display, or if raw=True raw json data to
201 The Python objects to display, or if raw=True raw json data to
209 display.
202 display.
210 raw : bool
203 raw : bool
211 Are the data objects raw data or Python objects that need to be
204 Are the data objects raw data or Python objects that need to be
212 formatted before display? [default: False]
205 formatted before display? [default: False]
213 """
206 """
214 raw = kwargs.pop('raw',False)
207 raw = kwargs.pop('raw',False)
215 if raw:
208 if raw:
216 for obj in objs:
209 for obj in objs:
217 publish_json(obj)
210 publish_json(obj)
218 else:
211 else:
219 display(*objs, include=['text/plain','application/json'])
212 display(*objs, include=['text/plain','application/json'])
220
213
221
214
222 def display_javascript(*objs, **kwargs):
215 def display_javascript(*objs, **kwargs):
223 """Display the Javascript representation of an object.
216 """Display the Javascript representation of an object.
224
217
225 Parameters
218 Parameters
226 ----------
219 ----------
227 objs : tuple of objects
220 objs : tuple of objects
228 The Python objects to display, or if raw=True raw javascript data to
221 The Python objects to display, or if raw=True raw javascript data to
229 display.
222 display.
230 raw : bool
223 raw : bool
231 Are the data objects raw data or Python objects that need to be
224 Are the data objects raw data or Python objects that need to be
232 formatted before display? [default: False]
225 formatted before display? [default: False]
233 """
226 """
234 raw = kwargs.pop('raw',False)
227 raw = kwargs.pop('raw',False)
235 if raw:
228 if raw:
236 for obj in objs:
229 for obj in objs:
237 publish_javascript(obj)
230 publish_javascript(obj)
238 else:
231 else:
239 display(*objs, include=['text/plain','application/javascript'])
232 display(*objs, include=['text/plain','application/javascript'])
240
233
241 #-----------------------------------------------------------------------------
234 #-----------------------------------------------------------------------------
242 # Smart classes
235 # Smart classes
243 #-----------------------------------------------------------------------------
236 #-----------------------------------------------------------------------------
244
237
245
238
246 class DisplayObject(object):
239 class DisplayObject(object):
247 """An object that wraps data to be displayed."""
240 """An object that wraps data to be displayed."""
248
241
249 _read_flags = 'r'
242 _read_flags = 'r'
250
243
251 def __init__(self, data=None, url=None, filename=None):
244 def __init__(self, data=None, url=None, filename=None):
252 """Create a display object given raw data.
245 """Create a display object given raw data.
253
246
254 When this object is returned by an expression or passed to the
247 When this object is returned by an expression or passed to the
255 display function, it will result in the data being displayed
248 display function, it will result in the data being displayed
256 in the frontend. The MIME type of the data should match the
249 in the frontend. The MIME type of the data should match the
257 subclasses used, so the Png subclass should be used for 'image/png'
250 subclasses used, so the Png subclass should be used for 'image/png'
258 data. If the data is a URL, the data will first be downloaded
251 data. If the data is a URL, the data will first be downloaded
259 and then displayed. If
252 and then displayed. If
260
253
261 Parameters
254 Parameters
262 ----------
255 ----------
263 data : unicode, str or bytes
256 data : unicode, str or bytes
264 The raw data or a URL or file to load the data from
257 The raw data or a URL or file to load the data from
265 url : unicode
258 url : unicode
266 A URL to download the data from.
259 A URL to download the data from.
267 filename : unicode
260 filename : unicode
268 Path to a local file to load the data from.
261 Path to a local file to load the data from.
269 """
262 """
270 if data is not None and isinstance(data, string_types):
263 if data is not None and isinstance(data, string_types):
271 if data.startswith('http') and url is None:
264 if data.startswith('http') and url is None:
272 url = data
265 url = data
273 filename = None
266 filename = None
274 data = None
267 data = None
275 elif _safe_exists(data) and filename is None:
268 elif _safe_exists(data) and filename is None:
276 url = None
269 url = None
277 filename = data
270 filename = data
278 data = None
271 data = None
279
272
280 self.data = data
273 self.data = data
281 self.url = url
274 self.url = url
282 self.filename = None if filename is None else unicode(filename)
275 self.filename = None if filename is None else unicode(filename)
283
276
284 self.reload()
277 self.reload()
285
278
286 def reload(self):
279 def reload(self):
287 """Reload the raw data from file or URL."""
280 """Reload the raw data from file or URL."""
288 if self.filename is not None:
281 if self.filename is not None:
289 with open(self.filename, self._read_flags) as f:
282 with open(self.filename, self._read_flags) as f:
290 self.data = f.read()
283 self.data = f.read()
291 elif self.url is not None:
284 elif self.url is not None:
292 try:
285 try:
293 import urllib2
286 import urllib2
294 response = urllib2.urlopen(self.url)
287 response = urllib2.urlopen(self.url)
295 self.data = response.read()
288 self.data = response.read()
296 # extract encoding from header, if there is one:
289 # extract encoding from header, if there is one:
297 encoding = None
290 encoding = None
298 for sub in response.headers['content-type'].split(';'):
291 for sub in response.headers['content-type'].split(';'):
299 sub = sub.strip()
292 sub = sub.strip()
300 if sub.startswith('charset'):
293 if sub.startswith('charset'):
301 encoding = sub.split('=')[-1].strip()
294 encoding = sub.split('=')[-1].strip()
302 break
295 break
303 # decode data, if an encoding was specified
296 # decode data, if an encoding was specified
304 if encoding:
297 if encoding:
305 self.data = self.data.decode(encoding, 'replace')
298 self.data = self.data.decode(encoding, 'replace')
306 except:
299 except:
307 self.data = None
300 self.data = None
308
301
309 class Pretty(DisplayObject):
302 class Pretty(DisplayObject):
310
303
311 def _repr_pretty_(self):
304 def _repr_pretty_(self):
312 return self.data
305 return self.data
313
306
314
307
315 class HTML(DisplayObject):
308 class HTML(DisplayObject):
316
309
317 def _repr_html_(self):
310 def _repr_html_(self):
318 return self.data
311 return self.data
319
312
320
313
321 class Math(DisplayObject):
314 class Math(DisplayObject):
322
315
323 def _repr_latex_(self):
316 def _repr_latex_(self):
324 s = self.data.strip('$')
317 s = self.data.strip('$')
325 return "$$%s$$" % s
318 return "$$%s$$" % s
326
319
327
320
328 class Latex(DisplayObject):
321 class Latex(DisplayObject):
329
322
330 def _repr_latex_(self):
323 def _repr_latex_(self):
331 return self.data
324 return self.data
332
325
333
326
334 class SVG(DisplayObject):
327 class SVG(DisplayObject):
335
328
336 # wrap data in a property, which extracts the <svg> tag, discarding
329 # wrap data in a property, which extracts the <svg> tag, discarding
337 # document headers
330 # document headers
338 _data = None
331 _data = None
339
332
340 @property
333 @property
341 def data(self):
334 def data(self):
342 return self._data
335 return self._data
343
336
344 @data.setter
337 @data.setter
345 def data(self, svg):
338 def data(self, svg):
346 if svg is None:
339 if svg is None:
347 self._data = None
340 self._data = None
348 return
341 return
349 # parse into dom object
342 # parse into dom object
350 from xml.dom import minidom
343 from xml.dom import minidom
351 x = minidom.parseString(svg)
344 x = minidom.parseString(svg)
352 # get svg tag (should be 1)
345 # get svg tag (should be 1)
353 found_svg = x.getElementsByTagName('svg')
346 found_svg = x.getElementsByTagName('svg')
354 if found_svg:
347 if found_svg:
355 svg = found_svg[0].toxml()
348 svg = found_svg[0].toxml()
356 else:
349 else:
357 # fallback on the input, trust the user
350 # fallback on the input, trust the user
358 # but this is probably an error.
351 # but this is probably an error.
359 pass
352 pass
360 self._data = svg
353 self._data = svg
361
354
362 def _repr_svg_(self):
355 def _repr_svg_(self):
363 return self.data
356 return self.data
364
357
365
358
366 class JSON(DisplayObject):
359 class JSON(DisplayObject):
367
360
368 def _repr_json_(self):
361 def _repr_json_(self):
369 return self.data
362 return self.data
370
363
371 css_t = """$("head").append($("<link/>").attr({
364 css_t = """$("head").append($("<link/>").attr({
372 rel: "stylesheet",
365 rel: "stylesheet",
373 type: "text/css",
366 type: "text/css",
374 href: "%s"
367 href: "%s"
375 }));
368 }));
376 """
369 """
377
370
378 lib_t1 = """$.getScript("%s", function () {
371 lib_t1 = """$.getScript("%s", function () {
379 """
372 """
380 lib_t2 = """});
373 lib_t2 = """});
381 """
374 """
382
375
383 class Javascript(DisplayObject):
376 class Javascript(DisplayObject):
384
377
385 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
378 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
386 """Create a Javascript display object given raw data.
379 """Create a Javascript display object given raw data.
387
380
388 When this object is returned by an expression or passed to the
381 When this object is returned by an expression or passed to the
389 display function, it will result in the data being displayed
382 display function, it will result in the data being displayed
390 in the frontend. If the data is a URL, the data will first be
383 in the frontend. If the data is a URL, the data will first be
391 downloaded and then displayed.
384 downloaded and then displayed.
392
385
393 In the Notebook, the containing element will be available as `element`,
386 In the Notebook, the containing element will be available as `element`,
394 and jQuery will be available. The output area starts hidden, so if
387 and jQuery will be available. The output area starts hidden, so if
395 the js appends content to `element` that should be visible, then
388 the js appends content to `element` that should be visible, then
396 it must call `container.show()` to unhide the area.
389 it must call `container.show()` to unhide the area.
397
390
398 Parameters
391 Parameters
399 ----------
392 ----------
400 data : unicode, str or bytes
393 data : unicode, str or bytes
401 The Javascript source code or a URL to download it from.
394 The Javascript source code or a URL to download it from.
402 url : unicode
395 url : unicode
403 A URL to download the data from.
396 A URL to download the data from.
404 filename : unicode
397 filename : unicode
405 Path to a local file to load the data from.
398 Path to a local file to load the data from.
406 lib : list or str
399 lib : list or str
407 A sequence of Javascript library URLs to load asynchronously before
400 A sequence of Javascript library URLs to load asynchronously before
408 running the source code. The full URLs of the libraries should
401 running the source code. The full URLs of the libraries should
409 be given. A single Javascript library URL can also be given as a
402 be given. A single Javascript library URL can also be given as a
410 string.
403 string.
411 css: : list or str
404 css: : list or str
412 A sequence of css files to load before running the source code.
405 A sequence of css files to load before running the source code.
413 The full URLs of the css files should be given. A single css URL
406 The full URLs of the css files should be given. A single css URL
414 can also be given as a string.
407 can also be given as a string.
415 """
408 """
416 if isinstance(lib, basestring):
409 if isinstance(lib, basestring):
417 lib = [lib]
410 lib = [lib]
418 elif lib is None:
411 elif lib is None:
419 lib = []
412 lib = []
420 if isinstance(css, basestring):
413 if isinstance(css, basestring):
421 css = [css]
414 css = [css]
422 elif css is None:
415 elif css is None:
423 css = []
416 css = []
424 if not isinstance(lib, (list,tuple)):
417 if not isinstance(lib, (list,tuple)):
425 raise TypeError('expected sequence, got: %r' % lib)
418 raise TypeError('expected sequence, got: %r' % lib)
426 if not isinstance(css, (list,tuple)):
419 if not isinstance(css, (list,tuple)):
427 raise TypeError('expected sequence, got: %r' % css)
420 raise TypeError('expected sequence, got: %r' % css)
428 self.lib = lib
421 self.lib = lib
429 self.css = css
422 self.css = css
430 super(Javascript, self).__init__(data=data, url=url, filename=filename)
423 super(Javascript, self).__init__(data=data, url=url, filename=filename)
431
424
432 def _repr_javascript_(self):
425 def _repr_javascript_(self):
433 r = ''
426 r = ''
434 for c in self.css:
427 for c in self.css:
435 r += css_t % c
428 r += css_t % c
436 for l in self.lib:
429 for l in self.lib:
437 r += lib_t1 % l
430 r += lib_t1 % l
438 r += self.data
431 r += self.data
439 r += lib_t2*len(self.lib)
432 r += lib_t2*len(self.lib)
440 return r
433 return r
441
434
442 # constants for identifying png/jpeg data
435 # constants for identifying png/jpeg data
443 _PNG = b'\x89PNG\r\n\x1a\n'
436 _PNG = b'\x89PNG\r\n\x1a\n'
444 _JPEG = b'\xff\xd8'
437 _JPEG = b'\xff\xd8'
445
438
446 class Image(DisplayObject):
439 class Image(DisplayObject):
447
440
448 _read_flags = 'rb'
441 _read_flags = 'rb'
449 _FMT_JPEG = u'jpeg'
442 _FMT_JPEG = u'jpeg'
450 _FMT_PNG = u'png'
443 _FMT_PNG = u'png'
451 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
444 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
452
445
453 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None):
446 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None):
454 """Create a display an PNG/JPEG image given raw data.
447 """Create a display an PNG/JPEG image given raw data.
455
448
456 When this object is returned by an expression or passed to the
449 When this object is returned by an expression or passed to the
457 display function, it will result in the image being displayed
450 display function, it will result in the image being displayed
458 in the frontend.
451 in the frontend.
459
452
460 Parameters
453 Parameters
461 ----------
454 ----------
462 data : unicode, str or bytes
455 data : unicode, str or bytes
463 The raw data or a URL to download the data from.
456 The raw data or a URL to download the data from.
464 url : unicode
457 url : unicode
465 A URL to download the data from.
458 A URL to download the data from.
466 filename : unicode
459 filename : unicode
467 Path to a local file to load the data from.
460 Path to a local file to load the data from.
468 format : unicode
461 format : unicode
469 The format of the image data (png/jpeg/jpg). If a filename or URL is given
462 The format of the image data (png/jpeg/jpg). If a filename or URL is given
470 for format will be inferred from the filename extension.
463 for format will be inferred from the filename extension.
471 embed : bool
464 embed : bool
472 Should the image data be embedded using a data URI (True) or be
465 Should the image data be embedded using a data URI (True) or be
473 loaded using an <img> tag. Set this to True if you want the image
466 loaded using an <img> tag. Set this to True if you want the image
474 to be viewable later with no internet connection in the notebook.
467 to be viewable later with no internet connection in the notebook.
475
468
476 Default is `True`, unless the keyword argument `url` is set, then
469 Default is `True`, unless the keyword argument `url` is set, then
477 default value is `False`.
470 default value is `False`.
478
471
479 Note that QtConsole is not able to display images if `embed` is set to `False`
472 Note that QtConsole is not able to display images if `embed` is set to `False`
480 width : int
473 width : int
481 Width to which to constrain the image in html
474 Width to which to constrain the image in html
482 height : int
475 height : int
483 Height to which to constrain the image in html
476 Height to which to constrain the image in html
484
477
485 Examples
478 Examples
486 --------
479 --------
487 # embed implicitly True, works in qtconsole and notebook
480 # embed implicitly True, works in qtconsole and notebook
488 Image('http://www.google.fr/images/srpr/logo3w.png')
481 Image('http://www.google.fr/images/srpr/logo3w.png')
489
482
490 # embed implicitly False, does not works in qtconsole but works in notebook if
483 # embed implicitly False, does not works in qtconsole but works in notebook if
491 # internet connection available
484 # internet connection available
492 Image(url='http://www.google.fr/images/srpr/logo3w.png')
485 Image(url='http://www.google.fr/images/srpr/logo3w.png')
493
486
494 """
487 """
495 if filename is not None:
488 if filename is not None:
496 ext = self._find_ext(filename)
489 ext = self._find_ext(filename)
497 elif url is not None:
490 elif url is not None:
498 ext = self._find_ext(url)
491 ext = self._find_ext(url)
499 elif data is None:
492 elif data is None:
500 raise ValueError("No image data found. Expecting filename, url, or data.")
493 raise ValueError("No image data found. Expecting filename, url, or data.")
501 elif isinstance(data, string_types) and (
494 elif isinstance(data, string_types) and (
502 data.startswith('http') or _safe_exists(data)
495 data.startswith('http') or _safe_exists(data)
503 ):
496 ):
504 ext = self._find_ext(data)
497 ext = self._find_ext(data)
505 else:
498 else:
506 ext = None
499 ext = None
507
500
508 if ext is not None:
501 if ext is not None:
509 format = ext.lower()
502 format = ext.lower()
510 if ext == u'jpg' or ext == u'jpeg':
503 if ext == u'jpg' or ext == u'jpeg':
511 format = self._FMT_JPEG
504 format = self._FMT_JPEG
512 if ext == u'png':
505 if ext == u'png':
513 format = self._FMT_PNG
506 format = self._FMT_PNG
514 elif isinstance(data, bytes) and format == 'png':
507 elif isinstance(data, bytes) and format == 'png':
515 # infer image type from image data header,
508 # infer image type from image data header,
516 # only if format might not have been specified.
509 # only if format might not have been specified.
517 if data[:2] == _JPEG:
510 if data[:2] == _JPEG:
518 format = 'jpeg'
511 format = 'jpeg'
519
512
520 self.format = unicode(format).lower()
513 self.format = unicode(format).lower()
521 self.embed = embed if embed is not None else (url is None)
514 self.embed = embed if embed is not None else (url is None)
522
515
523 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
516 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
524 raise ValueError("Cannot embed the '%s' image format" % (self.format))
517 raise ValueError("Cannot embed the '%s' image format" % (self.format))
525 self.width = width
518 self.width = width
526 self.height = height
519 self.height = height
527 super(Image, self).__init__(data=data, url=url, filename=filename)
520 super(Image, self).__init__(data=data, url=url, filename=filename)
528
521
529 def reload(self):
522 def reload(self):
530 """Reload the raw data from file or URL."""
523 """Reload the raw data from file or URL."""
531 if self.embed:
524 if self.embed:
532 super(Image,self).reload()
525 super(Image,self).reload()
533
526
534 def _repr_html_(self):
527 def _repr_html_(self):
535 if not self.embed:
528 if not self.embed:
536 width = height = ''
529 width = height = ''
537 if self.width:
530 if self.width:
538 width = ' width="%d"' % self.width
531 width = ' width="%d"' % self.width
539 if self.height:
532 if self.height:
540 height = ' height="%d"' % self.height
533 height = ' height="%d"' % self.height
541 return u'<img src="%s"%s%s/>' % (self.url, width, height)
534 return u'<img src="%s"%s%s/>' % (self.url, width, height)
542
535
543 def _data_and_metadata(self):
536 def _data_and_metadata(self):
544 """shortcut for returning metadata with shape information, if defined"""
537 """shortcut for returning metadata with shape information, if defined"""
545 md = {}
538 md = {}
546 if self.width:
539 if self.width:
547 md['width'] = self.width
540 md['width'] = self.width
548 if self.height:
541 if self.height:
549 md['height'] = self.height
542 md['height'] = self.height
550 if md:
543 if md:
551 return self.data, md
544 return self.data, md
552 else:
545 else:
553 return self.data
546 return self.data
554
547
555 def _repr_png_(self):
548 def _repr_png_(self):
556 if self.embed and self.format == u'png':
549 if self.embed and self.format == u'png':
557 return self._data_and_metadata()
550 return self._data_and_metadata()
558
551
559 def _repr_jpeg_(self):
552 def _repr_jpeg_(self):
560 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
553 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
561 return self._data_and_metadata()
554 return self._data_and_metadata()
562
555
563 def _find_ext(self, s):
556 def _find_ext(self, s):
564 return unicode(s.split('.')[-1].lower())
557 return unicode(s.split('.')[-1].lower())
565
558
566
559
567 def clear_output(stdout=True, stderr=True, other=True):
560 def clear_output(stdout=True, stderr=True, other=True):
568 """Clear the output of the current cell receiving output.
561 """Clear the output of the current cell receiving output.
569
562
570 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
563 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
571 produced by display()) can be excluded from the clear event.
564 produced by display()) can be excluded from the clear event.
572
565
573 By default, everything is cleared.
566 By default, everything is cleared.
574
567
575 Parameters
568 Parameters
576 ----------
569 ----------
577 stdout : bool [default: True]
570 stdout : bool [default: True]
578 Whether to clear stdout.
571 Whether to clear stdout.
579 stderr : bool [default: True]
572 stderr : bool [default: True]
580 Whether to clear stderr.
573 Whether to clear stderr.
581 other : bool [default: True]
574 other : bool [default: True]
582 Whether to clear everything else that is not stdout/stderr
575 Whether to clear everything else that is not stdout/stderr
583 (e.g. figures,images,HTML, any result of display()).
576 (e.g. figures,images,HTML, any result of display()).
584 """
577 """
585 from IPython.core.interactiveshell import InteractiveShell
578 from IPython.core.interactiveshell import InteractiveShell
586 if InteractiveShell.initialized():
579 if InteractiveShell.initialized():
587 InteractiveShell.instance().display_pub.clear_output(
580 InteractiveShell.instance().display_pub.clear_output(
588 stdout=stdout, stderr=stderr, other=other,
581 stdout=stdout, stderr=stderr, other=other,
589 )
582 )
590 else:
583 else:
591 from IPython.utils import io
584 from IPython.utils import io
592 if stdout:
585 if stdout:
593 print('\033[2K\r', file=io.stdout, end='')
586 print('\033[2K\r', file=io.stdout, end='')
594 io.stdout.flush()
587 io.stdout.flush()
595 if stderr:
588 if stderr:
596 print('\033[2K\r', file=io.stderr, end='')
589 print('\033[2K\r', file=io.stderr, end='')
597 io.stderr.flush()
590 io.stderr.flush()
598
591
@@ -1,312 +1,164 b''
1 """An interface for publishing rich data to frontends.
1 """An interface for publishing rich data to frontends.
2
2
3 There are two components of the display system:
3 There are two components of the display system:
4
4
5 * Display formatters, which take a Python object and compute the
5 * Display formatters, which take a Python object and compute the
6 representation of the object in various formats (text, HTML, SVg, etc.).
6 representation of the object in various formats (text, HTML, SVG, etc.).
7 * The display publisher that is used to send the representation data to the
7 * The display publisher that is used to send the representation data to the
8 various frontends.
8 various frontends.
9
9
10 This module defines the logic display publishing. The display publisher uses
10 This module defines the logic display publishing. The display publisher uses
11 the ``display_data`` message type that is defined in the IPython messaging
11 the ``display_data`` message type that is defined in the IPython messaging
12 spec.
12 spec.
13
13
14 Authors:
14 Authors:
15
15
16 * Brian Granger
16 * Brian Granger
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Copyright (C) 2008-2011 The IPython Development Team
20 # Copyright (C) 2008-2011 The IPython Development Team
21 #
21 #
22 # Distributed under the terms of the BSD License. The full license is in
22 # Distributed under the terms of the BSD License. The full license is in
23 # the file COPYING, distributed as part of this software.
23 # the file COPYING, distributed as part of this software.
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Imports
27 # Imports
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 from __future__ import print_function
30 from __future__ import print_function
31
31
32 from IPython.config.configurable import Configurable
32 from IPython.config.configurable import Configurable
33 from IPython.utils import io
33 from IPython.utils import io
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Main payload class
36 # Main payload class
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 class DisplayPublisher(Configurable):
39 class DisplayPublisher(Configurable):
40 """A traited class that publishes display data to frontends.
40 """A traited class that publishes display data to frontends.
41
41
42 Instances of this class are created by the main IPython object and should
42 Instances of this class are created by the main IPython object and should
43 be accessed there.
43 be accessed there.
44 """
44 """
45
45
46 def _validate_data(self, source, data, metadata=None):
46 def _validate_data(self, source, data, metadata=None):
47 """Validate the display data.
47 """Validate the display data.
48
48
49 Parameters
49 Parameters
50 ----------
50 ----------
51 source : str
51 source : str
52 The fully dotted name of the callable that created the data, like
52 The fully dotted name of the callable that created the data, like
53 :func:`foo.bar.my_formatter`.
53 :func:`foo.bar.my_formatter`.
54 data : dict
54 data : dict
55 The formata data dictionary.
55 The formata data dictionary.
56 metadata : dict
56 metadata : dict
57 Any metadata for the data.
57 Any metadata for the data.
58 """
58 """
59
59
60 if not isinstance(source, basestring):
60 if not isinstance(source, basestring):
61 raise TypeError('source must be a str, got: %r' % source)
61 raise TypeError('source must be a str, got: %r' % source)
62 if not isinstance(data, dict):
62 if not isinstance(data, dict):
63 raise TypeError('data must be a dict, got: %r' % data)
63 raise TypeError('data must be a dict, got: %r' % data)
64 if metadata is not None:
64 if metadata is not None:
65 if not isinstance(metadata, dict):
65 if not isinstance(metadata, dict):
66 raise TypeError('metadata must be a dict, got: %r' % data)
66 raise TypeError('metadata must be a dict, got: %r' % data)
67
67
68 def publish(self, source, data, metadata=None):
68 def publish(self, source, data, metadata=None):
69 """Publish data and metadata to all frontends.
69 """Publish data and metadata to all frontends.
70
70
71 See the ``display_data`` message in the messaging documentation for
71 See the ``display_data`` message in the messaging documentation for
72 more details about this message type.
72 more details about this message type.
73
73
74 The following MIME types are currently implemented:
74 The following MIME types are currently implemented:
75
75
76 * text/plain
76 * text/plain
77 * text/html
77 * text/html
78 * text/latex
78 * text/latex
79 * application/json
79 * application/json
80 * application/javascript
80 * application/javascript
81 * image/png
81 * image/png
82 * image/jpeg
82 * image/jpeg
83 * image/svg+xml
83 * image/svg+xml
84
84
85 Parameters
85 Parameters
86 ----------
86 ----------
87 source : str
87 source : str
88 A string that give the function or method that created the data,
88 A string that give the function or method that created the data,
89 such as 'IPython.core.page'.
89 such as 'IPython.core.page'.
90 data : dict
90 data : dict
91 A dictionary having keys that are valid MIME types (like
91 A dictionary having keys that are valid MIME types (like
92 'text/plain' or 'image/svg+xml') and values that are the data for
92 'text/plain' or 'image/svg+xml') and values that are the data for
93 that MIME type. The data itself must be a JSON'able data
93 that MIME type. The data itself must be a JSON'able data
94 structure. Minimally all data should have the 'text/plain' data,
94 structure. Minimally all data should have the 'text/plain' data,
95 which can be displayed by all frontends. If more than the plain
95 which can be displayed by all frontends. If more than the plain
96 text is given, it is up to the frontend to decide which
96 text is given, it is up to the frontend to decide which
97 representation to use.
97 representation to use.
98 metadata : dict
98 metadata : dict
99 A dictionary for metadata related to the data. This can contain
99 A dictionary for metadata related to the data. This can contain
100 arbitrary key, value pairs that frontends can use to interpret
100 arbitrary key, value pairs that frontends can use to interpret
101 the data. Metadata specific to each mime-type can be specified
101 the data. Metadata specific to each mime-type can be specified
102 in the metadata dict with the same mime-type keys as
102 in the metadata dict with the same mime-type keys as
103 the data itself.
103 the data itself.
104 """
104 """
105
105
106 # The default is to simply write the plain text data using io.stdout.
106 # The default is to simply write the plain text data using io.stdout.
107 if 'text/plain' in data:
107 if 'text/plain' in data:
108 print(data['text/plain'], file=io.stdout)
108 print(data['text/plain'], file=io.stdout)
109
109
110 def clear_output(self, stdout=True, stderr=True, other=True):
110 def clear_output(self, stdout=True, stderr=True, other=True):
111 """Clear the output of the cell receiving output."""
111 """Clear the output of the cell receiving output."""
112 if stdout:
112 if stdout:
113 print('\033[2K\r', file=io.stdout, end='')
113 print('\033[2K\r', file=io.stdout, end='')
114 io.stdout.flush()
114 io.stdout.flush()
115 if stderr:
115 if stderr:
116 print('\033[2K\r', file=io.stderr, end='')
116 print('\033[2K\r', file=io.stderr, end='')
117 io.stderr.flush()
117 io.stderr.flush()
118
118
119
119
120
120
121 def publish_display_data(source, data, metadata=None):
121 def publish_display_data(source, data, metadata=None):
122 """Publish data and metadata to all frontends.
122 """Publish data and metadata to all frontends.
123
123
124 See the ``display_data`` message in the messaging documentation for
124 See the ``display_data`` message in the messaging documentation for
125 more details about this message type.
125 more details about this message type.
126
126
127 The following MIME types are currently implemented:
127 The following MIME types are currently implemented:
128
128
129 * text/plain
129 * text/plain
130 * text/html
130 * text/html
131 * text/latex
131 * text/latex
132 * application/json
132 * application/json
133 * application/javascript
133 * application/javascript
134 * image/png
134 * image/png
135 * image/jpeg
135 * image/jpeg
136 * image/svg+xml
136 * image/svg+xml
137
137
138 Parameters
138 Parameters
139 ----------
139 ----------
140 source : str
140 source : str
141 A string that give the function or method that created the data,
141 A string that give the function or method that created the data,
142 such as 'IPython.core.page'.
142 such as 'IPython.core.page'.
143 data : dict
143 data : dict
144 A dictionary having keys that are valid MIME types (like
144 A dictionary having keys that are valid MIME types (like
145 'text/plain' or 'image/svg+xml') and values that are the data for
145 'text/plain' or 'image/svg+xml') and values that are the data for
146 that MIME type. The data itself must be a JSON'able data
146 that MIME type. The data itself must be a JSON'able data
147 structure. Minimally all data should have the 'text/plain' data,
147 structure. Minimally all data should have the 'text/plain' data,
148 which can be displayed by all frontends. If more than the plain
148 which can be displayed by all frontends. If more than the plain
149 text is given, it is up to the frontend to decide which
149 text is given, it is up to the frontend to decide which
150 representation to use.
150 representation to use.
151 metadata : dict
151 metadata : dict
152 A dictionary for metadata related to the data. This can contain
152 A dictionary for metadata related to the data. This can contain
153 arbitrary key, value pairs that frontends can use to interpret
153 arbitrary key, value pairs that frontends can use to interpret
154 the data. mime-type keys matching those in data can be used
154 the data. mime-type keys matching those in data can be used
155 to specify metadata about particular representations.
155 to specify metadata about particular representations.
156 """
156 """
157 from IPython.core.interactiveshell import InteractiveShell
157 from IPython.core.interactiveshell import InteractiveShell
158 InteractiveShell.instance().display_pub.publish(
158 InteractiveShell.instance().display_pub.publish(
159 source,
159 source,
160 data,
160 data,
161 metadata
161 metadata
162 )
162 )
163
163
164
164
165 def publish_pretty(data, metadata=None):
166 """Publish raw text data to all frontends.
167
168 Parameters
169 ----------
170 data : unicode
171 The raw text data to publish.
172 metadata : dict
173 A dictionary for metadata related to the data. This can contain
174 arbitrary key, value pairs that frontends can use to interpret
175 the data.
176 """
177 publish_display_data(
178 u'IPython.core.displaypub.publish_pretty',
179 {'text/plain':data},
180 metadata=metadata
181 )
182
183
184 def publish_html(data, metadata=None):
185 """Publish raw HTML data to all frontends.
186
187 Parameters
188 ----------
189 data : unicode
190 The raw HTML data to publish.
191 metadata : dict
192 A dictionary for metadata related to the data. This can contain
193 arbitrary key, value pairs that frontends can use to interpret
194 the data.
195 """
196 publish_display_data(
197 u'IPython.core.displaypub.publish_html',
198 {'text/html':data},
199 metadata=metadata
200 )
201
202
203 def publish_latex(data, metadata=None):
204 """Publish raw LaTeX data to all frontends.
205
206 Parameters
207 ----------
208 data : unicode
209 The raw LaTeX data to publish.
210 metadata : dict
211 A dictionary for metadata related to the data. This can contain
212 arbitrary key, value pairs that frontends can use to interpret
213 the data.
214 """
215 publish_display_data(
216 u'IPython.core.displaypub.publish_latex',
217 {'text/latex':data},
218 metadata=metadata
219 )
220
221 def publish_png(data, metadata=None):
222 """Publish raw binary PNG data to all frontends.
223
224 Parameters
225 ----------
226 data : str/bytes
227 The raw binary PNG data to publish.
228 metadata : dict
229 A dictionary for metadata related to the data. This can contain
230 arbitrary key, value pairs that frontends can use to interpret
231 the data.
232 """
233 publish_display_data(
234 u'IPython.core.displaypub.publish_png',
235 {'image/png':data},
236 metadata=metadata
237 )
238
239
240 def publish_jpeg(data, metadata=None):
241 """Publish raw binary JPEG data to all frontends.
242
243 Parameters
244 ----------
245 data : str/bytes
246 The raw binary JPEG data to publish.
247 metadata : dict
248 A dictionary for metadata related to the data. This can contain
249 arbitrary key, value pairs that frontends can use to interpret
250 the data.
251 """
252 publish_display_data(
253 u'IPython.core.displaypub.publish_jpeg',
254 {'image/jpeg':data},
255 metadata=metadata
256 )
257
258
259 def publish_svg(data, metadata=None):
260 """Publish raw SVG data to all frontends.
261
262 Parameters
263 ----------
264 data : unicode
265 The raw SVG data to publish.
266 metadata : dict
267 A dictionary for metadata related to the data. This can contain
268 arbitrary key, value pairs that frontends can use to interpret
269 the data.
270 """
271 publish_display_data(
272 u'IPython.core.displaypub.publish_svg',
273 {'image/svg+xml':data},
274 metadata=metadata
275 )
276
277 def publish_json(data, metadata=None):
278 """Publish raw JSON data to all frontends.
279
280 Parameters
281 ----------
282 data : unicode
283 The raw JSON data to publish.
284 metadata : dict
285 A dictionary for metadata related to the data. This can contain
286 arbitrary key, value pairs that frontends can use to interpret
287 the data.
288 """
289 publish_display_data(
290 u'IPython.core.displaypub.publish_json',
291 {'application/json':data},
292 metadata=metadata
293 )
294
295 def publish_javascript(data, metadata=None):
296 """Publish raw Javascript data to all frontends.
297
298 Parameters
299 ----------
300 data : unicode
301 The raw Javascript data to publish.
302 metadata : dict
303 A dictionary for metadata related to the data. This can contain
304 arbitrary key, value pairs that frontends can use to interpret
305 the data.
306 """
307 publish_display_data(
308 u'IPython.core.displaypub.publish_javascript',
309 {'application/javascript':data},
310 metadata=metadata
311 )
312
@@ -1,17 +1,16 b''
1 """Public API for display tools in IPython.
1 """Public API for display tools in IPython.
2 """
2 """
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2012 The IPython Development Team
5 # Copyright (C) 2012 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from IPython.core.display import *
15 from IPython.core.display import *
16 from IPython.core.displaypub import *
17 from IPython.lib.display import *
16 from IPython.lib.display import *
General Comments 0
You need to be logged in to leave comments. Login now