module Pretty:sig..end
Utility functions for pretty-printing. The major features provided by this module are
fprintf-style interface with support for user-defined printersPretty-printing occurs in two stages:
Pretty.doc object that encodes all of the elements to be
printed
along with alignment specifiers and optional and mandatory newlinesPretty.doc to a certain width and emit it as a string, to an
output stream or pass it to a user-defined functionThe formatting algorithm is not optimal but it does a pretty good job while still operating in linear time. The original version was based on a pretty printer by Philip Wadler which turned out to not scale to large jobs.
API
type doc
The type of unformated documents. Elements of this type can be
constructed in two ways. Either with a number of constructor shown below,
or using the Pretty.dprintf function with a printf-like interface.
The Pretty.dprintf method is slightly slower so we do not use it for
large jobs such as the output routines for a compiler. But we use it for
small jobs such as logging and error messages.
Constructors for the doc type.
val nil : docConstructs an empty document
val (++) : doc -> doc -> docConcatenates two documents. This is an infix operator that associates to the left.
val concat : doc -> doc -> doc
val text : string -> docA document that prints the given string
val num : int -> docA document that prints an integer in decimal form
val num64 : int64 -> docA document that prints a 64-bit int in decimal form
val real : float -> docA document that prints a real number
val chr : char -> docA document that prints a character. This is just like Pretty.text
with a one-character string.
val line : docA document that consists of a mandatory newline. This is just like (text
"\n"). The new line will be indented to the current indentation level,
unless you use Pretty.leftflush right after this.
val leftflush : docUse after a Pretty.line to prevent the indentation. Whatever follows
next will be flushed left. Indentation resumes on the next line.
val break : docA document that consists of either a space or a line break. Also called an optional line break. Such a break will be taken only if necessary to fit the document in a given width. If the break is not taken a space is printed instead.
val align : docMark the current column as the current indentation level. Does not print anything. All taken line breaks will align to this column. The previous alignment level is saved on a stack.
val unalign : docReverts to the last saved indentation level.
val mark : docMark the beginning of a markup section. The width of a markup section is considered 0 for the purpose of computing identation
val unmark : docThe end of a markup section
Syntactic sugar
val indent : int -> doc -> docIndents the document. Same as ((text " ") ++ align ++ doc ++ unalign),
with the specified number of spaces.
val markup : doc -> docPrints a document as markup. The marked document cannot contain line breaks or alignment constructs.
val seq : sep:doc -> doit:('a -> doc) -> elements:'a list -> docFormats a sequence. sep is a separator, doit is a function that
converts an element to a document.
val docList : ?sep:doc -> ('a -> doc) -> unit -> 'a list -> docAn alternative function for printing a list. The unit argument is there
to make this function more easily usable with the Pretty.dprintf
interface. The first argument is a separator, by default a comma.
val d_list : string -> (unit -> 'a -> doc) -> unit -> 'a list -> docsm: Yet another list printer. This one accepts the same kind of
printing function that Pretty.dprintf does, and itself works
in the dprintf context. Also accepts
a string as the separator since that's by far the most common.
val docArray : ?sep:doc ->
(int -> 'a -> doc) -> unit -> 'a array -> docFormats an array. A separator and a function that prints an array element. The default separator is a comma.
val docOpt : ('a -> doc) -> unit -> 'a option -> docPrints an 'a option with None or Some
val d_int32 : int32 -> docPrint an int32
val f_int32 : unit -> int32 -> doc
val d_int64 : int64 -> doc
val f_int64 : unit -> int64 -> doc
module MakeMapPrinter:functor (Map:sigtypekeytype'atval fold :(key -> 'a -> 'b -> 'b) ->
'a t -> 'b -> 'bend) ->sig..end
Format maps.
module MakeSetPrinter:
Format sets.
val insert : unit -> doc -> docA function that is useful with the printf-like interface
val dprintf : ('a, unit, doc, doc) Stdlib.format4 -> 'aThis function provides an alternative method for constructing
doc objects. The first argument for this function is a format string
argument (of type ('a, unit, doc) format; if you insist on
understanding what that means see the module Printf). The format string
is like that for the printf function in C, except that it understands a
few more formatting controls, all starting with the @ character.
See the gprintf function if you want to pipe the result of dprintf into some other functions.
The following special formatting characters are understood (these do not correspond to arguments of the function):
Pretty.align. Every format string must have matching
Pretty.align and Pretty.unalign. Pretty.unalign.Pretty.line. Just like "\n"Pretty.break.Pretty.mark. Pretty.unmark.Pretty.leftflush
Should be used immediately after @! or "\n".In addition to the usual printf % formatting characters the following two
new characters are supported:
unit -> doc. This argument is
invoked to produce a documentunit -> 'a -> doc
and the second of type 'a. (The extra unit is do to the
peculiarities of the built-in support for format strings in Ocaml. It
turns out that it is not a major problem.) Here is an example of how
you use this:dprintf "Name=%s, SSN=%7d, Children=@[%a@]\n"
pers.name pers.ssn (docList (chr ',' ++ break) text)
pers.children
The result of dprintf is a Pretty.doc. You can format the document and
emit it using the functions Pretty.fprint and Pretty.sprint.
val gprintf : (doc -> 'b) -> ('a, unit, doc, 'b) Stdlib.format4 -> 'aLike Pretty.dprintf but more general. It also takes a function that is
invoked on the constructed document but before any formatting is done. The
type of the format argument means that 'a is the type of the parameters of
this function, unit is the type of the first argument to %a and %t
formats, doc is the type of the intermediate result, and 'b is the type of
the result of gprintf.
val fprint : Stdlib.out_channel -> width:int -> doc -> unitFormat the document to the given width and emit it to the given channel
val sprint : width:int -> doc -> stringFormat the document to the given width and emit it as a string
val fprintf : Stdlib.out_channel -> ('a, unit, doc) Stdlib.format -> 'aLike Pretty.dprintf followed by Pretty.fprint
val printf : ('a, unit, doc) Stdlib.format -> 'aLike Pretty.fprintf applied to stdout
val eprintf : ('a, unit, doc) Stdlib.format -> 'aLike Pretty.fprintf applied to stderr
val withPrintDepth : int -> (unit -> unit) -> unitInvokes a thunk, with printDepth temporarily set to the specified value
The following variables can be used to control the operation of the printer
val printDepth : int Stdlib.refSpecifies the nesting depth of the align/unalign pairs at which
everything is replaced with ellipsis
val printIndent : bool Stdlib.refIf false then does not indent
val fastMode : bool Stdlib.refIf set to true then optional breaks are taken only when the document
has exceeded the given width. This means that the printout will looked
more ragged but it will be faster
val flushOften : bool Stdlib.refIf true the it flushes after every print
val flattenBeforePrint : bool Stdlib.refWhether to rebalance doc before printing it to avoid stack-overflows
val countNewLines : int Stdlib.refKeep a running count of the taken newlines. You can read and write this from the client code if you want
val auto_printer : string -> 'bA function that when used at top-level in a module will direct the pa_prtype module generate automatically the printing functions for a type