the-sett / elm-pretty-printer / Pretty

Wadler's Pretty printer. Use the constructor functions to build up a Doc and lay it out to fit a page width using the pretty function.


type alias Doc t =
Internals.Doc t

The type of documents that can be pretty printed.

Pretty printing documents

pretty : Basics.Int -> Doc t -> String

Pretty prints a document trying to fit it as best as possible to the specified column width of the page.

Building documents from string data

empty : Doc t

Creates an empty document. Empties are discarded during pretty printing.

Note that the join, lines, softlines and words functions also filter out empties. So if a list of Docs are joined by spaces any that are empty will be dircarded and not result in a double space in the result. For this reason empty is not the same as string "".

pretty 10 empty == ""

space : Doc t

Creates a document consisting of a single space.

string : String -> Doc t

Creates a document from a string.

taggedString : String -> t -> Doc t

Creates a document from a string and tags it.

Later on the tag can be used to change how the string is displayed. For example you might tag something as a Keyword then use a layout handler to show keywords in bold, and so on.

This is intended as a way of tagging strings in a Doc for the purpose of syntax highlighting.

char : Char -> Doc t

Creates a document from a character.

Joining documents together

append : Doc t -> Doc t -> Doc t

Appends two documents together.

a : Doc t -> Doc t -> Doc t

Short hand notation for append. Usefull when appending multiple parts together:

string "Hello"
    |> a space
    |> a "World"
    |> a (char '!')
    |> a line

join : Doc t -> List (Doc t) -> Doc t

Concatenates a list of documents together interspersed with a separator document.

Any empty docs in the list are dropped, so that multiple separators will not be placed together with nothing in between them. If this behaviour is intended use string "" instead of empty.

lines : List (Doc t) -> Doc t

Concatenate a list of documents together interspersed with lines. Very convenient when laying out lines after another:

lines
  [ string "Heading"
  , words [string "First", string "paragraph"]
  ...
  ]

==

string "Heading"
  |> a line
  |> a (string "First")
  |> a space
  |> a (string "paragraph")
  ...

Any empty docs in the list are dropped, so multiple lines will not be inserted around any empties.

See also words.

separators : String -> List (Doc t) -> Doc t

Concatenates a list of documents together interspersed with lines and separator strings. This is convenient when laying out lines where each line begins with a separator, for example if commas are to go on the start rather than the ends of lines:

separators ", "
  [ string "Heading"
  , words [string "First", string "paragraph"]
  ...
  ]

==

string "Heading"
  |> a line
  |> a (string ", ")
  |> a (string "First")
  |> a space
  |> a (string "paragraph")
  ...

The separator string is kept with the line break. If lines built in this way are placed into a group, then the inline version of the group will include the separators. The broken version of the group will have the separators after any indentation but otherwise at the start of each line.

separators ", "
  [ string "One"
  , string "Two"
  ...
  ]
  |> group

Can render as:

  One, Two, ...

Or

  One
  , Two
  , ...

Any empty docs in the list are dropped, so multiple lines will not be inserted around any empties.

See also words.

softlines : List (Doc t) -> Doc t

Like lines but uses softline instead.

Any empty docs in the list are dropped, so multiple lines will not be inserted around any empties.

words : List (Doc t) -> Doc t

Concatenate a list of documents together interspersed with spaces. Very convenient when laying out words after another.

See also lines.

Any empty docs in the list are dropped, so multiple spaces will not be inserted around any empties.

fold : (a -> Doc t -> Doc t) -> List a -> Doc t

Fold a list of documents from left to right using a given function.

fold f == List.foldl f empty

Fitting documents onto lines

group : Doc t -> Doc t

Tries to fit a document on a single line, replacing line breaks with single spaces where possible to achieve this.

line : Doc t

Creates a hard line break. This creates a new line, with subsequent text at the current indentation level.

Note that a line break can be undone, when it sits beneath a group operation. If this happens and the text after the line break is printed on the same line then the line break will be replaced by a space character.

tightline : Doc t

Creates a hard line break. This creates a new line, with subsequent text at the current indentation level.

Note that a line break can be undone, when it sits beneath a group operation. If this happens and the text after the line break is printed on the same line then this kind of line break will be replaced by an empty string; text before the break will flow directly into text after with no space added between.

This is sometimes useful where you wan an end delimiter such as '}', ']' or ')' to appear on a new line when the document is broken over multiple lines, but with no space before it when the document is rendered on a single line. For example:

long (function and args) -- Note the bracket has no space before it.

versus

long
    (function
        and
        args
    )

softline : Doc t

Creates a line break that will render to a single space if the documents it separates can be fitted onto one line, or a line break otherwise.

Indenting and alinging documents

align : Doc t -> Doc t

Adds an indent of the current column position to all line breaks in the document. The first line will not be indented, only subsequent nested lines will be.

nest : Basics.Int -> Doc t -> Doc t

Adds an indent of the given number of spaces to all line breakss in the document. The first line will not be indented, only subsequent nested lines will be.

hang : Basics.Int -> Doc t -> Doc t

Adds an indent of the current column position to all line breaks in the document and a further indent of the specified number of columns. The first line will not be indented, only subsequent nested lines will be.

indent : Basics.Int -> Doc t -> Doc t

Indents a whole document by a given number of spaces.

Putting things around documents

surround : Doc t -> Doc t -> Doc t -> Doc t

Places a document inside left and right book ends.

pretty 100 (surround (char '\') (char '/') string "hello")
  == "\hello/"

parens : Doc t -> Doc t

Wraps a document in parnethesese

braces : Doc t -> Doc t

Wraps a document in braces.

brackets : Doc t -> Doc t

Wraps a document in brackets.

Updating tags in documents

setTag : t -> Doc t -> Doc t

Set the tag of every string in the document.

updateTag : (String -> Maybe t -> Maybe t) -> Doc t -> Doc t

Conditionally update the tag of every string in the document.

The update function is called with the string and its current tag and should return a new tag for the string or Nothing to remove the current tag.