Wadler-style pretty printer for MoonBit: documents, groups and layout that fits a line width
Dependencies
let items = [@pretty.text("a"), @pretty.text("b"), @pretty.text("c")]
let doc = @pretty.group(
@pretty.text("[") +
@pretty.nest(2, @pretty.line() + @pretty.join(items, @pretty.text(",") + @pretty.line())) +
@pretty.line() +
@pretty.text("]"),
)
@pretty.render(doc) // "[ a, b, c ]"
@pretty.render(doc, width=6) // "[\n a,\n b,\n c\n]"| Function | Flat | Broken |
|---|---|---|
| text(s) | s | s |
| verbatim(s) | s | s, no indentation after its line feeds |
| line() | a space | a line break |
| softline() | nothing | a line break |
| hardline() | always a line break | |
| nest(n, d) | d | d, indented by n more |
| align(d) | d | d, indented to its start column |
| tab(n, d) | d | d, indented to the next multiple of n |
| group(d) | flat if it fits | else broken |
| if_break(b, f) | f | b |
| group_alone(d) | flat if d alone fits | else broken |
| break_(b, u) | u | b, then a line break |
| flex_break(b, u) | u | u when the rest fits, else b and a line break |
| lines(n) | n line breaks (does not force the group) | |
| zero_width(s) | s, width 0 | s, width 0 |
| raw_text(s) | s as one atom: line feeds kept, no indentation, every cluster counts | |
| force_break(d) | d; its group never fits | |
| next_break_fits(d, m) | d; Enabled lets the group fit up to the first break in d | |
| nest_if_broken(n, d) | d | d, indented by n more |
| set_nesting(n, d) | d | d, indented to column n |
type Doctest {
let d = @pretty.group_alone(
@pretty.text("a") + @pretty.break_(",", ", ") + @pretty.text("b"),
)
inspect(@pretty.render(d, width=80), content="a, b")
inspect(@pretty.render(d, width=3), content="a,\nb")
}test {
let d = @pretty.group(@pretty.text("a") + @pretty.line() + @pretty.text("b"))
inspect(@pretty.render(d, width=3), content="a b")
inspect(@pretty.render(d, width=2), content="a\nb")
}test {
let body = @pretty.text("a") + @pretty.line() + @pretty.text("b")
inspect(
@pretty.render(@pretty.group_alone(body) + @pretty.text("cc"), width=3),
content="a bcc",
)
inspect(
@pretty.render(@pretty.group(body) + @pretty.text("cc"), width=3),
content="a\nbcc",
)
let with_hardline = @pretty.group_alone(
body + @pretty.hardline() + @pretty.text("c"),
)
inspect(@pretty.render(with_hardline, width=80), content="a b\nc")
}test {
inspect(
@pretty.render(
@pretty.nest(2, @pretty.text("a") + @pretty.lines(2) + @pretty.text("b")),
),
content="a\n\n b",
)
}test {
let block = @pretty.group_alone(
@pretty.force_break(
@pretty.text("{") +
@pretty.nest(2, @pretty.break_("", " ") + @pretty.text("x")) +
@pretty.break_("", " ") +
@pretty.text("}"),
),
)
let call = @pretty.group_alone(
@pretty.text("f(") +
@pretty.nest(
2,
@pretty.break_("", "") + @pretty.next_break_fits(block, Enabled),
) +
@pretty.break_("", "") +
@pretty.text(")"),
)
inspect(@pretty.render(call), content="f({\n x\n })")
}test {
let d = @pretty.nest(
2,
@pretty.raw_text("ab\ncd") + @pretty.flex_break("", " ") + @pretty.text("x"),
)
inspect(@pretty.render(d, width=7), content="ab\ncd x")
inspect(@pretty.render(d, width=6), content="ab\ncd\n x")
}test {
let items = [@pretty.text("a"), @pretty.text("b")]
let d = @pretty.group(
@pretty.text("[") +
@pretty.nest(
2,
@pretty.line() + @pretty.join(items, @pretty.text(",") + @pretty.line()),
) +
@pretty.line() +
@pretty.text("]"),
)
inspect(@pretty.render(d), content="[ a, b ]")
inspect(@pretty.render(d, width=4), content="[\n a,\n b\n]")
}test {
let body = @pretty.text("x") +
@pretty.tab(4, @pretty.hardline() + @pretty.text("y"))
inspect(
@pretty.render(@pretty.text("ab") + @pretty.align(body)),
content="abx\n y",
)
inspect(
@pretty.render(@pretty.text("abcd") + @pretty.align(body)),
content="abcdx\n y",
)
}test {
inspect(
@pretty.render(@pretty.nest(2, @pretty.text("a\nb"))),
content="a\n b",
)
}Install
Download zipWadler-style pretty printer for MoonBit: documents, groups and layout that fits a line width
Dependencies