11package main
22
33import (
4+ "bytes"
45 "errors"
56 "fmt"
7+ "io"
8+ "io/ioutil"
9+ "net/http"
610 r "reflect"
711 "strings"
812
@@ -33,13 +37,59 @@ func stubDisplay(Data) error {
3337
3438// TODO handle the metadata
3539
40+ func read (data interface {}) ([]byte , string ) {
41+ var b []byte
42+ var s string
43+ switch x := data .(type ) {
44+ case string :
45+ s = x
46+ case []byte :
47+ b = x
48+ case io.Reader :
49+ bb , err := ioutil .ReadAll (x )
50+ if err != nil {
51+ panic (err )
52+ }
53+ b = bb
54+ case io.WriterTo :
55+ var buf bytes.Buffer
56+ x .WriteTo (& buf )
57+ b = buf .Bytes ()
58+ default :
59+ panic (errors .New (fmt .Sprintf ("unsupported type, cannot display: expecting string, []byte, io.Reader or io.WriterTo, found %T" , data )))
60+ }
61+ if len (s ) == 0 {
62+ s = fmt .Sprint (data )
63+ }
64+ return b , s
65+ }
66+
67+ func Any (mimeType string , data interface {}) Data {
68+ b , s := read (data )
69+ if len (mimeType ) == 0 {
70+ mimeType = http .DetectContentType (b )
71+ }
72+ d := Data {
73+ Data : BundledMIMEData {
74+ "text/plain" : s ,
75+ },
76+ }
77+ if mimeType != "text/plain" {
78+ d .Data [mimeType ] = b
79+ }
80+ return d
81+ }
82+
3683func MakeData (mimeType string , data interface {}) Data {
37- return Data {
84+ d := Data {
3885 Data : BundledMIMEData {
39- "text/plain" : fmt .Sprint (data ),
40- mimeType : data ,
86+ mimeType : data ,
4187 },
4288 }
89+ if mimeType != "text/plain" {
90+ d .Data ["text/plain" ] = fmt .Sprint (data )
91+ }
92+ return d
4393}
4494
4595func MakeData3 (mimeType string , plaintext string , data interface {}) Data {
@@ -52,51 +102,82 @@ func MakeData3(mimeType string, plaintext string, data interface{}) Data {
52102}
53103
54104func Bytes (mimeType string , bytes []byte ) Data {
105+ if len (mimeType ) == 0 {
106+ mimeType = http .DetectContentType (bytes )
107+ }
55108 return MakeData3 (mimeType , mimeType , bytes )
56109}
57110
111+ func File (mimeType string , path string ) Data {
112+ bytes , err := ioutil .ReadFile (path )
113+ if err != nil {
114+ panic (err )
115+ }
116+ return Bytes (mimeType , bytes )
117+ }
118+
58119func HTML (html string ) Data {
59- return MakeData (MIMETypeHTML , html )
120+ return String (MIMETypeHTML , html )
60121}
61122
62123func JSON (json map [string ]interface {}) Data {
63124 return MakeData (MIMETypeJSON , json )
64125}
65126
66127func JavaScript (javascript string ) Data {
67- return MakeData (MIMETypeJavaScript , javascript )
128+ return String (MIMETypeJavaScript , javascript )
68129}
69130
70131func JPEG (jpeg []byte ) Data {
71- return MakeData3 (MIMETypeJPEG , " jpeg image" , jpeg ) // []byte are encoded as base64 by the marshaller
132+ return Bytes (MIMETypeJPEG , jpeg )
72133}
73134
74135func Latex (latex string ) Data {
75136 return MakeData3 (MIMETypeLatex , latex , "$" + strings .Trim (latex , "$" )+ "$" )
76137}
77138
78139func Markdown (markdown string ) Data {
79- return MakeData (MIMETypeMarkdown , markdown )
140+ return String (MIMETypeMarkdown , markdown )
80141}
81142
82143func Math (latex string ) Data {
83144 return MakeData3 (MIMETypeLatex , latex , "$$" + strings .Trim (latex , "$" )+ "$$" )
84145}
85146
86147func PDF (pdf []byte ) Data {
87- return MakeData3 (MIMETypePDF , " pdf document" , pdf ) // []byte are encoded as base64 by the marshaller
148+ return Bytes (MIMETypePDF , pdf )
88149}
89150
90151func PNG (png []byte ) Data {
91- return MakeData3 (MIMETypePNG , "png image" , png ) // []byte are encoded as base64 by the marshaller
152+ return Bytes (MIMETypePNG , png )
153+ }
154+
155+ func Reader (mimeType string , r io.Reader ) Data {
156+ b , err := ioutil .ReadAll (r )
157+ if err != nil {
158+ panic (err )
159+ }
160+ return Bytes (mimeType , b )
92161}
93162
94163func String (mimeType string , s string ) Data {
95- return MakeData (mimeType , s )
164+ if len (mimeType ) == 0 {
165+ mimeType = http .DetectContentType ([]byte (s ))
166+ }
167+ return MakeData3 (mimeType , s , s )
96168}
97169
98170func SVG (svg string ) Data {
99- return MakeData (MIMETypeSVG , svg )
171+ return String (MIMETypeSVG , svg )
172+ }
173+
174+ func WriterTo (mimeType string , to io.WriterTo ) Data {
175+ var buf bytes.Buffer
176+ _ , err := to .WriteTo (& buf )
177+ if err != nil {
178+ panic (err )
179+ }
180+ return Bytes (mimeType , buf .Bytes ())
100181}
101182
102183// MIME encapsulates the data and metadata into a Data.
@@ -113,7 +194,9 @@ func MIME(data, metadata map[string]interface{}) Data {
113194// prepare imports.Package for interpreted code
114195var display = imports.Package {
115196 Binds : map [string ]r.Value {
197+ "Any" : r .ValueOf (Any ),
116198 "Bytes" : r .ValueOf (Bytes ),
199+ "File" : r .ValueOf (File ),
117200 "HTML" : r .ValueOf (HTML ),
118201 "Image" : r .ValueOf (Image ),
119202 "JPEG" : r .ValueOf (JPEG ),
@@ -136,8 +219,10 @@ var display = imports.Package{
136219 "MIMETypeSVG" : r .ValueOf (MIMETypeSVG ),
137220 "PDF" : r .ValueOf (PDF ),
138221 "PNG" : r .ValueOf (PNG ),
222+ "Reader" : r .ValueOf (Reader ),
139223 "String" : r .ValueOf (String ),
140224 "SVG" : r .ValueOf (SVG ),
225+ "WriterTo" : r .ValueOf (WriterTo ),
141226 },
142227 Types : map [string ]r.Type {
143228 "BundledMIMEData" : r .TypeOf ((* BundledMIMEData )(nil )).Elem (),
0 commit comments