The display package

The package `github.com/gopherdata/gophernotes` is automatically imported with the name `display`.

It provides several functions that convert string, []byte, image.Image, io.Reader or io.WriterTo containing images, HTML, Markdown, LaTeX etc. to display.Data, which is shown graphically if returned at prompt. Example:


In [1]:
display.HTML(`<h1 style="color:green;">Hello, World</h1>`)


Out[1]:

Hello, World

Display function

Sometimes, returning `display.Data` at prompt is not handy - for example from deep inside functions or blocks, or because you want to display multiple data at once.

In such cases, you can call the function `Display(display.Data) error` to display the data immediately:


In [2]:
{
    Display(display.Markdown("* hello from markdown"))
    Display(display.Math(`e^{i\pi}+1=0`))
}


  • hello from markdown
$$e^{i\pi}+1=0$$

Images

The functions to display JPEG, PNG or SVG images and `image.Image` are:


In [3]:
import "image"
// in package "display"
func JPEG([]byte) error
func PNG([]byte) error
func SVG(string) error
func Image(image.Image) error

In [4]:
// Example: download and display a PNG
import (
    "net/http"
    "io/ioutil"
)
resp, err := http.Get("https://github.com/gopherdata/gophernotes/raw/master/files/gophernotes-logo.png")
bytes, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
display.PNG(bytes)


Out[4]:

In [5]:
// download and display an SVG
resp, err := http.Get("http://jupyter.org/assets/nav_logo.svg")
bytes, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
display.SVG(string(bytes))


Out[5]:
logo.svg Created using Figma 0.90

In [6]:
// download and display a JPEG
resp, err := http.Get("https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Gophercolor.jpg/320px-Gophercolor.jpg")
bytes, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
display.JPEG(bytes)


Out[6]:

Or, if you prefer to use image.Image:


In [7]:
import "image"
resp, err := http.Get("https://github.com/gopherdata/gophernotes/raw/master/files/gophernotes-logo.png")
img, ext, err := image.Decode(resp.Body)
resp.Body.Close()
display.Image(img)


Out[7]:

Reference

The list of available constants, types, and functions in package display is:


In [8]:
// in package "display"

const (
	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"
	MIMETypeText       = "text/plain"
)

// MIMEMap holds data that can be presented in multiple formats. The keys are MIME types
// and the values are the data formatted with respect to its MIME type.
// If a map does not contain a "text/plain" key with a string value,
// it will be set automatically.
type MIMEMap = map[string]interface{}

// Data is the exact structure sent to the front-end (Jupyter...) for displaying.
// It contains all the information needed to graphically show a value.
type Data = struct {
	Data      MIMEMap
	Metadata  MIMEMap
	Transient MIMEMap
}

// the functions Any() and Auto() accept string, []byte, image.Image, io.Reader, io.WriterTo
func Any(mimeType string, data interface{}) Data // if mimeType is empty, autodetects it
func Auto(data         interface{}) Data // autodetects mimeType

func HTML(html         string) Data
func JSON(json         map[string]interface{}) Data
func JavaScript(javascript string) Data
func JPEG(jpeg         []byte) Data
func Image(img         image.Image) Data
func Latex(latex       string) Data
func Markdown(markdown string) Data
func Math(latex        string) Data // LaTeX formula, without starting and ending '$$' 
func PDF(pdf           []byte) Data
func PNG(png           []byte) Data
func SVG(svg           string) Data

func MakeData(mimeType string, data interface{}) Data
func MakeData3(mimeType string, plaintext string, data interface{}) Data
func MIME(data, metadata MIMEMap) Data

Advanced usage

gophernotes also provides the following interfaces, mainly targeted at authors of Go libraries.

If the only non-nil value returned at prompt has type Data or implements one of these interfaces, it will be automatically rendered graphically


In [9]:
/**
 * general interface, allows libraries to fully specify
 * how their data is displayed by Jupyter.
 * Supports multiple MIME formats.
 *
 * Note that Data defined above is an alias:
 * libraries can implement Renderer without importing gophernotes
 */
type Renderer = interface {
	Render() Data
}

/**
 * simplified interface, allows libraries to specify
 * how their data is displayed by Jupyter.
 * Supports multiple MIME formats.
 *
 * Note that MIMEMap defined above is an alias:
 * libraries can implement SimpleRenderer without importing gophernotes
 */
type SimpleRenderer = interface {
	SimpleRender() MIMEMap
}

/**
 * specialized interfaces, each is dedicated to a specific MIME type.
 *
 * They are type aliases to emphasize that method signatures
 * are the only important thing, not the interface names.
 * Thus libraries can implement them without importing gophernotes
 */
type HTMLer = interface {
	HTML() string
}
type JavaScripter = interface {
	JavaScript() string
}
type JPEGer = interface {
	JPEG() []byte
}
type JSONer = interface {
	JSON() map[string]interface{}
}
type Latexer = interface {
	Latex() string
}
type Markdowner = interface {
	Markdown() string
}
type PNGer = interface {
	PNG() []byte
}
type PDFer = interface {
	PDF() []byte
}
type SVGer = interface {
	SVG() string
}

If you want, interpreted code can implement the above interfaces too:


In [10]:
// implement HTMLer
type H struct {
}
func (h H) HTML() string {
    return `<h2 style="color:blue;">Hello again, world!</h2>`
}
H{}


Out[10]:

Hello again, world!


In [11]:
// implement SimpleRenderer
type S struct {
}
func (s S) SimpleRender() display.MIMEMap {
    return display.MIMEMap{
        // Maxwell equations, in covariant formulation
        display.MIMETypeLatex: `$\partial_\alpha F^{\alpha\beta} = \mu_0 J^\beta$`,
    }
}
S{}


Out[11]:
$\partial_\alpha F^{\alpha\beta} = \mu_0 J^\beta$

Or also, if you want to fully control how your data should be rendered:


In [12]:
// implement Renderer
type R struct {
}
func (r R) Render() display.Data {
    return display.Data{
        Data: display.MIMEMap{
            // Einstein general relativity equations
            display.MIMETypeLatex: `$G_{\mu\nu} = \frac{8 \pi G}{c^4} T_{\mu\nu}$`,
        },
    }
}
R{}


Out[12]:
$G_{\mu\nu} = \frac{8 \pi G}{c^4} T_{\mu\nu}$