Skip to content

Commit

Permalink
Fix non-text/plain output for Markdown
Browse files Browse the repository at this point in the history
and LaTeX output by capturing several
output representations and let each writer
choose which one to render,
fixes  #916, fixes fredrikekre/Literate.jl#49.
  • Loading branch information
fredrikekre committed Feb 5, 2019
1 parent 43cb56a commit 6ce3420
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 19 deletions.
4 changes: 4 additions & 0 deletions src/Documents.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ struct RawNode
text::String
end

struct MultiOutput
content::Vector
end

# Navigation
# ----------------------

Expand Down
22 changes: 4 additions & 18 deletions src/Expanders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -562,28 +562,14 @@ function Selectors.runner(::Type{ExampleBlocks}, x, page, doc)
content = []
input = droplines(x.code)

# Special-case support for displaying SVG and PNG graphics. TODO: make this more general.
output = if showable(MIME"text/html"(), result)
Documents.RawHTML(Base.invokelatest(stringmime, MIME"text/html"(), result))
elseif showable(MIME"image/svg+xml"(), result)
Documents.RawHTML(Base.invokelatest(stringmime, MIME"image/svg+xml"(), result))
elseif showable(MIME"image/png"(), result)
Documents.RawHTML(string("<img src=\"data:image/png;base64,", Base.invokelatest(stringmime, MIME"image/png"(), result), "\" />"))
elseif showable(MIME"image/webp"(), result)
Documents.RawHTML(string("<img src=\"data:image/webp;base64,", Base.invokelatest(stringmime, MIME"image/webp"(), result), "\" />"))
elseif showable(MIME"image/gif"(), result)
Documents.RawHTML(string("<img src=\"data:image/gif;base64,", Base.invokelatest(stringmime, MIME"image/gif"(), result), "\" />"))
elseif showable(MIME"image/jpeg"(), result)
Documents.RawHTML(string("<img src=\"data:image/jpeg;base64,", Base.invokelatest(stringmime, MIME"image/jpeg"(), result), "\" />"))
else
Markdown.Code(Documenter.DocTests.result_to_string(buffer, result))
end
# Generate different in different formats and let each writer select
output = Base.invokelatest(Utilities.display_dict, result)

# Only add content when there's actually something to add.
isempty(input) || push!(content, Markdown.Code("julia", input))
isempty(output.code) || push!(content, output)
isempty(output) || push!(content, output)
# ... and finally map the original code block to the newly generated ones.
page.mapping[x] = Markdown.MD(content)
page.mapping[x] = Documents.MultiOutput(content)
end

# @repl
Expand Down
16 changes: 16 additions & 0 deletions src/Utilities/Utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,22 @@ function mdparse(s::AbstractString; mode=:single)
end
end

# Capturing output in different representations similar to IJulia.jl
import Base64: stringmime
function display_dict(x)
out = Dict{MIME,Any}()
# Always generate text/plain
out[MIME"text/plain"()] = stringmime(MIME"text/plain"(), x)
let m = MIME"text/html"(); if showable(m, x); out[m] = stringmime(m, x); end end
let m = MIME"image/svg+xml"(); if showable(m, x); out[m] = stringmime(m, x); end end
let m = MIME"image/png"(); if showable(m, x); out[m] = stringmime(m, x); end end
let m = MIME"image/webp"(); if showable(m, x); out[m] = stringmime(m, x); end end
let m = MIME"image/gif"(); if showable(m, x); out[m] = stringmime(m, x); end end
let m = MIME"image/jpeg"(); if showable(m, x); out[m] = stringmime(m, x); end end
let m = MIME"text/latex"(); if showable(m, x); out[m] = stringmime(m, x); end end
return out
end

include("DOM.jl")
include("MDFlatten.jl")
include("TextDiff.jl")
Expand Down
25 changes: 25 additions & 0 deletions src/Writers/HTMLWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,31 @@ end

mdconvert(html::Documents.RawHTML, parent; kwargs...) = Tag(Symbol("#RAW#"))(html.code)

# Select the "best" representation for HTML output.
mdconvert(mo::Documents.MultiOutput, parent; kwargs...) =
Base.invokelatest(mdconvert, mo.content, parent; kwargs...)
function mdconvert(d::Dict{MIME,Any}, parent; kwargs...)
if haskey(d, MIME"text/html"())
out = Documents.RawHTML(d[MIME"text/html"()])
elseif haskey(d, MIME"image/svg+xml"())
out = Documents.RawHTML(d[MIME"image/svg+xml"()])
elseif haskey(d, MIME"image/png"())
out = Documents.RawHTML(string("<img src=\"data:image/png;base64,", d[MIME"image/png"()], "\" />"))
elseif haskey(d, MIME"image/webp"())
out = Documents.RawHTML(string("<img src=\"data:image/webp;base64,", d[MIME"image/webp"()], "\" />"))
elseif haskey(d, MIME"image/gif"())
out = Documents.RawHTML(string("<img src=\"data:image/gif;base64,", d[MIME"image/gif"()], "\" />"))
elseif haskey(d, MIME"image/jpeg"())
out = Documents.RawHTML(string("<img src=\"data:image/jpeg;base64,", d[MIME"image/jpeg"()], "\" />"))
elseif haskey(d, MIME"text/latex"())
out = Utilities.mdparse(d[MIME"text/latex"()]; mode = :single)
elseif haskey(d, MIME"text/plain"())
out = Markdown.Code(d[MIME"text/plain"()])
else
error("this should never happen.")
end
return mdconvert(out, parent; kwargs...)
end

# fixlinks!
# ------------------------------------------------------------------------------
Expand Down
33 changes: 33 additions & 0 deletions src/Writers/LaTeXWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,39 @@ function latex(io::IO, node::Documents.EvalNode, page, doc)
node.result === nothing ? nothing : latex(io, node.result, page, doc)
end

# Select the "best" representation for LaTeX output.
using Base64: base64decode
function latex(io::IO, mo::Documents.MultiOutput)
foreach(x->Base.invokelatest(latex, io, x), mo.content)
end
function latex(io::IO, d::Dict{MIME,Any})
filename = String(rand('a':'z', 7))
if haskey(d, MIME"image/png"())
write("$(filename).png", base64decode(d[MIME"image/png"()]))
_println(io, """
\\begin{figure}[H]
\\centering
\\includegraphics{$(filename)}
\\end{figure}
""")
elseif haskey(d, MIME"image/jpeg"())
write("$(filename).jpeg", base64decode(d[MIME"image/jpeg"()]))
_println(io, """
\\begin{figure}[H]
\\centering
\\includegraphics{$(filename)}
\\end{figure}
""")
elseif haskey(d, MIME"text/latex"())
latex(io, Utilities.mdparse(d[MIME"text/latex"()]; mode = :single))
elseif haskey(d, MIME"text/plain"())
latex(io, Markdown.Code(d[MIME"text/plain"()]))
else
error("this should never happen.")
end
return nothing
end


## Basic Nodes. AKA: any other content that hasn't been handled yet.

Expand Down
35 changes: 35 additions & 0 deletions src/Writers/MarkdownWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,41 @@ function render(io::IO, mime::MIME"text/plain", node::Documents.EvalNode, page,
node.result === nothing ? nothing : render(io, mime, node.result, page, doc)
end

# Select the "best" representation for Markdown output.
using Base64: base64decode
function render(io::IO, mime::MIME"text/plain", d::Documents.MultiOutput, page, doc)
foreach(x -> Base.invokelatest(render, io, mime, x, page, doc), d.content)
end
function render(io::IO, mime::MIME"text/plain", d::Dict{MIME,Any}, page, doc)
filename = String(rand('a':'z', 7))
if haskey(d, MIME"image/png"())
write(joinpath(dirname(page.build), "$(filename).png"), base64decode(d[MIME"image/png"()]))
println(io, """
![]($(filename).png)
""")
elseif haskey(d, MIME"image/webp"())
write(joinpath(dirname(page.build), "$(filename).webp"), base64decode(d[MIME"image/webp"()]))
println(io, """
![]($(filename).webp)
""")
elseif haskey(d, MIME"image/jpeg"())
write(joinpath(dirname(page.build), "$(filename).jpeg"), base64decode(d[MIME"image/jpeg"()]))
println(io, """
![]($(filename).jpeg)
""")
elseif haskey(d, MIME"image/gif"())
write(joinpath(dirname(page.build), "$(filename).gif"), base64decode(d[MIME"image/gif"()]))
println(io, """
![]($(filename).gif)
""")
elseif haskey(d, MIME"text/plain"())
render(io, mime, MarkdownStdlib.Code(d[MIME"text/plain"()]), page, doc)
else
error("this should never happen.")
end
return nothing
end


## Basic Nodes. AKA: any other content that hasn't been handled yet.

Expand Down
2 changes: 1 addition & 1 deletion test/examples/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extra_javascript:
- https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML
- assets/mathjaxhelper.js

docs_dir: 'build'
docs_dir: 'builds/markdown'

pages:
- Home: index.md
Expand Down

0 comments on commit 6ce3420

Please sign in to comment.