A Pug template engine implementation in MoonBit.
///|
test "usage example" {
let pug =
#|doctype html
#|html
#| head
#| title Hello Pug
#| body
#| h1#greeting.title Hello, World!
#| p This is rendered from Pug.
// Render to compact HTML
let html = @pug.render(pug)
inspect(
html,
content="<!DOCTYPE html><html><head><title>Hello Pug</title></head><body><h1 class=\"title\" id=\"greeting\">Hello, World!</h1><p>This is rendered from Pug.</p></body></html>",
)
// Render to pretty-printed HTML
let _pretty_html = @pug.render_pretty(pug)
}div
p Hello World
span.highlight Textdiv#main
div.container
div#app.container.active#main
.containera(href="https://example.com") Click me
input(type="text", name="username", placeholder="Enter name")
img(src="photo.jpg", alt="A photo")html
head
title My Page
body
h1 Welcome
p This is content.// This is a rendered comment
//- This is not rendereddoctype htmlp Hello #{name}!
p Welcome to #{place}///|
test "compile api" {
// Compile template once
let template = @pug.compile("p Hello #{name}!")
// Render with different locals
let locals1 = @pug.Locals::new()
locals1.set("name", "Alice")
inspect(template.render(locals1), content="<p>Hello Alice!</p>")
let locals2 = @pug.Locals::new()
locals2.set("name", "Bob")
inspect(template.render(locals2), content="<p>Hello Bob!</p>")
}///|
test "render with locals" {
let locals = @pug.Locals::new()
locals.set("name", "World")
let html = @pug.render_with_locals("p Hello #{name}!", locals)
inspect(html, content="<p>Hello World!</p>")
}fn CompiledTemplate::render_with_options(self : CompiledTemplate, locals : Locals, options : RenderOptions) -> Stringfn Document::render_with_locals(self : Document, locals : Locals, options~ : RenderOptions) -> Stringfn Document::render_with_registry(self : Document, locals : Locals, registry : TemplateRegistry, options~ : RenderOptions) -> Stringtype Lexerpub enum Node {
Element(tag~ : String, id~ : String, classes~ : Array[String], attributes~ : Array[Attribute], children~ : Array[Node], self_closing~ : Bool)
Text(String)
Interpolation(String)
UnescapedInterpolation(String)
Comment(text~ : String, render~ : Bool)
Doctype(String)
Conditional(condition~ : String, if_true~ : Array[Node], if_false~ : Array[Node], is_unless~ : Bool)
Each(item_var~ : String, index_var~ : String, collection~ : String, body~ : Array[Node], else_body~ : Array[Node])
Case(expr~ : String, cases~ : Array[(String, Array[Node])], default~ : Array[Node])
When(value~ : String, body~ : Array[Node])
Default(body~ : Array[Node])
MixinDef(name~ : String, params~ : Array[(String, String)], body~ : Array[Node])
MixinCall(name~ : String, args~ : Array[String], block~ : Array[Node], attrs~ : Array[(String, String)])
Block
VarAssign(name~ : String, value~ : String)
While(condition~ : String, body~ : Array[Node])
NamedBlock(name~ : String, body~ : Array[Node], mode~ : String)
Include(path~ : String)
IncludeFiltered(filter~ : String, path~ : String)
Extends(path~ : String)
Filter(name~ : String, content~ : String)
} derive(Eq, Debug, ToJson)type Parserpub struct RenderOptions {
pretty : Bool
indent_str : String
}pub enum Token {
Indent(Int)
Tag(String)
Id(String)
Class(String)
AttrName(String)
AttrValue(String)
Text(String)
Interpolation(String)
UnescapedInterpolation(String)
TagInterpolation(String)
LParen
RParen
Equals
UnescapedEquals
Newline
Comment(String)
UnbufferedComment(String)
Doctype(String)
BlockExpand
PipedText(String)
BlockTextMarker
BlockText(String)
If(String)
ElseIf(String)
Else
Unless(String)
Each(String, String, String)
Case(String)
When(String)
Default
Block
MixinDef(String, Array[(String, String)])
MixinCall(String, Array[String], Array[(String, String)])
BufferedOutput(String)
UnescapedBufferedOutput(String)
VarAssign(String, String)
While(String)
NamedBlock(String)
AppendBlock(String)
PrependBlock(String)
Include(String)
IncludeFiltered(String, String)
Extends(String)
Filter(String, String)
SelfClose
EOF
} derive(Eq, Debug)fn apply_filter(filter : String, content : String) -> Stringfn get_doctype(name : String) -> Stringfn render_pretty(input : String) -> String