diff --git a/src/Literate.jl b/src/Literate.jl index 15dec7a..a54fabb 100644 --- a/src/Literate.jl +++ b/src/Literate.jl @@ -6,7 +6,7 @@ https://fredrikekre.github.io/Literate.jl/ for documentation. """ module Literate -import JSON, REPL, IOCapture +import JSON, REPL, IOCapture, Base64 include("IJulia.jl") import .IJulia @@ -648,10 +648,8 @@ function execute_markdown!(io::IO, sb::Module, block::String, outputdir; plain_fence = "\n````\n" => "\n````" # Any explicit calls to display(...) - for dict in display_dicts - for (mime, data) in dict - display_markdown(io, data, outputdir, flavor, image_formats, file_prefix, plain_fence) - end + for (i, d) in enumerate(display_dicts) + display_markdown_mime(io, d, outputdir, flavor, image_formats, "$(file_prefix)-$i", plain_fence) end if r !== nothing && !REPL.ends_with_semicolon(block) @@ -678,7 +676,7 @@ function display_markdown(io, data, outputdir, flavor, image_formats, file_prefi open(joinpath(outputdir, file), "w") do io Base.invokelatest(show, io, mime, data) end - write(io, "![](", file, ")\n") + write(io, "\n![](", file, ")\n") return end end @@ -695,6 +693,52 @@ function display_markdown(io, data, outputdir, flavor, image_formats, file_prefi return end +function display_markdown_mime(io, mime_dict, outputdir, flavor, image_formats, file_prefix, plain_fence) + if (flavor isa FranklinFlavor || flavor isa DocumenterFlavor) && + haskey(mime_dict, "text/html") + htmlfence = flavor isa FranklinFlavor ? ("~~~" => "~~~") : ("```@raw html" => "```") + data = mime_dict["text/html"] + write(io, "\n", htmlfence.first, "\n") + write(io, data) + write(io, "\n", htmlfence.second, "\n") + return + end + + for (mime, ext) in image_formats + if haskey(mime_dict, string(mime)) + data = mime_dict[string(mime)] + file = file_prefix * ext + if istextmime(mime) + write(joinpath(outputdir, file), data) + else + data_decoded = Base64.base64decode(data) + write(joinpath(outputdir, file), data_decoded) + end + write(io, "\n![](", file, ")\n") + return + end + end + + if haskey(mime_dict, "text/latex") + data = mime_dict["text/latex"] + write(io, "\n```latex\n", data, "\n```\n") + return + end + + if haskey(mime_dict, "text/markdown") + data = mime_dict["text/markdown"] + write(io, '\n', data, '\n') + return + end + + # fallback to text/plain + @assert haskey(mime_dict, "text/plain") + write(io, plain_fence.first) + write(io, mime_dict["text/plain"]) + write(io, plain_fence.second, '\n') +end + + const JUPYTER_VERSION = v"4.3.0" parse_nbmeta(line::Pair) = parse_nbmeta(line.second) diff --git a/test/runtests.jl b/test/runtests.jl index 78b0224..e781d42 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -987,25 +987,52 @@ end end # Calls to display(x) and display(mime, x) script = """ - struct DF x end - Base.show(io::IO, ::MIME"text/plain", df::DF) = print(io, "DF(\$(df.x)) as text/plain") - Base.show(io::IO, ::MIME"text/html", df::DF) = print(io, "DF(\$(df.x)) as text/html") - Base.show(io::IO, ::MIME"text/latex", df::DF) = print(io, "DF(\$(df.x)) as text/latex") + struct DF{N} x end + DF(x) = DF{x}(x) + Base.show(io::IO, ::MIME"text/plain", df::DF{1}) = print(io, "DF(\$(df.x)) as text/plain") + Base.show(io::IO, ::MIME"text/html", df::DF{2}) = print(io, "DF(\$(df.x)) as text/html") + Base.show(io::IO, ::MIME"text/markdown", df::DF{3}) = print(io, "DF(\$(df.x)) as text/markdown") + Base.show(io::IO, ::MIME"text/latex", df::DF{4}) = print(io, "DF(\$(df.x)) as text/latex") + Base.show(io::IO, ::MIME"image/svg+xml", df::DF{5}) = print(io, "DF(\$(df.x)) as image/svg+xml") + Base.show(io::IO, ::MIME"image/png", df::DF{6}) = print(io, "DF(\$(df.x)) as image/png") #- - foreach(display, [DF(1), DF(2)]) - DF(3) + foreach(display, [DF(1), DF(2), DF(3), DF(4), DF(5)]) + DF(6) #- display(MIME("text/latex"), DF(4)) """ write(inputfile, script) Literate.markdown(inputfile, outdir; execute=true) markdown = read(joinpath(outdir, "inputfile.md"), String) - @test occursin("````\n\"DF(1) as text/plain\"\n````", markdown) - @test occursin("````\n\"DF(1) as text/html\"\n````", markdown) - @test occursin("````\n\"DF(2) as text/plain\"\n````", markdown) - @test occursin("````\n\"DF(2) as text/html\"\n````", markdown) - @test occursin("```@raw html\nDF(3) as text/html\n```", markdown) - @test occursin("````\n\"DF(4) as text/latex\"\n````", markdown) + + # Make sure each one shows up. + @test occursin("DF(1)", markdown) + @test occursin("DF(2)", markdown) + @test occursin("DF(3)", markdown) + @test occursin("DF(4)", markdown) + @test occursin("inputfile-3-5.svg", markdown) + @test occursin("inputfile-3.png", markdown) + + # Check the ordering. + @test findfirst("DF(1)", markdown)[1] < findfirst("DF(2)", markdown)[1] + @test findfirst("DF(2)", markdown)[1] < findfirst("DF(3)", markdown)[1] + @test findfirst("DF(3)", markdown)[1] < findfirst("DF(4)", markdown)[1] + @test findfirst("DF(4)", markdown)[1] < findfirst("inputfile-3-5.svg", markdown)[1] + @test findfirst("inputfile-3-5.svg", markdown)[1] < findfirst("inputfile-3.png", markdown)[1] + + # Check the formatting. + @test occursin("````\nDF(1) as text/plain\n````", markdown) + @test occursin("```@raw html\nDF(2) as text/html\n```", markdown) + @test occursin("\nDF(3) as text/markdown\n", markdown) + @test occursin("```latex\nDF(4) as text/latex\n```", markdown) + @test occursin("\n![](inputfile-3-5.svg)\n", markdown) + @test occursin("\n![](inputfile-3.png)\n", markdown) + + svg = read(joinpath(outdir, "inputfile-3-5.svg"), String) + @test svg == "DF(5) as image/svg+xml" + + png = read(joinpath(outdir, "inputfile-3.png"), String) + @test png == "DF(6) as image/png" # Softscope write(