module Pp: Pp
The pretty printer provided by the Pp
module is intended for tree-like
structures. Documents are represented by an abstract type t
. A document
can be printed to a file or a string and during this process the pretty
printer decides about the final outcome of the document. The only parameter
it takes into account is the total line width and the number of characters a
sub-document occupies.
A document of type t
can be very small entity like a single word.
Functions combine small documents to larger ones which then can be pretty
printed.
type
t
val empty : t
empty
is used in one branch of an if
statement.val ($) : t -> t -> t
x $ y
concatenates two documents x
and y
into a
larger one. It does not introduce any space or other separation between the two
original documents.val text : string -> t
text
function turns a string into a document. The pretty printed
representation of the resulting document is exactly the string text
was
applied to.val break : t
break
s. A break
can be
either represented by a single space or a newline followed by a number of spaces.
The pretty printer makes this decision based on the available space. So think
of a break
as a space that might come out as a newline. To give the pretty
printer enough flexibility documents must be joined with break
s:
x $ break $ y
.val break_null : t
break_null
behaves like break
except it does not insert anything when no
newline is inserted.val break_with : string -> t
break
my be not always appropriate. The
function break_with s
behaves like break
except that it uses a user supplied
string s
instead of the space.break
s not one by one but
looks at all break
s of a sub-document. Documents are structured into
sub-documents by group-operators. Different group operators exist to control the
behavior of the pretty printer.val nest : int -> t -> t
break
as a newline it also
prints some spaces after it to indent the following line. The number of spaces
is controlled by the nest
operator that takes a document as argument:
nest n d
. All breaks turned to newlines inside document d
are followed by n
spaces. The nest
operator nests properly such that it takes the spaces
introduced by nest
s on the outer level also into account.val hgrp : t -> t
hgrp
operator creates a horizontal group. Breaks inside a hgrp
are never
turned into newlines but always come out as spaces. This group has a very
limited usefulness because it easily overruns any given line length.val vgrp : t -> t
vgrp
operator creates a vertical group. All break
s inside a
vgrp
are represented as newlines followed by spaces. Although all break
s
come out as newlines the indentation of lines inside the group may differ:
nesting is independent of grouping and thus different nesting levels can be
active in the same group. Because of the fixed pretty printing strategy vgrp
s
are used mostly at the top level of documents only.val agrp : t -> t
agrp
is the most versatile. Breaks inside this
group are either all turned into newlines (followed by spaces), or into spaces.
Subgroups are, of course, not affected but considered individually.val fgrp : t -> t
agrp
is fixed for all breaks of the group.
Inside a flexible group fgrp
each break
is considered individually: when
the document up to the next break
fits into the current line the break
comes
out as space. Otherwise it comes out as newline followed by spaces.val to_string : ?width:int -> t -> string
val to_file : ?width:int -> Pervasives.out_channel -> t -> unit
val list : sep:t -> f:('a -> t) -> 'a list -> t
list sep f
function takes care to insert the separator only between objects
but not at the end of the list. It creates a sep
separated list. Individual
items are printed using f
. For the common case where commas are used for
separating we also provide an extra definitionval commalist : f:('a -> t) -> 'a list -> t
val ($/) : t -> t -> t
x $ break $ y
to insert a break
it is convenient to
define an operator for this: x ^/ y
joins x
and y
with a break
.val ($//) : t -> t -> t
break_null
.val block : ?indent:int -> f:('a -> t) -> 'a list -> t
block
contains objects xs
formatted by f
and enclosed by curly
braces. Its body will be indented in case it does not fit on a single line.
The default indentation is 4module Infix:sig
..end
val hlist : t list -> t
hlist [x1,..,xn] = hgrp [x1; break; x2; ...; break; xn)
val vlist : t list -> t
vlist [x1,..,xn] = vgrp [x1; break; x2; ...; break; xn)
val alist : t list -> t