exfmt v0.5.0 Exfmt.Algebra
A set of functions for creating and manipulating algebra documents.
This module implements the functionality described in “Strictly Pretty” (2000) by Christian Lindig, with a few extensions detailed below.
It serves an alternative printer to the one defined in
Inspect.Algebra, which is part of the Elixir standard library
but does not entirely conform to the algorithm described by Christian
Lindig in a way that makes it unsuitable for use in ExFmt.
Extensions
nest/1can take the atom:currentinstead of an integer. With this value the formatter will set the indentation level to the current column position.break/2allows the user to specify a string that can be rendered in the document when the break is rendering in a flat layout. This was added to insert trailing newlines.break_parent/0can be used to force all parent groups to break. Inspired by Prettier’sbreakParent.
Link to this section Summary
Functions
Returns a document entity with the " " string as break
Returns a document entity with the " " string as break
Returns a document entity representing a break based on the given
string
Forces all parent groups to break
Concatenates a list of documents returning a new document
Concatenates two document entities returning a new document
Formats a given document for a given width
Glues two documents together inserting " " as a break between them
Glues two documents (doc1 and doc2) together inserting the given
break break_string between them
Returns a group containing the specified document doc.
Documents in a group are attempted to be rendered together
to the best of the renderer ability.
Examples
iex> doc = Inspect.Algebra.group(
...> Inspect.Algebra.concat(
...> Inspect.Algebra.group(
...> Inspect.Algebra.concat(
...> "Hello,",
...> Inspect.Algebra.concat(
...> Inspect.Algebra.break,
...> "A"
...> )
...> )
...> ),
...> Inspect.Algebra.concat(
...> Inspect.Algebra.break,
...> "B"
...> )
...> ))
iex> Inspect.Algebra.format(doc, 80)
["Hello,", " ", "A", " ", "B"]
iex> Inspect.Algebra.format(doc, 6)
["Hello,", "\n", "A", " ", "B"]
Insert a new line
Nests the given document at the given level
Surrounds a document with characters.
Puts the given document doc between the left and right documents enclosing
and nesting it. The document is marked as a group, to show the maximum as
possible concisely together.
Examples
iex> doc = Inspect.Algebra.surround("[", Inspect.Algebra.glue("a", "b"), "]")
iex> Inspect.Algebra.format(doc, 3)
["[", "a", "\n ", "b", "]"]
Maps and glues a collection of items
Converts an Elixir term to an algebra document
according to the Inspect protocol
Link to this section Types
t :: :doc_nil | :doc_line | :doc_break_parent | doc_cons | doc_nest | doc_break | doc_group | binary
Link to this section Functions
Returns a document entity with the " " string as break.
See break/2 for more information.
Returns a document entity with the " " string as break.
See break/2 for more information.
Returns a document entity representing a break based on the given
string.
This break can be rendered as a broken followed by a linebreak and or as
the given unbroken, depending on the mode of the chosen layout or the
provided separator.
Examples
Let’s create a document by concatenating two strings with a break between them:
iex> doc = Inspect.Algebra.concat(["a", Inspect.Algebra.break("\t"), "b"])
iex> Inspect.Algebra.format(doc, 80)
["a", "\t", "b"]
Notice the break was represented with the given string, because we didn’t reach a line limit. Once we do, it is replaced by a newline:
iex> break = Inspect.Algebra.break("\t")
iex> doc = Inspect.Algebra.concat([String.duplicate("a", 20), break, "b"])
iex> Inspect.Algebra.format(doc, 10)
["aaaaaaaaaaaaaaaaaaaa", "\n", "b"]
Forces all parent groups to break.
Concatenates a list of documents returning a new document.
Examples
iex> doc = concat(["a", "b", "c"])
...> format(doc, 80)
["a", "b", "c"]
Concatenates two document entities returning a new document.
Examples
iex> doc = concat("hello", "world")
...> format(doc, 80)
["hello", "world"]
Formats a given document for a given width.
Takes the maximum width and a document to print as its arguments and returns an IO data representation of the best layout for the document to fit in the given width.
Examples
iex> doc = glue("hello", " ", "world")
iex> format(doc, 30) |> IO.iodata_to_binary()
"hello world"
iex> format(doc, 10) |> IO.iodata_to_binary()
"hello\nworld"
Glues two documents together inserting " " as a break between them.
This means the two documents will be separated by " " in case they
fit in the same line. Otherwise a line break is used.
Examples
iex> doc = glue("hello", "world")
...> format(doc, 80)
["hello", " ", "world"]
Glues two documents (doc1 and doc2) together inserting the given
break break_string between them.
For more information on how the break is inserted, see break/1.
Examples
iex> doc = glue("hello", "\t", "world")
...> format(doc, 80)
["hello", "\t", "world"]
Returns a group containing the specified document doc.
Documents in a group are attempted to be rendered together
to the best of the renderer ability.
Examples
iex> doc = Inspect.Algebra.group(
...> Inspect.Algebra.concat(
...> Inspect.Algebra.group(
...> Inspect.Algebra.concat(
...> "Hello,",
...> Inspect.Algebra.concat(
...> Inspect.Algebra.break,
...> "A"
...> )
...> )
...> ),
...> Inspect.Algebra.concat(
...> Inspect.Algebra.break,
...> "B"
...> )
...> ))
iex> Inspect.Algebra.format(doc, 80)
["Hello,", " ", "A", " ", "B"]
iex> Inspect.Algebra.format(doc, 6)
["Hello,", "\n", "A", " ", "B"]
Insert a new line
Nests the given document at the given level.
Nesting will be appended to the line breaks.
Examples
iex> doc = Inspect.Algebra.nest(Inspect.Algebra.glue("hello", "world"), 5)
iex> Inspect.Algebra.format(doc, 5)
["hello", "\n ", "world"]
Surrounds a document with characters.
Puts the given document doc between the left and right documents enclosing
and nesting it. The document is marked as a group, to show the maximum as
possible concisely together.
Examples
iex> doc = Inspect.Algebra.surround("[", Inspect.Algebra.glue("a", "b"), "]")
iex> Inspect.Algebra.format(doc, 3)
["[", "a", "\n ", "b", "]"]
Maps and glues a collection of items.
It uses the given left and right documents as surrounding and the
separator document separator to separate items in docs.
Examples
iex> doc = surround_many("[", Enum.to_list(1..5), "]", &to_string/1)
iex> format(doc, 5) |> IO.iodata_to_binary
"[1,\n 2,\n 3,\n 4,\n 5]"
Converts an Elixir term to an algebra document
according to the Inspect protocol.