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