Slab is a programmable markup language to generate HTML.
$ cat data/values.json
[
{
"username": "Alice",
"email": "alice@example.com"
},
{
"username": "Bob",
"email": "bob@example.com"
}
]
$ cat example.slab
frag hello(name)
li.greeting
p Hello, #(name).
content
let values = ./data/values.json
ul
for value in values
hello(value['username'])
p Some content.
$ slab render --pretty example.slab
<ul>
<li class="greeting">
<p>
Hello, Alice.
</p>
<p>
Some content.
</p>
</li>
<li class="greeting">
<p>
Hello, Bob.
</p>
<p>
Some content.
</p>
</li>
</ul>
You can think of Slab as HTML + functions and imports, and read more about it at slab-lang.org.
Slab is written in Haskell and this repository provides a Nix-based development
environment. Running scripts/ghci.sh
automatically enters a Nix shell with
the necessary dependencies and configures GHCi to make working on Slab easier:
$ scripts/ghci.sh
Welcome to Slab's GHCi environment.
Type :about to see this help text.
Other interesting commands and expressions include:
:main --help
runExamples
Discover the code base with e.g.:
:doc runExamples
:i about
:e tests/Slab/GHCi.hs
→
The main command for a user of Slab is the build
command. But Slab also
offers commands to better understand and debug its various stages (parsing,
preprocessing, evaluating, running external commands, and rendering).
→ :main --help
slab - A programmable markup language to generate HTML
Usage: slab COMMAND
Slab is a programmable markup language to generate HTML.
Available options:
-h,--help Show this help text
Available commands:
build Build a library of Slab templates to HTML
watch Watch and build a library of Slab templates to HTML
serve Watch and serve a library of Slab templates to HTML
report Analyse a library of Slab templates
render Render a Slab template to HTML
run Execute a Slab template
evaluate Evaluate a Slab template
parse Parse a Slab template to AST
generate Generate code corresponding to a Slab template
classes Parse a Slab template and report its CSS classes
fragments Parse a Slab template and report its fragments
Note: GHCi is an Haskell interpreter. Within GHCi, instead of calling a
compiled binary (called slab
in our case), we can call the special command
:main
and pass it arguments in the same way we would on a regular
command-line.
During development, it helps to create small .slab
files and run our code on
them. In particular, given an examples/a.slab
file, we can use parse
and
evaluate
to introspect the ASTs at the different stages.
ghci> :main parse --shallow examples/a.slab
ghci> :main parse examples/a.slab
ghci> :main evaluate examples/a.slab
ghci> :main evaluate --simplify examples/a.slab
ghci> :main render --pretty examples/a.slab
ghci> :main render examples/a.slab
The test cases in examples/cases/
come from the original Pug test
suite. The
expected HTML is not exactly the same: we pretty print it differently, or some
tags are explicitely closed in Pug.js (e.g. <source>
vs. <source/>
.
Modules from the code base are almost always imported "qualified". For example,
the module Slab.Parse
is imported within Slab.Run
as Parse
. This is
replicated within GHCi too:
ghci> :i Parse.parseExpr
ghci> Parse.parseExpr "1 + 2 * a"
To run the test suite, use the runExamples
function within GHCi.
To debug a failing test, use render --pretty
:
:main render --pretty examples/fragments.slab
The result should match (in this example) examples/fragments.html
.
In addition of the above development environment, this repository exposes
another Nix shell where the compiled slab
program is available, together with
its Bash tab-completion.
$ nix-shell default.nix -A shell
$ slab <TAB>
Slab is available on Hackage, where the library documentation is visible.
In addition of generating static HTML files from Slab templates, we explore generating code.
ghci> :main generate a.slab
Currently, a very small subset of the Slab language is supported, and only Haskell code can be generated.
In the context of memory management, slab allocation is a mechanism designed to reduce fragmentation caused by allocations and deallocations.
Slab the language is designed to define, combine and, eventually evaluate fragments to HTML.
Slab was initially a port to Haskell of the Pug.js templating language.