|
5 | 5 | import Base.Libc: flush_cstdio |
6 | 6 | import Pkg |
7 | 7 |
|
8 | | -const text_plain = MIME("text/plain") |
9 | | -const image_svg = MIME("image/svg+xml") |
10 | | -const image_png = MIME("image/png") |
11 | | -const image_jpeg = MIME("image/jpeg") |
12 | | -const text_markdown = MIME("text/markdown") |
13 | | -const text_html = MIME("text/html") |
14 | | -const text_latex = MIME("text/latex") # Jupyter expects this |
15 | | -const text_latex2 = MIME("application/x-latex") # but this is more standard? |
16 | | -const application_vnd_vega_v3 = MIME("application/vnd.vega.v3+json") |
17 | | -const application_vnd_vegalite_v2 = MIME("application/vnd.vegalite.v2+json") |
18 | | -const application_vnd_dataresource = MIME("application/vnd.dataresource+json") |
| 8 | +Base.showable(a::AbstractVector{<:MIME}, x) = any(m -> showable(m, x), a) |
| 9 | + |
| 10 | +""" |
| 11 | +A vector of MIME types (or vectors of MIME types) that IJulia will try to |
| 12 | +render. IJulia will try to render every MIME type specified in the first level |
| 13 | +of the vector. If a vector of MIME types is specified, IJulia will include only |
| 14 | +the first MIME type that is renderable (this allows for the expression of |
| 15 | +priority and exclusion of redundant data). |
| 16 | +
|
| 17 | +For example, since "text/plain" is specified as a first-child of the array, |
| 18 | +IJulia will always try to include a "text/plain" representation of anything that |
| 19 | +is displayed. Since markdown and latex are specified within a sub-vector, IJulia |
| 20 | +will always try to render "text/markdown", and will only try to render |
| 21 | +"text/latex" if markdown isn't possible. |
| 22 | +""" |
| 23 | +const ijulia_mime_types = Vector{Union{MIME, AbstractVector{MIME}}}() |
| 24 | + |
| 25 | +register_mime(x::Union{M, AbstractVector{M}}) where {M <: MIME} = push!(ijulia_mime_types, x) |
19 | 26 |
|
20 | 27 | include("magics.jl") |
21 | 28 |
|
22 | 29 | # return a String=>Any dictionary to attach as metadata |
23 | 30 | # in Jupyter display_data and pyout messages |
24 | 31 | metadata(x) = Dict() |
25 | 32 |
|
26 | | -# return a String=>String dictionary of mimetype=>data |
27 | | -# for passing to Jupyter display_data and execute_result messages. |
28 | | -function display_dict(x) |
29 | | - data = Dict{String,Any}("text/plain" => limitstringmime(text_plain, x)) |
30 | | - if showable(application_vnd_vegalite_v2, x) |
31 | | - data[string(application_vnd_vegalite_v2)] = JSON.JSONText(limitstringmime(application_vnd_vegalite_v2, x)) |
32 | | - elseif showable(application_vnd_vega_v3, x) # don't send vega if we have vega-lite |
33 | | - data[string(application_vnd_vega_v3)] = JSON.JSONText(limitstringmime(application_vnd_vega_v3, x)) |
34 | | - end |
35 | | - if showable(application_vnd_dataresource, x) |
36 | | - data[string(application_vnd_dataresource)] = JSON.JSONText(limitstringmime(application_vnd_dataresource, x)) |
| 33 | +""" |
| 34 | +Generate the preferred MIME representation of x. |
| 35 | +
|
| 36 | +Returns a tuple with the selected MIME type and the representation of the data |
| 37 | +using that MIME type. |
| 38 | +""" |
| 39 | +function display_mimestring(mime_array::AbstractVector{MIME}, x) |
| 40 | + for m in mime_array |
| 41 | + if showable(mime_array, x) |
| 42 | + return display_mimestring(m, x) |
| 43 | + end |
37 | 44 | end |
38 | | - if showable(image_svg, x) |
39 | | - data[string(image_svg)] = limitstringmime(image_svg, x) |
| 45 | + error("No displayable MIME types in mime array.") |
| 46 | +end |
| 47 | + |
| 48 | +abstract type MIMEStringType end |
| 49 | +display_mimestring(m::MIME, x) = display_mimestring(m, mimestringtype(m), x) |
| 50 | + |
| 51 | +""" |
| 52 | + If false then data of the mime type should be sent to ipython in b64-encoded string. |
| 53 | + If true then it will be sent as is. |
| 54 | + Defaults to the value of istextmime. |
| 55 | +""" |
| 56 | +_istextmime(m::MIME) = istextmime(m) |
| 57 | + |
| 58 | +struct RawMIMEString <: MIMEStringType end |
| 59 | +for m in [ |
| 60 | + MIME("text/plain"), |
| 61 | + MIME("image/svg+xml"), |
| 62 | + [MIME("image/png"),MIME("image/jpeg")], |
| 63 | + [ |
| 64 | + MIME("text/markdown"), |
| 65 | + MIME("text/html"), |
| 66 | + MIME("text/latex"), # Jupyter expects this |
| 67 | + MIME("application/x-latex"), # but this is more standard? |
| 68 | + ], |
| 69 | +] |
| 70 | + register_mime(m) |
| 71 | + if m isa MIME |
| 72 | + @eval mimestringtype(::$m) = RawMIMEString |
| 73 | + else |
| 74 | + for _m in m |
| 75 | + @eval mimestringtype(::$m) = RawMIMEString |
| 76 | + end |
40 | 77 | end |
41 | | - if showable(image_png, x) |
42 | | - data[string(image_png)] = limitstringmime(image_png, x) |
43 | | - elseif showable(image_jpeg, x) # don't send jpeg if we have png |
44 | | - data[string(image_jpeg)] = limitstringmime(image_jpeg, x) |
| 78 | +end |
| 79 | +display_mimestring(m::MIME, ::RawMIMEString, x) = (m, limitstringmime(m, x)) |
| 80 | + |
| 81 | +struct JSONMIMEString <: MIMEStringType end |
| 82 | +for m in [ |
| 83 | + [MIME("application/vnd.vegalite.v2+json"), MIME("application/vnd.vega.v3+json")], |
| 84 | + MIME("application/vnd.dataresource+json") |
| 85 | +] |
| 86 | + register_mime(m) |
| 87 | + if m <: MIME |
| 88 | + @eval mimestringtype(::$m) = JSONMIMEString |
| 89 | + @eval _istextmime(::$m) = true |
| 90 | + else |
| 91 | + for _m in m |
| 92 | + @eval mimestringtype(::$m) = JSONMIMEString |
| 93 | + @eval _istextmime(::$m) = true |
| 94 | + end |
45 | 95 | end |
46 | | - if showable(text_markdown, x) |
47 | | - data[string(text_markdown)] = limitstringmime(text_markdown, x) |
48 | | - elseif showable(text_html, x) |
49 | | - data[string(text_html)] = limitstringmime(text_html, x) |
50 | | - elseif showable(text_latex, x) |
51 | | - data[string(text_latex)] = limitstringmime(text_latex, x) |
52 | | - elseif showable(text_latex2, x) |
53 | | - data[string(text_latex)] = limitstringmime(text_latex2, x) |
| 96 | +end |
| 97 | +display_mimestring(m::MIME, ::JSONMIMEString, x) = (m, JSON.JSONText(limitstringmime(m, x))) |
| 98 | + |
| 99 | +""" |
| 100 | +Generate a dictionary of `mime_type => data` pairs for all registered MIME |
| 101 | +types. This is the format that Jupyter expects in display_data and |
| 102 | +execute_result messages. |
| 103 | +""" |
| 104 | +function display_dict(x) |
| 105 | + data = Dict{String, Union{String, JSONText}}() |
| 106 | + for m in ijulia_mime_types |
| 107 | + if showable(m, x) |
| 108 | + mime, mime_repr = display_mimestring(m, x) |
| 109 | + data[string(mime)] = mime_repr |
| 110 | + end |
54 | 111 | end |
55 | 112 | return data |
56 | 113 | end |
|
0 commit comments