Show More
@@ -21,15 +21,10 b' from __future__ import print_function' | |||
|
21 | 21 | |
|
22 | 22 | import os |
|
23 | 23 | |
|
24 | from .displaypub import ( | |
|
25 | publish_pretty, publish_html, | |
|
26 | publish_latex, publish_svg, | |
|
27 | publish_png, publish_json, | |
|
28 | publish_javascript, publish_jpeg | |
|
29 | ) | |
|
30 | ||
|
31 | 24 | from IPython.utils.py3compat import string_types |
|
32 | 25 | |
|
26 | from .displaypub import publish_display_data | |
|
27 | ||
|
33 | 28 | #----------------------------------------------------------------------------- |
|
34 | 29 | # utility functions |
|
35 | 30 | #----------------------------------------------------------------------------- |
@@ -41,6 +36,41 b' def _safe_exists(path):' | |||
|
41 | 36 | except Exception: |
|
42 | 37 | return False |
|
43 | 38 | |
|
39 | def _merge(d1, d2): | |
|
40 | """Like update, but merges sub-dicts instead of clobbering at the top level. | |
|
41 | ||
|
42 | Updates d1 in-place | |
|
43 | """ | |
|
44 | ||
|
45 | if not isinstance(d2, dict) or not isinstance(d1, dict): | |
|
46 | return d2 | |
|
47 | for key, value in d2.items(): | |
|
48 | d1[key] = _merge(d1.get(key), value) | |
|
49 | return d1 | |
|
50 | ||
|
51 | def _display_mimetype(mimetype, objs, raw=False, metadata=None): | |
|
52 | """internal implementation of all display_foo methods | |
|
53 | ||
|
54 | Parameters | |
|
55 | ---------- | |
|
56 | mimetype : str | |
|
57 | The mimetype to be published (e.g. 'image/png') | |
|
58 | objs : tuple of objects | |
|
59 | The Python objects to display, or if raw=True raw text data to | |
|
60 | display. | |
|
61 | raw : bool | |
|
62 | Are the data objects raw data or Python objects that need to be | |
|
63 | formatted before display? [default: False] | |
|
64 | metadata : dict (optional) | |
|
65 | Metadata to be associated with the specific mimetype output. | |
|
66 | """ | |
|
67 | if metadata: | |
|
68 | metadata = {mimetype: metadata} | |
|
69 | if raw: | |
|
70 | # turn list of pngdata into list of { 'image/png': pngdata } | |
|
71 | objs = [ {mimetype: obj} for obj in objs ] | |
|
72 | display(*objs, raw=raw, metadata=metadata, include=[mimetype]) | |
|
73 | ||
|
44 | 74 | #----------------------------------------------------------------------------- |
|
45 | 75 | # Main functions |
|
46 | 76 | #----------------------------------------------------------------------------- |
@@ -55,6 +85,9 b' def display(*objs, **kwargs):' | |||
|
55 | 85 | ---------- |
|
56 | 86 | objs : tuple of objects |
|
57 | 87 | The Python objects to display. |
|
88 | raw : bool, optional | |
|
89 | Are the objects to be displayed already mimetype-keyed dicts of raw display data, | |
|
90 | or Python objects that need to be formatted before display? [default: False] | |
|
58 | 91 | include : list or tuple, optional |
|
59 | 92 | A list of format type strings (MIME types) to include in the |
|
60 | 93 | format data dict. If this is set *only* the format types included |
@@ -63,18 +96,29 b' def display(*objs, **kwargs):' | |||
|
63 | 96 | A list of format type strings (MIME types) to exclude in the format |
|
64 | 97 | data dict. If this is set all format types will be computed, |
|
65 | 98 | except for those included in this argument. |
|
99 | metadata : dict, optional | |
|
100 | A dictionary of metadata to associate with the output. | |
|
101 | mime-type keys in this dictionary will be associated with the individual | |
|
102 | representation formats, if they exist. | |
|
66 | 103 | """ |
|
104 | raw = kwargs.get('raw', False) | |
|
67 | 105 | include = kwargs.get('include') |
|
68 | 106 | exclude = kwargs.get('exclude') |
|
107 | metadata = kwargs.get('metadata') | |
|
69 | 108 | |
|
70 | 109 | from IPython.core.interactiveshell import InteractiveShell |
|
71 | inst = InteractiveShell.instance() | |
|
72 | format = inst.display_formatter.format | |
|
73 | publish = inst.display_pub.publish | |
|
74 | ||
|
75 | for obj in objs: | |
|
76 | format_dict = format(obj, include=include, exclude=exclude) | |
|
77 | publish('IPython.core.display.display', format_dict) | |
|
110 | ||
|
111 | if raw: | |
|
112 | for obj in objs: | |
|
113 | publish_display_data('display', obj, metadata) | |
|
114 | else: | |
|
115 | format = InteractiveShell.instance().display_formatter.format | |
|
116 | for obj in objs: | |
|
117 | format_dict, md_dict = format(obj, include=include, exclude=exclude) | |
|
118 | if metadata: | |
|
119 | # kwarg-specified metadata gets precedence | |
|
120 | _merge(md_dict, metadata) | |
|
121 | publish_display_data('display', format_dict, md_dict) | |
|
78 | 122 | |
|
79 | 123 | |
|
80 | 124 | def display_pretty(*objs, **kwargs): |
@@ -88,13 +132,10 b' def display_pretty(*objs, **kwargs):' | |||
|
88 | 132 | raw : bool |
|
89 | 133 | Are the data objects raw data or Python objects that need to be |
|
90 | 134 | formatted before display? [default: False] |
|
135 | metadata : dict (optional) | |
|
136 | Metadata to be associated with the specific mimetype output. | |
|
91 | 137 | """ |
|
92 | raw = kwargs.pop('raw',False) | |
|
93 | if raw: | |
|
94 | for obj in objs: | |
|
95 | publish_pretty(obj) | |
|
96 | else: | |
|
97 | display(*objs, include=['text/plain']) | |
|
138 | _display_mimetype('text/plain', objs, **kwargs) | |
|
98 | 139 | |
|
99 | 140 | |
|
100 | 141 | def display_html(*objs, **kwargs): |
@@ -108,13 +149,10 b' def display_html(*objs, **kwargs):' | |||
|
108 | 149 | raw : bool |
|
109 | 150 | Are the data objects raw data or Python objects that need to be |
|
110 | 151 | formatted before display? [default: False] |
|
152 | metadata : dict (optional) | |
|
153 | Metadata to be associated with the specific mimetype output. | |
|
111 | 154 | """ |
|
112 | raw = kwargs.pop('raw',False) | |
|
113 | if raw: | |
|
114 | for obj in objs: | |
|
115 | publish_html(obj) | |
|
116 | else: | |
|
117 | display(*objs, include=['text/plain','text/html']) | |
|
155 | _display_mimetype('text/html', objs, **kwargs) | |
|
118 | 156 | |
|
119 | 157 | |
|
120 | 158 | def display_svg(*objs, **kwargs): |
@@ -128,13 +166,10 b' def display_svg(*objs, **kwargs):' | |||
|
128 | 166 | raw : bool |
|
129 | 167 | Are the data objects raw data or Python objects that need to be |
|
130 | 168 | formatted before display? [default: False] |
|
169 | metadata : dict (optional) | |
|
170 | Metadata to be associated with the specific mimetype output. | |
|
131 | 171 | """ |
|
132 | raw = kwargs.pop('raw',False) | |
|
133 | if raw: | |
|
134 | for obj in objs: | |
|
135 | publish_svg(obj) | |
|
136 | else: | |
|
137 | display(*objs, include=['text/plain','image/svg+xml']) | |
|
172 | _display_mimetype('image/svg+xml', objs, **kwargs) | |
|
138 | 173 | |
|
139 | 174 | |
|
140 | 175 | def display_png(*objs, **kwargs): |
@@ -148,13 +183,10 b' def display_png(*objs, **kwargs):' | |||
|
148 | 183 | raw : bool |
|
149 | 184 | Are the data objects raw data or Python objects that need to be |
|
150 | 185 | formatted before display? [default: False] |
|
186 | metadata : dict (optional) | |
|
187 | Metadata to be associated with the specific mimetype output. | |
|
151 | 188 | """ |
|
152 | raw = kwargs.pop('raw',False) | |
|
153 | if raw: | |
|
154 | for obj in objs: | |
|
155 | publish_png(obj) | |
|
156 | else: | |
|
157 | display(*objs, include=['text/plain','image/png']) | |
|
189 | _display_mimetype('image/png', objs, **kwargs) | |
|
158 | 190 | |
|
159 | 191 | |
|
160 | 192 | def display_jpeg(*objs, **kwargs): |
@@ -168,13 +200,10 b' def display_jpeg(*objs, **kwargs):' | |||
|
168 | 200 | raw : bool |
|
169 | 201 | Are the data objects raw data or Python objects that need to be |
|
170 | 202 | formatted before display? [default: False] |
|
203 | metadata : dict (optional) | |
|
204 | Metadata to be associated with the specific mimetype output. | |
|
171 | 205 | """ |
|
172 | raw = kwargs.pop('raw',False) | |
|
173 | if raw: | |
|
174 | for obj in objs: | |
|
175 | publish_jpeg(obj) | |
|
176 | else: | |
|
177 | display(*objs, include=['text/plain','image/jpeg']) | |
|
206 | _display_mimetype('image/jpeg', objs, **kwargs) | |
|
178 | 207 | |
|
179 | 208 | |
|
180 | 209 | def display_latex(*objs, **kwargs): |
@@ -188,13 +217,10 b' def display_latex(*objs, **kwargs):' | |||
|
188 | 217 | raw : bool |
|
189 | 218 | Are the data objects raw data or Python objects that need to be |
|
190 | 219 | formatted before display? [default: False] |
|
220 | metadata : dict (optional) | |
|
221 | Metadata to be associated with the specific mimetype output. | |
|
191 | 222 | """ |
|
192 | raw = kwargs.pop('raw',False) | |
|
193 | if raw: | |
|
194 | for obj in objs: | |
|
195 | publish_latex(obj) | |
|
196 | else: | |
|
197 | display(*objs, include=['text/plain','text/latex']) | |
|
223 | _display_mimetype('text/latex', objs, **kwargs) | |
|
198 | 224 | |
|
199 | 225 | |
|
200 | 226 | def display_json(*objs, **kwargs): |
@@ -210,13 +236,10 b' def display_json(*objs, **kwargs):' | |||
|
210 | 236 | raw : bool |
|
211 | 237 | Are the data objects raw data or Python objects that need to be |
|
212 | 238 | formatted before display? [default: False] |
|
239 | metadata : dict (optional) | |
|
240 | Metadata to be associated with the specific mimetype output. | |
|
213 | 241 | """ |
|
214 | raw = kwargs.pop('raw',False) | |
|
215 | if raw: | |
|
216 | for obj in objs: | |
|
217 | publish_json(obj) | |
|
218 | else: | |
|
219 | display(*objs, include=['text/plain','application/json']) | |
|
242 | _display_mimetype('application/json', objs, **kwargs) | |
|
220 | 243 | |
|
221 | 244 | |
|
222 | 245 | def display_javascript(*objs, **kwargs): |
@@ -230,13 +253,10 b' def display_javascript(*objs, **kwargs):' | |||
|
230 | 253 | raw : bool |
|
231 | 254 | Are the data objects raw data or Python objects that need to be |
|
232 | 255 | formatted before display? [default: False] |
|
256 | metadata : dict (optional) | |
|
257 | Metadata to be associated with the specific mimetype output. | |
|
233 | 258 | """ |
|
234 | raw = kwargs.pop('raw',False) | |
|
235 | if raw: | |
|
236 | for obj in objs: | |
|
237 | publish_javascript(obj) | |
|
238 | else: | |
|
239 | display(*objs, include=['text/plain','application/javascript']) | |
|
259 | _display_mimetype('application/javascript', objs, **kwargs) | |
|
240 | 260 | |
|
241 | 261 | #----------------------------------------------------------------------------- |
|
242 | 262 | # Smart classes |
@@ -539,14 +559,26 b' class Image(DisplayObject):' | |||
|
539 | 559 | if self.height: |
|
540 | 560 | height = ' height="%d"' % self.height |
|
541 | 561 | return u'<img src="%s"%s%s/>' % (self.url, width, height) |
|
562 | ||
|
563 | def _data_and_metadata(self): | |
|
564 | """shortcut for returning metadata with shape information, if defined""" | |
|
565 | md = {} | |
|
566 | if self.width: | |
|
567 | md['width'] = self.width | |
|
568 | if self.height: | |
|
569 | md['height'] = self.height | |
|
570 | if md: | |
|
571 | return self.data, md | |
|
572 | else: | |
|
573 | return self.data | |
|
542 | 574 | |
|
543 | 575 | def _repr_png_(self): |
|
544 | 576 | if self.embed and self.format == u'png': |
|
545 | return self.data | |
|
577 | return self._data_and_metadata() | |
|
546 | 578 | |
|
547 | 579 | def _repr_jpeg_(self): |
|
548 | 580 | if self.embed and (self.format == u'jpeg' or self.format == u'jpg'): |
|
549 | return self.data | |
|
581 | return self._data_and_metadata() | |
|
550 | 582 | |
|
551 | 583 | def _find_ext(self, s): |
|
552 | 584 | return unicode(s.split('.')[-1].lower()) |
@@ -145,15 +145,18 b' class DisplayHook(Configurable):' | |||
|
145 | 145 | |
|
146 | 146 | Returns |
|
147 | 147 | ------- |
|
148 |
format_d |
|
|
149 |
|
|
|
148 | (format_dict, md_dict) : dict | |
|
149 | format_dict is a :class:`dict` whose keys are valid MIME types and values are | |
|
150 | 150 | JSON'able raw data for that MIME type. It is recommended that |
|
151 | 151 | all return values of this should always include the "text/plain" |
|
152 | 152 | MIME type representation of the object. |
|
153 | md_dict is a :class:`dict` with the same MIME type keys | |
|
154 | of metadata associated with each output. | |
|
155 | ||
|
153 | 156 | """ |
|
154 | 157 | return self.shell.display_formatter.format(result) |
|
155 | 158 | |
|
156 | def write_format_data(self, format_dict): | |
|
159 | def write_format_data(self, format_dict, md_dict=None): | |
|
157 | 160 | """Write the format data dict to the frontend. |
|
158 | 161 | |
|
159 | 162 | This default version of this method simply writes the plain text |
@@ -165,6 +168,8 b' class DisplayHook(Configurable):' | |||
|
165 | 168 | ---------- |
|
166 | 169 | format_dict : dict |
|
167 | 170 | The format dict for the object passed to `sys.displayhook`. |
|
171 | md_dict : dict (optional) | |
|
172 | The metadata dict to be associated with the display data. | |
|
168 | 173 | """ |
|
169 | 174 | # We want to print because we want to always make sure we have a |
|
170 | 175 | # newline, even if all the prompt separators are ''. This is the |
@@ -239,8 +244,8 b' class DisplayHook(Configurable):' | |||
|
239 | 244 | if result is not None and not self.quiet(): |
|
240 | 245 | self.start_displayhook() |
|
241 | 246 | self.write_output_prompt() |
|
242 | format_dict = self.compute_format_data(result) | |
|
243 | self.write_format_data(format_dict) | |
|
247 | format_dict, md_dict = self.compute_format_data(result) | |
|
248 | self.write_format_data(format_dict, md_dict) | |
|
244 | 249 | self.update_user_ns(result) |
|
245 | 250 | self.log_output(format_dict) |
|
246 | 251 | self.finish_displayhook() |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | There are two components of the display system: |
|
4 | 4 | |
|
5 | 5 | * Display formatters, which take a Python object and compute the |
|
6 |
representation of the object in various formats (text, HTML, SV |
|
|
6 | representation of the object in various formats (text, HTML, SVG, etc.). | |
|
7 | 7 | * The display publisher that is used to send the representation data to the |
|
8 | 8 | various frontends. |
|
9 | 9 | |
@@ -98,7 +98,9 b' class DisplayPublisher(Configurable):' | |||
|
98 | 98 | metadata : dict |
|
99 | 99 | A dictionary for metadata related to the data. This can contain |
|
100 | 100 | arbitrary key, value pairs that frontends can use to interpret |
|
101 | the data. | |
|
101 | the data. Metadata specific to each mime-type can be specified | |
|
102 | in the metadata dict with the same mime-type keys as | |
|
103 | the data itself. | |
|
102 | 104 | """ |
|
103 | 105 | |
|
104 | 106 | # The default is to simply write the plain text data using io.stdout. |
@@ -149,8 +151,9 b' def publish_display_data(source, data, metadata=None):' | |||
|
149 | 151 | metadata : dict |
|
150 | 152 | A dictionary for metadata related to the data. This can contain |
|
151 | 153 | arbitrary key, value pairs that frontends can use to interpret |
|
152 | the data. | |
|
153 | """ | |
|
154 | the data. mime-type keys matching those in data can be used | |
|
155 | to specify metadata about particular representations. | |
|
156 | """ | |
|
154 | 157 | from IPython.core.interactiveshell import InteractiveShell |
|
155 | 158 | InteractiveShell.instance().display_pub.publish( |
|
156 | 159 | source, |
@@ -159,151 +162,3 b' def publish_display_data(source, data, metadata=None):' | |||
|
159 | 162 | ) |
|
160 | 163 | |
|
161 | 164 | |
|
162 | def publish_pretty(data, metadata=None): | |
|
163 | """Publish raw text data to all frontends. | |
|
164 | ||
|
165 | Parameters | |
|
166 | ---------- | |
|
167 | data : unicode | |
|
168 | The raw text data to publish. | |
|
169 | metadata : dict | |
|
170 | A dictionary for metadata related to the data. This can contain | |
|
171 | arbitrary key, value pairs that frontends can use to interpret | |
|
172 | the data. | |
|
173 | """ | |
|
174 | publish_display_data( | |
|
175 | u'IPython.core.displaypub.publish_pretty', | |
|
176 | {'text/plain':data}, | |
|
177 | metadata=metadata | |
|
178 | ) | |
|
179 | ||
|
180 | ||
|
181 | def publish_html(data, metadata=None): | |
|
182 | """Publish raw HTML data to all frontends. | |
|
183 | ||
|
184 | Parameters | |
|
185 | ---------- | |
|
186 | data : unicode | |
|
187 | The raw HTML data to publish. | |
|
188 | metadata : dict | |
|
189 | A dictionary for metadata related to the data. This can contain | |
|
190 | arbitrary key, value pairs that frontends can use to interpret | |
|
191 | the data. | |
|
192 | """ | |
|
193 | publish_display_data( | |
|
194 | u'IPython.core.displaypub.publish_html', | |
|
195 | {'text/html':data}, | |
|
196 | metadata=metadata | |
|
197 | ) | |
|
198 | ||
|
199 | ||
|
200 | def publish_latex(data, metadata=None): | |
|
201 | """Publish raw LaTeX data to all frontends. | |
|
202 | ||
|
203 | Parameters | |
|
204 | ---------- | |
|
205 | data : unicode | |
|
206 | The raw LaTeX data to publish. | |
|
207 | metadata : dict | |
|
208 | A dictionary for metadata related to the data. This can contain | |
|
209 | arbitrary key, value pairs that frontends can use to interpret | |
|
210 | the data. | |
|
211 | """ | |
|
212 | publish_display_data( | |
|
213 | u'IPython.core.displaypub.publish_latex', | |
|
214 | {'text/latex':data}, | |
|
215 | metadata=metadata | |
|
216 | ) | |
|
217 | ||
|
218 | def publish_png(data, metadata=None): | |
|
219 | """Publish raw binary PNG data to all frontends. | |
|
220 | ||
|
221 | Parameters | |
|
222 | ---------- | |
|
223 | data : str/bytes | |
|
224 | The raw binary PNG data to publish. | |
|
225 | metadata : dict | |
|
226 | A dictionary for metadata related to the data. This can contain | |
|
227 | arbitrary key, value pairs that frontends can use to interpret | |
|
228 | the data. | |
|
229 | """ | |
|
230 | publish_display_data( | |
|
231 | u'IPython.core.displaypub.publish_png', | |
|
232 | {'image/png':data}, | |
|
233 | metadata=metadata | |
|
234 | ) | |
|
235 | ||
|
236 | ||
|
237 | def publish_jpeg(data, metadata=None): | |
|
238 | """Publish raw binary JPEG data to all frontends. | |
|
239 | ||
|
240 | Parameters | |
|
241 | ---------- | |
|
242 | data : str/bytes | |
|
243 | The raw binary JPEG data to publish. | |
|
244 | metadata : dict | |
|
245 | A dictionary for metadata related to the data. This can contain | |
|
246 | arbitrary key, value pairs that frontends can use to interpret | |
|
247 | the data. | |
|
248 | """ | |
|
249 | publish_display_data( | |
|
250 | u'IPython.core.displaypub.publish_jpeg', | |
|
251 | {'image/jpeg':data}, | |
|
252 | metadata=metadata | |
|
253 | ) | |
|
254 | ||
|
255 | ||
|
256 | def publish_svg(data, metadata=None): | |
|
257 | """Publish raw SVG data to all frontends. | |
|
258 | ||
|
259 | Parameters | |
|
260 | ---------- | |
|
261 | data : unicode | |
|
262 | The raw SVG data to publish. | |
|
263 | metadata : dict | |
|
264 | A dictionary for metadata related to the data. This can contain | |
|
265 | arbitrary key, value pairs that frontends can use to interpret | |
|
266 | the data. | |
|
267 | """ | |
|
268 | publish_display_data( | |
|
269 | u'IPython.core.displaypub.publish_svg', | |
|
270 | {'image/svg+xml':data}, | |
|
271 | metadata=metadata | |
|
272 | ) | |
|
273 | ||
|
274 | def publish_json(data, metadata=None): | |
|
275 | """Publish raw JSON data to all frontends. | |
|
276 | ||
|
277 | Parameters | |
|
278 | ---------- | |
|
279 | data : unicode | |
|
280 | The raw JSON data to publish. | |
|
281 | metadata : dict | |
|
282 | A dictionary for metadata related to the data. This can contain | |
|
283 | arbitrary key, value pairs that frontends can use to interpret | |
|
284 | the data. | |
|
285 | """ | |
|
286 | publish_display_data( | |
|
287 | u'IPython.core.displaypub.publish_json', | |
|
288 | {'application/json':data}, | |
|
289 | metadata=metadata | |
|
290 | ) | |
|
291 | ||
|
292 | def publish_javascript(data, metadata=None): | |
|
293 | """Publish raw Javascript data to all frontends. | |
|
294 | ||
|
295 | Parameters | |
|
296 | ---------- | |
|
297 | data : unicode | |
|
298 | The raw Javascript data to publish. | |
|
299 | metadata : dict | |
|
300 | A dictionary for metadata related to the data. This can contain | |
|
301 | arbitrary key, value pairs that frontends can use to interpret | |
|
302 | the data. | |
|
303 | """ | |
|
304 | publish_display_data( | |
|
305 | u'IPython.core.displaypub.publish_javascript', | |
|
306 | {'application/javascript':data}, | |
|
307 | metadata=metadata | |
|
308 | ) | |
|
309 |
@@ -127,28 +127,43 b' class DisplayFormatter(Configurable):' | |||
|
127 | 127 | |
|
128 | 128 | Returns |
|
129 | 129 | ------- |
|
130 | format_dict : dict | |
|
131 | A dictionary of key/value pairs, one or each format that was | |
|
130 | (format_dict, metadata_dict) : tuple of two dicts | |
|
131 | ||
|
132 | format_dict is a dictionary of key/value pairs, one of each format that was | |
|
132 | 133 | generated for the object. The keys are the format types, which |
|
133 | 134 | will usually be MIME type strings and the values and JSON'able |
|
134 | 135 | data structure containing the raw data for the representation in |
|
135 | 136 | that format. |
|
137 | ||
|
138 | metadata_dict is a dictionary of metadata about each mime-type output. | |
|
139 | Its keys will be a strict subset of the keys in format_dict. | |
|
136 | 140 | """ |
|
137 | 141 | format_dict = {} |
|
142 | md_dict = {} | |
|
138 | 143 | |
|
139 | 144 | for format_type, formatter in self.formatters.items(): |
|
140 | 145 | if include and format_type not in include: |
|
141 | 146 | continue |
|
142 | 147 | if exclude and format_type in exclude: |
|
143 | 148 | continue |
|
149 | ||
|
150 | md = None | |
|
144 | 151 | try: |
|
145 | 152 | data = formatter(obj) |
|
146 | 153 | except: |
|
147 | 154 | # FIXME: log the exception |
|
148 | 155 | raise |
|
156 | ||
|
157 | # formatters can return raw data or (data, metadata) | |
|
158 | if isinstance(data, tuple) and len(data) == 2: | |
|
159 | data, md = data | |
|
160 | ||
|
149 | 161 | if data is not None: |
|
150 | 162 | format_dict[format_type] = data |
|
151 | return format_dict | |
|
163 | if md is not None: | |
|
164 | md_dict[format_type] = md | |
|
165 | ||
|
166 | return format_dict, md_dict | |
|
152 | 167 | |
|
153 | 168 | @property |
|
154 | 169 | def format_types(self): |
@@ -13,5 +13,4 b'' | |||
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | |
|
15 | 15 | from IPython.core.display import * |
|
16 | from IPython.core.displaypub import * | |
|
17 | 16 | from IPython.lib.display import * |
@@ -178,9 +178,11 b' var IPython = (function (IPython) {' | |||
|
178 | 178 | json.stream = content.name; |
|
179 | 179 | } else if (msg_type === "display_data") { |
|
180 | 180 | json = this.convert_mime_types(json, content.data); |
|
181 | json.metadata = this.convert_mime_types({}, content.metadata); | |
|
181 | 182 | } else if (msg_type === "pyout") { |
|
182 | 183 | json.prompt_number = content.execution_count; |
|
183 | 184 | json = this.convert_mime_types(json, content.data); |
|
185 | json.metadata = this.convert_mime_types({}, content.metadata); | |
|
184 | 186 | } else if (msg_type === "pyerr") { |
|
185 | 187 | json.ename = content.ename; |
|
186 | 188 | json.evalue = content.evalue; |
@@ -273,7 +275,7 b' var IPython = (function (IPython) {' | |||
|
273 | 275 | } |
|
274 | 276 | s = s + '\n'; |
|
275 | 277 | var toinsert = this.create_output_area(); |
|
276 | this.append_text(s, toinsert); | |
|
278 | this.append_text(s, {}, toinsert); | |
|
277 | 279 | this.element.append(toinsert); |
|
278 | 280 | } |
|
279 | 281 | }; |
@@ -310,7 +312,7 b' var IPython = (function (IPython) {' | |||
|
310 | 312 | |
|
311 | 313 | // If we got here, attach a new div |
|
312 | 314 | var toinsert = this.create_output_area(); |
|
313 | this.append_text(text, toinsert, "output_stream "+subclass); | |
|
315 | this.append_text(text, {}, toinsert, "output_stream "+subclass); | |
|
314 | 316 | this.element.append(toinsert); |
|
315 | 317 | }; |
|
316 | 318 | |
@@ -331,12 +333,16 b' var IPython = (function (IPython) {' | |||
|
331 | 333 | for(var type_i in OutputArea.display_order){ |
|
332 | 334 | var type = OutputArea.display_order[type_i]; |
|
333 | 335 | if(json[type] != undefined ){ |
|
336 | var md = {}; | |
|
337 | if (json.metadata && json.metadata[type]) { | |
|
338 | md = json.metadata[type]; | |
|
339 | }; | |
|
334 | 340 | if(type == 'javascript'){ |
|
335 | 341 | if (dynamic) { |
|
336 | this.append_javascript(json.javascript, element, dynamic); | |
|
342 | this.append_javascript(json.javascript, md, element, dynamic); | |
|
337 | 343 | } |
|
338 | 344 | } else { |
|
339 | this['append_'+type](json[type], element); | |
|
345 | this['append_'+type](json[type], md, element); | |
|
340 | 346 | } |
|
341 | 347 | return; |
|
342 | 348 | } |
@@ -344,14 +350,14 b' var IPython = (function (IPython) {' | |||
|
344 | 350 | }; |
|
345 | 351 | |
|
346 | 352 | |
|
347 | OutputArea.prototype.append_html = function (html, element) { | |
|
353 | OutputArea.prototype.append_html = function (html, md, element) { | |
|
348 | 354 | var toinsert = $("<div/>").addClass("output_subarea output_html rendered_html"); |
|
349 | 355 | toinsert.append(html); |
|
350 | 356 | element.append(toinsert); |
|
351 | 357 | }; |
|
352 | 358 | |
|
353 | 359 | |
|
354 | OutputArea.prototype.append_javascript = function (js, container) { | |
|
360 | OutputArea.prototype.append_javascript = function (js, md, container) { | |
|
355 | 361 | // We just eval the JS code, element appears in the local scope. |
|
356 | 362 | var element = $("<div/>").addClass("output_subarea"); |
|
357 | 363 | container.append(element); |
@@ -375,7 +381,7 b' var IPython = (function (IPython) {' | |||
|
375 | 381 | }; |
|
376 | 382 | |
|
377 | 383 | |
|
378 | OutputArea.prototype.append_text = function (data, element, extra_class) { | |
|
384 | OutputArea.prototype.append_text = function (data, md, element, extra_class) { | |
|
379 | 385 | var toinsert = $("<div/>").addClass("output_subarea output_text"); |
|
380 | 386 | // escape ANSI & HTML specials in plaintext: |
|
381 | 387 | data = utils.fixConsole(data); |
@@ -389,7 +395,7 b' var IPython = (function (IPython) {' | |||
|
389 | 395 | }; |
|
390 | 396 | |
|
391 | 397 | |
|
392 | OutputArea.prototype.append_svg = function (svg, element) { | |
|
398 | OutputArea.prototype.append_svg = function (svg, md, element) { | |
|
393 | 399 | var toinsert = $("<div/>").addClass("output_subarea output_svg"); |
|
394 | 400 | toinsert.append(svg); |
|
395 | 401 | element.append(toinsert); |
@@ -423,25 +429,37 b' var IPython = (function (IPython) {' | |||
|
423 | 429 | }; |
|
424 | 430 | |
|
425 | 431 | |
|
426 | OutputArea.prototype.append_png = function (png, element) { | |
|
432 | OutputArea.prototype.append_png = function (png, md, element) { | |
|
427 | 433 | var toinsert = $("<div/>").addClass("output_subarea output_png"); |
|
428 | 434 | var img = $("<img/>").attr('src','data:image/png;base64,'+png); |
|
435 | if (md['height']) { | |
|
436 | img.attr('height', md['height']); | |
|
437 | } | |
|
438 | if (md['width']) { | |
|
439 | img.attr('width', md['width']); | |
|
440 | } | |
|
429 | 441 | this._dblclick_to_reset_size(img); |
|
430 | 442 | toinsert.append(img); |
|
431 | 443 | element.append(toinsert); |
|
432 | 444 | }; |
|
433 | 445 | |
|
434 | 446 | |
|
435 | OutputArea.prototype.append_jpeg = function (jpeg, element) { | |
|
447 | OutputArea.prototype.append_jpeg = function (jpeg, md, element) { | |
|
436 | 448 | var toinsert = $("<div/>").addClass("output_subarea output_jpeg"); |
|
437 | 449 | var img = $("<img/>").attr('src','data:image/jpeg;base64,'+jpeg); |
|
450 | if (md['height']) { | |
|
451 | img.attr('height', md['height']); | |
|
452 | } | |
|
453 | if (md['width']) { | |
|
454 | img.attr('width', md['width']); | |
|
455 | } | |
|
438 | 456 | this._dblclick_to_reset_size(img); |
|
439 | 457 | toinsert.append(img); |
|
440 | 458 | element.append(toinsert); |
|
441 | 459 | }; |
|
442 | 460 | |
|
443 | 461 | |
|
444 | OutputArea.prototype.append_latex = function (latex, element) { | |
|
462 | OutputArea.prototype.append_latex = function (latex, md, element) { | |
|
445 | 463 | // This method cannot do the typesetting because the latex first has to |
|
446 | 464 | // be on the page. |
|
447 | 465 | var toinsert = $("<div/>").addClass("output_subarea output_latex"); |
@@ -52,8 +52,9 b' class ZMQShellDisplayHook(DisplayHook):' | |||
|
52 | 52 | """Write the output prompt.""" |
|
53 | 53 | self.msg['content']['execution_count'] = self.prompt_count |
|
54 | 54 | |
|
55 | def write_format_data(self, format_dict): | |
|
55 | def write_format_data(self, format_dict, md_dict=None): | |
|
56 | 56 | self.msg['content']['data'] = encode_images(format_dict) |
|
57 | self.msg['content']['metadata'] = md_dict | |
|
57 | 58 | |
|
58 | 59 | def finish_displayhook(self): |
|
59 | 60 | """Finish up all displayhook activities.""" |
@@ -53,12 +53,18 b' def from_dict(d):' | |||
|
53 | 53 | def new_output(output_type=None, output_text=None, output_png=None, |
|
54 | 54 | output_html=None, output_svg=None, output_latex=None, output_json=None, |
|
55 | 55 | output_javascript=None, output_jpeg=None, prompt_number=None, |
|
56 | ename=None, evalue=None, traceback=None, stream=None): | |
|
56 | ename=None, evalue=None, traceback=None, stream=None, metadata=None): | |
|
57 | 57 | """Create a new code cell with input and output""" |
|
58 | 58 | output = NotebookNode() |
|
59 | 59 | if output_type is not None: |
|
60 | 60 | output.output_type = unicode(output_type) |
|
61 | 61 | |
|
62 | if metadata is None: | |
|
63 | metadata = {} | |
|
64 | if not isinstance(metadata, dict): | |
|
65 | raise TypeError("metadata must be dict") | |
|
66 | output.metadata = metadata | |
|
67 | ||
|
62 | 68 | if output_type != 'pyerr': |
|
63 | 69 | if output_text is not None: |
|
64 | 70 | output.text = unicode(output_text) |
@@ -91,7 +97,7 b' def new_output(output_type=None, output_text=None, output_png=None,' | |||
|
91 | 97 | |
|
92 | 98 | if output_type == u'stream': |
|
93 | 99 | output.stream = 'stdout' if stream is None else unicode(stream) |
|
94 | ||
|
100 | ||
|
95 | 101 | return output |
|
96 | 102 | |
|
97 | 103 |
@@ -808,8 +808,7 b' Message type: ``display_data``::' | |||
|
808 | 808 | |
|
809 | 809 | # The data dict contains key/value pairs, where the kids are MIME |
|
810 | 810 | # types and the values are the raw data of the representation in that |
|
811 | # format. The data dict must minimally contain the ``text/plain`` | |
|
812 | # MIME type which is used as a backup representation. | |
|
811 | # format. | |
|
813 | 812 | 'data' : dict, |
|
814 | 813 | |
|
815 | 814 | # Any metadata that describes the data |
@@ -817,6 +816,24 b' Message type: ``display_data``::' | |||
|
817 | 816 | } |
|
818 | 817 | |
|
819 | 818 | |
|
819 | The ``metadata`` contains any metadata that describes the output. | |
|
820 | Global keys are assumed to apply to the output as a whole. | |
|
821 | The ``metadata`` dict can also contain mime-type keys, which will be sub-dictionaries, | |
|
822 | which are interpreted as applying only to output of that type. | |
|
823 | Third parties should put any data they write into a single dict | |
|
824 | with a reasonably unique name to avoid conflicts. | |
|
825 | ||
|
826 | The only metadata keys currently defined in IPython are the width and height | |
|
827 | of images:: | |
|
828 | ||
|
829 | 'metadata' : { | |
|
830 | 'image/png' : { | |
|
831 | 'width': 640, | |
|
832 | 'height': 480 | |
|
833 | } | |
|
834 | } | |
|
835 | ||
|
836 | ||
|
820 | 837 | Raw Data Publication |
|
821 | 838 | -------------------- |
|
822 | 839 |
General Comments 0
You need to be logged in to leave comments.
Login now