To be able to edit code and run cells, you need to run the notebook yourself. Where would you like to run the notebook?

This notebook takes about 20 seconds to run.

In the cloud (experimental)

Binder is a free, open source service that runs scientific notebooks in the cloud! It will take a while, usually 2-7 minutes to get a session.

On your computer

(Recommended if you want to store your changes.)

  1. Copy the notebook URL:
  2. Run Pluto

    (Also see: How to install Julia and Pluto)

  3. Paste URL in the Open box

Frontmatter

If you are publishing this notebook on the web, you can set the parameters below to provide HTML metadata. This is useful for search engines and social media.

Author 1
👀 Reading hidden code
using HypertextLiteral
: @htl, @htl_str

27.8 ms
👀 Reading hidden code
# little patch for HTL
Base.get(ep::HypertextLiteral.EscapeProxy, name, default) = get(ep.io, name, default)
471 μs
👀 Reading hidden code
@assert :b == get(
HypertextLiteral.EscapeProxy(IOContext(devnull, :a => :b)),
:a,
123
)
15.5 ms
👀 Reading hidden code
using PlutoUI
411 ms
PlutoUI.ExperimentalLayout
👀 Reading hidden code
const Layout = PlutoUI.ExperimentalLayout
134 μs
👀 Reading hidden code
69.0 μs

Examples

👀 Reading hidden code
183 μs
counter1 (generic function with 1 method)
👀 Reading hidden code
counter1() = @htl """
<script id=$(@give_me_script_id())>
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>
"""
465 μs
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
6.4 ms
123
x = 123
👀 Reading hidden code
12.5 μs
1 1
let
x
PlutoDiv([
counter1(),
counter2(),
])
end
👀 Reading hidden code
25.7 μs
just_script (generic function with 1 method)
just_script() = @htl """

<script id=$(@give_me_script_id())>
</script>

"""
👀 Reading hidden code
486 μs

What the HTML looks like

👀 Reading hidden code
187 μs

<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
25.8 ms

<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
23.7 ms

Counter stack

👀 Reading hidden code
180 μs
Union{Int64, Symbol}
const StackElement = Union{Symbol,Int}
👀 Reading hidden code
135 μs
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
831 μs
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
1.2 ms

Macro that uses it for a script ID

👀 Reading hidden code
184 μs
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
1.8 ms

<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&apos;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
604 ms
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
2.8 ms
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
2.8 ms

👀 Reading hidden code
68.1 μs
# 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
15.7 μs
<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
87.3 ms
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
1.3 ms
give_me_script_id (generic function with 1 method)
give_me_script_id(s::LineNumberNode) = ScriptIDGiver(s)
👀 Reading hidden code
392 μs
@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
446 μs
Error message

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
---