Module PPrintEngine

A pretty-printing engine and a set of basic document combinators.

Building documents

type document

This is the abstract type of documents.

val empty : document

empty is the empty document.

val char : char -> document

char c is a document that consists of the single character c. This character must not be a newline.

val string : string -> document

string s is a document that consists of the string s. 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 string s delimited by the offset ofs and the length len. This portion must not contain a newline.

val fancystring : string -> int -> document

fancystring s apparent_length is a document that consists of the string s. 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 string s delimited by the offset ofs and the length len. 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 string s. 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 of n blank characters.

val break : int -> document

break n is a document which consists of either n 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 the group combinator.

val (^^) : document -> document -> document

doc1 ^^ doc2 is the concatenation of the documents doc1 and doc2.

val nest : int -> document -> document

nest j doc is the document doc, in which the indentation level has been increased by j, that is, in which j 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 document group doc is rendered on a single line. Otherwise, the group is dissolved, and doc is rendered. There might be further groups within doc, whose presence will lead to further choices being explored.

val ifflat : document -> document -> document

ifflat doc1 doc2 is rendered as doc1 if part of a group that can be successfully flattened, and is rendered as doc2 otherwise. Use this operation with caution. Because the pretty-printer is free to choose between doc1 and doc2, these documents should be semantically equivalent.

val align : document -> document

align doc is the document doc, 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.

type point = int * int

A point is a pair of a line number and a column number.

type range = point * point

A range is a pair of points.

val range : (range -> unit) -> document -> document

range hook doc is printed exactly like the document doc, 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

type requirement = int
val infinity : requirement
class type output = object ... end
type state = {
width : int;

The line width. This parameter is fixed throughout the execution of the renderer.

ribbon : int;

The ribbon width. This parameter is fixed throughout the execution of the renderer.

mutable last_indent : int;

The number of blanks that were printed at the beginning of the current line. This field is updated (only) when a hardline is emitted. It is used (only) to determine whether the ribbon width constraint is respected.

mutable line : int;

The current line. This field is updated (only) when a hardline is emitted. It is not used by the pretty-printing engine itself.

mutable column : int;

The current column. This field must be updated whenever something is sent to the output channel. It is used (only) to determine whether the width constraint is respected.

}
class type custom = object ... end
val custom : custom -> document

The function custom constructs a custom document. In other words, it converts an object of type custom to a document.

val requirement : document -> requirement

requirement doc computes the width requirement of the document doc. It works in constant time.

val pretty : output -> state -> int -> bool -> document -> unit

pretty output state indent flatten doc prints the document doc. See the documentation of the method pretty.

val compact : output -> document -> unit

compact output doc prints the document doc. See the documentation of the method compact.