JuliaLang/julia — pull request #3932 by stevengj (2013-08-04 03:57:39+00:00)
Title: RFC: add multimedia I/O mechanism (display, mm_write, and friends); fixes #3817

This patch addresses #3817, by providing a general mechanism in Julia to display objects via rich multimedia representations, via three components:

* A function `display` to request the richest available multimedia display of a Julia object.
* Overloading `mm_write` allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.
* Multimedia-capable display backends may be registered by subclassing a generic ``Display`` type and pushing it onto a stack of display "devices" via `push_display`.

This design has gone through several iterations since the inception of #3817, and is in part inspired by the [design of IPython's custom display logic](http://nbviewer.ipython.org/url/github.com/ipython/ipython/raw/master/examples/notebooks/Custom%20Display%20Logic.ipynb). It is especially critical for the development of IJulia, where I have tested this technique and found that it works very well.

The main difference from my most recent proposal in #3817 is that I generalized the mechanism to be extensible to arbitrary MIME types without modifying `Base`, using a parametric singleton-type technique similar to @StefanKarpinski's beautiful `MathConst` trick, in order to allow Julia to dispatch on the MIME type. For example, if I have a type `MyImage` that I know how to write as PNG, I can simply define a new `mm_write` method:
```
import Base.mm_write
mm_write(stream, ::@MIME("image/png"), x::MyImage) = ...write x as PNG to stream...
```
and any ``MyImage`` type will automatically display as a PNG image in IJulia or in any other display device supporting image/png.

See the changes to `doc/stdlib/base.rst` for the complete documentation.

I also added and documented a `base64(x)` function to base64-encode binary data, as this is generically useful for sending MIME data to backends (and is essential for IJulia), based on some code by @StefanKarpinski.

cc: @JeffBezanson, @ViralShah, @timholy, @fperez