diff --git a/Project.toml b/Project.toml index 487e620c..f3897790 100644 --- a/Project.toml +++ b/Project.toml @@ -4,6 +4,7 @@ authors = ["Douglas Bates ", "Randy Lai ") + elseif format == :svg + svg_str = read(temp_plot_file, String) + HTML(_fix_svg_ids(svg_str)) + end + end +end + +function _close_and_show_temp_plot(temp_plot_file) + _close_and_show_temp_plot(temp_plot_file, _DEFAULT_FORMAT) +end + + +""" +It executes the R code and returns an `HTML` object containing the plot. +This macro is handy to inline R plots inside Pluto notebooks. + +`@html_plot` can take two arguments; the first is the code block to evaluate +to produce the R plot. The second argument is the plot format (optional); +it could be `png` (the default) or `svg`. For example: + +```julia +@html_plot R"plot(c(1,2,5,3,4), type='o', col='blue')" +``` + +To use the `svg` format: + +```julia +@html_plot R"plot(c(1,2,5,3,4), type='o', col='blue')" svg +``` + +**NOTE:** To see a *ggplot2* plot, it is necessary to `print` it explicitly: + +```julia +@html_plot R\""" +library(ggplot2) + +plt <- ggplot(data = diamonds) + + geom_bar( + mapping = aes(x = cut, fill = clarity), + position = "fill" + ) + +print(plt) +\""" +``` + +""" +macro html_plot(r_code, format...) + quote + temp_plot_file = _open_temp_plot($format...) + $r_code + _close_and_show_temp_plot(temp_plot_file, $format...) + end +end diff --git a/src/ijulia.jl b/src/ijulia.jl index 1554f234..3d29c2cf 100644 --- a/src/ijulia.jl +++ b/src/ijulia.jl @@ -34,16 +34,20 @@ function ijulia_displayfile(m::MIME"image/png", f) display(m,d) end end -function ijulia_displayfile(m::MIME"image/svg+xml", f) + +function _fix_svg_ids(svg_str::String) # R svg images use named defs, which cause problem when used inline, see # https://github.com/jupyter/notebook/issues/333 # we get around this by renaming the elements. + rand_id = randstring() + svg_str = replace(svg_str, "id=\"glyph" => "id=\"glyph"*rand_id) + replace(svg_str, "href=\"#glyph" => "href=\"#glyph"*rand_id) +end + +function ijulia_displayfile(m::MIME"image/svg+xml", f) open(f) do f - r = randstring() - d = read(f, String) - d = replace(d, "id=\"glyph" => "id=\"glyph"*r) - d = replace(d, "href=\"#glyph" => "href=\"#glyph"*r) - display(m,d) + svg_str = read(f, String) + display(m, _fix_svg_ids(svg_str)) end end diff --git a/test/html_plot.jl b/test/html_plot.jl new file mode 100644 index 00000000..fd0426ac --- /dev/null +++ b/test/html_plot.jl @@ -0,0 +1,21 @@ +@test RCall._fix_svg_ids("id=\"glyph") != "id=\"glyph" +@test RCall._fix_svg_ids("href=\"#glyph") != "href=\"#glyph" + +@test RCall._DEFAULT_FORMAT == :png + +@test_throws ErrorException @html_plot R"plot(1, 2)" :png # : is not needed as the macro is already taking a Symbol +@test_throws ErrorException @html_plot R"plot(1, 2)" pdf # only svg and png are supported + +@test @html_plot(R"plot(1, 2)") == @html_plot(R"plot(1, 2)", png) # png is the default format + +let png_plot = @html_plot R"plot(1, 2)" png + @test isa(png_plot, HTML) + @test startswith(png_plot.content, "