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