##// END OF EJS Templates
Adding PDFFormatter and kernel side handling of PDF display data.
Brian E. Granger -
Show More
@@ -271,6 +271,24 b' def display_javascript(*objs, **kwargs):'
271 271 """
272 272 _display_mimetype('application/javascript', objs, **kwargs)
273 273
274
275 def display_pdf(*objs, **kwargs):
276 """Display the PDF representation of an object.
277
278 Parameters
279 ----------
280 objs : tuple of objects
281 The Python objects to display, or if raw=True raw javascript data to
282 display.
283 raw : bool
284 Are the data objects raw data or Python objects that need to be
285 formatted before display? [default: False]
286 metadata : dict (optional)
287 Metadata to be associated with the specific mimetype output.
288 """
289 _display_mimetype('application/pdf', objs, **kwargs)
290
291
274 292 #-----------------------------------------------------------------------------
275 293 # Smart classes
276 294 #-----------------------------------------------------------------------------
@@ -93,6 +93,7 b' class DisplayFormatter(Configurable):'
93 93 HTMLFormatter,
94 94 SVGFormatter,
95 95 PNGFormatter,
96 PDFFormatter,
96 97 JPEGFormatter,
97 98 LatexFormatter,
98 99 JSONFormatter,
@@ -116,6 +117,7 b' class DisplayFormatter(Configurable):'
116 117 * text/latex
117 118 * application/json
118 119 * application/javascript
120 * application/pdf
119 121 * image/png
120 122 * image/jpeg
121 123 * image/svg+xml
@@ -766,11 +768,29 b' class JavascriptFormatter(BaseFormatter):'
766 768
767 769 print_method = ObjectName('_repr_javascript_')
768 770
771
772 class PDFFormatter(BaseFormatter):
773 """A PDF formatter.
774
775 To defined the callables that compute to PDF representation of your
776 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
777 or :meth:`for_type_by_name` methods to register functions that handle
778 this.
779
780 The return value of this formatter should be raw PDF data, *not*
781 base64 encoded.
782 """
783 format_type = Unicode('application/pdf')
784
785 print_method = ObjectName('_repr_pdf_')
786
787
769 788 FormatterABC.register(BaseFormatter)
770 789 FormatterABC.register(PlainTextFormatter)
771 790 FormatterABC.register(HTMLFormatter)
772 791 FormatterABC.register(SVGFormatter)
773 792 FormatterABC.register(PNGFormatter)
793 FormatterABC.register(PDFFormatter)
774 794 FormatterABC.register(JPEGFormatter)
775 795 FormatterABC.register(LatexFormatter)
776 796 FormatterABC.register(JSONFormatter)
@@ -789,6 +809,7 b' def format_display_data(obj, include=None, exclude=None):'
789 809 * text/latex
790 810 * application/json
791 811 * application/javascript
812 * application/pdf
792 813 * image/png
793 814 * image/jpeg
794 815 * image/svg+xml
@@ -8,7 +8,9 b' except:'
8 8 numpy = None
9 9 import nose.tools as nt
10 10
11 from IPython.core.formatters import PlainTextFormatter, HTMLFormatter, _mod_name_key
11 from IPython.core.formatters import (
12 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key
13 )
12 14 from IPython.utils.io import capture_output
13 15
14 16 class A(object):
@@ -279,4 +281,11 b' def test_warn_error_pretty_method():'
279 281 nt.assert_in("text/plain", captured.stderr)
280 282 nt.assert_in("argument", captured.stderr)
281 283
284 class MakePDF(object):
285 def _repr_pdf_(self):
286 return 'PDF'
282 287
288 def test_pdf_formatter():
289 pdf = MakePDF()
290 f = PDFFormatter()
291 nt.assert_equal(f(pdf), 'PDF')
@@ -119,6 +119,8 b" PNG64 = b'iVBORw0KG'"
119 119 JPEG = b'\xff\xd8'
120 120 # front of JPEG base64-encoded
121 121 JPEG64 = b'/9'
122 # front of PDF base64-encoded
123 PDF64 = b'JVBER'
122 124
123 125 def encode_images(format_dict):
124 126 """b64-encodes images in a displaypub format dict
@@ -136,7 +138,7 b' def encode_images(format_dict):'
136 138
137 139 format_dict : dict
138 140 A copy of the same dictionary,
139 but binary image data ('image/png' or 'image/jpeg')
141 but binary image data ('image/png', 'image/jpeg' or 'application/pdf')
140 142 is base64-encoded.
141 143
142 144 """
@@ -156,6 +158,13 b' def encode_images(format_dict):'
156 158 jpegdata = encodebytes(jpegdata)
157 159 encoded['image/jpeg'] = jpegdata.decode('ascii')
158 160
161 pdfdata = format_dict.get('application/pdf')
162 if isinstance(pdfdata, bytes):
163 # make sure we don't double-encode
164 if not pdfdata.startswith(PDF64):
165 pdfdata = encodebytes(pdfdata)
166 encoded['application/pdf'] = pdfdata.decode('ascii')
167
159 168 return encoded
160 169
161 170
@@ -69,10 +69,12 b' def test_encode_images():'
69 69 # invalid data, but the header and footer are from real files
70 70 pngdata = b'\x89PNG\r\n\x1a\nblahblahnotactuallyvalidIEND\xaeB`\x82'
71 71 jpegdata = b'\xff\xd8\xff\xe0\x00\x10JFIFblahblahjpeg(\xa0\x0f\xff\xd9'
72 pdfdata = b'%PDF-1.\ntrailer<</Root<</Pages<</Kids[<</MediaBox[0 0 3 3]>>]>>>>>>'
72 73
73 74 fmt = {
74 75 'image/png' : pngdata,
75 76 'image/jpeg' : jpegdata,
77 'application/pdf' : pdfdata
76 78 }
77 79 encoded = encode_images(fmt)
78 80 for key, value in iteritems(fmt):
General Comments 0
You need to be logged in to leave comments. Login now