2018-06-02 17:55:12 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
r "reflect"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/cosmos72/gomacro/imports"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Support an interface similar - but not identical - to the IPython (canonical Jupyter kernel).
|
|
|
|
// See http://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.display
|
|
|
|
// for a good overview of the support types. Note: This is missing _repr_markdown_ and _repr_javascript_.
|
|
|
|
|
|
|
|
const (
|
2018-06-04 21:55:35 +02:00
|
|
|
MIMETypeHTML = "text/html"
|
|
|
|
MIMETypeJavaScript = "application/javascript"
|
|
|
|
MIMETypeJPEG = "image/jpeg"
|
|
|
|
MIMETypeJSON = "application/json"
|
|
|
|
MIMETypeLatex = "text/latex"
|
|
|
|
MIMETypeMarkdown = "text/markdown"
|
|
|
|
MIMETypePNG = "image/png"
|
|
|
|
MIMETypePDF = "application/pdf"
|
|
|
|
MIMETypeSVG = "image/svg+xml"
|
2018-06-02 17:55:12 +02:00
|
|
|
)
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
// injected as placeholder in the interpreter, it's then replaced at runtime
|
|
|
|
// by a closure that knows how to talk with Jupyter
|
|
|
|
func stubDisplay(DisplayData) error {
|
|
|
|
return errors.New("cannot display: connection with Jupiter not registered")
|
|
|
|
}
|
|
|
|
|
2018-06-02 17:55:12 +02:00
|
|
|
// TODO handle the metadata
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func MakeDisplayData(mimeType string, data interface{}) DisplayData {
|
|
|
|
return DisplayData{
|
|
|
|
Data: BundledMIMEData{
|
|
|
|
"text/plain": fmt.Sprint(data),
|
|
|
|
mimeType: data,
|
|
|
|
},
|
|
|
|
}
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func MakeDisplayData3(mimeType string, plaintext string, data interface{}) DisplayData {
|
|
|
|
return DisplayData{
|
|
|
|
Data: BundledMIMEData{
|
|
|
|
"text/plain": plaintext,
|
2018-06-02 17:55:12 +02:00
|
|
|
mimeType: data,
|
2018-06-04 21:55:35 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Bytes(mimeType string, bytes []byte) DisplayData {
|
|
|
|
return MakeDisplayData3(mimeType, mimeType, bytes)
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func HTML(html string) DisplayData {
|
|
|
|
return MakeDisplayData(MIMETypeHTML, html)
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func JSON(json map[string]interface{}) DisplayData {
|
|
|
|
return MakeDisplayData(MIMETypeJSON, json)
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func JavaScript(javascript string) DisplayData {
|
|
|
|
return MakeDisplayData(MIMETypeJavaScript, javascript)
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func JPEG(jpeg []byte) DisplayData {
|
|
|
|
return MakeDisplayData3(MIMETypeJPEG, "jpeg image", jpeg) // []byte are encoded as base64 by the marshaller
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func Latex(latex string) DisplayData {
|
|
|
|
return MakeDisplayData3(MIMETypeLatex, latex, "$"+strings.Trim(latex, "$")+"$")
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func Markdown(markdown string) DisplayData {
|
|
|
|
return MakeDisplayData(MIMETypeMarkdown, markdown)
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func Math(latex string) DisplayData {
|
|
|
|
return MakeDisplayData3(MIMETypeLatex, latex, "$$"+strings.Trim(latex, "$")+"$$")
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func PDF(pdf []byte) DisplayData {
|
|
|
|
return MakeDisplayData3(MIMETypePDF, "pdf document", pdf) // []byte are encoded as base64 by the marshaller
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func PNG(png []byte) DisplayData {
|
|
|
|
return MakeDisplayData3(MIMETypePNG, "png image", png) // []byte are encoded as base64 by the marshaller
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func String(mimeType string, s string) DisplayData {
|
|
|
|
return MakeDisplayData(mimeType, s)
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
func SVG(svg string) DisplayData {
|
|
|
|
return MakeDisplayData(MIMETypeSVG, svg)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MIME encapsulates the data and metadata into a DisplayData.
|
|
|
|
// The 'data' map is expected to contain at least one {key,value} pair,
|
|
|
|
// with value being a string, []byte or some other JSON serializable representation,
|
|
|
|
// and key equal to the MIME type of such value.
|
|
|
|
// The exact structure of value is determined by what the frontend expects.
|
|
|
|
// Some easier-to-use functions for common formats supported by the Jupyter frontend
|
2018-06-02 17:55:12 +02:00
|
|
|
// are provided by the various functions above.
|
2018-06-04 21:55:35 +02:00
|
|
|
func MIME(data, metadata map[string]interface{}) DisplayData {
|
|
|
|
return DisplayData{data, metadata, nil}
|
2018-06-02 17:55:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// prepare imports.Package for interpreted code
|
|
|
|
var display = imports.Package{
|
|
|
|
Binds: map[string]r.Value{
|
2018-06-04 21:55:35 +02:00
|
|
|
"Bytes": r.ValueOf(Bytes),
|
|
|
|
"HTML": r.ValueOf(HTML),
|
|
|
|
"Image": r.ValueOf(Image),
|
|
|
|
"JPEG": r.ValueOf(JPEG),
|
|
|
|
"JSON": r.ValueOf(JSON),
|
|
|
|
"JavaScript": r.ValueOf(JavaScript),
|
|
|
|
"Latex": r.ValueOf(Latex),
|
|
|
|
"MakeDisplayData": r.ValueOf(MakeDisplayData),
|
|
|
|
"MakeDisplayData3": r.ValueOf(MakeDisplayData3),
|
|
|
|
"Markdown": r.ValueOf(Markdown),
|
|
|
|
"Math": r.ValueOf(Math),
|
|
|
|
"MIME": r.ValueOf(MIME),
|
|
|
|
"MIMETypeHTML": r.ValueOf(MIMETypeHTML),
|
|
|
|
"MIMETypeJavaScript": r.ValueOf(MIMETypeJavaScript),
|
|
|
|
"MIMETypeJPEG": r.ValueOf(MIMETypeJPEG),
|
|
|
|
"MIMETypeJSON": r.ValueOf(MIMETypeJSON),
|
|
|
|
"MIMETypeLatex": r.ValueOf(MIMETypeLatex),
|
|
|
|
"MIMETypeMarkdown": r.ValueOf(MIMETypeMarkdown),
|
|
|
|
"MIMETypePDF": r.ValueOf(MIMETypePDF),
|
|
|
|
"MIMETypePNG": r.ValueOf(MIMETypePNG),
|
|
|
|
"MIMETypeSVG": r.ValueOf(MIMETypeSVG),
|
|
|
|
"PDF": r.ValueOf(PDF),
|
|
|
|
"PNG": r.ValueOf(PNG),
|
|
|
|
"String": r.ValueOf(String),
|
|
|
|
"SVG": r.ValueOf(SVG),
|
|
|
|
},
|
|
|
|
Types: map[string]r.Type{
|
|
|
|
"BundledMIMEData": r.TypeOf((*BundledMIMEData)(nil)).Elem(),
|
|
|
|
"DisplayData": r.TypeOf((*DisplayData)(nil)).Elem(),
|
2018-06-02 17:55:12 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2018-06-04 21:55:35 +02:00
|
|
|
// allow importing "display" and "github.com/gopherdata/gophernotes" packages
|
2018-06-02 17:55:12 +02:00
|
|
|
func init() {
|
|
|
|
imports.Packages["display"] = display
|
|
|
|
imports.Packages["github.com/gopherdata/gophernotes"] = display
|
|
|
|
}
|