##// END OF EJS Templates
Merge pull request #5993 from payne92/master...
Jonathan Frederic -
r17004:c6a9fee0 merge
parent child Browse files
Show More
@@ -1,812 +1,811 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 import struct
23 import struct
24
24
25 from IPython.core.formatters import _safe_get_formatter_method
25 from IPython.core.formatters import _safe_get_formatter_method
26 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
26 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
27 unicode_type)
27 unicode_type)
28 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.testing.skipdoctest import skip_doctest
29 from .displaypub import publish_display_data
29 from .displaypub import publish_display_data
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # utility functions
32 # utility functions
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35 def _safe_exists(path):
35 def _safe_exists(path):
36 """Check path, but don't let exceptions raise"""
36 """Check path, but don't let exceptions raise"""
37 try:
37 try:
38 return os.path.exists(path)
38 return os.path.exists(path)
39 except Exception:
39 except Exception:
40 return False
40 return False
41
41
42 def _merge(d1, d2):
42 def _merge(d1, d2):
43 """Like update, but merges sub-dicts instead of clobbering at the top level.
43 """Like update, but merges sub-dicts instead of clobbering at the top level.
44
44
45 Updates d1 in-place
45 Updates d1 in-place
46 """
46 """
47
47
48 if not isinstance(d2, dict) or not isinstance(d1, dict):
48 if not isinstance(d2, dict) or not isinstance(d1, dict):
49 return d2
49 return d2
50 for key, value in d2.items():
50 for key, value in d2.items():
51 d1[key] = _merge(d1.get(key), value)
51 d1[key] = _merge(d1.get(key), value)
52 return d1
52 return d1
53
53
54 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
54 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
55 """internal implementation of all display_foo methods
55 """internal implementation of all display_foo methods
56
56
57 Parameters
57 Parameters
58 ----------
58 ----------
59 mimetype : str
59 mimetype : str
60 The mimetype to be published (e.g. 'image/png')
60 The mimetype to be published (e.g. 'image/png')
61 objs : tuple of objects
61 objs : tuple of objects
62 The Python objects to display, or if raw=True raw text data to
62 The Python objects to display, or if raw=True raw text data to
63 display.
63 display.
64 raw : bool
64 raw : bool
65 Are the data objects raw data or Python objects that need to be
65 Are the data objects raw data or Python objects that need to be
66 formatted before display? [default: False]
66 formatted before display? [default: False]
67 metadata : dict (optional)
67 metadata : dict (optional)
68 Metadata to be associated with the specific mimetype output.
68 Metadata to be associated with the specific mimetype output.
69 """
69 """
70 if metadata:
70 if metadata:
71 metadata = {mimetype: metadata}
71 metadata = {mimetype: metadata}
72 if raw:
72 if raw:
73 # turn list of pngdata into list of { 'image/png': pngdata }
73 # turn list of pngdata into list of { 'image/png': pngdata }
74 objs = [ {mimetype: obj} for obj in objs ]
74 objs = [ {mimetype: obj} for obj in objs ]
75 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
75 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
76
76
77 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
78 # Main functions
78 # Main functions
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80
80
81 def display(*objs, **kwargs):
81 def display(*objs, **kwargs):
82 """Display a Python object in all frontends.
82 """Display a Python object in all frontends.
83
83
84 By default all representations will be computed and sent to the frontends.
84 By default all representations will be computed and sent to the frontends.
85 Frontends can decide which representation is used and how.
85 Frontends can decide which representation is used and how.
86
86
87 Parameters
87 Parameters
88 ----------
88 ----------
89 objs : tuple of objects
89 objs : tuple of objects
90 The Python objects to display.
90 The Python objects to display.
91 raw : bool, optional
91 raw : bool, optional
92 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
92 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
93 or Python objects that need to be formatted before display? [default: False]
93 or Python objects that need to be formatted before display? [default: False]
94 include : list or tuple, optional
94 include : list or tuple, optional
95 A list of format type strings (MIME types) to include in the
95 A list of format type strings (MIME types) to include in the
96 format data dict. If this is set *only* the format types included
96 format data dict. If this is set *only* the format types included
97 in this list will be computed.
97 in this list will be computed.
98 exclude : list or tuple, optional
98 exclude : list or tuple, optional
99 A list of format type strings (MIME types) to exclude in the format
99 A list of format type strings (MIME types) to exclude in the format
100 data dict. If this is set all format types will be computed,
100 data dict. If this is set all format types will be computed,
101 except for those included in this argument.
101 except for those included in this argument.
102 metadata : dict, optional
102 metadata : dict, optional
103 A dictionary of metadata to associate with the output.
103 A dictionary of metadata to associate with the output.
104 mime-type keys in this dictionary will be associated with the individual
104 mime-type keys in this dictionary will be associated with the individual
105 representation formats, if they exist.
105 representation formats, if they exist.
106 """
106 """
107 raw = kwargs.get('raw', False)
107 raw = kwargs.get('raw', False)
108 include = kwargs.get('include')
108 include = kwargs.get('include')
109 exclude = kwargs.get('exclude')
109 exclude = kwargs.get('exclude')
110 metadata = kwargs.get('metadata')
110 metadata = kwargs.get('metadata')
111
111
112 from IPython.core.interactiveshell import InteractiveShell
112 from IPython.core.interactiveshell import InteractiveShell
113
113
114 if not raw:
114 if not raw:
115 format = InteractiveShell.instance().display_formatter.format
115 format = InteractiveShell.instance().display_formatter.format
116
116
117 for obj in objs:
117 for obj in objs:
118
118
119 # If _ipython_display_ is defined, use that to display this object.
119 # If _ipython_display_ is defined, use that to display this object.
120 display_method = _safe_get_formatter_method(obj, '_ipython_display_')
120 display_method = _safe_get_formatter_method(obj, '_ipython_display_')
121 if display_method is not None:
121 if display_method is not None:
122 try:
122 try:
123 display_method(**kwargs)
123 display_method(**kwargs)
124 except NotImplementedError:
124 except NotImplementedError:
125 pass
125 pass
126 else:
126 else:
127 continue
127 continue
128 if raw:
128 if raw:
129 publish_display_data(data=obj, metadata=metadata)
129 publish_display_data(data=obj, metadata=metadata)
130 else:
130 else:
131 format_dict, md_dict = format(obj, include=include, exclude=exclude)
131 format_dict, md_dict = format(obj, include=include, exclude=exclude)
132 if metadata:
132 if metadata:
133 # kwarg-specified metadata gets precedence
133 # kwarg-specified metadata gets precedence
134 _merge(md_dict, metadata)
134 _merge(md_dict, metadata)
135 publish_display_data(data=format_dict, metadata=md_dict)
135 publish_display_data(data=format_dict, metadata=md_dict)
136
136
137
137
138 def display_pretty(*objs, **kwargs):
138 def display_pretty(*objs, **kwargs):
139 """Display the pretty (default) representation of an object.
139 """Display the pretty (default) representation of an object.
140
140
141 Parameters
141 Parameters
142 ----------
142 ----------
143 objs : tuple of objects
143 objs : tuple of objects
144 The Python objects to display, or if raw=True raw text data to
144 The Python objects to display, or if raw=True raw text data to
145 display.
145 display.
146 raw : bool
146 raw : bool
147 Are the data objects raw data or Python objects that need to be
147 Are the data objects raw data or Python objects that need to be
148 formatted before display? [default: False]
148 formatted before display? [default: False]
149 metadata : dict (optional)
149 metadata : dict (optional)
150 Metadata to be associated with the specific mimetype output.
150 Metadata to be associated with the specific mimetype output.
151 """
151 """
152 _display_mimetype('text/plain', objs, **kwargs)
152 _display_mimetype('text/plain', objs, **kwargs)
153
153
154
154
155 def display_html(*objs, **kwargs):
155 def display_html(*objs, **kwargs):
156 """Display the HTML representation of an object.
156 """Display the HTML representation of an object.
157
157
158 Parameters
158 Parameters
159 ----------
159 ----------
160 objs : tuple of objects
160 objs : tuple of objects
161 The Python objects to display, or if raw=True raw HTML data to
161 The Python objects to display, or if raw=True raw HTML data to
162 display.
162 display.
163 raw : bool
163 raw : bool
164 Are the data objects raw data or Python objects that need to be
164 Are the data objects raw data or Python objects that need to be
165 formatted before display? [default: False]
165 formatted before display? [default: False]
166 metadata : dict (optional)
166 metadata : dict (optional)
167 Metadata to be associated with the specific mimetype output.
167 Metadata to be associated with the specific mimetype output.
168 """
168 """
169 _display_mimetype('text/html', objs, **kwargs)
169 _display_mimetype('text/html', objs, **kwargs)
170
170
171
171
172 def display_markdown(*objs, **kwargs):
172 def display_markdown(*objs, **kwargs):
173 """Displays the Markdown representation of an object.
173 """Displays the Markdown representation of an object.
174
174
175 Parameters
175 Parameters
176 ----------
176 ----------
177 objs : tuple of objects
177 objs : tuple of objects
178 The Python objects to display, or if raw=True raw markdown data to
178 The Python objects to display, or if raw=True raw markdown data to
179 display.
179 display.
180 raw : bool
180 raw : bool
181 Are the data objects raw data or Python objects that need to be
181 Are the data objects raw data or Python objects that need to be
182 formatted before display? [default: False]
182 formatted before display? [default: False]
183 metadata : dict (optional)
183 metadata : dict (optional)
184 Metadata to be associated with the specific mimetype output.
184 Metadata to be associated with the specific mimetype output.
185 """
185 """
186
186
187 _display_mimetype('text/markdown', objs, **kwargs)
187 _display_mimetype('text/markdown', objs, **kwargs)
188
188
189
189
190 def display_svg(*objs, **kwargs):
190 def display_svg(*objs, **kwargs):
191 """Display the SVG representation of an object.
191 """Display the SVG representation of an object.
192
192
193 Parameters
193 Parameters
194 ----------
194 ----------
195 objs : tuple of objects
195 objs : tuple of objects
196 The Python objects to display, or if raw=True raw svg data to
196 The Python objects to display, or if raw=True raw svg data to
197 display.
197 display.
198 raw : bool
198 raw : bool
199 Are the data objects raw data or Python objects that need to be
199 Are the data objects raw data or Python objects that need to be
200 formatted before display? [default: False]
200 formatted before display? [default: False]
201 metadata : dict (optional)
201 metadata : dict (optional)
202 Metadata to be associated with the specific mimetype output.
202 Metadata to be associated with the specific mimetype output.
203 """
203 """
204 _display_mimetype('image/svg+xml', objs, **kwargs)
204 _display_mimetype('image/svg+xml', objs, **kwargs)
205
205
206
206
207 def display_png(*objs, **kwargs):
207 def display_png(*objs, **kwargs):
208 """Display the PNG representation of an object.
208 """Display the PNG representation of an object.
209
209
210 Parameters
210 Parameters
211 ----------
211 ----------
212 objs : tuple of objects
212 objs : tuple of objects
213 The Python objects to display, or if raw=True raw png data to
213 The Python objects to display, or if raw=True raw png data to
214 display.
214 display.
215 raw : bool
215 raw : bool
216 Are the data objects raw data or Python objects that need to be
216 Are the data objects raw data or Python objects that need to be
217 formatted before display? [default: False]
217 formatted before display? [default: False]
218 metadata : dict (optional)
218 metadata : dict (optional)
219 Metadata to be associated with the specific mimetype output.
219 Metadata to be associated with the specific mimetype output.
220 """
220 """
221 _display_mimetype('image/png', objs, **kwargs)
221 _display_mimetype('image/png', objs, **kwargs)
222
222
223
223
224 def display_jpeg(*objs, **kwargs):
224 def display_jpeg(*objs, **kwargs):
225 """Display the JPEG representation of an object.
225 """Display the JPEG representation of an object.
226
226
227 Parameters
227 Parameters
228 ----------
228 ----------
229 objs : tuple of objects
229 objs : tuple of objects
230 The Python objects to display, or if raw=True raw JPEG data to
230 The Python objects to display, or if raw=True raw JPEG data to
231 display.
231 display.
232 raw : bool
232 raw : bool
233 Are the data objects raw data or Python objects that need to be
233 Are the data objects raw data or Python objects that need to be
234 formatted before display? [default: False]
234 formatted before display? [default: False]
235 metadata : dict (optional)
235 metadata : dict (optional)
236 Metadata to be associated with the specific mimetype output.
236 Metadata to be associated with the specific mimetype output.
237 """
237 """
238 _display_mimetype('image/jpeg', objs, **kwargs)
238 _display_mimetype('image/jpeg', objs, **kwargs)
239
239
240
240
241 def display_latex(*objs, **kwargs):
241 def display_latex(*objs, **kwargs):
242 """Display the LaTeX representation of an object.
242 """Display the LaTeX representation of an object.
243
243
244 Parameters
244 Parameters
245 ----------
245 ----------
246 objs : tuple of objects
246 objs : tuple of objects
247 The Python objects to display, or if raw=True raw latex data to
247 The Python objects to display, or if raw=True raw latex data to
248 display.
248 display.
249 raw : bool
249 raw : bool
250 Are the data objects raw data or Python objects that need to be
250 Are the data objects raw data or Python objects that need to be
251 formatted before display? [default: False]
251 formatted before display? [default: False]
252 metadata : dict (optional)
252 metadata : dict (optional)
253 Metadata to be associated with the specific mimetype output.
253 Metadata to be associated with the specific mimetype output.
254 """
254 """
255 _display_mimetype('text/latex', objs, **kwargs)
255 _display_mimetype('text/latex', objs, **kwargs)
256
256
257
257
258 def display_json(*objs, **kwargs):
258 def display_json(*objs, **kwargs):
259 """Display the JSON representation of an object.
259 """Display the JSON representation of an object.
260
260
261 Note that not many frontends support displaying JSON.
261 Note that not many frontends support displaying JSON.
262
262
263 Parameters
263 Parameters
264 ----------
264 ----------
265 objs : tuple of objects
265 objs : tuple of objects
266 The Python objects to display, or if raw=True raw json data to
266 The Python objects to display, or if raw=True raw json data to
267 display.
267 display.
268 raw : bool
268 raw : bool
269 Are the data objects raw data or Python objects that need to be
269 Are the data objects raw data or Python objects that need to be
270 formatted before display? [default: False]
270 formatted before display? [default: False]
271 metadata : dict (optional)
271 metadata : dict (optional)
272 Metadata to be associated with the specific mimetype output.
272 Metadata to be associated with the specific mimetype output.
273 """
273 """
274 _display_mimetype('application/json', objs, **kwargs)
274 _display_mimetype('application/json', objs, **kwargs)
275
275
276
276
277 def display_javascript(*objs, **kwargs):
277 def display_javascript(*objs, **kwargs):
278 """Display the Javascript representation of an object.
278 """Display the Javascript representation of an object.
279
279
280 Parameters
280 Parameters
281 ----------
281 ----------
282 objs : tuple of objects
282 objs : tuple of objects
283 The Python objects to display, or if raw=True raw javascript data to
283 The Python objects to display, or if raw=True raw javascript data to
284 display.
284 display.
285 raw : bool
285 raw : bool
286 Are the data objects raw data or Python objects that need to be
286 Are the data objects raw data or Python objects that need to be
287 formatted before display? [default: False]
287 formatted before display? [default: False]
288 metadata : dict (optional)
288 metadata : dict (optional)
289 Metadata to be associated with the specific mimetype output.
289 Metadata to be associated with the specific mimetype output.
290 """
290 """
291 _display_mimetype('application/javascript', objs, **kwargs)
291 _display_mimetype('application/javascript', objs, **kwargs)
292
292
293
293
294 def display_pdf(*objs, **kwargs):
294 def display_pdf(*objs, **kwargs):
295 """Display the PDF representation of an object.
295 """Display the PDF representation of an object.
296
296
297 Parameters
297 Parameters
298 ----------
298 ----------
299 objs : tuple of objects
299 objs : tuple of objects
300 The Python objects to display, or if raw=True raw javascript data to
300 The Python objects to display, or if raw=True raw javascript data to
301 display.
301 display.
302 raw : bool
302 raw : bool
303 Are the data objects raw data or Python objects that need to be
303 Are the data objects raw data or Python objects that need to be
304 formatted before display? [default: False]
304 formatted before display? [default: False]
305 metadata : dict (optional)
305 metadata : dict (optional)
306 Metadata to be associated with the specific mimetype output.
306 Metadata to be associated with the specific mimetype output.
307 """
307 """
308 _display_mimetype('application/pdf', objs, **kwargs)
308 _display_mimetype('application/pdf', objs, **kwargs)
309
309
310
310
311 #-----------------------------------------------------------------------------
311 #-----------------------------------------------------------------------------
312 # Smart classes
312 # Smart classes
313 #-----------------------------------------------------------------------------
313 #-----------------------------------------------------------------------------
314
314
315
315
316 class DisplayObject(object):
316 class DisplayObject(object):
317 """An object that wraps data to be displayed."""
317 """An object that wraps data to be displayed."""
318
318
319 _read_flags = 'r'
319 _read_flags = 'r'
320 _show_mem_addr = False
320 _show_mem_addr = False
321
321
322 def __init__(self, data=None, url=None, filename=None):
322 def __init__(self, data=None, url=None, filename=None):
323 """Create a display object given raw data.
323 """Create a display object given raw data.
324
324
325 When this object is returned by an expression or passed to the
325 When this object is returned by an expression or passed to the
326 display function, it will result in the data being displayed
326 display function, it will result in the data being displayed
327 in the frontend. The MIME type of the data should match the
327 in the frontend. The MIME type of the data should match the
328 subclasses used, so the Png subclass should be used for 'image/png'
328 subclasses used, so the Png subclass should be used for 'image/png'
329 data. If the data is a URL, the data will first be downloaded
329 data. If the data is a URL, the data will first be downloaded
330 and then displayed. If
330 and then displayed. If
331
331
332 Parameters
332 Parameters
333 ----------
333 ----------
334 data : unicode, str or bytes
334 data : unicode, str or bytes
335 The raw data or a URL or file to load the data from
335 The raw data or a URL or file to load the data from
336 url : unicode
336 url : unicode
337 A URL to download the data from.
337 A URL to download the data from.
338 filename : unicode
338 filename : unicode
339 Path to a local file to load the data from.
339 Path to a local file to load the data from.
340 """
340 """
341 if data is not None and isinstance(data, string_types):
341 if data is not None and isinstance(data, string_types):
342 if data.startswith('http') and url is None:
342 if data.startswith('http') and url is None:
343 url = data
343 url = data
344 filename = None
344 filename = None
345 data = None
345 data = None
346 elif _safe_exists(data) and filename is None:
346 elif _safe_exists(data) and filename is None:
347 url = None
347 url = None
348 filename = data
348 filename = data
349 data = None
349 data = None
350
350
351 self.data = data
351 self.data = data
352 self.url = url
352 self.url = url
353 self.filename = None if filename is None else unicode_type(filename)
353 self.filename = None if filename is None else unicode_type(filename)
354
354
355 self.reload()
355 self.reload()
356 self._check_data()
356 self._check_data()
357
357
358 def __repr__(self):
358 def __repr__(self):
359 if not self._show_mem_addr:
359 if not self._show_mem_addr:
360 cls = self.__class__
360 cls = self.__class__
361 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
361 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
362 else:
362 else:
363 r = super(DisplayObject, self).__repr__()
363 r = super(DisplayObject, self).__repr__()
364 return r
364 return r
365
365
366 def _check_data(self):
366 def _check_data(self):
367 """Override in subclasses if there's something to check."""
367 """Override in subclasses if there's something to check."""
368 pass
368 pass
369
369
370 def reload(self):
370 def reload(self):
371 """Reload the raw data from file or URL."""
371 """Reload the raw data from file or URL."""
372 if self.filename is not None:
372 if self.filename is not None:
373 with open(self.filename, self._read_flags) as f:
373 with open(self.filename, self._read_flags) as f:
374 self.data = f.read()
374 self.data = f.read()
375 elif self.url is not None:
375 elif self.url is not None:
376 try:
376 try:
377 try:
377 try:
378 from urllib.request import urlopen # Py3
378 from urllib.request import urlopen # Py3
379 except ImportError:
379 except ImportError:
380 from urllib2 import urlopen
380 from urllib2 import urlopen
381 response = urlopen(self.url)
381 response = urlopen(self.url)
382 self.data = response.read()
382 self.data = response.read()
383 # extract encoding from header, if there is one:
383 # extract encoding from header, if there is one:
384 encoding = None
384 encoding = None
385 for sub in response.headers['content-type'].split(';'):
385 for sub in response.headers['content-type'].split(';'):
386 sub = sub.strip()
386 sub = sub.strip()
387 if sub.startswith('charset'):
387 if sub.startswith('charset'):
388 encoding = sub.split('=')[-1].strip()
388 encoding = sub.split('=')[-1].strip()
389 break
389 break
390 # decode data, if an encoding was specified
390 # decode data, if an encoding was specified
391 if encoding:
391 if encoding:
392 self.data = self.data.decode(encoding, 'replace')
392 self.data = self.data.decode(encoding, 'replace')
393 except:
393 except:
394 self.data = None
394 self.data = None
395
395
396 class TextDisplayObject(DisplayObject):
396 class TextDisplayObject(DisplayObject):
397 """Validate that display data is text"""
397 """Validate that display data is text"""
398 def _check_data(self):
398 def _check_data(self):
399 if self.data is not None and not isinstance(self.data, string_types):
399 if self.data is not None and not isinstance(self.data, string_types):
400 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
400 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
401
401
402 class Pretty(TextDisplayObject):
402 class Pretty(TextDisplayObject):
403
403
404 def _repr_pretty_(self):
404 def _repr_pretty_(self):
405 return self.data
405 return self.data
406
406
407
407
408 class HTML(TextDisplayObject):
408 class HTML(TextDisplayObject):
409
409
410 def _repr_html_(self):
410 def _repr_html_(self):
411 return self.data
411 return self.data
412
412
413 def __html__(self):
413 def __html__(self):
414 """
414 """
415 This method exists to inform other HTML-using modules (e.g. Markupsafe,
415 This method exists to inform other HTML-using modules (e.g. Markupsafe,
416 htmltag, etc) that this object is HTML and does not need things like
416 htmltag, etc) that this object is HTML and does not need things like
417 special characters (<>&) escaped.
417 special characters (<>&) escaped.
418 """
418 """
419 return self._repr_html_()
419 return self._repr_html_()
420
420
421
421
422 class Markdown(TextDisplayObject):
422 class Markdown(TextDisplayObject):
423
423
424 def _repr_markdown_(self):
424 def _repr_markdown_(self):
425 return self.data
425 return self.data
426
426
427
427
428 class Math(TextDisplayObject):
428 class Math(TextDisplayObject):
429
429
430 def _repr_latex_(self):
430 def _repr_latex_(self):
431 s = self.data.strip('$')
431 s = self.data.strip('$')
432 return "$$%s$$" % s
432 return "$$%s$$" % s
433
433
434
434
435 class Latex(TextDisplayObject):
435 class Latex(TextDisplayObject):
436
436
437 def _repr_latex_(self):
437 def _repr_latex_(self):
438 return self.data
438 return self.data
439
439
440
440
441 class SVG(DisplayObject):
441 class SVG(DisplayObject):
442
442
443 # wrap data in a property, which extracts the <svg> tag, discarding
443 # wrap data in a property, which extracts the <svg> tag, discarding
444 # document headers
444 # document headers
445 _data = None
445 _data = None
446
446
447 @property
447 @property
448 def data(self):
448 def data(self):
449 return self._data
449 return self._data
450
450
451 @data.setter
451 @data.setter
452 def data(self, svg):
452 def data(self, svg):
453 if svg is None:
453 if svg is None:
454 self._data = None
454 self._data = None
455 return
455 return
456 # parse into dom object
456 # parse into dom object
457 from xml.dom import minidom
457 from xml.dom import minidom
458 svg = cast_bytes_py2(svg)
458 svg = cast_bytes_py2(svg)
459 x = minidom.parseString(svg)
459 x = minidom.parseString(svg)
460 # get svg tag (should be 1)
460 # get svg tag (should be 1)
461 found_svg = x.getElementsByTagName('svg')
461 found_svg = x.getElementsByTagName('svg')
462 if found_svg:
462 if found_svg:
463 svg = found_svg[0].toxml()
463 svg = found_svg[0].toxml()
464 else:
464 else:
465 # fallback on the input, trust the user
465 # fallback on the input, trust the user
466 # but this is probably an error.
466 # but this is probably an error.
467 pass
467 pass
468 svg = cast_unicode(svg)
468 svg = cast_unicode(svg)
469 self._data = svg
469 self._data = svg
470
470
471 def _repr_svg_(self):
471 def _repr_svg_(self):
472 return self.data
472 return self.data
473
473
474
474
475 class JSON(TextDisplayObject):
475 class JSON(TextDisplayObject):
476
476
477 def _repr_json_(self):
477 def _repr_json_(self):
478 return self.data
478 return self.data
479
479
480 css_t = """$("head").append($("<link/>").attr({
480 css_t = """$("head").append($("<link/>").attr({
481 rel: "stylesheet",
481 rel: "stylesheet",
482 type: "text/css",
482 type: "text/css",
483 href: "%s"
483 href: "%s"
484 }));
484 }));
485 """
485 """
486
486
487 lib_t1 = """$.getScript("%s", function () {
487 lib_t1 = """$.getScript("%s", function () {
488 """
488 """
489 lib_t2 = """});
489 lib_t2 = """});
490 """
490 """
491
491
492 class Javascript(TextDisplayObject):
492 class Javascript(TextDisplayObject):
493
493
494 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
494 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
495 """Create a Javascript display object given raw data.
495 """Create a Javascript display object given raw data.
496
496
497 When this object is returned by an expression or passed to the
497 When this object is returned by an expression or passed to the
498 display function, it will result in the data being displayed
498 display function, it will result in the data being displayed
499 in the frontend. If the data is a URL, the data will first be
499 in the frontend. If the data is a URL, the data will first be
500 downloaded and then displayed.
500 downloaded and then displayed.
501
501
502 In the Notebook, the containing element will be available as `element`,
502 In the Notebook, the containing element will be available as `element`,
503 and jQuery will be available. The output area starts hidden, so if
503 and jQuery will be available. Content appended to `element` will be
504 the js appends content to `element` that should be visible, then
504 visible in the output area.
505 it must call `container.show()` to unhide the area.
506
505
507 Parameters
506 Parameters
508 ----------
507 ----------
509 data : unicode, str or bytes
508 data : unicode, str or bytes
510 The Javascript source code or a URL to download it from.
509 The Javascript source code or a URL to download it from.
511 url : unicode
510 url : unicode
512 A URL to download the data from.
511 A URL to download the data from.
513 filename : unicode
512 filename : unicode
514 Path to a local file to load the data from.
513 Path to a local file to load the data from.
515 lib : list or str
514 lib : list or str
516 A sequence of Javascript library URLs to load asynchronously before
515 A sequence of Javascript library URLs to load asynchronously before
517 running the source code. The full URLs of the libraries should
516 running the source code. The full URLs of the libraries should
518 be given. A single Javascript library URL can also be given as a
517 be given. A single Javascript library URL can also be given as a
519 string.
518 string.
520 css: : list or str
519 css: : list or str
521 A sequence of css files to load before running the source code.
520 A sequence of css files to load before running the source code.
522 The full URLs of the css files should be given. A single css URL
521 The full URLs of the css files should be given. A single css URL
523 can also be given as a string.
522 can also be given as a string.
524 """
523 """
525 if isinstance(lib, string_types):
524 if isinstance(lib, string_types):
526 lib = [lib]
525 lib = [lib]
527 elif lib is None:
526 elif lib is None:
528 lib = []
527 lib = []
529 if isinstance(css, string_types):
528 if isinstance(css, string_types):
530 css = [css]
529 css = [css]
531 elif css is None:
530 elif css is None:
532 css = []
531 css = []
533 if not isinstance(lib, (list,tuple)):
532 if not isinstance(lib, (list,tuple)):
534 raise TypeError('expected sequence, got: %r' % lib)
533 raise TypeError('expected sequence, got: %r' % lib)
535 if not isinstance(css, (list,tuple)):
534 if not isinstance(css, (list,tuple)):
536 raise TypeError('expected sequence, got: %r' % css)
535 raise TypeError('expected sequence, got: %r' % css)
537 self.lib = lib
536 self.lib = lib
538 self.css = css
537 self.css = css
539 super(Javascript, self).__init__(data=data, url=url, filename=filename)
538 super(Javascript, self).__init__(data=data, url=url, filename=filename)
540
539
541 def _repr_javascript_(self):
540 def _repr_javascript_(self):
542 r = ''
541 r = ''
543 for c in self.css:
542 for c in self.css:
544 r += css_t % c
543 r += css_t % c
545 for l in self.lib:
544 for l in self.lib:
546 r += lib_t1 % l
545 r += lib_t1 % l
547 r += self.data
546 r += self.data
548 r += lib_t2*len(self.lib)
547 r += lib_t2*len(self.lib)
549 return r
548 return r
550
549
551 # constants for identifying png/jpeg data
550 # constants for identifying png/jpeg data
552 _PNG = b'\x89PNG\r\n\x1a\n'
551 _PNG = b'\x89PNG\r\n\x1a\n'
553 _JPEG = b'\xff\xd8'
552 _JPEG = b'\xff\xd8'
554
553
555 def _pngxy(data):
554 def _pngxy(data):
556 """read the (width, height) from a PNG header"""
555 """read the (width, height) from a PNG header"""
557 ihdr = data.index(b'IHDR')
556 ihdr = data.index(b'IHDR')
558 # next 8 bytes are width/height
557 # next 8 bytes are width/height
559 w4h4 = data[ihdr+4:ihdr+12]
558 w4h4 = data[ihdr+4:ihdr+12]
560 return struct.unpack('>ii', w4h4)
559 return struct.unpack('>ii', w4h4)
561
560
562 def _jpegxy(data):
561 def _jpegxy(data):
563 """read the (width, height) from a JPEG header"""
562 """read the (width, height) from a JPEG header"""
564 # adapted from http://www.64lines.com/jpeg-width-height
563 # adapted from http://www.64lines.com/jpeg-width-height
565
564
566 idx = 4
565 idx = 4
567 while True:
566 while True:
568 block_size = struct.unpack('>H', data[idx:idx+2])[0]
567 block_size = struct.unpack('>H', data[idx:idx+2])[0]
569 idx = idx + block_size
568 idx = idx + block_size
570 if data[idx:idx+2] == b'\xFF\xC0':
569 if data[idx:idx+2] == b'\xFF\xC0':
571 # found Start of Frame
570 # found Start of Frame
572 iSOF = idx
571 iSOF = idx
573 break
572 break
574 else:
573 else:
575 # read another block
574 # read another block
576 idx += 2
575 idx += 2
577
576
578 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
577 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
579 return w, h
578 return w, h
580
579
581 class Image(DisplayObject):
580 class Image(DisplayObject):
582
581
583 _read_flags = 'rb'
582 _read_flags = 'rb'
584 _FMT_JPEG = u'jpeg'
583 _FMT_JPEG = u'jpeg'
585 _FMT_PNG = u'png'
584 _FMT_PNG = u'png'
586 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
585 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
587
586
588 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
587 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
589 """Create a PNG/JPEG image object given raw data.
588 """Create a PNG/JPEG image object given raw data.
590
589
591 When this object is returned by an input cell or passed to the
590 When this object is returned by an input cell or passed to the
592 display function, it will result in the image being displayed
591 display function, it will result in the image being displayed
593 in the frontend.
592 in the frontend.
594
593
595 Parameters
594 Parameters
596 ----------
595 ----------
597 data : unicode, str or bytes
596 data : unicode, str or bytes
598 The raw image data or a URL or filename to load the data from.
597 The raw image data or a URL or filename to load the data from.
599 This always results in embedded image data.
598 This always results in embedded image data.
600 url : unicode
599 url : unicode
601 A URL to download the data from. If you specify `url=`,
600 A URL to download the data from. If you specify `url=`,
602 the image data will not be embedded unless you also specify `embed=True`.
601 the image data will not be embedded unless you also specify `embed=True`.
603 filename : unicode
602 filename : unicode
604 Path to a local file to load the data from.
603 Path to a local file to load the data from.
605 Images from a file are always embedded.
604 Images from a file are always embedded.
606 format : unicode
605 format : unicode
607 The format of the image data (png/jpeg/jpg). If a filename or URL is given
606 The format of the image data (png/jpeg/jpg). If a filename or URL is given
608 for format will be inferred from the filename extension.
607 for format will be inferred from the filename extension.
609 embed : bool
608 embed : bool
610 Should the image data be embedded using a data URI (True) or be
609 Should the image data be embedded using a data URI (True) or be
611 loaded using an <img> tag. Set this to True if you want the image
610 loaded using an <img> tag. Set this to True if you want the image
612 to be viewable later with no internet connection in the notebook.
611 to be viewable later with no internet connection in the notebook.
613
612
614 Default is `True`, unless the keyword argument `url` is set, then
613 Default is `True`, unless the keyword argument `url` is set, then
615 default value is `False`.
614 default value is `False`.
616
615
617 Note that QtConsole is not able to display images if `embed` is set to `False`
616 Note that QtConsole is not able to display images if `embed` is set to `False`
618 width : int
617 width : int
619 Width to which to constrain the image in html
618 Width to which to constrain the image in html
620 height : int
619 height : int
621 Height to which to constrain the image in html
620 Height to which to constrain the image in html
622 retina : bool
621 retina : bool
623 Automatically set the width and height to half of the measured
622 Automatically set the width and height to half of the measured
624 width and height.
623 width and height.
625 This only works for embedded images because it reads the width/height
624 This only works for embedded images because it reads the width/height
626 from image data.
625 from image data.
627 For non-embedded images, you can just set the desired display width
626 For non-embedded images, you can just set the desired display width
628 and height directly.
627 and height directly.
629
628
630 Examples
629 Examples
631 --------
630 --------
632 # embedded image data, works in qtconsole and notebook
631 # embedded image data, works in qtconsole and notebook
633 # when passed positionally, the first arg can be any of raw image data,
632 # when passed positionally, the first arg can be any of raw image data,
634 # a URL, or a filename from which to load image data.
633 # a URL, or a filename from which to load image data.
635 # The result is always embedding image data for inline images.
634 # The result is always embedding image data for inline images.
636 Image('http://www.google.fr/images/srpr/logo3w.png')
635 Image('http://www.google.fr/images/srpr/logo3w.png')
637 Image('/path/to/image.jpg')
636 Image('/path/to/image.jpg')
638 Image(b'RAW_PNG_DATA...')
637 Image(b'RAW_PNG_DATA...')
639
638
640 # Specifying Image(url=...) does not embed the image data,
639 # Specifying Image(url=...) does not embed the image data,
641 # it only generates `<img>` tag with a link to the source.
640 # it only generates `<img>` tag with a link to the source.
642 # This will not work in the qtconsole or offline.
641 # This will not work in the qtconsole or offline.
643 Image(url='http://www.google.fr/images/srpr/logo3w.png')
642 Image(url='http://www.google.fr/images/srpr/logo3w.png')
644
643
645 """
644 """
646 if filename is not None:
645 if filename is not None:
647 ext = self._find_ext(filename)
646 ext = self._find_ext(filename)
648 elif url is not None:
647 elif url is not None:
649 ext = self._find_ext(url)
648 ext = self._find_ext(url)
650 elif data is None:
649 elif data is None:
651 raise ValueError("No image data found. Expecting filename, url, or data.")
650 raise ValueError("No image data found. Expecting filename, url, or data.")
652 elif isinstance(data, string_types) and (
651 elif isinstance(data, string_types) and (
653 data.startswith('http') or _safe_exists(data)
652 data.startswith('http') or _safe_exists(data)
654 ):
653 ):
655 ext = self._find_ext(data)
654 ext = self._find_ext(data)
656 else:
655 else:
657 ext = None
656 ext = None
658
657
659 if ext is not None:
658 if ext is not None:
660 format = ext.lower()
659 format = ext.lower()
661 if ext == u'jpg' or ext == u'jpeg':
660 if ext == u'jpg' or ext == u'jpeg':
662 format = self._FMT_JPEG
661 format = self._FMT_JPEG
663 if ext == u'png':
662 if ext == u'png':
664 format = self._FMT_PNG
663 format = self._FMT_PNG
665 elif isinstance(data, bytes) and format == 'png':
664 elif isinstance(data, bytes) and format == 'png':
666 # infer image type from image data header,
665 # infer image type from image data header,
667 # only if format might not have been specified.
666 # only if format might not have been specified.
668 if data[:2] == _JPEG:
667 if data[:2] == _JPEG:
669 format = 'jpeg'
668 format = 'jpeg'
670
669
671 self.format = unicode_type(format).lower()
670 self.format = unicode_type(format).lower()
672 self.embed = embed if embed is not None else (url is None)
671 self.embed = embed if embed is not None else (url is None)
673
672
674 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
673 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
675 raise ValueError("Cannot embed the '%s' image format" % (self.format))
674 raise ValueError("Cannot embed the '%s' image format" % (self.format))
676 self.width = width
675 self.width = width
677 self.height = height
676 self.height = height
678 self.retina = retina
677 self.retina = retina
679 super(Image, self).__init__(data=data, url=url, filename=filename)
678 super(Image, self).__init__(data=data, url=url, filename=filename)
680
679
681 if retina:
680 if retina:
682 self._retina_shape()
681 self._retina_shape()
683
682
684 def _retina_shape(self):
683 def _retina_shape(self):
685 """load pixel-doubled width and height from image data"""
684 """load pixel-doubled width and height from image data"""
686 if not self.embed:
685 if not self.embed:
687 return
686 return
688 if self.format == 'png':
687 if self.format == 'png':
689 w, h = _pngxy(self.data)
688 w, h = _pngxy(self.data)
690 elif self.format == 'jpeg':
689 elif self.format == 'jpeg':
691 w, h = _jpegxy(self.data)
690 w, h = _jpegxy(self.data)
692 else:
691 else:
693 # retina only supports png
692 # retina only supports png
694 return
693 return
695 self.width = w // 2
694 self.width = w // 2
696 self.height = h // 2
695 self.height = h // 2
697
696
698 def reload(self):
697 def reload(self):
699 """Reload the raw data from file or URL."""
698 """Reload the raw data from file or URL."""
700 if self.embed:
699 if self.embed:
701 super(Image,self).reload()
700 super(Image,self).reload()
702 if self.retina:
701 if self.retina:
703 self._retina_shape()
702 self._retina_shape()
704
703
705 def _repr_html_(self):
704 def _repr_html_(self):
706 if not self.embed:
705 if not self.embed:
707 width = height = ''
706 width = height = ''
708 if self.width:
707 if self.width:
709 width = ' width="%d"' % self.width
708 width = ' width="%d"' % self.width
710 if self.height:
709 if self.height:
711 height = ' height="%d"' % self.height
710 height = ' height="%d"' % self.height
712 return u'<img src="%s"%s%s/>' % (self.url, width, height)
711 return u'<img src="%s"%s%s/>' % (self.url, width, height)
713
712
714 def _data_and_metadata(self):
713 def _data_and_metadata(self):
715 """shortcut for returning metadata with shape information, if defined"""
714 """shortcut for returning metadata with shape information, if defined"""
716 md = {}
715 md = {}
717 if self.width:
716 if self.width:
718 md['width'] = self.width
717 md['width'] = self.width
719 if self.height:
718 if self.height:
720 md['height'] = self.height
719 md['height'] = self.height
721 if md:
720 if md:
722 return self.data, md
721 return self.data, md
723 else:
722 else:
724 return self.data
723 return self.data
725
724
726 def _repr_png_(self):
725 def _repr_png_(self):
727 if self.embed and self.format == u'png':
726 if self.embed and self.format == u'png':
728 return self._data_and_metadata()
727 return self._data_and_metadata()
729
728
730 def _repr_jpeg_(self):
729 def _repr_jpeg_(self):
731 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
730 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
732 return self._data_and_metadata()
731 return self._data_and_metadata()
733
732
734 def _find_ext(self, s):
733 def _find_ext(self, s):
735 return unicode_type(s.split('.')[-1].lower())
734 return unicode_type(s.split('.')[-1].lower())
736
735
737
736
738 def clear_output(wait=False):
737 def clear_output(wait=False):
739 """Clear the output of the current cell receiving output.
738 """Clear the output of the current cell receiving output.
740
739
741 Parameters
740 Parameters
742 ----------
741 ----------
743 wait : bool [default: false]
742 wait : bool [default: false]
744 Wait to clear the output until new output is available to replace it."""
743 Wait to clear the output until new output is available to replace it."""
745 from IPython.core.interactiveshell import InteractiveShell
744 from IPython.core.interactiveshell import InteractiveShell
746 if InteractiveShell.initialized():
745 if InteractiveShell.initialized():
747 InteractiveShell.instance().display_pub.clear_output(wait)
746 InteractiveShell.instance().display_pub.clear_output(wait)
748 else:
747 else:
749 from IPython.utils import io
748 from IPython.utils import io
750 print('\033[2K\r', file=io.stdout, end='')
749 print('\033[2K\r', file=io.stdout, end='')
751 io.stdout.flush()
750 io.stdout.flush()
752 print('\033[2K\r', file=io.stderr, end='')
751 print('\033[2K\r', file=io.stderr, end='')
753 io.stderr.flush()
752 io.stderr.flush()
754
753
755
754
756 @skip_doctest
755 @skip_doctest
757 def set_matplotlib_formats(*formats, **kwargs):
756 def set_matplotlib_formats(*formats, **kwargs):
758 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
757 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
759
758
760 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
759 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
761
760
762 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
761 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
763
762
764 To set this in your config files use the following::
763 To set this in your config files use the following::
765
764
766 c.InlineBackend.figure_formats = {'png', 'jpeg'}
765 c.InlineBackend.figure_formats = {'png', 'jpeg'}
767 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
766 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
768
767
769 Parameters
768 Parameters
770 ----------
769 ----------
771 *formats : strs
770 *formats : strs
772 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
771 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
773 **kwargs :
772 **kwargs :
774 Keyword args will be relayed to ``figure.canvas.print_figure``.
773 Keyword args will be relayed to ``figure.canvas.print_figure``.
775 """
774 """
776 from IPython.core.interactiveshell import InteractiveShell
775 from IPython.core.interactiveshell import InteractiveShell
777 from IPython.core.pylabtools import select_figure_formats
776 from IPython.core.pylabtools import select_figure_formats
778 from IPython.kernel.zmq.pylab.config import InlineBackend
777 from IPython.kernel.zmq.pylab.config import InlineBackend
779 # build kwargs, starting with InlineBackend config
778 # build kwargs, starting with InlineBackend config
780 kw = {}
779 kw = {}
781 cfg = InlineBackend.instance()
780 cfg = InlineBackend.instance()
782 kw.update(cfg.print_figure_kwargs)
781 kw.update(cfg.print_figure_kwargs)
783 kw.update(**kwargs)
782 kw.update(**kwargs)
784 shell = InteractiveShell.instance()
783 shell = InteractiveShell.instance()
785 select_figure_formats(shell, formats, **kw)
784 select_figure_formats(shell, formats, **kw)
786
785
787 @skip_doctest
786 @skip_doctest
788 def set_matplotlib_close(close=True):
787 def set_matplotlib_close(close=True):
789 """Set whether the inline backend closes all figures automatically or not.
788 """Set whether the inline backend closes all figures automatically or not.
790
789
791 By default, the inline backend used in the IPython Notebook will close all
790 By default, the inline backend used in the IPython Notebook will close all
792 matplotlib figures automatically after each cell is run. This means that
791 matplotlib figures automatically after each cell is run. This means that
793 plots in different cells won't interfere. Sometimes, you may want to make
792 plots in different cells won't interfere. Sometimes, you may want to make
794 a plot in one cell and then refine it in later cells. This can be accomplished
793 a plot in one cell and then refine it in later cells. This can be accomplished
795 by::
794 by::
796
795
797 In [1]: set_matplotlib_close(False)
796 In [1]: set_matplotlib_close(False)
798
797
799 To set this in your config files use the following::
798 To set this in your config files use the following::
800
799
801 c.InlineBackend.close_figures = False
800 c.InlineBackend.close_figures = False
802
801
803 Parameters
802 Parameters
804 ----------
803 ----------
805 close : bool
804 close : bool
806 Should all matplotlib figures be automatically closed after each cell is
805 Should all matplotlib figures be automatically closed after each cell is
807 run?
806 run?
808 """
807 """
809 from IPython.kernel.zmq.pylab.config import InlineBackend
808 from IPython.kernel.zmq.pylab.config import InlineBackend
810 cfg = InlineBackend.instance()
809 cfg = InlineBackend.instance()
811 cfg.close_figures = close
810 cfg.close_figures = close
812
811
General Comments 0
You need to be logged in to leave comments. Login now