Skip to content

Instantly share code, notes, and snippets.

@pankgeorg
Created February 10, 2022 08:09
Show Gist options
  • Save pankgeorg/d8e7f2766500869ecbf91a56e59f7891 to your computer and use it in GitHub Desktop.
Save pankgeorg/d8e7f2766500869ecbf91a56e59f7891 to your computer and use it in GitHub Desktop.
### A Pluto.jl notebook ###
# v0.18.0
using Markdown
using InteractiveUtils
# ╔═╡ c1d90180-8a47-11ec-2229-a74cca7d8eb2
import Pkg; Pkg.activate()
# ╔═╡ 6bbe1c41-8150-4b35-8891-154ac4bce694
Pkg.add(Pkg.PackageSpec(url="https://github.com/MichaelHatherly/CommonMark.jl", rev="mh/fix-38"))
# ╔═╡ ccb348c1-a9a3-43c2-a503-ce76086e6071
Pkg.add("HypertextLiteral")
# ╔═╡ 1e1eb82d-8fe7-4dab-bc99-40fd6c11c5ea
Pkg.status()
# ╔═╡ 12aeeb06-458b-4c55-a74e-00560c7de1a0
import HypertextLiteral, CommonMark
# ╔═╡ c83f5ab2-65a2-4711-b264-9fb5773fe982
begin
"""
```julia
@markdown(""\"
# MarkdownLiteral.jl
The macro `@markdown` lets you write [Markdown](https://www.markdownguide.org/getting-started/) inside Pluto notebooks. *Here is an example:*
""\")
```
You can also use the macro to write HTML!
```julia
@markdown(""\"
<p>
The macro <code>@markdown</code> lets you write <a href="https://developer.mozilla.org/docs/Web/HTML">HTML</a> inside Pluto notebooks.
<em>Here is an example:</em>
</p>
""\")
```
## Interpolation
You can unlock superpowers by combining `@markdown` with **interpolation** (using `\$`). For our example, let's create some data:
```julia
films = [
(title="Frances Ha", director="Noah Baumbach", year=2012)
(title="Portrait de la jeune fille en feu", director="Céline Sciamma", year=2019)
(title="De noorderlingen", director="Alex van Warmerdam", year=1992)
]
```
Now, we can use *interpolation* to display our data:
```julia
@markdown(""\"
My films:
\$([
"- **\$(f.title)** (\$(f.year)) by _\$(f.director)_\n"
for f in films
])
""\")
```
This gives us:
> My films:
> - **Frances Ha** (2012) by _Noah Baumbach_
> - **Portrait de la jeune fille en feu** (2019) by _Céline Sciamma_
> - **De noorderlingen** (1992) by _Alex van Warmerdam_
Alternatively, you could write this using HTML instead of Markdown (*with the same macro!*):
```julia
@markdown(""\"
<p>My films:</p>
<ul>
\$([
@markdown("<li>
<b>\$(f.title)</b> (\$(f.year)) by <em>\$(f.director)</em>
</li>")
for f in films
])
</ul>
""\")
```
## Advanced interpolation
Because interpolation is powered by [HypertextLiteral.jl](https://github.com/MechanicalRabbit/HypertextLiteral.jl), you can use advanced features:
- Interpolated attributes are automatically escaped
- You can use a `NamedTuple` or `Dict` for the CSS `style` attribute
- Interpolating Julia objects into a `<script>` will automatically convert to JavaScript code(!)
For
```julia
logs = [
(text="Info", urgent=false),
(text="Alert", urgent=true),
(text="Update", urgent=false),
]
```
```julia
@markdown("\$((
@markdown("<div style=\$((
font_weight=900,
padding=".5em",
background=log.urgent ? "pink" : "lightblue",
))>\$(log.text)</div>")
for log in logs
))")
```
Result:
![](https://user-images.githubusercontent.com/6933510/146623300-316e5a17-2daf-43ed-b70c-6c33278faf32.png)
"""
macro markdown(expr)
cm_parser = CommonMark.Parser()
CommonMark.enable!(cm_parser, [
CommonMark.AdmonitionRule(),
CommonMark.AttributeRule(),
CommonMark.AutoIdentifierRule(),
CommonMark.CitationRule(),
CommonMark.FootnoteRule(),
CommonMark.MathRule(),
CommonMark.RawContentRule(),
CommonMark.TableRule(),
CommonMark.TypographyRule(),
])
quote
result = $(esc(Expr(:macrocall, getfield(HypertextLiteral, Symbol("@htl")), __source__, expr)))
CMParsedRenderer(contents = result, parser = $cm_parser)
end
end
Base.@kwdef struct CMParsedRenderer
contents::Any
parser::CommonMark.Parser
end
function Base.show(io::IO, m::MIME"text/html", p::CMParsedRenderer)
# Use the given IO as context, render to HTML
html_render = sprint(show, m, p.contents; context = io)
# Parse the result
cm_parsed = p.parser(html_render)
# And render to HTML again
show(io, m, cm_parsed)
end
# Some aliases, it's up to you which one to import.
const var"@markdownliteral" = var"@markdown"
const var"@mdx" = var"@markdown"
end
# ╔═╡ 7da69021-7a22-4763-bb20-ace70f3450fd
@markdown """
Days of week 41 of the year 1582.
| Weekday | European | Hebrew | Islamic |
| ---: | :---: | :---: | :---: |
| Monday | 1582-10-01 | 5343-07-15 | 0990-09-13 |
| Tuesday | 1582-10-02 | 5343-07-16 | 0990-09-14 |
| Wednesday | 1582-10-03 | 5343-07-17 | 0990-09-15 |
| Thursday | 1582-10-04 | 5343-07-18 | 0990-09-16 |
"""
# ╔═╡ a5b91969-b50f-494b-b895-6c65153e78d3
# ╔═╡ fc317bca-de78-4b17-8b23-3e92030431a9
# ╔═╡ Cell order:
# ╠═c1d90180-8a47-11ec-2229-a74cca7d8eb2
# ╠═6bbe1c41-8150-4b35-8891-154ac4bce694
# ╠═ccb348c1-a9a3-43c2-a503-ce76086e6071
# ╠═1e1eb82d-8fe7-4dab-bc99-40fd6c11c5ea
# ╠═12aeeb06-458b-4c55-a74e-00560c7de1a0
# ╠═c83f5ab2-65a2-4711-b264-9fb5773fe982
# ╠═7da69021-7a22-4763-bb20-ace70f3450fd
# ╠═a5b91969-b50f-494b-b895-6c65153e78d3
# ╠═fc317bca-de78-4b17-8b23-3e92030431a9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment