Skip to content

Commit

Permalink
format_html was missing
Browse files Browse the repository at this point in the history
  • Loading branch information
schlichtanders committed Jul 6, 2024
1 parent 512adf8 commit 024017c
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 111 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "JolinPluto"
uuid = "5b0b4ef8-f4e6-4363-b674-3f031f7b9530"
authors = ["Stephan Sahm <[email protected]> and contributors"]
version = "0.1.62"
version = "0.1.63"

[deps]
AbstractPlutoDingetjes = "6e696c72-6542-2067-7265-42206c756150"
Expand Down
2 changes: 1 addition & 1 deletion src/JolinPluto.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export @output_below, @clipboard_image_to_clipboard_html
export output_below, clipboard_image_to_clipboard_html, embedLargeHTML, plotly_responsive
export Setter, @get, @cell_ids_create_wrapper, @cell_ids_push!
export cell_ids_create_wrapper, cell_ids_push!, cell_ids_push
export MD
export MD, format_html
export bindr, bindpy, bindjl
export init_jolin

Expand Down
67 changes: 0 additions & 67 deletions src/experimental_layout.jl

This file was deleted.

119 changes: 118 additions & 1 deletion src/frontend.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,121 @@ IMPORTANT: Works only if `plotly()` backend is activated
Makes the plotly plot responsive and returns the new plot.
"""
function plotly_responsive end # See this issue for updates https://github.com/JuliaPlots/Plots.jl/issues/4775
function plotly_responsive end # See this issue for updates https://github.com/JuliaPlots/Plots.jl/issues/4775





# We build an individual CommonMark parser with a special inline `<> ... </>` component.
import CommonMark

struct HtmlFragmentInlineRule end
struct HtmlFragmentInline <: CommonMark.AbstractInline end
function parse_html_fragment(parser::CommonMark.InlineParser, block::CommonMark.Node)
m = CommonMark.consume(parser, match(r"<>.*</>", parser))
m === nothing && return false
node = CommonMark.Node(HtmlFragmentInline())
node.literal = @views m.match[begin+length("<>"):end-length("</>")]
CommonMark.append_child(block, node)
return true
end
CommonMark.inline_rule(::HtmlFragmentInlineRule) = CommonMark.Rule(parse_html_fragment, 1.5, "<")

function CommonMark.write_term(::HtmlFragmentInline, render, node, enter)
# macroexpand solves this problem https://discourse.julialang.org/t/how-to-properly-import-a-macro-inside-a-begin-end-block/106037/4
style = @macroexpand CommonMark.crayon"dark_gray"
CommonMark.print_literal(render, style)
CommonMark.push_inline!(render, style)
CommonMark.print_literal(render, node.literal)
CommonMark.pop_inline!(render)
CommonMark.print_literal(render, inv(style))
end
CommonMark.write_html(::HtmlFragmentInline, r, n, ent) = CommonMark.literal(r, r.format.safe ? "<!-- raw HTML omitted -->" : n.literal)
CommonMark.write_latex(::HtmlFragmentInline, w, node, ent) = nothing
CommonMark.write_markdown(::HtmlFragmentInline, w, node, ent) = CommonMark.literal(w, node.literal)

const _MD_parser = CommonMark.Parser()
CommonMark.enable!(_MD_parser, CommonMark.DollarMathRule())
CommonMark.enable!(_MD_parser, CommonMark.TableRule())
CommonMark.enable!(_MD_parser, HtmlFragmentInlineRule())

"""
MD("# Markdown String")
"""
function MD(args...; kwargs...)
_MD_parser(args...; kwargs...)
end


"""
format_html(anything)
Transform an object to raw html respresentation.
Note, this is a single line representation so that it can also be used inside Markdown Tables.
"""
function format_html(ans)
isdefined(Main, :PlutoRunner) || return repr("text/html", ans)

str, mime = Main.PlutoRunner.format_output(ans; context=PlutoRunner.IOContext(
Main.PlutoRunner.default_iocontext,
:extra_items=>Dict{Main.PlutoRunner.ObjectDimPair,Int64}(),
:module => Main.PlutoRunner.currently_running_module[],
:pluto_notebook_id => Main.PlutoRunner.notebook_id[],
:pluto_cell_id => Main.PlutoRunner.currently_running_cell_id[],
))
function replace_script_inner(script_str)
# core idea to make it single_line: we eval a string
# for this we need to escape
# escape single strings inside and then wrap everything into one single quote string
# escape single strings inside and then wrap everything into one single quote string
raw"return await eval('(async function() {\n" * replace(script_str,
r"(?<=\\)'" => raw"\\'",
r"(?<!\\)'" => raw"\'",
r"\\n" => raw"\\n",
r"\n" => raw"\n",
) * raw"\n})()')"
end
str_script_singleline = replace(str, r"(?<=<script>).*(?=</script>)"s => replace_script_inner)
str_singleline = replace(str_script_singleline, r"\s*(\n|\r\n)\s*" => " ")
str_singleline
end


# experimental layout (HTML wrapper which uses Pluto Div to correctly separate outputs and inputs)

PlutoHTML(html::HypertextLiteral.Result) = PlutoHTML(format_html(html))
PlutoHTML(md::CommonMark.Node) = PlutoHTML(format_html(md))
PlutoHTML(html::AbstractString) = PlutoHTML(parsehtml(html, noerror=true))
function PlutoHTML(html::EzXML.Document)
body = only(elements(root(html)))
# make the outer level always an ExperimentalLayout (and not an @htl)
# because of https://github.com/JuliaPluto/PlutoUI.jl/issues/284
if countelements(body) == 1
PlutoHTML(elements(body)[1])
elseif countelements(body) > 1
PlutoUI.ExperimentalLayout.Div(PlutoHTML.(elements(body)))
end
end

function PlutoHTML(node::EzXML.Node)
res = if nodename(node) == "div" && countelements(node) > 1
PlutoUI.ExperimentalLayout.Div(
PlutoHTML.(nodes(node)),
class=getdefault(node, "class", nothing),
style=getdefault(node, "style", ""),
)
elseif iselement(node) && nodename(node) == "bond"
# special case - we do not want to recurse into pluto bind elements
HTML(sprint(print, node))
elseif iselement(node)
attrs = Dict(nodename(a) => nodecontent(a) for a in eachattribute(node))
@htl "<$(nodename(node)) $attrs>$(PlutoHTML.(nodes(node))...)</$(nodename(node))>"
elseif istext(node)
@htl "$(nodecontent(node))"
else
HTML(sprint(print, node))
end
return res
end
41 changes: 0 additions & 41 deletions src/languages.jl
Original file line number Diff line number Diff line change
@@ -1,46 +1,5 @@
# common things for both R and Python

# We build an individual CommonMark parser with a special inline `<> ... </>` component.
import CommonMark

struct HtmlFragmentInlineRule end
struct HtmlFragmentInline <: CommonMark.AbstractInline end
function parse_html_fragment(parser::CommonMark.InlineParser, block::CommonMark.Node)
m = CommonMark.consume(parser, match(r"<>.*</>", parser))
m === nothing && return false
node = CommonMark.Node(HtmlFragmentInline())
node.literal = @views m.match[begin+length("<>"):end-length("</>")]
CommonMark.append_child(block, node)
return true
end
CommonMark.inline_rule(::HtmlFragmentInlineRule) = CommonMark.Rule(parse_html_fragment, 1.5, "<")

function CommonMark.write_term(::HtmlFragmentInline, render, node, enter)
# macroexpand solves this problem https://discourse.julialang.org/t/how-to-properly-import-a-macro-inside-a-begin-end-block/106037/4
style = @macroexpand CommonMark.crayon"dark_gray"
CommonMark.print_literal(render, style)
CommonMark.push_inline!(render, style)
CommonMark.print_literal(render, node.literal)
CommonMark.pop_inline!(render)
CommonMark.print_literal(render, inv(style))
end
CommonMark.write_html(::HtmlFragmentInline, r, n, ent) = CommonMark.literal(r, r.format.safe ? "<!-- raw HTML omitted -->" : n.literal)
CommonMark.write_latex(::HtmlFragmentInline, w, node, ent) = nothing
CommonMark.write_markdown(::HtmlFragmentInline, w, node, ent) = CommonMark.literal(w, node.literal)

const _MD_parser = CommonMark.Parser()
CommonMark.enable!(_MD_parser, CommonMark.DollarMathRule())
CommonMark.enable!(_MD_parser, CommonMark.TableRule())
CommonMark.enable!(_MD_parser, HtmlFragmentInlineRule())

"""
MD("# Markdown String")
"""
function MD(args...; kwargs...)
_MD_parser(args...; kwargs...)
end


# it turns out using a function variant of `bind` does not work well with using Pluto as a plain Julia file.
# because it might be in a nested module somewhere... and julia functions do not have access to its calling module because of possible inlining
# hence we need at least one macro call to get the module information
Expand Down

0 comments on commit 024017c

Please sign in to comment.