Created
February 10, 2022 08:09
-
-
Save pankgeorg/d8e7f2766500869ecbf91a56e59f7891 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### 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