glam/doc
Types
Values
pub fn append(
to first: Document,
doc second: Document,
) -> Document
Joins a document into the end of another.
Examples
from_string("pretty")
|> append(from_string(" printer"))
|> to_string(80)
// -> "pretty printer"
pub fn append_docs(
first: Document,
docs: List(Document),
) -> Document
Joins multiple documents into the end of another.
This is a shorthand for append(to: first, doc: concat(docs)).
Examples
from_string("pretty")
|> append_docs([
from_string("printing"),
space,
from_string("rocks!"),
])
|> to_string(80)
// -> "pretty printing rocks!"
pub fn break(unbroken: String, broken: String) -> Document
A document after which the pretty printer can insert a new line.
A newline is added after a break document if the group it’s part of
could not be rendered on a single line.
If the pretty printer decides to add a newline after break it will be
rendered as its second argument, otherwise as its first argument.
Examples
let message =
[from_string("pretty"), break("•", "↩"), from_string("printed")]
|> concat
|> group
message |> to_string(20)
// -> "pretty•printed"
message |> to_string(10)
// -> "pretty↩
// printed"
pub fn concat(docs: List(Document)) -> Document
Joins a list of documents into a single document.
The resulting pretty printed document would be the same as pretty printing
each document separately and concatenating it together with <>:
docs |> concat |> to_string(n) ==
docs |> list.map(to_string(n)) |> string.concat
Examples
["pretty", " ", "printed"]
|> list.map(from_string)
|> concat
|> to_string(80)
// -> "pretty printed"
pub fn concat_join(
docs: List(Document),
with separators: List(Document),
) -> Document
Joins a list of documents into a single one by inserting the given separators between each existing document.
This is a shorthand for join(docs, concat(separators)).
Examples
["wow", "so", "many", "commas"]
|> list.map(from_string)
|> concat_join([from_string(","), space])
|> to_string(80)
// -> "wow, so, many, commas"
pub fn debug(document: Document) -> Document
Returns a debug version of the given document that can be pretty printed to see the structure of a document.
This can help you see how your data structures get turned into documents and check if the document is what you’d expect.
groups are surrounded by square brackets.nests are surrounded by angle brackets and have a smal superscript with the nesting.concatenated documents are separated by dots.breaks are rendered surrounded by curly brackets and show both the broken and unbroken versions.lines are rendered as the stringlffollowed by a superscript number of lines.
pub const empty: Document
An empty document that is printed as an empty string.
Examples
empty |> to_string(80)
// -> ""
pub fn flex_break(unbroken: String, broken: String) -> Document
A document after which the pretty printer can insert a new line.
The difference with a simple break is that, the pretty printer will decide
wether to add a new line or not on a space-by-space basis.
While all the break inside a group are broken or not, some flex_breaks
may be broken and some not, depending wether the document can fit on a
single line or not. Hence the name flex.
If the pretty printer decides to add a newline after flex_break it will be
rendered as its first argument, otherwise as its first argument.
Examples
let message =
[from_string("pretty"), from_string("printed"), from_string("string")]
|> join(with: flex_break("•", "↩"))
|> group
message |> to_string(80)
// -> "pretty•printed•string"
message |> to_string(20)
// -> "pretty•printed↩
// string"
pub const flex_space: Document
A document that is rendered as a single whitespace " " but can be broken
by the pretty printer into newlines instead.
Instead of splitting all spaces or no spaces (like it would do with
space inside a group), the pretty printer can decide on a space-by-space
basis.
If a flex_space inside a group needs to be broken to fit it on multiple
lines, following flex_spaces may end up not being broken.
This is a shorthand for flex_break(" ", "").
Examples
let message =
["Gleam", "is", "fun!"]
|> list.map(from_string)
|> join(with: flex_space)
|> group
to_string(message, 80)
// -> "Gleam is fun!"
to_string(message, 10)
// -> "Gleam is
fun!"
to_string(message, 4) // -> “Gleam // is // fun!”
pub fn force_break(doc: Document) -> Document
Forces the pretty printer to break all the breaks of the outermost
document. This still has no effect on groups as the pretty printer will
always try to put them on a single line before splitting them.
Examples
[from_string("pretty"), break("•", "↩"), from_string("printed")]
|> concat
|> force_break
|> group
|> to_string(100)
// -> "pretty↩
// printed"
pub fn from_string(string: String) -> Document
Turns a string into a document.
Examples
"doc" |> from_string |> to_string(80)
// -> "doc"
pub fn group(doc: Document) -> Document
Allows the pretty printer to break the break documents inside the given
group.
When the pretty printer runs into a group it first tries to render it on a single line, displaying all the breaks as their first argument. If the group fits this is the final pretty printed result.
However, if the group does not fit on a single line all the breaks
inside that group are rendered as their second argument and immediately
followed by a newline.
Any nested group is considered on its own and may or may not be split, depending if it fits on a single line or not. So, even if the outermost group is broken, its nested groups may still end up on a single line.
Examples
let food =
["lasagna", "ravioli", "pizza"]
|> list.map(from_string) |> join(with: space) |> group
let message =
[from_string("Food I love:"), space, food] |> concat |> group
message |> to_string(80)
// -> "Food I love: lasagna ravioli pizza"
message |> to_string(30)
// -> "Food I love:
// lasagna ravioli pizza"
// ^-- After splitting the outer group, the inner one can fit
// on a single line so the pretty printer does not split it
message |> to_string(20)
// "Food I love:
// lasagna
// ravioli
// pizza"
// ^-- Even after splitting the outer group, the inner one wouldn't
// fit on a single line, so the pretty printer splits that as well
pub fn join(
docs: List(Document),
with separator: Document,
) -> Document
Joins a list of documents inserting the given separator between each existing document.
Examples
let message =
["Gleam", "is", "fun!"]
|> list.map(from_string)
|> join(with: space)
message |> to_string(80)
// -> "Gleam is fun!"
pub const line: Document
A document that is always printed as a single new line.
Examples
line |> to_string(80)
// -> "\n"
pub fn lines(size: Int) -> Document
A document that is always printed as a series of consecutive newlines.
Examples
lines(3) |> to_string(80)
// -> "\n\n\n"
pub fn nest(doc: Document, by indentation: Int) -> Document
Increases the nesting level of a document by the given amount.
When the pretty printer breaks a group by inserting a newline, it also adds a whitespace padding equal to its nesting level.
Examples
let one = [space, from_string("one")] |> concat |> nest(by: 1)
let two = [space, from_string("two")] |> concat |> nest(by: 2)
let three = [space, from_string("three")] |> concat |> nest(by: 3)
let list = [from_string("list:"), one, two, three] |> concat |> group
list |> to_string(10)
// -> "list:
// one
// two
// three"
pub fn nest_docs(
docs: List(Document),
by indentation: Int,
) -> Document
Joins together a list of documents and increases their nesting level.
This is a shorthand for nest(concat(docs), by: indentation).
Examples
[from_string("one"), space, from_string("two")]
|> nest_docs(by: 2)
|> append(space)
|> append(from_string("three"))
|> group
|> to_string(5)
// ->
// one
// two
// three
pub fn prepend(
to first: Document,
doc second: Document,
) -> Document
Prefixes a document to another one.
Examples
from_string("printed!")
|> prepend(from_string("pretty "))
|> to_string(80)
// -> "pretty printed!"
pub fn prepend_docs(
first: Document,
docs: List(Document),
) -> Document
Prefixes multiple documents to another one.
This is a shorthand for prepend(to: first, doc: concat(docs)).
Examples
from_string("fun!")
|> prepend_docs([from_string("Gleam "), from_string("is ")])
|> to_string(80)
// -> "Gleam is fun!"
pub const soft_break: Document
A document that is always rendered as an empty string but can act as a breaking point for the pretty printer.
This is a shorthand for break("", "").
Examples
let doc = [from_string("soft"), soft_break, from_string("break")]
doc |> to_string(80)
// -> "softbreak"
doc |> to_string(5)
// -> "soft
// break"
pub const space: Document
A document that is rendered as a single whitespace " " but can be broken
by the pretty printer into newlines instead.
This is a shorthand for break(" ", "").
Examples
let doc =
["pretty", "printed"]
|> list.map(from_string)
|> join(with: space)
doc |> to_string(80)
// -> "pretty printed"
doc |> to_string(10)
// -> "pretty
// printed"
pub fn to_string(doc: Document, limit: Int) -> String
Turns a document into a pretty printed string, trying to fit it into lines
of maximum size specified by limit.
The pretty printed process can be thought of as follows:
- the pretty printer first tries to print every group on a single line
- all the
breakdocuments are rendered as their first argument - if the string fits on the specified width this is the result
- if the string does not fit on a single line the outermost group is split:
- all of its
breakdocuments are rendered as their second argument - a newline is inserted after every
break - a padding of the given nesting level is added after every inserted newline
- all inner groups are then considered on their own: the splitting of the outermost group does not imply that the inner groups will be split as well
- all of its
Examples
For some examples of how pretty printing works for each kind of document you can have a look at the package documentation. There’s also a step-by-step tutorial that will guide you through the implementation of a simple pretty printer, covering most of the Glam API.
pub fn zero_width_string(string: String) -> Document
Turns a string into a document whose length is not taken into account when formatting it.
This kind of string can be used to render non-visible characters like ansi color codes.
Examples
// Should break in two lines, but doesn't because of the zero_width_string
// does not contribute to the total line length.
[
zero_width_string("\u{001b}[1;31m"),
from_string("I'm a red"),
break(", ", ","),
from_string("bold text"),
]
|> concat
|> group
|> to_string(20)
// -> "\u{001b}[1;31mI'm a red, bold text"