##// END OF EJS Templates
Add javascript library and css stylesheet loading to JS class.
Brian Granger -
Show More
@@ -1,441 +1,503 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Top-level display functions for displaying object in different formats.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2008-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from xml.dom import minidom
21 21
22 22 from .displaypub import (
23 23 publish_pretty, publish_html,
24 24 publish_latex, publish_svg,
25 25 publish_png, publish_json,
26 26 publish_javascript, publish_jpeg
27 27 )
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Main functions
31 31 #-----------------------------------------------------------------------------
32 32
33 33 def display(*objs, **kwargs):
34 34 """Display a Python object in all frontends.
35 35
36 36 By default all representations will be computed and sent to the frontends.
37 37 Frontends can decide which representation is used and how.
38 38
39 39 Parameters
40 40 ----------
41 41 objs : tuple of objects
42 42 The Python objects to display.
43 43 include : list or tuple, optional
44 44 A list of format type strings (MIME types) to include in the
45 45 format data dict. If this is set *only* the format types included
46 46 in this list will be computed.
47 47 exclude : list or tuple, optional
48 48 A list of format type string (MIME types) to exclue in the format
49 49 data dict. If this is set all format types will be computed,
50 50 except for those included in this argument.
51 51 """
52 52 include = kwargs.get('include')
53 53 exclude = kwargs.get('exclude')
54 54
55 55 from IPython.core.interactiveshell import InteractiveShell
56 56 inst = InteractiveShell.instance()
57 57 format = inst.display_formatter.format
58 58 publish = inst.display_pub.publish
59 59
60 60 for obj in objs:
61 61 format_dict = format(obj, include=include, exclude=exclude)
62 62 publish('IPython.core.display.display', format_dict)
63 63
64 64
65 65 def display_pretty(*objs, **kwargs):
66 66 """Display the pretty (default) representation of an object.
67 67
68 68 Parameters
69 69 ----------
70 70 objs : tuple of objects
71 71 The Python objects to display, or if raw=True raw text data to
72 72 display.
73 73 raw : bool
74 74 Are the data objects raw data or Python objects that need to be
75 75 formatted before display? [default: False]
76 76 """
77 77 raw = kwargs.pop('raw',False)
78 78 if raw:
79 79 for obj in objs:
80 80 publish_pretty(obj)
81 81 else:
82 82 display(*objs, include=['text/plain'])
83 83
84 84
85 85 def display_html(*objs, **kwargs):
86 86 """Display the HTML representation of an object.
87 87
88 88 Parameters
89 89 ----------
90 90 objs : tuple of objects
91 91 The Python objects to display, or if raw=True raw HTML data to
92 92 display.
93 93 raw : bool
94 94 Are the data objects raw data or Python objects that need to be
95 95 formatted before display? [default: False]
96 96 """
97 97 raw = kwargs.pop('raw',False)
98 98 if raw:
99 99 for obj in objs:
100 100 publish_html(obj)
101 101 else:
102 102 display(*objs, include=['text/plain','text/html'])
103 103
104 104
105 105 def display_svg(*objs, **kwargs):
106 106 """Display the SVG representation of an object.
107 107
108 108 Parameters
109 109 ----------
110 110 objs : tuple of objects
111 111 The Python objects to display, or if raw=True raw svg data to
112 112 display.
113 113 raw : bool
114 114 Are the data objects raw data or Python objects that need to be
115 115 formatted before display? [default: False]
116 116 """
117 117 raw = kwargs.pop('raw',False)
118 118 if raw:
119 119 for obj in objs:
120 120 publish_svg(obj)
121 121 else:
122 122 display(*objs, include=['text/plain','image/svg+xml'])
123 123
124 124
125 125 def display_png(*objs, **kwargs):
126 126 """Display the PNG representation of an object.
127 127
128 128 Parameters
129 129 ----------
130 130 objs : tuple of objects
131 131 The Python objects to display, or if raw=True raw png data to
132 132 display.
133 133 raw : bool
134 134 Are the data objects raw data or Python objects that need to be
135 135 formatted before display? [default: False]
136 136 """
137 137 raw = kwargs.pop('raw',False)
138 138 if raw:
139 139 for obj in objs:
140 140 publish_png(obj)
141 141 else:
142 142 display(*objs, include=['text/plain','image/png'])
143 143
144 144
145 145 def display_jpeg(*objs, **kwargs):
146 146 """Display the JPEG representation of an object.
147 147
148 148 Parameters
149 149 ----------
150 150 objs : tuple of objects
151 151 The Python objects to display, or if raw=True raw JPEG data to
152 152 display.
153 153 raw : bool
154 154 Are the data objects raw data or Python objects that need to be
155 155 formatted before display? [default: False]
156 156 """
157 157 raw = kwargs.pop('raw',False)
158 158 if raw:
159 159 for obj in objs:
160 160 publish_jpeg(obj)
161 161 else:
162 162 display(*objs, include=['text/plain','image/jpeg'])
163 163
164 164
165 165 def display_latex(*objs, **kwargs):
166 166 """Display the LaTeX representation of an object.
167 167
168 168 Parameters
169 169 ----------
170 170 objs : tuple of objects
171 171 The Python objects to display, or if raw=True raw latex data to
172 172 display.
173 173 raw : bool
174 174 Are the data objects raw data or Python objects that need to be
175 175 formatted before display? [default: False]
176 176 """
177 177 raw = kwargs.pop('raw',False)
178 178 if raw:
179 179 for obj in objs:
180 180 publish_latex(obj)
181 181 else:
182 182 display(*objs, include=['text/plain','text/latex'])
183 183
184 184
185 185 def display_json(*objs, **kwargs):
186 186 """Display the JSON representation of an object.
187 187
188 188 Parameters
189 189 ----------
190 190 objs : tuple of objects
191 191 The Python objects to display, or if raw=True raw json data to
192 192 display.
193 193 raw : bool
194 194 Are the data objects raw data or Python objects that need to be
195 195 formatted before display? [default: False]
196 196 """
197 197 raw = kwargs.pop('raw',False)
198 198 if raw:
199 199 for obj in objs:
200 200 publish_json(obj)
201 201 else:
202 202 display(*objs, include=['text/plain','application/json'])
203 203
204 204
205 205 def display_javascript(*objs, **kwargs):
206 206 """Display the Javascript representation of an object.
207 207
208 208 Parameters
209 209 ----------
210 210 objs : tuple of objects
211 211 The Python objects to display, or if raw=True raw javascript data to
212 212 display.
213 213 raw : bool
214 214 Are the data objects raw data or Python objects that need to be
215 215 formatted before display? [default: False]
216 216 """
217 217 raw = kwargs.pop('raw',False)
218 218 if raw:
219 219 for obj in objs:
220 220 publish_javascript(obj)
221 221 else:
222 222 display(*objs, include=['text/plain','application/javascript'])
223 223
224 224 #-----------------------------------------------------------------------------
225 225 # Smart classes
226 226 #-----------------------------------------------------------------------------
227 227
228 228
229 229 class DisplayObject(object):
230 230 """An object that wraps data to be displayed."""
231 231
232 232 _read_flags = 'r'
233 233
234 234 def __init__(self, data=None, url=None, filename=None):
235 235 """Create a display object given raw data.
236 236
237 237 When this object is returned by an expression or passed to the
238 238 display function, it will result in the data being displayed
239 239 in the frontend. The MIME type of the data should match the
240 240 subclasses used, so the Png subclass should be used for 'image/png'
241 241 data. If the data is a URL, the data will first be downloaded
242 242 and then displayed. If
243 243
244 244 Parameters
245 245 ----------
246 246 data : unicode, str or bytes
247 247 The raw data or a URL to download the data from.
248 248 url : unicode
249 249 A URL to download the data from.
250 250 filename : unicode
251 251 Path to a local file to load the data from.
252 252 """
253 253 if data is not None and data.startswith('http'):
254 254 self.url = data
255 255 self.filename = None
256 256 self.data = None
257 257 else:
258 258 self.data = data
259 259 self.url = url
260 260 self.filename = None if filename is None else unicode(filename)
261 261 self.reload()
262 262
263 263 def reload(self):
264 264 """Reload the raw data from file or URL."""
265 265 if self.filename is not None:
266 266 with open(self.filename, self._read_flags) as f:
267 267 self.data = f.read()
268 268 elif self.url is not None:
269 269 try:
270 270 import urllib2
271 271 response = urllib2.urlopen(self.url)
272 272 self.data = response.read()
273 273 # extract encoding from header, if there is one:
274 274 encoding = None
275 275 for sub in response.headers['content-type'].split(';'):
276 276 sub = sub.strip()
277 277 if sub.startswith('charset'):
278 278 encoding = sub.split('=')[-1].strip()
279 279 break
280 280 # decode data, if an encoding was specified
281 281 if encoding:
282 282 self.data = self.data.decode(encoding, 'replace')
283 283 except:
284 284 self.data = None
285 285
286 286 class Pretty(DisplayObject):
287 287
288 288 def _repr_pretty_(self):
289 289 return self.data
290 290
291 291
292 292 class HTML(DisplayObject):
293 293
294 294 def _repr_html_(self):
295 295 return self.data
296 296
297 297
298 298 class Math(DisplayObject):
299 299
300 300 def _repr_latex_(self):
301 301 s = self.data.strip('$')
302 302 return "$$%s$$" % s
303 303
304 304
305 305 class Latex(DisplayObject):
306 306
307 307 def _repr_latex_(self):
308 308 return self.data
309 309
310 310
311 311 class SVG(DisplayObject):
312 312
313 313 # wrap data in a property, which extracts the <svg> tag, discarding
314 314 # document headers
315 315 _data = None
316 316
317 317 @property
318 318 def data(self):
319 319 return self._data
320 320
321 321 @data.setter
322 322 def data(self, svg):
323 323 if svg is None:
324 324 self._data = None
325 325 return
326 326 # parse into dom object
327 327 x = minidom.parseString(svg)
328 328 # get svg tag (should be 1)
329 329 found_svg = x.getElementsByTagName('svg')
330 330 if found_svg:
331 331 svg = found_svg[0].toxml()
332 332 else:
333 333 # fallback on the input, trust the user
334 334 # but this is probably an error.
335 335 pass
336 336 self._data = svg
337 337
338 338 def _repr_svg_(self):
339 339 return self.data
340 340
341 341
342 342 class JSON(DisplayObject):
343 343
344 344 def _repr_json_(self):
345 345 return self.data
346 346
347 css_t = """$("head").append($("<link/>").attr({
348 rel: "stylesheet",
349 type: "text/css",
350 href: "%s"
351 }));
352 """
353
354 lib_t1 = """$.getScript("%s", function () {
355 """
356 lib_t2 = """});
357 """
347 358
348 359 class Javascript(DisplayObject):
349 360
361 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
362 """Create a Javascript display object given raw data.
363
364 When this object is returned by an expression or passed to the
365 display function, it will result in the data being displayed
366 in the frontend. If the data is a URL, the data will first be
367 downloaded and then displayed.
368
369 Parameters
370 ----------
371 data : unicode, str or bytes
372 The Javascript source code or a URL to download it from.
373 url : unicode
374 A URL to download the data from.
375 filename : unicode
376 Path to a local file to load the data from.
377 lib : list or str
378 A sequence of Javascript library URLs to load asynchronously before
379 running the source code. The full URLs of the libraries should
380 be given. A single Javascript library URL can also be given as a
381 string.
382 css: : list or str
383 A sequence of css files to load before running the source code.
384 The full URLs of the css files should be give. A single css URL
385 can also be given as a string.
386 """
387 if isinstance(lib, basestring):
388 lib = [lib]
389 elif lib is None:
390 lib = []
391 if isinstance(css, basestring):
392 css = [css]
393 elif css is None:
394 css = []
395 if not isinstance(lib, (list,tuple)):
396 raise TypeError('expected sequence, got: %r' % lib)
397 if not isinstance(css, (list,tuple)):
398 raise TypeError('expected sequence, got: %r' % css)
399 self.lib = lib
400 self.css = css
401 super(Javascript, self).__init__(data=data, url=url, filename=filename)
402
350 403 def _repr_javascript_(self):
351 return self.data
404 r = ''
405 for c in self.css:
406 r += css_t % c
407 for l in self.lib:
408 r += lib_t1 % l
409 r += self.data
410 if self.lib:
411 for i in range(len(self.lib)):
412 r+= lib_t2
413 return r
352 414
353 415
354 416 class Image(DisplayObject):
355 417
356 418 _read_flags = 'rb'
357 419
358 420 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=False):
359 421 """Create a display an PNG/JPEG image given raw data.
360 422
361 423 When this object is returned by an expression or passed to the
362 424 display function, it will result in the image being displayed
363 425 in the frontend.
364 426
365 427 Parameters
366 428 ----------
367 429 data : unicode, str or bytes
368 430 The raw data or a URL to download the data from.
369 431 url : unicode
370 432 A URL to download the data from.
371 433 filename : unicode
372 434 Path to a local file to load the data from.
373 435 format : unicode
374 436 The format of the image data (png/jpeg/jpg). If a filename or URL is given
375 437 for format will be inferred from the filename extension.
376 438 embed : bool
377 439 Should the image data be embedded in the notebook using a data URI (True)
378 440 or be loaded using an <img> tag. Set this to True if you want the image
379 441 to be viewable later with no internet connection. If a filename is given
380 442 embed is always set to True.
381 443 """
382 444 if filename is not None:
383 445 ext = self._find_ext(filename)
384 446 elif url is not None:
385 447 ext = self._find_ext(url)
386 448 elif data.startswith('http'):
387 449 ext = self._find_ext(data)
388 450 else:
389 451 ext = None
390 452 if ext is not None:
391 453 if ext == u'jpg' or ext == u'jpeg':
392 454 format = u'jpeg'
393 455 if ext == u'png':
394 456 format = u'png'
395 457 self.format = unicode(format).lower()
396 458 self.embed = True if filename is not None else embed
397 459 super(Image, self).__init__(data=data, url=url, filename=filename)
398 460
399 461 def reload(self):
400 462 """Reload the raw data from file or URL."""
401 463 if self.embed:
402 464 super(Image,self).reload()
403 465
404 466 def _repr_html_(self):
405 467 if not self.embed:
406 468 return u'<img src="%s" />' % self.url
407 469
408 470 def _repr_png_(self):
409 471 if self.embed and self.format == u'png':
410 472 return self.data
411 473
412 474 def _repr_jpeg_(self):
413 475 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
414 476 return self.data
415 477
416 478 def _find_ext(self, s):
417 479 return unicode(s.split('.')[-1].lower())
418 480
419 481
420 482 def clear_output(stdout=True, stderr=True, other=True):
421 483 """Clear the output of the current cell receiving output.
422 484
423 485 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
424 486 produced by display()) can be excluded from the clear event.
425 487
426 488 By default, everything is cleared.
427 489
428 490 Parameters
429 491 ----------
430 492 stdout : bool [default: True]
431 493 Whether to clear stdout.
432 494 stderr : bool [default: True]
433 495 Whether to clear stderr.
434 496 other : bool [default: True]
435 497 Whether to clear everything else that is not stdout/stderr
436 498 (e.g. figures,images,HTML, any result of display()).
437 499 """
438 500 from IPython.core.interactiveshell import InteractiveShell
439 501 InteractiveShell.instance().display_pub.clear_output(
440 502 stdout=stdout, stderr=stderr, other=other,
441 503 )
General Comments 0
You need to be logged in to leave comments. Login now