We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
GRDR Beam
The most over built Static Site Generator
Written in Elixir and Rust, btw
Who am I?
- Software Engineer
- Red Hat for 3 years
- BHS for 3 years
- Bachelor’s from USC
- OMSCS @ GT
- Red Hat for 3 years
- BHS for 3 years
General Architecture
- GRDR-Beam
- Elixir/Phoenix UI
- GRDR
- Rust library that converts Markdown to HTML
- Rivets
- Series of plugins that change how the markdown is converted
- Elixir/Phoenix UI
- Rust library that converts Markdown to HTML
- Series of plugins that change how the markdown is converted
Format
title = README
date = 3333-12-31
author = Stephen M. Reaves
author_twitter = rpscln
author_twitch = rapscallionreaves
author_mastodon = rapscallionreaves
tags = ["grdr"]
description = Readme to understand GRDR
slides = false
rivets = []
---
## Foo
bar
- mark
- down
- stuff
title = README
date = 3333-12-31
author = Stephen M. Reaves
author_twitter = rpscln
author_twitch = rapscallionreaves
author_mastodon = rapscallionreaves
tags = ["grdr"]
description = Readme to understand GRDR
slides = false
rivets = []
---
## Foo
bar
- mark
- down
- stuff
Rivets
Rivets are dynamic parsers to augment normal markdown.
Rivets need to be enabled in the front matter, and inside the content.
Rivets
title = README
date = 3333-12-31
author = Stephen M. Reaves
author_twitter = rpscln
author_twitch = rapscallionreaves
author_mastodon = rapscallionreaves
tags = ["grdr"]
description = Readme to understand GRDR
slides = false
rivets = [katex]
---
## Foo
$ katex e = mc^2 katex $
title = README
date = 3333-12-31
author = Stephen M. Reaves
author_twitter = rpscln
author_twitch = rapscallionreaves
author_mastodon = rapscallionreaves
tags = ["grdr"]
description = Readme to understand GRDR
slides = false
rivets = [katex]
---
## Foo
$ katex e = mc^2 katex $
Math
Math
$ katex centered
\sigma \equiv \sqrt{\operatorname E\left[(X - \mu)^2\right]} = \sqrt{ \int_{-\infty}^{+\infty} (x-\mu)^2 f(x) \, \mathrm dx }
katex $
$ katex centered
\sigma \equiv \sqrt{\operatorname E\left[(X - \mu)^2\right]} = \sqrt{ \int_{-\infty}^{+\infty} (x-\mu)^2 f(x) \, \mathrm dx }
katex $
Graphs
$ graphviz
digraph G {
bgcolor=invis;
graph [labelloc="t"];
node [shape=rect; style=filled; fillcolor=gray95];
a -> b -> c;
}
graphviz $
$ graphviz
digraph G {
bgcolor=invis;
graph [labelloc="t"];
node [shape=rect; style=filled; fillcolor=gray95];
a -> b -> c;
}
graphviz $
Graphs
Graphs
Quotes
Linux is obsolete.
Andrew Tanenbaum
Andrew Tanenbaum
Quotes
$ quote Andrew Tanenbaum
Linux is obsolete.
quote $
$ quote Andrew Tanenbaum
Linux is obsolete.
quote $
Hide
$ hide hello
world!
hello $
hello
world!
$ hide hello
world!
hello $
hello
world!GRDR-Beam
Elixir/Phoenix application leveraging GRDR to serve my personal website
Components
.
├── content
│ ├── drafts
│ ├── notes
│ ├── posts
│ ├── static
│ ├── talks
│ └── topLevel
├── lib
│ ├── grdr_beam
│ └── grdr_beam_web
└── native
└── grdr_builder
.
├── content
│ ├── drafts
│ ├── notes
│ ├── posts
│ ├── static
│ ├── talks
│ └── topLevel
├── lib
│ ├── grdr_beam
│ └── grdr_beam_web
└── native
└── grdr_builder
lib/grdr_beam_web.ex
Handles routes, controllers, and ETS cache
ETS Cache
Erlang Term Storage
Essentially built-in Redis
ETS Cache
- URL -> filename
- /notes/cdn -> notes/OMSCS/6210/cdn.md
- filename -> file content
- notes/OMSCS/6210/cdn.md -> grdr-built html
- /notes/cdn -> notes/OMSCS/6210/cdn.md
- notes/OMSCS/6210/cdn.md -> grdr-built html
lib/grdr_beam_web/controllers/post_controller.ex
def note(conn, params) do
file(conn, params, lookup: &GrdrBeamWeb.note_lookup/1, layout: :app, render: :post)
end
def post(conn, params) do
file(conn, params, lookup: &GrdrBeamWeb.lookup/1, layout: :app, render: :post)
end
defp file(conn, params, lookup: lookup, layout: layout, render: template) do
# ...
case lookup.(params["name"] <> ".md") do
{:ok, filepath} ->
# File content cache
GrdrBeamWeb.build_or_get(
&GrdrBeam.build_file/1,
%{name: filepath, cache: params["cache"]}
)
|> Enum.map(fn {k, v} -> {String.to_atom(k), v} end)
{:not_found} ->
%{content: GrdrBeam.oops(), front_matter: :not_found}
end
# ...
end
def note(conn, params) do
file(conn, params, lookup: &GrdrBeamWeb.note_lookup/1, layout: :app, render: :post)
end
def post(conn, params) do
file(conn, params, lookup: &GrdrBeamWeb.lookup/1, layout: :app, render: :post)
end
defp file(conn, params, lookup: lookup, layout: layout, render: template) do
# ...
case lookup.(params["name"] <> ".md") do
{:ok, filepath} ->
# File content cache
GrdrBeamWeb.build_or_get(
&GrdrBeam.build_file/1,
%{name: filepath, cache: params["cache"]}
)
|> Enum.map(fn {k, v} -> {String.to_atom(k), v} end)
{:not_found} ->
%{content: GrdrBeam.oops(), front_matter: :not_found}
end
# ...
end
lib/grdr_beam.ex
Handles grdr library
lib/grdr_beam.ex
def build_file(name) do
name |> build |> Jason.decode() |> elem(1)
end
def build_file(name) do
name |> build |> Jason.decode() |> elem(1)
end
Handling Rivets
Rivets are defined by the library
Handling Rivets
Rivets are defined by the library
How do you add new ones?
Handling Rivets
Rivets are defined by the library
How do you add new ones?
Grdr functions take in a list of rivets
Handling Rivets
pub fn build_from(file_name: AsRef<Path>, rl: RivetList) -> Self
pub fn build_from(file_name: AsRef<Path>, rl: RivetList) -> Self
Handling Rivets
pub type Rivet = fn(file_name: &str, input: &str) -> String;
pub type RivetIdentifier = (&'static str, Rivet);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RivetList(Vec<RivetIdentifier>);
impl RivetList {
pub fn add_rivet(mut self, ri: RivetIdentifier) -> Self {
self.0.push(ri);
self
}
pub fn add_rivets(mut self, ris: Vec<RivetIdentifier>) -> Self {
self.0.extend(ris);
self
}
}
impl Default for RivetList {
fn default() -> Self {
Self(vec![
// ...
])
}
}
pub type Rivet = fn(file_name: &str, input: &str) -> String;
pub type RivetIdentifier = (&'static str, Rivet);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RivetList(Vec<RivetIdentifier>);
impl RivetList {
pub fn add_rivet(mut self, ri: RivetIdentifier) -> Self {
self.0.push(ri);
self
}
pub fn add_rivets(mut self, ris: Vec<RivetIdentifier>) -> Self {
self.0.extend(ris);
self
}
}
impl Default for RivetList {
fn default() -> Self {
Self(vec![
// ...
])
}
}
Handling Rivets
Foo
$ foo foo $
$ foo foo $
FOO
QR Example
$ qr https://reaves.dev/talks/grdrBeam qr $
$ qr https://reaves.dev/talks/grdrBeam qr $