A semantic CSS syntax tree for MoonBit: a tolerant parser, a printer with pretty, compact and minified modes, and structured diagnostics
Dependencies
///|
test "parse then print" {
let p = @css.parse(".card{display:grid;gap:1rem}")
inspect(
@css.to_css(p.sheet()),
content=(
#|.card {
#| display: grid;
#| gap: 1rem;
#|}
#|
),
)
inspect(
@css.to_css(p.sheet(), style=Minified),
content=".card{display:grid;gap:1rem}",
)
}///|
test "a bad declaration does not take the rule with it" {
let p = @css.parse("a { color red; margin: 0 }")
inspect(@css.to_css(p.sheet(), style=Minified), content="a{margin:0}")
inspect(p.diagnostics().length(), content="1")
inspect(p.diagnostics()[0].kind.code(), content="css::expected_colon")
}///|
test "numbers and hex colours keep their spelling" {
let p = @css.parse("a{w:1.50;c:#FFF}")
inspect(@css.to_css(p.sheet(), style=Minified), content="a{w:1.50;c:#FFF}")
}///|
test "an unknown at-rule survives" {
let p = @css.parse("@tailwind base;\na{b:c}")
inspect(
@css.to_css(p.sheet(), style=Minified),
content="@tailwind base;a{b:c}",
)
inspect(p.diagnostics()[0].kind.code(), content="css::unknown_at_rule")
}///|
test "lenses read an untyped tree" {
let p = @css.parse("a { width: 10px; color: #f80 }")
match p.sheet().items[0] {
Rule(Style(r)) => {
match r.body[0] {
Decl(d) =>
match @css.as_length(d.value[0]) {
Some(len) => inspect(len.unit, content="px")
None => fail("10px is a length")
}
_ => fail("expected a declaration")
}
match r.body[1] {
Decl(d) =>
match @css.as_color(d.value[0]) {
Some(c) =>
match @value.to_rgba(c) {
Some((r, g, b, _)) => {
assert_eq(r, 255)
assert_eq(g, 136)
assert_eq(b, 0)
}
None => fail("#f80 resolves")
}
None => fail("#f80 is a colour")
}
_ => fail("expected a declaration")
}
}
_ => fail("expected a style rule")
}
}///|
test "specificity is computed, not stored" {
let p = @css.parse("#a .b c { x: y }")
match p.sheet().items[0] {
Rule(Style(r)) => {
let (a, b, c) = @css.specificity(r.selectors[0]).to_triple()
assert_eq(a, 1)
assert_eq(b, 1)
assert_eq(c, 1)
}
_ => fail("expected a style rule")
}
}| package | what | depends on |
|---|---|---|
| span | source ranges, in UTF-16 code units | nothing |
| kind | the closed set of error kinds | nothing |
| ast | the tree | span, kind |
| write | the printer, three modes | ast |
| error | diagnostics, and the one bridge to error-report | span, kind |
| token | the CSS Syntax Level 3 tokenizer | span |
| value | typed lenses over values, and specificity | ast |
| parse | CSS text to a tree | all of the above |
Install
Download zipA semantic CSS syntax tree for MoonBit: a tolerant parser, a printer with pretty, compact and minified modes, and structured diagnostics
Dependencies