Show More
@@ -21,15 +21,10 b' from __future__ import print_function' | |||||
21 |
|
21 | |||
22 | import os |
|
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 | from IPython.utils.py3compat import string_types |
|
24 | from IPython.utils.py3compat import string_types | |
32 |
|
25 | |||
|
26 | from .displaypub import publish_display_data | |||
|
27 | ||||
33 | #----------------------------------------------------------------------------- |
|
28 | #----------------------------------------------------------------------------- | |
34 | # utility functions |
|
29 | # utility functions | |
35 | #----------------------------------------------------------------------------- |
|
30 | #----------------------------------------------------------------------------- | |
@@ -41,6 +36,41 b' def _safe_exists(path):' | |||||
41 | except Exception: |
|
36 | except Exception: | |
42 | return False |
|
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 | # Main functions |
|
75 | # Main functions | |
46 | #----------------------------------------------------------------------------- |
|
76 | #----------------------------------------------------------------------------- | |
@@ -55,6 +85,9 b' def display(*objs, **kwargs):' | |||||
55 | ---------- |
|
85 | ---------- | |
56 | objs : tuple of objects |
|
86 | objs : tuple of objects | |
57 | The Python objects to display. |
|
87 | The Python objects to display. | |
|
88 | raw : bool, optional | |||
|
89 | Are the objects to be displayed already mimetype-keyed dicts of raw display data, | |||
|
90 | or Python objects that need to be formatted before display? [default: False] | |||
58 | include : list or tuple, optional |
|
91 | include : list or tuple, optional | |
59 | A list of format type strings (MIME types) to include in the |
|
92 | A list of format type strings (MIME types) to include in the | |
60 | format data dict. If this is set *only* the format types included |
|
93 | format data dict. If this is set *only* the format types included | |
@@ -63,18 +96,29 b' def display(*objs, **kwargs):' | |||||
63 | A list of format type strings (MIME types) to exclude in the format |
|
96 | A list of format type strings (MIME types) to exclude in the format | |
64 | data dict. If this is set all format types will be computed, |
|
97 | data dict. If this is set all format types will be computed, | |
65 | except for those included in this argument. |
|
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 | include = kwargs.get('include') |
|
105 | include = kwargs.get('include') | |
68 | exclude = kwargs.get('exclude') |
|
106 | exclude = kwargs.get('exclude') | |
|
107 | metadata = kwargs.get('metadata') | |||
69 |
|
108 | |||
70 | from IPython.core.interactiveshell import InteractiveShell |
|
109 | from IPython.core.interactiveshell import InteractiveShell | |
71 | inst = InteractiveShell.instance() |
|
110 | ||
72 | format = inst.display_formatter.format |
|
111 | if raw: | |
73 | publish = inst.display_pub.publish |
|
112 | for obj in objs: | |
74 |
|
113 | publish_display_data('display', obj, metadata) | ||
75 | for obj in objs: |
|
114 | else: | |
76 | format_dict = format(obj, include=include, exclude=exclude) |
|
115 | format = InteractiveShell.instance().display_formatter.format | |
77 | publish('IPython.core.display.display', format_dict) |
|
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 | def display_pretty(*objs, **kwargs): |
|
124 | def display_pretty(*objs, **kwargs): | |
@@ -88,13 +132,10 b' def display_pretty(*objs, **kwargs):' | |||||
88 | raw : bool |
|
132 | raw : bool | |
89 | Are the data objects raw data or Python objects that need to be |
|
133 | Are the data objects raw data or Python objects that need to be | |
90 | formatted before display? [default: False] |
|
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) |
|
138 | _display_mimetype('text/plain', objs, **kwargs) | |
93 | if raw: |
|
|||
94 | for obj in objs: |
|
|||
95 | publish_pretty(obj) |
|
|||
96 | else: |
|
|||
97 | display(*objs, include=['text/plain']) |
|
|||
98 |
|
139 | |||
99 |
|
140 | |||
100 | def display_html(*objs, **kwargs): |
|
141 | def display_html(*objs, **kwargs): | |
@@ -108,13 +149,10 b' def display_html(*objs, **kwargs):' | |||||
108 | raw : bool |
|
149 | raw : bool | |
109 | Are the data objects raw data or Python objects that need to be |
|
150 | Are the data objects raw data or Python objects that need to be | |
110 | formatted before display? [default: False] |
|
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) |
|
155 | _display_mimetype('text/html', objs, **kwargs) | |
113 | if raw: |
|
|||
114 | for obj in objs: |
|
|||
115 | publish_html(obj) |
|
|||
116 | else: |
|
|||
117 | display(*objs, include=['text/plain','text/html']) |
|
|||
118 |
|
156 | |||
119 |
|
157 | |||
120 | def display_svg(*objs, **kwargs): |
|
158 | def display_svg(*objs, **kwargs): | |
@@ -128,13 +166,10 b' def display_svg(*objs, **kwargs):' | |||||
128 | raw : bool |
|
166 | raw : bool | |
129 | Are the data objects raw data or Python objects that need to be |
|
167 | Are the data objects raw data or Python objects that need to be | |
130 | formatted before display? [default: False] |
|
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) |
|
172 | _display_mimetype('image/svg+xml', objs, **kwargs) | |
133 | if raw: |
|
|||
134 | for obj in objs: |
|
|||
135 | publish_svg(obj) |
|
|||
136 | else: |
|
|||
137 | display(*objs, include=['text/plain','image/svg+xml']) |
|
|||
138 |
|
173 | |||
139 |
|
174 | |||
140 | def display_png(*objs, **kwargs): |
|
175 | def display_png(*objs, **kwargs): | |
@@ -148,13 +183,10 b' def display_png(*objs, **kwargs):' | |||||
148 | raw : bool |
|
183 | raw : bool | |
149 | Are the data objects raw data or Python objects that need to be |
|
184 | Are the data objects raw data or Python objects that need to be | |
150 | formatted before display? [default: False] |
|
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) |
|
189 | _display_mimetype('image/png', objs, **kwargs) | |
153 | if raw: |
|
|||
154 | for obj in objs: |
|
|||
155 | publish_png(obj) |
|
|||
156 | else: |
|
|||
157 | display(*objs, include=['text/plain','image/png']) |
|
|||
158 |
|
190 | |||
159 |
|
191 | |||
160 | def display_jpeg(*objs, **kwargs): |
|
192 | def display_jpeg(*objs, **kwargs): | |
@@ -168,13 +200,10 b' def display_jpeg(*objs, **kwargs):' | |||||
168 | raw : bool |
|
200 | raw : bool | |
169 | Are the data objects raw data or Python objects that need to be |
|
201 | Are the data objects raw data or Python objects that need to be | |
170 | formatted before display? [default: False] |
|
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) |
|
206 | _display_mimetype('image/jpeg', objs, **kwargs) | |
173 | if raw: |
|
|||
174 | for obj in objs: |
|
|||
175 | publish_jpeg(obj) |
|
|||
176 | else: |
|
|||
177 | display(*objs, include=['text/plain','image/jpeg']) |
|
|||
178 |
|
207 | |||
179 |
|
208 | |||
180 | def display_latex(*objs, **kwargs): |
|
209 | def display_latex(*objs, **kwargs): | |
@@ -188,13 +217,10 b' def display_latex(*objs, **kwargs):' | |||||
188 | raw : bool |
|
217 | raw : bool | |
189 | Are the data objects raw data or Python objects that need to be |
|
218 | Are the data objects raw data or Python objects that need to be | |
190 | formatted before display? [default: False] |
|
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) |
|
223 | _display_mimetype('text/latex', objs, **kwargs) | |
193 | if raw: |
|
|||
194 | for obj in objs: |
|
|||
195 | publish_latex(obj) |
|
|||
196 | else: |
|
|||
197 | display(*objs, include=['text/plain','text/latex']) |
|
|||
198 |
|
224 | |||
199 |
|
225 | |||
200 | def display_json(*objs, **kwargs): |
|
226 | def display_json(*objs, **kwargs): | |
@@ -210,13 +236,10 b' def display_json(*objs, **kwargs):' | |||||
210 | raw : bool |
|
236 | raw : bool | |
211 | Are the data objects raw data or Python objects that need to be |
|
237 | Are the data objects raw data or Python objects that need to be | |
212 | formatted before display? [default: False] |
|
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) |
|
242 | _display_mimetype('application/json', objs, **kwargs) | |
215 | if raw: |
|
|||
216 | for obj in objs: |
|
|||
217 | publish_json(obj) |
|
|||
218 | else: |
|
|||
219 | display(*objs, include=['text/plain','application/json']) |
|
|||
220 |
|
243 | |||
221 |
|
244 | |||
222 | def display_javascript(*objs, **kwargs): |
|
245 | def display_javascript(*objs, **kwargs): | |
@@ -230,13 +253,10 b' def display_javascript(*objs, **kwargs):' | |||||
230 | raw : bool |
|
253 | raw : bool | |
231 | Are the data objects raw data or Python objects that need to be |
|
254 | Are the data objects raw data or Python objects that need to be | |
232 | formatted before display? [default: False] |
|
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) |
|
259 | _display_mimetype('application/javascript', objs, **kwargs) | |
235 | if raw: |
|
|||
236 | for obj in objs: |
|
|||
237 | publish_javascript(obj) |
|
|||
238 | else: |
|
|||
239 | display(*objs, include=['text/plain','application/javascript']) |
|
|||
240 |
|
260 | |||
241 | #----------------------------------------------------------------------------- |
|
261 | #----------------------------------------------------------------------------- | |
242 | # Smart classes |
|
262 | # Smart classes | |
@@ -539,14 +559,26 b' class Image(DisplayObject):' | |||||
539 | if self.height: |
|
559 | if self.height: | |
540 | height = ' height="%d"' % self.height |
|
560 | height = ' height="%d"' % self.height | |
541 | return u'<img src="%s"%s%s/>' % (self.url, width, height) |
|
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 | def _repr_png_(self): |
|
575 | def _repr_png_(self): | |
544 | if self.embed and self.format == u'png': |
|
576 | if self.embed and self.format == u'png': | |
545 | return self.data |
|
577 | return self._data_and_metadata() | |
546 |
|
578 | |||
547 | def _repr_jpeg_(self): |
|
579 | def _repr_jpeg_(self): | |
548 | if self.embed and (self.format == u'jpeg' or self.format == u'jpg'): |
|
580 | if self.embed and (self.format == u'jpeg' or self.format == u'jpg'): | |
549 | return self.data |
|
581 | return self._data_and_metadata() | |
550 |
|
582 | |||
551 | def _find_ext(self, s): |
|
583 | def _find_ext(self, s): | |
552 | return unicode(s.split('.')[-1].lower()) |
|
584 | return unicode(s.split('.')[-1].lower()) |
@@ -145,15 +145,18 b' class DisplayHook(Configurable):' | |||||
145 |
|
145 | |||
146 | Returns |
|
146 | Returns | |
147 | ------- |
|
147 | ------- | |
148 |
format_d |
|
148 | (format_dict, md_dict) : dict | |
149 |
|
|
149 | format_dict is a :class:`dict` whose keys are valid MIME types and values are | |
150 | JSON'able raw data for that MIME type. It is recommended that |
|
150 | JSON'able raw data for that MIME type. It is recommended that | |
151 | all return values of this should always include the "text/plain" |
|
151 | all return values of this should always include the "text/plain" | |
152 | MIME type representation of the object. |
|
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 | return self.shell.display_formatter.format(result) |
|
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 | """Write the format data dict to the frontend. |
|
160 | """Write the format data dict to the frontend. | |
158 |
|
161 | |||
159 | This default version of this method simply writes the plain text |
|
162 | This default version of this method simply writes the plain text | |
@@ -165,6 +168,8 b' class DisplayHook(Configurable):' | |||||
165 | ---------- |
|
168 | ---------- | |
166 | format_dict : dict |
|
169 | format_dict : dict | |
167 | The format dict for the object passed to `sys.displayhook`. |
|
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 | # We want to print because we want to always make sure we have a |
|
174 | # We want to print because we want to always make sure we have a | |
170 | # newline, even if all the prompt separators are ''. This is the |
|
175 | # newline, even if all the prompt separators are ''. This is the | |
@@ -239,8 +244,8 b' class DisplayHook(Configurable):' | |||||
239 | if result is not None and not self.quiet(): |
|
244 | if result is not None and not self.quiet(): | |
240 | self.start_displayhook() |
|
245 | self.start_displayhook() | |
241 | self.write_output_prompt() |
|
246 | self.write_output_prompt() | |
242 | format_dict = self.compute_format_data(result) |
|
247 | format_dict, md_dict = self.compute_format_data(result) | |
243 | self.write_format_data(format_dict) |
|
248 | self.write_format_data(format_dict, md_dict) | |
244 | self.update_user_ns(result) |
|
249 | self.update_user_ns(result) | |
245 | self.log_output(format_dict) |
|
250 | self.log_output(format_dict) | |
246 | self.finish_displayhook() |
|
251 | self.finish_displayhook() |
@@ -3,7 +3,7 b'' | |||||
3 | There are two components of the display system: |
|
3 | There are two components of the display system: | |
4 |
|
4 | |||
5 | * Display formatters, which take a Python object and compute the |
|
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 | * The display publisher that is used to send the representation data to the |
|
7 | * The display publisher that is used to send the representation data to the | |
8 | various frontends. |
|
8 | various frontends. | |
9 |
|
9 | |||
@@ -98,7 +98,9 b' class DisplayPublisher(Configurable):' | |||||
98 | metadata : dict |
|
98 | metadata : dict | |
99 | A dictionary for metadata related to the data. This can contain |
|
99 | A dictionary for metadata related to the data. This can contain | |
100 | arbitrary key, value pairs that frontends can use to interpret |
|
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 | # The default is to simply write the plain text data using io.stdout. |
|
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 | metadata : dict |
|
151 | metadata : dict | |
150 | A dictionary for metadata related to the data. This can contain |
|
152 | A dictionary for metadata related to the data. This can contain | |
151 | arbitrary key, value pairs that frontends can use to interpret |
|
153 | arbitrary key, value pairs that frontends can use to interpret | |
152 | the data. |
|
154 | the data. mime-type keys matching those in data can be used | |
153 | """ |
|
155 | to specify metadata about particular representations. | |
|
156 | """ | |||
154 | from IPython.core.interactiveshell import InteractiveShell |
|
157 | from IPython.core.interactiveshell import InteractiveShell | |
155 | InteractiveShell.instance().display_pub.publish( |
|
158 | InteractiveShell.instance().display_pub.publish( | |
156 | source, |
|
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 | Returns |
|
128 | Returns | |
129 | ------- |
|
129 | ------- | |
130 | format_dict : dict |
|
130 | (format_dict, metadata_dict) : tuple of two dicts | |
131 | A dictionary of key/value pairs, one or each format that was |
|
131 | ||
|
132 | format_dict is a dictionary of key/value pairs, one of each format that was | |||
132 | generated for the object. The keys are the format types, which |
|
133 | generated for the object. The keys are the format types, which | |
133 | will usually be MIME type strings and the values and JSON'able |
|
134 | will usually be MIME type strings and the values and JSON'able | |
134 | data structure containing the raw data for the representation in |
|
135 | data structure containing the raw data for the representation in | |
135 | that format. |
|
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 | format_dict = {} |
|
141 | format_dict = {} | |
|
142 | md_dict = {} | |||
138 |
|
143 | |||
139 | for format_type, formatter in self.formatters.items(): |
|
144 | for format_type, formatter in self.formatters.items(): | |
140 | if include and format_type not in include: |
|
145 | if include and format_type not in include: | |
141 | continue |
|
146 | continue | |
142 | if exclude and format_type in exclude: |
|
147 | if exclude and format_type in exclude: | |
143 | continue |
|
148 | continue | |
|
149 | ||||
|
150 | md = None | |||
144 | try: |
|
151 | try: | |
145 | data = formatter(obj) |
|
152 | data = formatter(obj) | |
146 | except: |
|
153 | except: | |
147 | # FIXME: log the exception |
|
154 | # FIXME: log the exception | |
148 | raise |
|
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 | if data is not None: |
|
161 | if data is not None: | |
150 | format_dict[format_type] = data |
|
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 | @property |
|
168 | @property | |
154 | def format_types(self): |
|
169 | def format_types(self): |
@@ -13,5 +13,4 b'' | |||||
13 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
14 |
|
14 | |||
15 | from IPython.core.display import * |
|
15 | from IPython.core.display import * | |
16 | from IPython.core.displaypub import * |
|
|||
17 | from IPython.lib.display import * |
|
16 | from IPython.lib.display import * |
@@ -178,9 +178,11 b' var IPython = (function (IPython) {' | |||||
178 | json.stream = content.name; |
|
178 | json.stream = content.name; | |
179 | } else if (msg_type === "display_data") { |
|
179 | } else if (msg_type === "display_data") { | |
180 | json = this.convert_mime_types(json, content.data); |
|
180 | json = this.convert_mime_types(json, content.data); | |
|
181 | json.metadata = this.convert_mime_types({}, content.metadata); | |||
181 | } else if (msg_type === "pyout") { |
|
182 | } else if (msg_type === "pyout") { | |
182 | json.prompt_number = content.execution_count; |
|
183 | json.prompt_number = content.execution_count; | |
183 | json = this.convert_mime_types(json, content.data); |
|
184 | json = this.convert_mime_types(json, content.data); | |
|
185 | json.metadata = this.convert_mime_types({}, content.metadata); | |||
184 | } else if (msg_type === "pyerr") { |
|
186 | } else if (msg_type === "pyerr") { | |
185 | json.ename = content.ename; |
|
187 | json.ename = content.ename; | |
186 | json.evalue = content.evalue; |
|
188 | json.evalue = content.evalue; | |
@@ -273,7 +275,7 b' var IPython = (function (IPython) {' | |||||
273 | } |
|
275 | } | |
274 | s = s + '\n'; |
|
276 | s = s + '\n'; | |
275 | var toinsert = this.create_output_area(); |
|
277 | var toinsert = this.create_output_area(); | |
276 | this.append_text(s, toinsert); |
|
278 | this.append_text(s, {}, toinsert); | |
277 | this.element.append(toinsert); |
|
279 | this.element.append(toinsert); | |
278 | } |
|
280 | } | |
279 | }; |
|
281 | }; | |
@@ -310,7 +312,7 b' var IPython = (function (IPython) {' | |||||
310 |
|
312 | |||
311 | // If we got here, attach a new div |
|
313 | // If we got here, attach a new div | |
312 | var toinsert = this.create_output_area(); |
|
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 | this.element.append(toinsert); |
|
316 | this.element.append(toinsert); | |
315 | }; |
|
317 | }; | |
316 |
|
318 | |||
@@ -331,12 +333,16 b' var IPython = (function (IPython) {' | |||||
331 | for(var type_i in OutputArea.display_order){ |
|
333 | for(var type_i in OutputArea.display_order){ | |
332 | var type = OutputArea.display_order[type_i]; |
|
334 | var type = OutputArea.display_order[type_i]; | |
333 | if(json[type] != undefined ){ |
|
335 | if(json[type] != undefined ){ | |
|
336 | var md = {}; | |||
|
337 | if (json.metadata && json.metadata[type]) { | |||
|
338 | md = json.metadata[type]; | |||
|
339 | }; | |||
334 | if(type == 'javascript'){ |
|
340 | if(type == 'javascript'){ | |
335 | if (dynamic) { |
|
341 | if (dynamic) { | |
336 | this.append_javascript(json.javascript, element, dynamic); |
|
342 | this.append_javascript(json.javascript, md, element, dynamic); | |
337 | } |
|
343 | } | |
338 | } else { |
|
344 | } else { | |
339 | this['append_'+type](json[type], element); |
|
345 | this['append_'+type](json[type], md, element); | |
340 | } |
|
346 | } | |
341 | return; |
|
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 | var toinsert = $("<div/>").addClass("output_subarea output_html rendered_html"); |
|
354 | var toinsert = $("<div/>").addClass("output_subarea output_html rendered_html"); | |
349 | toinsert.append(html); |
|
355 | toinsert.append(html); | |
350 | element.append(toinsert); |
|
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 | // We just eval the JS code, element appears in the local scope. |
|
361 | // We just eval the JS code, element appears in the local scope. | |
356 | var element = $("<div/>").addClass("output_subarea"); |
|
362 | var element = $("<div/>").addClass("output_subarea"); | |
357 | container.append(element); |
|
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 | var toinsert = $("<div/>").addClass("output_subarea output_text"); |
|
385 | var toinsert = $("<div/>").addClass("output_subarea output_text"); | |
380 | // escape ANSI & HTML specials in plaintext: |
|
386 | // escape ANSI & HTML specials in plaintext: | |
381 | data = utils.fixConsole(data); |
|
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 | var toinsert = $("<div/>").addClass("output_subarea output_svg"); |
|
399 | var toinsert = $("<div/>").addClass("output_subarea output_svg"); | |
394 | toinsert.append(svg); |
|
400 | toinsert.append(svg); | |
395 | element.append(toinsert); |
|
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 | var toinsert = $("<div/>").addClass("output_subarea output_png"); |
|
433 | var toinsert = $("<div/>").addClass("output_subarea output_png"); | |
428 | var img = $("<img/>").attr('src','data:image/png;base64,'+png); |
|
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 | this._dblclick_to_reset_size(img); |
|
441 | this._dblclick_to_reset_size(img); | |
430 | toinsert.append(img); |
|
442 | toinsert.append(img); | |
431 | element.append(toinsert); |
|
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 | var toinsert = $("<div/>").addClass("output_subarea output_jpeg"); |
|
448 | var toinsert = $("<div/>").addClass("output_subarea output_jpeg"); | |
437 | var img = $("<img/>").attr('src','data:image/jpeg;base64,'+jpeg); |
|
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 | this._dblclick_to_reset_size(img); |
|
456 | this._dblclick_to_reset_size(img); | |
439 | toinsert.append(img); |
|
457 | toinsert.append(img); | |
440 | element.append(toinsert); |
|
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 | // This method cannot do the typesetting because the latex first has to |
|
463 | // This method cannot do the typesetting because the latex first has to | |
446 | // be on the page. |
|
464 | // be on the page. | |
447 | var toinsert = $("<div/>").addClass("output_subarea output_latex"); |
|
465 | var toinsert = $("<div/>").addClass("output_subarea output_latex"); |
@@ -52,8 +52,9 b' class ZMQShellDisplayHook(DisplayHook):' | |||||
52 | """Write the output prompt.""" |
|
52 | """Write the output prompt.""" | |
53 | self.msg['content']['execution_count'] = self.prompt_count |
|
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 | self.msg['content']['data'] = encode_images(format_dict) |
|
56 | self.msg['content']['data'] = encode_images(format_dict) | |
|
57 | self.msg['content']['metadata'] = md_dict | |||
57 |
|
58 | |||
58 | def finish_displayhook(self): |
|
59 | def finish_displayhook(self): | |
59 | """Finish up all displayhook activities.""" |
|
60 | """Finish up all displayhook activities.""" |
@@ -53,12 +53,18 b' def from_dict(d):' | |||||
53 | def new_output(output_type=None, output_text=None, output_png=None, |
|
53 | def new_output(output_type=None, output_text=None, output_png=None, | |
54 | output_html=None, output_svg=None, output_latex=None, output_json=None, |
|
54 | output_html=None, output_svg=None, output_latex=None, output_json=None, | |
55 | output_javascript=None, output_jpeg=None, prompt_number=None, |
|
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 | """Create a new code cell with input and output""" |
|
57 | """Create a new code cell with input and output""" | |
58 | output = NotebookNode() |
|
58 | output = NotebookNode() | |
59 | if output_type is not None: |
|
59 | if output_type is not None: | |
60 | output.output_type = unicode(output_type) |
|
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 | if output_type != 'pyerr': |
|
68 | if output_type != 'pyerr': | |
63 | if output_text is not None: |
|
69 | if output_text is not None: | |
64 | output.text = unicode(output_text) |
|
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 | if output_type == u'stream': |
|
98 | if output_type == u'stream': | |
93 | output.stream = 'stdout' if stream is None else unicode(stream) |
|
99 | output.stream = 'stdout' if stream is None else unicode(stream) | |
94 |
|
100 | |||
95 | return output |
|
101 | return output | |
96 |
|
102 | |||
97 |
|
103 |
@@ -808,8 +808,7 b' Message type: ``display_data``::' | |||||
808 |
|
808 | |||
809 | # The data dict contains key/value pairs, where the kids are MIME |
|
809 | # The data dict contains key/value pairs, where the kids are MIME | |
810 | # types and the values are the raw data of the representation in that |
|
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`` |
|
811 | # format. | |
812 | # MIME type which is used as a backup representation. |
|
|||
813 | 'data' : dict, |
|
812 | 'data' : dict, | |
814 |
|
813 | |||
815 | # Any metadata that describes the data |
|
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 | Raw Data Publication |
|
837 | Raw Data Publication | |
821 | -------------------- |
|
838 | -------------------- | |
822 |
|
839 |
General Comments 0
You need to be logged in to leave comments.
Login now