👀 Reading hidden code
using HypertextLiteral
: @htl, @htl_str
👀 Reading hidden code
# little patch for HTL
👀 Reading hidden code
👀 Reading hidden code
using PlutoUI
PlutoUI.ExperimentalLayout
👀 Reading hidden code
👀 Reading hidden code
Examples
👀 Reading hidden code
counter1 (generic function with 1 method)
👀 Reading hidden code
counter1() = @htl """
let node
if(this == null) {
node = html`<span style='color: green'></span>`
node.val = {current: 0}
} else {
node = this
}
const val = node.val
val.current += 1
node.innerText = val.current
return node
</script>
"""
counter2 (generic function with 1 method)
counter2() = @htl """
<script id=$(@give_me_script_id())>
let node
if(this == null) {
node = html`<span style='color: red'></span>`
node.val = {current: 0}
} else {
node = this
}
const val = node.val
val.current += 1
node.innerText = val.current
return node
</script>
"""
👀 Reading hidden code
123
x = 123
👀 Reading hidden code
1
1
let
x
PlutoDiv([
counter1(),
counter2(),
])
end
👀 Reading hidden code
just_script (generic function with 1 method)
just_script() = @htl """
<script id=$(@give_me_script_id())>
</script>
"""
👀 Reading hidden code
What the HTML looks like
👀 Reading hidden code
<script id='id_A36au3YWNtk_1'>
</script>
<script id='id_A36au3YWNtk_2'>
</script>
render_like_plutorunner_would(@htl """
$(just_script())
$(just_script())
""").content |> Text
👀 Reading hidden code
<script id='id_A36au3YWNtk_1'>
</script>
<script id='id_A36au3YWNtk_2'>
</script>
<div>
<script id='id_A36au3YWNtk_3,1,1'>
</script>
<script id='id_A36au3YWNtk_3,2,1'>
</script>
</div>
<script id='id_A36au3YWNtk_4'>
</script>
render_like_plutorunner_would(@htl """
$(just_script())
$(just_script())
$(PlutoDiv([
just_script(),
just_script(),
]))
$(just_script())
""").content |> Text
👀 Reading hidden code
Counter stack
👀 Reading hidden code
Union{Int64, Symbol}
const StackElement = Union{Symbol,Int}
👀 Reading hidden code
get_and_increment_counter! (generic function with 1 method)
function get_and_increment_counter!(io::IO)
stack = get(io, :script_id_counter, StackElement[])::Vector{StackElement}
if length(stack) >= 1
stack[end] += 1
return join(stack, ",")
else
# Some fallback for when you use GiveMeScriptID inside an IO that never received a counter:
string(rand(Int))
end
end
👀 Reading hidden code
with_counter (generic function with 2 methods)
function with_counter(f::Function, io::IO, addkey::Union{StackElement,Nothing}=nothing)
oldstack = get(io, :script_id_counter, StackElement[])::Vector{StackElement}
newstack = if addkey === nothing
StackElement[oldstack..., 0]
else
StackElement[oldstack..., addkey, 0]
end
f(IOContext(io,
:script_id_counter => newstack,
))
end
👀 Reading hidden code
Macro that uses it for a script ID
👀 Reading hidden code
ScriptIDGiver
begin
struct ScriptIDGiver
source::LineNumberNode
end
function Base.show(io::IO, g::ScriptIDGiver)
name = "id_$(
string(hash(g.source), base=62)
)_$(
get_and_increment_counter!(io)
)"
write(io, name)
end
ScriptIDGiver
end
👀 Reading hidden code
<script id='id_A36au3YWNtk_1'>
</script>
<script id='id_A36au3YWNtk_2'>
</script>
<div>
<script id='id_A36au3YWNtk_3,aa,1'>
</script>
<script id='id_A36au3YWNtk_3,aa'bb,1'>
</script>
</div>
<script id='id_A36au3YWNtk_4'>
</script>
render_like_plutorunner_would(@htl """
$(just_script())
$(just_script())
$(PlutoKeyedDiv([
:aa => just_script(),
Symbol("aa'bb") => just_script(),
]))
$(just_script())
""").content |> Text
👀 Reading hidden code
begin
struct PlutoDiv
contents::Vector
end
function Base.show(io::IO, m::MIME"text/html", p::PlutoDiv)
get_and_increment_counter!(io)
write(io, "<div>")
for (i,e) in enumerate(p.contents)
with_counter(io, i) do io
show(io, m, e)
end
end
write(io, "</div>")
end
end
👀 Reading hidden code
begin
struct PlutoKeyedDiv
contents::Vector{Pair{Symbol,Any}}
end
function Base.show(io::IO, m::MIME"text/html", p::PlutoKeyedDiv)
get_and_increment_counter!(io)
write(io, "<div>")
for (i,e) in p.contents
with_counter(io, i) do io
show(io, m, e)
end
end
write(io, "</div>")
end
end
👀 Reading hidden code
👀 Reading hidden code
# begin
# Base.get(io::HypertextLiteral.EscapeProxy, args...) = Base.get(io.io, args...)
# Base.get!(io::HypertextLiteral.EscapeProxy, args...) = Base.get!(io.io, args...)
# Base.get!(f, io::HypertextLiteral.EscapeProxy, args...) = Base.get!(f, io.io, args...)
# Base.get(io::HypertextLiteral.EscapeProxy, args...) = Base.get(io.io, args...)
# IOContext
👀 Reading hidden code
<script id='id_JmryABLhgWu_8836153874878050597'>
let node
if(this == null) {
node = html`<span style='color: green'></span>`
node.val = {current: 0}
} else {
node = this
}
const val = node.val
val.current += 1
node.innerText = val.current
return node
</script>
repr(MIME"text/html"(), counter1()) |> Text
👀 Reading hidden code
render_like_plutorunner_would (generic function with 1 method)
render_like_plutorunner_would(x) = sprint() do io_raw
with_counter(io_raw) do io
show(io, MIME"text/html"(), x)
end
end |> HTML
👀 Reading hidden code
give_me_script_id (generic function with 1 method)
give_me_script_id(s::LineNumberNode) = ScriptIDGiver(s)
👀 Reading hidden code
@give_me_script_id (macro with 1 method)
begin
give_me_script_id
macro give_me_script_id()
give_me_script_id(__source__)
end
end
👀 Reading hidden code
Multiple expressions in one cell.
How would you like to fix it?
# hier maken wij automatisch keys: 1,2,3,...
PlutoLayout.hbox([
thing,
ook_thing,
hello
])
# maar dit is bv een probleem in dit geval:
PlutoLayout.hbox(cool ? [
first,
second
] : [
second,
first
])
# hierom kan je zelf keys aangeven:
# (API bestaat nog niet)
PlutoLayout.hbox(cool ? [
:e1 => first,
:e2 => second
] : [
:e2 => second,
:e1 => first
])
👀 Reading hidden code