Skip to content

Commit

Permalink
finish converting to MIME"" syntax and update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Aug 19, 2013
1 parent 85ccb54 commit af8c18c
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 23 deletions.
4 changes: 2 additions & 2 deletions base/datafmt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -221,5 +221,5 @@ end
writedlm(io, a) = writedlm(io, a, '\t')
writecsv(io, a) = writedlm(io, a, ',')

writemime(io::IO, ::@MIME("text/csv"), a::Union(AbstractVector,AbstractMatrix)) = writedlm(io, a, ',')
writemime(io::IO, ::@MIME("text/tab-separated-values"), a::Union(AbstractVector,AbstractMatrix)) = writedlm(io, a, '\t')
writemime(io::IO, ::MIME"text/csv", a::Union(AbstractVector,AbstractMatrix)) = writedlm(io, a, ',')
writemime(io::IO, ::MIME"text/tab-separated-values", a::Union(AbstractVector,AbstractMatrix)) = writedlm(io, a, '\t')
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,7 @@ export
istext,
MIME,
@MIME,
@MIME_str,
reprmime,
stringmime,
writemime,
Expand Down
29 changes: 15 additions & 14 deletions base/multimedia.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ export Display, display, pushdisplay, popdisplay, displayable, redisplay,

immutable MIME{mime} end

import Base: show, string, convert
import Base: show, print, string, convert
MIME(s) = MIME{symbol(s)}()
show{mime}(io::IO, ::MIME{mime}) = print(io, "MIME type ", string(mime))
string{mime}(::MIME{mime}) = string(mime)
print{mime}(io::IO, ::MIME{mime}) = print(io, mime)

# needs to be a macro so that we can use ::@mime(s) in type declarations
macro MIME(s)
warn_once("@MIME(\"\") is deprecated, use MIME\"\" instead.")
if isa(s,String)
:(MIME{$(Expr(:quote, symbol(s)))})
else
Expand All @@ -30,7 +31,7 @@ macro MIME_str(s)
end

###########################################################################
# For any type T one can define writemime(io, ::@MIME(mime), x::T) = ...
# For any type T one can define writemime(io, ::MIME"type", x::T) = ...
# in order to provide a way to export T as a given mime type.

mimewritable{mime}(::MIME{mime}, T::Type) =
Expand All @@ -55,16 +56,16 @@ mimewritable(m::String, T::Type) = mimewritable(MIME(m), T)
# passed to display(m::MIME, x).

for mime in ["text/vnd.graphviz", "text/latex", "text/calendar", "text/n3", "text/richtext", "text/x-setext", "text/sgml", "text/tab-separated-values", "text/x-vcalendar", "text/x-vcard", "text/cmd", "text/css", "text/csv", "text/html", "text/javascript", "text/plain", "text/vcard", "text/xml", "application/atom+xml", "application/ecmascript", "application/json", "application/rdf+xml", "application/rss+xml", "application/xml-dtd", "application/postscript", "image/svg+xml", "application/x-latex", "application/xhtml+xml", "application/javascript", "application/xml", "model/x3d+xml", "model/x3d+vrml", "model/vrml"]
@eval begin
istext(::@MIME($mime)) = true
reprmime(m::@MIME($mime), x::String) = x
reprmime(m::@MIME($mime), x) = sprint(writemime, m, x)
stringmime(m::@MIME($mime), x) = reprmime(m, x)
# avoid method ambiguities with definitions below:
# (Q: should we treat Vector{Uint8} as a bytestring?)
reprmime(m::@MIME($mime), x::Vector{Uint8}) = sprint(writemime, m, x)
stringmime(m::@MIME($mime), x::Vector{Uint8}) = reprmime(m, x)
end
mimeT = MIME{symbol(mime)}
global istext, reprmime, stringmime
istext(::mimeT) = true
reprmime(m::mimeT, x::String) = x
reprmime(m::mimeT, x) = sprint(writemime, m, x)
stringmime(m::mimeT, x) = reprmime(m, x)
# avoid method ambiguities with definitions below:
# (Q: should we treat Vector{Uint8} as a bytestring?)
reprmime(m::mimeT, x::Vector{Uint8}) = sprint(writemime, m, x)
stringmime(m::mimeT, x::Vector{Uint8}) = reprmime(m, x)
end

istext(::MIME) = false
Expand Down Expand Up @@ -105,7 +106,7 @@ displayable(mime::String) = displayable(MIME(mime))
immutable TextDisplay <: Display
io::IO
end
display(d::TextDisplay, ::@MIME("text/plain"), x) =
display(d::TextDisplay, ::MIME"text/plain", x) =
writemime(d.io, MIME("text/plain"), x)
display(d::TextDisplay, x) = display(d, MIME("text/plain"), x)

Expand Down
16 changes: 9 additions & 7 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ Julia environments (such as the IPython-based IJulia notebook).
redisplay(mime, x)
redisplay(d::Display, mime, x)

By default, the `redisplay` functions simply call ``display``. However,
By default, the ``redisplay`` functions simply call ``display``. However,
some display backends may override ``redisplay`` to modify an existing
display of ``x`` (if any). Using ``redisplay`` is also a hint to the
backend that ``x`` may be redisplayed several times, and the backend
Expand All @@ -1383,19 +1383,21 @@ Julia environments (such as the IPython-based IJulia notebook).
``stream`` (usually a memory buffer), if possible. In order to
provide a rich multimedia representation of a user-defined type
``T``, it is only necessary to define a new ``writemime`` method for
``T``, via: ``writemime(stream, ::@MIME(mime), x::T) = ...``, where
``T``, via: ``writemime(stream, ::MIME"mime", x::T) = ...``, where
``mime`` is a MIME-type string and the function body calls
``write`` (or similar) to write that representation of ``x`` to
``stream``.
``stream``. (Note that the ``MIME""`` notation only supports literal
strings; to construct ``MIME`` types in a more flexible manner use
``MIME{symbol("")}``.)

For example, if you define a ``MyImage`` type and know how to write
it to a PNG file, you could define a function ``writemime(stream,
::@MIME("image/png"), x::MyImage) = ...``` to allow your images to
::MIME"image/png", x::MyImage) = ...``` to allow your images to
be displayed on any PNG-capable ``Display`` (such as IJulia).
As usual, be sure to ``import Base.writemime`` in order to add
new methods to the built-in Julia function ``writemime``.

Technically, the ``@MIME(mime)`` macro defines a singleton type for
Technically, the ``MIME"mime"`` macro defines a singleton type for

This comment has been minimized.

Copy link
@kmsquire

kmsquire Aug 19, 2013

Member

Should probably be Technically, ``MIME"mime"`` defines a singleton type for...

the given ``mime`` string, which allows us to exploit Julia's
dispatch mechanisms in determining how to display objects of any
given type.
Expand Down Expand Up @@ -1431,14 +1433,14 @@ Julia environments (such as the IPython-based IJulia notebook).

As mentioned above, one can also define new display backends. For
example, a module that can display PNG images in a window can register
this capability with Julia, so that calling `display(x)` on types
this capability with Julia, so that calling ``display(x)`` on types
with PNG representations will automatically display the image using
the module's window.

In order to define a new display backend, one should first create a
subtype ``D`` of the abstract class ``Display``. Then, for each MIME
type (``mime`` string) that can be displayed on ``D``, one should
define a function ``display(d::D, ::@MIME(mime), x) = ...`` that
define a function ``display(d::D, ::MIME"mime", x) = ...`` that
displays ``x`` as that MIME type, usually by calling ``reprmime(mime,
x)``. A ``MethodError`` should be thrown if ``x`` cannot be displayed
as that MIME type; this is automatic if one calls ``reprmime``.
Expand Down

1 comment on commit af8c18c

@StefanKarpinski
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely more pleasant.

Please sign in to comment.