Show More
@@ -23,7 +23,7 b' from IPython.utils.py3compat import cast_unicode' | |||||
23 | from IPython.testing.skipdoctest import skip_doctest |
|
23 | from IPython.testing.skipdoctest import skip_doctest | |
24 |
|
24 | |||
25 | __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown', |
|
25 | __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown', | |
26 |
'display_svg', 'display_png', 'display_jpeg', ' |
|
26 | 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json', | |
27 | 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject', |
|
27 | 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject', | |
28 | 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'GeoJSON', 'Javascript', |
|
28 | 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'GeoJSON', 'Javascript', | |
29 | 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close', |
|
29 | 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close', | |
@@ -86,18 +86,7 b' def publish_display_data(data, metadata=None, source=None, *, transient=None, **' | |||||
86 | See the ``display_data`` message in the messaging documentation for |
|
86 | See the ``display_data`` message in the messaging documentation for | |
87 | more details about this message type. |
|
87 | more details about this message type. | |
88 |
|
88 | |||
89 | The following MIME types are currently implemented: |
|
89 | Keys of data and metadata can be any mime-type. | |
90 |
|
||||
91 | * text/plain |
|
|||
92 | * text/html |
|
|||
93 | * text/markdown |
|
|||
94 | * text/latex |
|
|||
95 | * application/json |
|
|||
96 | * application/javascript |
|
|||
97 | * image/png |
|
|||
98 | * image/jpeg |
|
|||
99 | * image/gif |
|
|||
100 | * image/svg+xml |
|
|||
101 |
|
90 | |||
102 | Parameters |
|
91 | Parameters | |
103 | ---------- |
|
92 | ---------- | |
@@ -257,11 +246,11 b' def display(*objs, include=None, exclude=None, metadata=None, transient=None, di' | |||||
257 | - `_repr_json_`: return a JSONable dict |
|
246 | - `_repr_json_`: return a JSONable dict | |
258 | - `_repr_jpeg_`: return raw JPEG data |
|
247 | - `_repr_jpeg_`: return raw JPEG data | |
259 | - `_repr_png_`: return raw PNG data |
|
248 | - `_repr_png_`: return raw PNG data | |
260 | - `_repr_gif_`: return raw GIF data |
|
|||
261 | - `_repr_svg_`: return raw SVG data as a string |
|
249 | - `_repr_svg_`: return raw SVG data as a string | |
262 | - `_repr_latex_`: return LaTeX commands in a string surrounded by "$". |
|
250 | - `_repr_latex_`: return LaTeX commands in a string surrounded by "$". | |
263 | - `_repr_mimebundle_`: return a full mimebundle containing the mapping |
|
251 | - `_repr_mimebundle_`: return a full mimebundle containing the mapping | |
264 | from all mimetypes to data |
|
252 | from all mimetypes to data. | |
|
253 | Use this for any mime-type not listed above. | |||
265 |
|
254 | |||
266 | When you are directly writing your own classes, you can adapt them for |
|
255 | When you are directly writing your own classes, you can adapt them for | |
267 | display in IPython by following the above approach. But in practice, you |
|
256 | display in IPython by following the above approach. But in practice, you | |
@@ -496,22 +485,6 b' def display_jpeg(*objs, **kwargs):' | |||||
496 | Metadata to be associated with the specific mimetype output. |
|
485 | Metadata to be associated with the specific mimetype output. | |
497 | """ |
|
486 | """ | |
498 | _display_mimetype('image/jpeg', objs, **kwargs) |
|
487 | _display_mimetype('image/jpeg', objs, **kwargs) | |
499 |
|
||||
500 | def display_gif(*objs, **kwargs): |
|
|||
501 | """Display the GIF representation of an object. |
|
|||
502 |
|
||||
503 | Parameters |
|
|||
504 | ---------- |
|
|||
505 | objs : tuple of objects |
|
|||
506 | The Python objects to display, or if raw=True raw gif data to |
|
|||
507 | display. |
|
|||
508 | raw : bool |
|
|||
509 | Are the data objects raw data or Python objects that need to be |
|
|||
510 | formatted before display? [default: False] |
|
|||
511 | metadata : dict (optional) |
|
|||
512 | Metadata to be associated with the specific mimetype output. |
|
|||
513 | """ |
|
|||
514 | _display_mimetype('image/gif', objs, **kwargs) |
|
|||
515 |
|
488 | |||
516 |
|
489 | |||
517 | def display_latex(*objs, **kwargs): |
|
490 | def display_latex(*objs, **kwargs): | |
@@ -984,11 +957,12 b' def _jpegxy(data):' | |||||
984 | idx += 2 |
|
957 | idx += 2 | |
985 |
|
958 | |||
986 | return struct.unpack('>HH', data[iSOF+5:iSOF+9]) |
|
959 | return struct.unpack('>HH', data[iSOF+5:iSOF+9]) | |
987 |
|
960 | |||
988 | def _gifxy(data): |
|
961 | def _gifxy(data): | |
989 | """read the (width, height) from a GIF header""" |
|
962 | """read the (width, height) from a GIF header""" | |
990 | return struct.unpack('<HH', data[6:10]) |
|
963 | return struct.unpack('<HH', data[6:10]) | |
991 |
|
964 | |||
|
965 | ||||
992 | class Image(DisplayObject): |
|
966 | class Image(DisplayObject): | |
993 |
|
967 | |||
994 | _read_flags = 'rb' |
|
968 | _read_flags = 'rb' | |
@@ -996,6 +970,11 b' class Image(DisplayObject):' | |||||
996 | _FMT_PNG = u'png' |
|
970 | _FMT_PNG = u'png' | |
997 | _FMT_GIF = u'gif' |
|
971 | _FMT_GIF = u'gif' | |
998 | _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF] |
|
972 | _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF] | |
|
973 | _MIMETYPES = { | |||
|
974 | _FMT_PNG: 'image/png', | |||
|
975 | _FMT_JPEG: 'image/jpeg', | |||
|
976 | _FMT_GIF: 'image/gif', | |||
|
977 | } | |||
999 |
|
978 | |||
1000 | def __init__(self, data=None, url=None, filename=None, format=None, |
|
979 | def __init__(self, data=None, url=None, filename=None, format=None, | |
1001 | embed=None, width=None, height=None, retina=False, |
|
980 | embed=None, width=None, height=None, retina=False, | |
@@ -1097,12 +1076,15 b' class Image(DisplayObject):' | |||||
1097 | if format.lower() == 'jpg': |
|
1076 | if format.lower() == 'jpg': | |
1098 | # jpg->jpeg |
|
1077 | # jpg->jpeg | |
1099 | format = self._FMT_JPEG |
|
1078 | format = self._FMT_JPEG | |
1100 |
|
1079 | |||
1101 | self.format = format.lower() |
|
1080 | self.format = format.lower() | |
1102 | self.embed = embed if embed is not None else (url is None) |
|
1081 | self.embed = embed if embed is not None else (url is None) | |
1103 |
|
1082 | |||
1104 | if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS: |
|
1083 | if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS: | |
1105 | raise ValueError("Cannot embed the '%s' image format" % (self.format)) |
|
1084 | raise ValueError("Cannot embed the '%s' image format" % (self.format)) | |
|
1085 | if self.embed: | |||
|
1086 | self._mimetype = self._MIMETYPES.get(self.format) | |||
|
1087 | ||||
1106 | self.width = width |
|
1088 | self.width = width | |
1107 | self.height = height |
|
1089 | self.height = height | |
1108 | self.retina = retina |
|
1090 | self.retina = retina | |
@@ -1119,6 +1101,7 b' class Image(DisplayObject):' | |||||
1119 | if retina: |
|
1101 | if retina: | |
1120 | self._retina_shape() |
|
1102 | self._retina_shape() | |
1121 |
|
1103 | |||
|
1104 | ||||
1122 | def _retina_shape(self): |
|
1105 | def _retina_shape(self): | |
1123 | """load pixel-doubled width and height from image data""" |
|
1106 | """load pixel-doubled width and height from image data""" | |
1124 | if not self.embed: |
|
1107 | if not self.embed: | |
@@ -1158,7 +1141,21 b' class Image(DisplayObject):' | |||||
1158 | klass=klass, |
|
1141 | klass=klass, | |
1159 | ) |
|
1142 | ) | |
1160 |
|
1143 | |||
1161 | def _data_and_metadata(self): |
|
1144 | def _repr_mimebundle_(self, include=None, exclude=None): | |
|
1145 | """Return the image as a mimebundle | |||
|
1146 | ||||
|
1147 | Any new mimetype support should be implemented here. | |||
|
1148 | """ | |||
|
1149 | if self.embed: | |||
|
1150 | mimetype = self._mimetype | |||
|
1151 | data, metadata = self._data_and_metadata(always_both=True) | |||
|
1152 | if metadata: | |||
|
1153 | metadata = {mimetype: metadata} | |||
|
1154 | return {mimetype: data}, metadata | |||
|
1155 | else: | |||
|
1156 | return {'text/html': self._repr_html_()} | |||
|
1157 | ||||
|
1158 | def _data_and_metadata(self, always_both=False): | |||
1162 | """shortcut for returning metadata with shape information, if defined""" |
|
1159 | """shortcut for returning metadata with shape information, if defined""" | |
1163 | md = {} |
|
1160 | md = {} | |
1164 | if self.metadata: |
|
1161 | if self.metadata: | |
@@ -1169,7 +1166,7 b' class Image(DisplayObject):' | |||||
1169 | md['height'] = self.height |
|
1166 | md['height'] = self.height | |
1170 | if self.unconfined: |
|
1167 | if self.unconfined: | |
1171 | md['unconfined'] = self.unconfined |
|
1168 | md['unconfined'] = self.unconfined | |
1172 | if md: |
|
1169 | if md or always_both: | |
1173 | return self.data, md |
|
1170 | return self.data, md | |
1174 | else: |
|
1171 | else: | |
1175 | return self.data |
|
1172 | return self.data | |
@@ -1179,16 +1176,13 b' class Image(DisplayObject):' | |||||
1179 | return self._data_and_metadata() |
|
1176 | return self._data_and_metadata() | |
1180 |
|
1177 | |||
1181 | def _repr_jpeg_(self): |
|
1178 | def _repr_jpeg_(self): | |
1182 |
if self.embed and |
|
1179 | if self.embed and self.format == self._FMT_JPEG: | |
1183 | return self._data_and_metadata() |
|
|||
1184 |
|
||||
1185 | def _repr_gif_(self): |
|
|||
1186 | if self.embed and self.format == self._FMT_GIF: |
|
|||
1187 | return self._data_and_metadata() |
|
1180 | return self._data_and_metadata() | |
1188 |
|
1181 | |||
1189 | def _find_ext(self, s): |
|
1182 | def _find_ext(self, s): | |
1190 | return s.split('.')[-1].lower() |
|
1183 | return s.split('.')[-1].lower() | |
1191 |
|
1184 | |||
|
1185 | ||||
1192 | class Video(DisplayObject): |
|
1186 | class Video(DisplayObject): | |
1193 |
|
1187 | |||
1194 | def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None): |
|
1188 | def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None): | |
@@ -1287,15 +1281,6 b' class Video(DisplayObject):' | |||||
1287 | # TODO |
|
1281 | # TODO | |
1288 | pass |
|
1282 | pass | |
1289 |
|
1283 | |||
1290 | def _repr_png_(self): |
|
|||
1291 | # TODO |
|
|||
1292 | pass |
|
|||
1293 | def _repr_jpeg_(self): |
|
|||
1294 | # TODO |
|
|||
1295 | pass |
|
|||
1296 | def _repr_gif_(self): |
|
|||
1297 | # TODO |
|
|||
1298 | pass |
|
|||
1299 |
|
1284 | |||
1300 | def clear_output(wait=False): |
|
1285 | def clear_output(wait=False): | |
1301 | """Clear the output of the current cell receiving output. |
|
1286 | """Clear the output of the current cell receiving output. |
@@ -74,7 +74,6 b' class DisplayFormatter(Configurable):' | |||||
74 | MarkdownFormatter, |
|
74 | MarkdownFormatter, | |
75 | SVGFormatter, |
|
75 | SVGFormatter, | |
76 | PNGFormatter, |
|
76 | PNGFormatter, | |
77 | GIFFormatter, |
|
|||
78 | PDFFormatter, |
|
77 | PDFFormatter, | |
79 | JPEGFormatter, |
|
78 | JPEGFormatter, | |
80 | LatexFormatter, |
|
79 | LatexFormatter, | |
@@ -780,24 +779,6 b' class JPEGFormatter(BaseFormatter):' | |||||
780 | _return_type = (bytes, str) |
|
779 | _return_type = (bytes, str) | |
781 |
|
780 | |||
782 |
|
781 | |||
783 | class GIFFormatter(BaseFormatter): |
|
|||
784 | """A PNG formatter. |
|
|||
785 |
|
||||
786 | To define the callables that compute the GIF representation of your |
|
|||
787 | objects, define a :meth:`_repr_gif_` method or use the :meth:`for_type` |
|
|||
788 | or :meth:`for_type_by_name` methods to register functions that handle |
|
|||
789 | this. |
|
|||
790 |
|
||||
791 | The return value of this formatter should be raw GIF data, *not* |
|
|||
792 | base64 encoded. |
|
|||
793 | """ |
|
|||
794 | format_type = Unicode('image/gif') |
|
|||
795 |
|
||||
796 | print_method = ObjectName('_repr_gif_') |
|
|||
797 |
|
||||
798 | _return_type = (bytes, str) |
|
|||
799 |
|
||||
800 |
|
||||
801 | class LatexFormatter(BaseFormatter): |
|
782 | class LatexFormatter(BaseFormatter): | |
802 | """A LaTeX formatter. |
|
783 | """A LaTeX formatter. | |
803 |
|
784 | |||
@@ -977,10 +958,7 b' class MimeBundleFormatter(BaseFormatter):' | |||||
977 | method = get_real_method(obj, self.print_method) |
|
958 | method = get_real_method(obj, self.print_method) | |
978 |
|
959 | |||
979 | if method is not None: |
|
960 | if method is not None: | |
980 | d = {} |
|
961 | return method(include=include, exclude=exclude) | |
981 | d['include'] = include |
|
|||
982 | d['exclude'] = exclude |
|
|||
983 | return method(**d) |
|
|||
984 | return None |
|
962 | return None | |
985 | else: |
|
963 | else: | |
986 | return None |
|
964 | return None | |
@@ -992,7 +970,6 b' FormatterABC.register(HTMLFormatter)' | |||||
992 | FormatterABC.register(MarkdownFormatter) |
|
970 | FormatterABC.register(MarkdownFormatter) | |
993 | FormatterABC.register(SVGFormatter) |
|
971 | FormatterABC.register(SVGFormatter) | |
994 | FormatterABC.register(PNGFormatter) |
|
972 | FormatterABC.register(PNGFormatter) | |
995 | FormatterABC.register(GIFFormatter) |
|
|||
996 | FormatterABC.register(PDFFormatter) |
|
973 | FormatterABC.register(PDFFormatter) | |
997 | FormatterABC.register(JPEGFormatter) |
|
974 | FormatterABC.register(JPEGFormatter) | |
998 | FormatterABC.register(LatexFormatter) |
|
975 | FormatterABC.register(LatexFormatter) | |
@@ -1007,19 +984,6 b' def format_display_data(obj, include=None, exclude=None):' | |||||
1007 |
|
984 | |||
1008 | By default all format types will be computed. |
|
985 | By default all format types will be computed. | |
1009 |
|
986 | |||
1010 | The following MIME types are currently implemented: |
|
|||
1011 |
|
||||
1012 | * text/plain |
|
|||
1013 | * text/html |
|
|||
1014 | * text/markdown |
|
|||
1015 | * text/latex |
|
|||
1016 | * application/json |
|
|||
1017 | * application/javascript |
|
|||
1018 | * application/pdf |
|
|||
1019 | * image/png |
|
|||
1020 | * image/jpeg |
|
|||
1021 | * image/svg+xml |
|
|||
1022 |
|
||||
1023 | Parameters |
|
987 | Parameters | |
1024 | ---------- |
|
988 | ---------- | |
1025 | obj : object |
|
989 | obj : object |
@@ -32,6 +32,15 b' def test_image_size():' | |||||
32 | nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_()) |
|
32 | nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_()) | |
33 |
|
33 | |||
34 |
|
34 | |||
|
35 | def test_image_mimes(): | |||
|
36 | fmt = get_ipython().display_formatter.format | |||
|
37 | for format in display.Image._ACCEPTABLE_EMBEDDINGS: | |||
|
38 | mime = display.Image._MIMETYPES[format] | |||
|
39 | img = display.Image(b'garbage', format=format) | |||
|
40 | data, metadata = fmt(img) | |||
|
41 | nt.assert_equal(sorted(data), sorted([mime, 'text/plain'])) | |||
|
42 | ||||
|
43 | ||||
35 | def test_geojson(): |
|
44 | def test_geojson(): | |
36 |
|
45 | |||
37 | gj = display.GeoJSON(data={ |
|
46 | gj = display.GeoJSON(data={ | |
@@ -361,3 +370,4 b' def test_display_handle():' | |||||
361 | }, |
|
370 | }, | |
362 | 'update': True, |
|
371 | 'update': True, | |
363 | }) |
|
372 | }) | |
|
373 |
@@ -30,7 +30,10 b' class RichOutput(object):' | |||||
30 | return data, self.metadata[mime] |
|
30 | return data, self.metadata[mime] | |
31 | else: |
|
31 | else: | |
32 | return data |
|
32 | return data | |
33 |
|
33 | |||
|
34 | def _repr_mimebundle_(self, include=None, exclude=None): | |||
|
35 | return self.data, self.metadata | |||
|
36 | ||||
34 | def _repr_html_(self): |
|
37 | def _repr_html_(self): | |
35 | return self._repr_mime_("text/html") |
|
38 | return self._repr_mime_("text/html") | |
36 |
|
39 | |||
@@ -48,9 +51,6 b' class RichOutput(object):' | |||||
48 |
|
51 | |||
49 | def _repr_jpeg_(self): |
|
52 | def _repr_jpeg_(self): | |
50 | return self._repr_mime_("image/jpeg") |
|
53 | return self._repr_mime_("image/jpeg") | |
51 |
|
||||
52 | def _repr_gif_(self): |
|
|||
53 | return self._repr_mime_("image/gif") |
|
|||
54 |
|
54 | |||
55 | def _repr_svg_(self): |
|
55 | def _repr_svg_(self): | |
56 | return self._repr_mime_("image/svg+xml") |
|
56 | return self._repr_mime_("image/svg+xml") |
General Comments 0
You need to be logged in to leave comments.
Login now