PPrint Library Reference

Synopsis

namespace PPrint
[<Sealed; NoEquality; NoComparison>] 
type Doc =
  static member (<^>): Doc * Doc -> Doc
  static member (<+>): Doc * Doc -> Doc
  static member (<.>): Doc * Doc -> Doc
  static member (</>): Doc * Doc -> Doc
  static member (<..>): Doc * Doc -> Doc
  static member (<//>): Doc * Doc -> Doc
[<AutoOpen>]
module PPrint =
  

Rendering

[<AbstractClass>] type Actions = new: unit -> Actions abstract Line: unit -> unit default Line: unit -> unit abstract User: obj -> unit default User: obj -> unit abstract Write: string -> unit val outputWithActions: Actions -> maxCols: option<int> -> doc: Doc -> unit val outputWithFun: write: (string -> unit) -> maxCols: option<int> -> doc: Doc -> unit val outputToWriter: writer: TextWriter -> maxCols: option<int> -> doc: Doc -> unit val render: maxCols: option<int> -> doc: Doc -> string

Basic Combinators

val empty: Doc val chr: char -> Doc val txt: string -> Doc val fmt: Printf.StringFormat<'a, Doc> -> 'a val nest: numCols: int -> (Doc -> Doc) val nestBy: prefix: string -> Doc -> Doc val line: Doc val linebreak: Doc val group: Doc -> Doc val gnest: numCols: int -> (Doc -> Doc) val choice: wide: Doc -> narrow: Doc -> Doc val delay: (unit -> Doc) -> Doc val softline: Doc val softbreak: Doc

User Defined Attributes

val user: obj -> Doc

Alignment Combinators

val column: (int -> Doc) -> Doc val nesting: (int -> Doc) -> Doc val indent: int -> Doc -> Doc val hang: int -> Doc -> Doc val align: Doc -> Doc val width: Doc -> (int -> Doc) -> Doc val fillBreak: width: int -> Doc -> Doc val fill: width: int -> Doc -> Doc

Sequence Combinators

val joinSep: Doc -> seq<Doc> -> Doc val joinWith: (Doc -> Doc -> Doc) -> seq<Doc> -> Doc val sep: seq<Doc> -> Doc val cat: seq<Doc> -> Doc val punctuate: punc: Doc -> docs: seq<Doc> -> seq<Doc> val hsep: seq<Doc> -> Doc val vsep: seq<Doc> -> Doc val fillSep: seq<Doc> -> Doc val hcat: seq<Doc> -> Doc val vcat: seq<Doc> -> Doc val fillCat: seq<Doc> -> Doc

Bracketing Combinators

val enclose: Doc * Doc -> Doc -> Doc val squotes: Doc -> Doc val dquotes: Doc -> Doc val parens: Doc -> Doc val angles: Doc -> Doc val braces: Doc -> Doc val brackets: Doc -> Doc

Bracketing Pairs

val lrsquote: Doc * Doc val lrdquote: Doc * Doc val lrparen: Doc * Doc val lrangle: Doc * Doc val lrbrace: Doc * Doc val lrbracket: Doc * Doc

Character Documents

val lparen: Doc val rparen: Doc val langle: Doc val rangle: Doc val lbrace: Doc val rbrace: Doc val lbracket: Doc val rbracket: Doc val squote: Doc val dquote: Doc val semi: Doc val colon: Doc val comma: Doc val space: Doc val dot: Doc val backslash: Doc val equals: Doc

Description

namespace PPrint

PPrint is a pretty printing combinator library for text documents that can be rendered to a desired maximum width.

PPrint is based on Wadler's and Leijen's work. Philip Wadler's article ''A prettier printer'' is a good introduction to the motivation and basic usage of this library. Daan Leijen's document ''PPrint, a prettier printer'' provides motivation for several additional primitives like align.

[<Sealed; NoEquality; NoComparison>] 
type Doc =

Represents a document that can be rendered to a given maximum width.

static member (<^>): Doc * Doc -> Doc

lhs <^> rhs is the concatenation of the documents lhs and rhs. For example, txt "a" <^> txt "b" renders as ab.

Note: This is the same as the operator <> used in the original Haskell libraries. In F#, the <> operator is already used.

static member (<+>): Doc * Doc -> Doc

Concatenates the given documents with a space in between. lhs <+> rhs is equivalent to lhs <^> space <^> rhs. For example, txt "a" <+> txt "b" renders as a b.

static member (<.>): Doc * Doc -> Doc

Concatenates the given documents with a line in between. lhs <.> rhs is equivalent to lhs <^> line <^> rhs.

For example

txt "a" <.> txt "b"

renders as

a
b

and

txt "a" <.> txt "b" |> group

renders as

a b

Note: In the original Haskell libraries, the symbol <$> was used for this operation, but it is not a legal symbol in F#.

static member (</>): Doc * Doc -> Doc

Concatenates the given documents with a softline in between. lhs </> rhs is equivalent to lhs <^> softline <^> rhs.

static member (<..>): Doc * Doc -> Doc

Concatenates the given documents with a linebreak in between. lhs <..> rhs is equivalent to lhs <^> linebreak <^> rhs.

For example

txt "a" <..> txt "b"

renders as

a
b

and

txt "a" <..> txt "b" |> group

renders as

ab
static member (<//>): Doc * Doc -> Doc

Concatenates the given documents with a softbreak in between. lhs <//> rhs is equivalent to lhs <^> softbreak <^> rhs.

[<AutoOpen>]
module PPrint =

Operations on pretty print documents.

[<AbstractClass>] 
type Actions =

Output actions.

abstract Line: unit -> unit

Called to output a newline.

default Line: unit -> unit

Default calls Write "\n".

abstract User: obj -> unit

Called for each user attribute within the document.

default User: obj -> unit

Default does nothing.

abstract Write: string -> unit

Called to write a string of characters.

val outputWithActions: Actions
                    -> maxCols: option<int>
                    -> doc: Doc
                    -> unit

Outputs the document using the given output actions.

val outputWithFun: write: (string -> unit)
                -> maxCols: option<int>
                -> doc: Doc
                -> unit

Outputs the document using the given output function.

val outputToWriter: writer: TextWriter
                 -> maxCols: option<int>
                 -> doc: Doc
                 -> unit

Outputs the document using the given text writer.

val render: maxCols: option<int> -> doc: Doc -> string

Renders the document as a string.

val empty: Doc

The empty document is equivalent to txt "".

val chr: char -> Doc

chr c renders to the character c. The character shouldn't be a newline. For example, chr 'x' renders to x.

val txt: string -> Doc

txt s renders to the string s. The string shouldn't contain any newline characters. For example, txt "hello" renders to hello.

val fmt: Printf.StringFormat<'a, Doc> -> 'a

fmt ... is equivalent to txt <| sprintf .... For example, to format an integer i, one could write fmt "%d" i.

val nest: numCols: int -> (Doc -> Doc)

doc |> nest n renders document doc indented by n more columns. See also: gnest and nestBy.

For example

[txt "x"; txt "y"; txt "z"]
|> punctuate comma
|> vsep
|> parens
|> nest 1

renders as

(x,
 y,
 z)

Note that in order for nest n doc to have any effect, you must have lines or linebreaks in the doc.

val nestBy: prefix: string -> Doc -> Doc

doc |> nestBy prefix renders document doc with given prefix added after line breaks. See also: nest.

For example

[txt "a"; txt "b"; txt "c"]
|> vsep
|> nestBy " * "
|> enclose (txt "(* ", line <^> txt " *)")

renders as

(* a
 * b
 * c
 *)
val line: Doc

Advances to the next line and indents, unless undone by group in which case line behaves like txt " ".

For example

[txt "a"; line; txt "b"]
|> hcat
|> nest 2

renders as

a
  b

while

[txt "a"; line; txt "b"]
|> hcat
|> nest 2
|> group

renders as

a b
val linebreak: Doc

Advances to the next line and indents, unless undone by group in which case linebreak behaves like empty.

For example

[txt "a"; linebreak; txt "b"]
|> hcat
|> nest 2

renders as

a
  b

while

[txt "a"; linebreak; txt "b"]
|> hcat
|> nest 2
|> group

renders as

ab
val group: Doc -> Doc

Used to specify alternative layouts. group doc undoes all line breaks in document doc. The resulting line of text is added to the current output if it fits. Otherwise, the document is rendered without changes (with line breaks).

For example

txt "a" <.> txt "b"

renders as

a
b

while

txt "a" <.> txt "b" |> group

renders as

a b

except when it wouldn't fit within the desired number of columns.

val gnest: numCols: int -> (Doc -> Doc)

doc |> gnest n is equivalent to doc |> group |> nest n which is equivalent to doc |> nest n |> group. nest is frequently combined with group.

val choice: wide: Doc -> narrow: Doc -> Doc

Used to specify alternative documents. The wide document is added to the current output line if it fits. Otherwise, the narrow document is rendered.

This combinator is not available in the original Haskell libraries. It allows one to create documents whose rendering may not produce optimal or easily predictable results. Nevertheless, careful use of this combinator can produce useful results. The initial use case for this combinator was to format Standard ML string literals so that they are either formatted onto a single line or onto multiple lines using line continuation characters.

For example, given

let wide = txt "\\\"a\\nb\\nc\\\""
let narrow = vsep [txt "\"a\\n\""; txt "\"b\\n\""; txt "\"c\""]

then

choice wide narrow

renders as the wide version

"a\nb\nc"

when it fits and as the narrow version

"a\n"
"b\n"
"c"

when the wide version does not fit.

val delay: (unit -> Doc) -> Doc

Creates a lazily computed document. delay <| fun () -> doc is equivalent to doc except that the expression doc may not be evaluated at all.

Note: This is primarily useful for specifying the narrow alternative to choice - unless, of course, there is a chance that the whole document will not be rendered at all.

val softline: Doc

Behaves like space if the resulting output fits, otherwise behaves like line.

val softbreak: Doc

Behaves like empty if the resulting output fits, otherwise behaves like line.

val user: obj -> Doc

user any is equivalent to empty except that the created document carries the given user attribute object any. The object is otherwise ignored by the library, but is carried throughout the layout computation and passed to the Actions.User rendering action at the point when everything before it has been rendered. This can be used to implement features such outputing ANSI control sequences to produce output with special effects.

val column: (int -> Doc) -> Doc

column f calls f with the current column during rendering to create a document to render.

val nesting: (int -> Doc) -> Doc

column f calls f with the current nesting during the layout process to create a document to render.

val indent: int -> Doc -> Doc

doc |> indent n indents doc by n columns.

val hang: int -> Doc -> Doc

doc |> hang n renders doc with nesting level set to the current column plus n.

val align: Doc -> Doc

doc |> align renders doc with the nesting level set to the current column.

For example

txt "foo" <^>
([txt "bar"; txt "baz"; txt "foobar"]
 |> punctuate comma
 |> vsep
 |> align
 |> parens)

renders as

foo(bar,
    baz,
    foobar)
val width: Doc -> (int -> Doc) -> Doc

width lhs rhs calls rhs with the width of lhs to create the document to concatenate to the right of lhs.

For example

width <| txt "foo" <| fun n ->
  [txt "bar"; txt "baz"; txt "foobar"]
  |> punctuate comma
  |> vsep
  |> parens
  |> nest (n+1)

renders to

foo(bar,
    baz,
    foobar)

Note that align can produce the above layout more directly, but other effects can be achieved with width.

val fillBreak: width: int -> Doc -> Doc

doc |> fillBreak width first renders doc and then appends spaces until the width of the output is at least width. If the width is already more than width, the nesting level is increased by width and a line is appended after doc.

val fill: width: int -> Doc -> Doc

doc |> fill width first renders doc and then appends spaces until the width is at least width.

val joinSep: Doc -> seq<Doc> -> Doc

joinSep sep is equivalent to joinWith <| fun l r -> l <^> sep <^> r.

val joinWith: (Doc -> Doc -> Doc) -> seq<Doc> -> Doc

Concatenate a sequence of documents using the given binary operator.

val sep: seq<Doc> -> Doc

docs |> sep is equivalent to docs |> vsep |> group.

val cat: seq<Doc> -> Doc

docs |> cat is equivalent to docs |> vcat |> group.

val punctuate: punc: Doc -> docs: seq<Doc> -> seq<Doc>

docs |> punctuate punc concatenates punc to the right of each document in docs except the last one.

For example

[txt "a"; txt "b"; txt "c"]
|> punctuate comma
|> hsep

renders to

a, b, c
val hsep: seq<Doc> -> Doc

Concatenates the documents using <+>.

For example

hsep [txt "a"; txt "b"; txt "c"]

renders to

a b c
val vsep: seq<Doc> -> Doc

Concatenates the documents using <.>.

For example

vsep [txt "a"; txt "b"; txt "c"]

renders to

a
b
c
val fillSep: seq<Doc> -> Doc

Concatenates the documents using </>.

val hcat: seq<Doc> -> Doc

Concatenates the documents using <^>.

For example

hcat [txt "a"; txt "b"; txt "c"]

renders to

abc
val vcat: seq<Doc> -> Doc

Concatenates the documents using <..>.

val fillCat: seq<Doc> -> Doc

Concatenates the documents using <//>.

val enclose: Doc * Doc -> Doc -> Doc

doc |> enclose (lhs, rhs) is equivalent to lhs <^> doc <^> rhs

val squotes: Doc -> Doc

squotes doc is equivalent to enclose lrsquote doc.

val dquotes: Doc -> Doc

dquotes doc is equivalent to enclose lrdquote doc.

val parens: Doc -> Doc

parens doc is equivalent to enclose lrparen doc.

val angles: Doc -> Doc

angles doc is equivalent to enclose lrangle doc.

val braces: Doc -> Doc

braces doc is equivalent to enclose lrbrace doc.

val brackets: Doc -> Doc

brackets doc is equivalent to enclose lrbracket doc.

val lrsquote: Doc * Doc

Equivalent to (squotesquote)

val lrdquote: Doc * Doc

Equivalent to (dquotedquote)

val lrparen: Doc * Doc

Equivalent to (lparenrparen)

val lrangle: Doc * Doc

Equivalent to (langlerangle)

val lrbrace: Doc * Doc

Equivalent to (lbracerbrace)

val lrbracket: Doc * Doc

Equivalent to (lbracketrbracket)

val lparen: Doc

Equivalent to txt "(".

val rparen: Doc

Equivalent to txt ")".

val langle: Doc

Equivalent to txt "<".

val rangle: Doc

Equivalent to txt ">".

val lbrace: Doc

Equivalent to txt "{".

val rbrace: Doc

Equivalent to txt "}".

val lbracket: Doc

Equivalent to txt "[".

val rbracket: Doc

Equivalent to txt "]".

val squote: Doc

Equivalent to txt "'".

val dquote: Doc

Equivalent to txt "\"".

val semi: Doc

Equivalent to txt ";".

val colon: Doc

Equivalent to txt ":".

val comma: Doc

Equivalent to txt ",".

val space: Doc

Equivalent to txt " ".

val dot: Doc

Equivalent to txt ".".

val backslash: Doc

Equivalent to txt "\\".

val equals: Doc

Equivalent to txt "=".