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