leaf-lang
write html with braces instead of angle brackets. leafc compiles .leaf files to .html.
install
requires node.js 14+
npm install -g leaf-langcheck it worked:
leafc --version
quick start
create index.leaf:
leaf {
head {
title "my page"
meta charset="UTF-8"
}
body {
h1 "hello world"
p "my first leaf page"
a href="https://github.com" target="_blank" "github"
}
}
compile it:
$ leafc index.leaf
ok index.leaf -> index.html 1.2 KB
open index.html in your browser.
index.leaf
leaf {
body {
h1 "hello"
p "world"
}
}index.html
<!DOCTYPE html>
<html>
<body>
<h1>hello</h1>
<p>world</p>
</body>
</html>commands
| command | what it does |
|---|---|
| leafc file.leaf | compile to file.html (same folder) |
| leafc file.leaf -o out.html | compile to a specific path |
| leafc --watch file.leaf | watch and recompile on save |
| leafc file.leaf --stdout | print html to terminal |
| leafc --version | print version |
| leafc --help | show help |
watch mode
recompiles every time you save the file. press Ctrl+C to stop.
$ leafc --watch index.leaf
ok index.leaf -> index.html 1.2 KB
watching index.leaf
structure
leaf is the root — it becomes <html>. nest tags with { }.
leaf {
head {
title "page title"
}
body {
div class="container" {
h1 "heading"
p "paragraph"
}
}
}
text
put text in quotes after the tag name.
h1 "page title"
p "paragraph text"
span "inline"
strong "bold"
em "italic"
attributes
write attributes between the tag name and the text content.
div class="box" id="main" { }
a href="https://example.com" target="_blank" "click"
p style="color:red" "red text"
boolean attributes (no value):
input type="checkbox" checked
video controls autoplay
void tags
self-closing — no braces needed.
brhrimginputmetalinksourcetrackwbrareabasecolembedparam
img src="photo.jpg" alt="photo"
meta charset="UTF-8"
meta name="viewport" content="width=device-width,initial-scale=1"
br
hr
input type="text" placeholder="name"
style & css
use a style tag in head:
head {
style "
body { font-family: sans-serif; padding: 2rem; }
h1 { color: #1D9E75; }
"
}
inline with style=:
div style="background:#1D9E75;padding:2rem;border-radius:8px" {
p style="color:#fff" "green box"
}
external stylesheet:
link rel="stylesheet" href="style.css"
links
# external
a href="https://github.com" target="_blank" "github"
# anchor
a href="#section" "jump to section"
# email
a href="mailto:me@example.com" "send email"
# phone
a href="tel:+60123456789" "call"
# download
a href="/file.zip" download "download"
images
img src="photo.jpg" alt="a photo"
img src="photo.jpg" alt="photo" style="width:100%;border-radius:8px"
# image as link
a href="https://example.com" {
img src="banner.jpg" alt="banner"
}
# with caption
figure {
img src="photo.jpg" alt="photo"
figcaption "caption goes here"
}
forms
form action="/submit" method="post" {
label "name"
input type="text" name="name" placeholder="your name"
label "pick one"
select name="choice" {
option "option a"
option "option b"
}
label "message"
textarea name="msg" rows="4"
button type="submit" "send"
}
tables
table {
thead {
tr { th "name" th "age" }
}
tbody {
tr { td "ahmad" td "20" }
}
}
node.js api
const { compile, parse } = require("leaf-lang");
// compile to html string
const html = compile(`
leaf {
head { title "test" }
body { h1 "hello" }
}
`);
// parse to ast (no render)
const ast = parse('div { p "hi" }');
console.log(ast.nodes);
compile() throws if the source is empty or not a string.
comments
start a line with
#. stripped from output.