Module PPrintEngine
A pretty-printing engine and a set of basic document combinators.
Building documents
val empty : document
empty
is the empty document.
val char : char -> document
char c
is a document that consists of the single characterc
. This character must not be a newline.
val string : string -> document
string s
is a document that consists of the strings
. This string must not contain a newline.
val substring : string -> int -> int -> document
substring s ofs len
is a document that consists of the portion of the strings
delimited by the offsetofs
and the lengthlen
. This portion must not contain a newline.
val fancystring : string -> int -> document
fancystring s apparent_length
is a document that consists of the strings
. This string must not contain a newline. The string may contain fancy characters: color escape characters, UTF-8 or multi-byte characters, etc. Thus, its apparent length (which measures how many columns the text will take up on screen) differs from its length in bytes.
val fancysubstring : string -> int -> int -> int -> document
fancysubstring s ofs len apparent_length
is a document that consists of the portion of the strings
delimited by the offsetofs
and the lengthlen
. This portion must contain a newline. The string may contain fancy characters.
val utf8string : string -> document
utf8string s
is a document that consists of the UTF-8-encoded strings
. This string must not contain a newline.
val hardline : document
hardline
is a forced newline document. This document forces all enclosing groups to be printed in non-flattening mode. In other words, any enclosing groups are dissolved.
val blank : int -> document
blank n
is a document that consists ofn
blank characters.
val break : int -> document
break n
is a document which consists of eithern
blank characters, when forced to display on a single line, or a single newline character, otherwise. Note that there is no choice at this point: choices are encoded by thegroup
combinator.
val (^^) : document -> document -> document
doc1 ^^ doc2
is the concatenation of the documentsdoc1
anddoc2
.
val nest : int -> document -> document
nest j doc
is the documentdoc
, in which the indentation level has been increased byj
, that is, in whichj
blanks have been inserted after every newline character. Read this again: indentation is inserted after every newline character. No indentation is inserted at the beginning of the document.
val group : document -> document
group doc
encodes a choice. If possible, then the entire documentgroup doc
is rendered on a single line. Otherwise, the group is dissolved, anddoc
is rendered. There might be further groups withindoc
, whose presence will lead to further choices being explored.
val ifflat : document -> document -> document
ifflat doc1 doc2
is rendered asdoc1
if part of a group that can be successfully flattened, and is rendered asdoc2
otherwise. Use this operation with caution. Because the pretty-printer is free to choose betweendoc1
anddoc2
, these documents should be semantically equivalent.
val align : document -> document
align doc
is the documentdoc
, in which the indentation level has been set to the current column. Thus,doc
is rendered within a box whose upper left corner is the current position.
val range : (range -> unit) -> document -> document
range hook doc
is printed exactly like the documentdoc
, but allows the caller to register a hook that is applied, when the document is printed, to the range occupied by this document in the output text. This offers a way of mapping positions in the output text back to (sub)documents.
Rendering documents
module ToChannel : PPrintRenderer.RENDERER with type channel = Stdlib.out_channel and type document = document
This renderer sends its output into an output channel.
module ToBuffer : PPrintRenderer.RENDERER with type channel = Stdlib.Buffer.t and type document = document
This renderer sends its output into a memory buffer.
module ToFormatter : PPrintRenderer.RENDERER with type channel = Stdlib.Format.formatter and type document = document
This renderer sends its output into a formatter channel.
Defining custom documents
val infinity : requirement
class type output = object ... end
type state
=
{
}
class type custom = object ... end
val custom : custom -> document
The function
custom
constructs a custom document. In other words, it converts an object of typecustom
to a document.
val requirement : document -> requirement
requirement doc
computes the width requirement of the documentdoc
. It works in constant time.