A pretty printing library
Document lines and columns are 0-based offsets.
Documents are built using append
as horizontal, line-wise concatenation.
The functions in this module let you build documents that respond well
to width constraints (such as flexGroup
and flexAlt
).
public func showDoc<A>(showAnn : A -> Text, doc : Doc<A>) : Text
public func mapDoc<A, B>(doc : Doc<A>, f : A -> B) : Doc<B>
Transforms all annotations in the given document, using the passed function
public func append<A>(d1 : Doc<A>, d2 : Doc<A>) : Doc<A>
Appending two documents will put them next to each other on a line.
public let empty : Doc<None>
The empty document
public func isEmpty<A>(doc : Doc<A>) : Bool
Checks whether the document is empty.
public func align<A>(n : Nat, doc : Doc<A>) : Doc<A>
Increases the indentation level by the number of spaces (for alignment purposes).
public func alignCurrentColumn<A>(doc : Doc<A>) : Doc<A>
Increases the indentation level so that it aligns to the current column.
public func annotate<A>(annotation : A, doc : Doc<A>) : Doc<A>
Adds an annotation to a document. Printers can interpret annotations to style their output, eg. ANSI colors.
public func flexGroup<A>(doc : Doc<A>) : Doc<A>
Attempts to layout the document with flex alternatives, falling back to defaults if it doesn't fit the page width.
public func flexSelect<A>(
doc : Doc<A>,
defaults : Doc<A>,
fallback : Doc<A>
) : Doc<A>
Attempts to layout the first document with flex alternatives, falling back to defaults if it doesn't fit the page width. If the flex alternatives are used then the second document will be appended, otherwise the third document will be appended.
public func flexAlt<A>(doc : Doc<A>, fallback : Doc<A>) : Doc<A>
Attempts to layout the first document when in a flex group, falling back to the second as a default.
public func withPosition<A>(f : Position -> Doc<A>) : Doc<A>
Build a document based on the current layout position.
public func text<A>(t : Text) : Doc<A>
The most basic document leaf. This should not contain newlines. If it does your document will look very funny.
public func lineBreak<A>() : Doc<A>
Inserts a hard line break.
public func spaceBreak<A>() : Doc<A>
Inserts a space when in a flex group, otherwise inserts a break.
public func softBreak<A>() : Doc<A>
Inserts nothing when in a flex group, otherwise inserts a break.
public func space<A>() : Doc<A>
A singe space character.
public func paragraph<A>(docs : [Doc<A>]) : Doc<A>
Appends documents with a space-break in between them.
public func textParagraph<A>(t : Text) : Doc<A>
Constructs a wrapping paragraph from a blob of text. Ignores newlines and multiple spaces.
public func appendBreak<A>(doc1 : Doc<A>, doc2 : Doc<A>) : Doc<A>
Appends two documents with a break between them.
public func appendSpace<A>(doc1 : Doc<A>, doc2 : Doc<A>) : Doc<A>
Appends two documents with a space between them.
public func appendSpaceBreak<A>(doc1 : Doc<A>, doc2 : Doc<A>) : Doc<A>
Appends two documents with a space between them, falling back to a break if that does not fit.
public func enclose<A>(
open : Doc<A>,
close : Doc<A>,
inner : Doc<A>
) : Doc<A>
Uses an opening and closing document to wrap another document.
public func encloseEmptyAlt<A>(
open : Doc<A>,
close : Doc<A>,
fallback : Doc<A>,
inner : Doc<A>
) : Doc<A>
Uses an opening and closing document to wrap another document, falling back when the inner document is empty.
encloseEmptyAlt(text("[ "), text(" ]"), text("[]"), #empty)
public func encloseWithSeparator<A>(
open : Doc<A>,
close : Doc<A>,
separator : Doc<A>,
inner : [Doc<A>]
) : Doc<A>
Uses an opening and closing document, as a well as a separator, to render a series of documents.
public func foldWithSeparator<A>(separator : Doc<A>, docs : [Doc<A>]) : Doc<A>
Appends a series of documents together with a separator in between them.
public func foldWith<A>(docs : [Doc<A>], f : (Doc<A>, Doc<A>) -> Doc<A>) : Doc<A>
Appends a series of documents together with a given append function. This is notable because it ignores empty documents.
public let plainText : Printer<Text, Any, Text>
A plain text printer. Can be used with any document.
Configuration options for the printer.
pageWidth
- The printer will try not to exceed this width on any given line.ribbonRatio
- Ratio between 0.0 and 1.0, defaults to 1.0. The printer will
use this ratio to calculate the printable area between the current indentation
level and the pageWidth
.indentUnit
- The string used for a single indent.indentWidth
- The assumed character width of a single indentUnit
.public let twoSpaces : PrintOptions
Prints 2-space indents, with a default 80-column page width.
public let fourSpaces : PrintOptions
Prints 4-space indents, with a default 80-column page width.
public func print<Buf, A, Res>(
printer : Printer<Buf, A, Res>,
opts : PrintOptions,
doc : Doc<A>
) : Res
Prints a documents given a printer and print options.
This will use full line-lookahead from the start of a flex group. If it encounters a break or content overflows the page-width, it will layout the group using flex alternative defaults instead.