package pprint
Install
Dune Dependency
Authors
Maintainers
Sources
md5=d6b20d1db73cf15f79b2884a9e38bf06
sha512=f9a4ea908248cc14df1ef93418ce80598e88666b9347f683d5cc6f67a8c28290f0a4e40ae6f1842efa1d9c38d4802e7e3c77bbcf2e6f986c45ba12907e9580c9
doc/pprint/PPrint/index.html
Module PPrint
Source
A package of all of the above.
include module type of struct include PPrintEngine end
Building documents
Documents must be built in memory before they are rendered. This may seem costly, but it is a simple approach, and works well.
The following operations form a set of basic (low-level) combinators for building documents. On top of these combinators, higher-level combinators can be defined: see PPrintCombinators
.
This is the abstract type of documents.
The following basic (low-level) combinators allow constructing documents.
char c
is a document that consists of the single character c
. This character must not be a newline.
string s
is a document that consists of the string s
. This string must not contain a newline.
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.
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.
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.
utf8string s
is a document that consists of the UTF-8-encoded string s
. This string must not contain a newline.
utf8format format <args>...
is equivalent to utf8string (Printf.sprintf format <args>...)
.
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.
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.
doc1 ^^ doc2
is the concatenation of the documents doc1
and doc2
.
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.
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.
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.
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.
A point is a pair of a line number and a column number.
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
This renderer sends its output into an output channel.
This renderer sends its output into a memory buffer.
This renderer sends its output into a formatter channel.
Defining custom documents
A width requirement is expressed as an integer, where the value max_int
is reserved and represents infinity.
An output channel is represented abstractly as an object equipped with methods for displaying one character and for displaying a substring.
The rendering engine maintains the following internal state. Its structure is subject to change in future versions of the library. Nevertheless, it is exposed to the user who wishes to define custom documents.
type state = PPrintEngine.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.
*)
}
A custom document is defined by implementing the following methods.
The function custom
constructs a custom document. In other words, it converts an object of type custom
to a document.
The key functions of the library are exposed, in the hope that they may be useful to authors of custom (leaf and non-leaf) documents. In the case of a leaf document, they can help perform certain basic functions; for instance, applying the function pretty
to the document hardline
is a simple way of printing a hardline, while respecting the indentation parameters and updating the state in a correct manner. Similarly, applying pretty
to the document blank n
is a simple way of printing n
spaces. In the case of a non-leaf document (i.e., one which contains sub-documents), these functions are essential: they allow computing the width requirement of a sub-document and displaying a sub-document.
requirement doc
computes the width requirement of the document doc
. It works in constant time.
pretty output state indent flatten doc
prints the document doc
. See the documentation of the method pretty
.
include module type of struct include PPrintCombinators end
Single characters
The following constant documents consist of a single character.
Delimiters
precede l x
is l ^^ x
.
terminate r x
is x ^^ r
.
val enclose :
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document
enclose l r x
is l ^^ x ^^ r
.
The following combinators enclose a document within a pair of delimiters. They are partial applications of enclose
. No whitespace or line break is introduced.
Repetition
twice doc
is the document obtained by concatenating two copies of the document doc
.
repeat n doc
is the document obtained by concatenating n
copies of the document doc
.
Lists and options
concat docs
is the concatenation of the documents in the list docs
.
separate sep docs
is the concatenation of the documents in the list docs
. The separator sep
is inserted between every two adjacent documents.
concat_map f xs
is equivalent to concat (List.map f xs)
.
val separate_map :
PPrintEngine.document ->
('a -> PPrintEngine.document) ->
'a list ->
PPrintEngine.document
separate_map sep f xs
is equivalent to separate sep (List.map f xs)
.
val separate2 :
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document list ->
PPrintEngine.document
separate2 sep last_sep docs
is the concatenation of the documents in the list docs
. The separator sep
is inserted between every two adjacent documents, except between the last two documents, where the separator last_sep
is used instead.
optional f None
is the empty document. optional f (Some x)
is the document f x
.
Text
lines s
is the list of documents obtained by splitting s
at newline characters, and turning each line into a document via substring
. This code is not UTF-8 aware.
arbitrary_string s
is equivalent to separate (break 1) (lines s)
. It is analogous to string s
, but is valid even if the string s
contains newline characters.
words s
is the list of documents obtained by splitting s
at whitespace characters, and turning each word into a document via substring
. All whitespace is discarded. This code is not UTF-8 aware.
split ok s
splits the string s
before and after every occurrence of a character that satisfies the predicate ok
. The substrings thus obtained are turned into documents, and a list of documents is returned. No information is lost: the concatenation of the documents yields the original string. This code is not UTF-8 aware.
flow sep docs
separates the documents in the list docs
with the separator sep
and arranges for a new line to begin whenever a document does not fit on the current line. This is useful for typesetting free-flowing, ragged-right text. A typical choice of sep
is break b
, where b
is the number of spaces that must be inserted between two consecutive words (when displayed on the same line).
val flow_map :
PPrintEngine.document ->
('a -> PPrintEngine.document) ->
'a list ->
PPrintEngine.document
flow_map sep f docs
is equivalent to flow sep (List.map f docs)
.
url s
is a possible way of displaying the URL s
. A potential line break is inserted immediately before and immediately after every slash and dot character.
Alignment and indentation
val prefix :
int ->
int ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document
prefix n b left right
has the following flat layout:
left right
and the following non-flat layout:
left
right
The parameter n
controls the nesting of right
(when not flat). The parameter b
controls the number of spaces between left
and right
(when flat).
jump n b right
is equivalent to prefix n b empty right
.
val infix :
int ->
int ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document
infix n b middle left right
has the following flat layout:
left middle right
and the following non-flat layout:
left middle
right
The parameter n
controls the nesting of right
(when not flat). The parameter b
controls the number of spaces between left
and middle
(always) and between middle
and right
(when flat).
val surround :
int ->
int ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document
surround n b opening contents closing
has the following flat layout:
opening contents closing
and the following non-flat layout:
opening
contents
closing
The parameter n
controls the nesting of contents
(when not flat). The parameter b
controls the number of spaces between opening
and contents
and between contents
and closing
(when flat).
val soft_surround :
int ->
int ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document
soft_surround
is analogous to surround
, but involves more than one group, so it offers possibilities other than the completely flat layout (where opening
, contents
, and closing
appear on a single line) and the completely developed layout (where opening
, contents
, and closing
appear on separate lines). It tries to place the beginning of contents
on the same line as opening
, and to place closing
on the same line as the end of contents
, if possible.
val surround_separate :
int ->
int ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document list ->
PPrintEngine.document
surround_separate n b void opening sep closing docs
is equivalent to surround n b opening (separate sep docs) closing
, except when the list docs
is empty, in which case it reduces to void
.
val surround_separate_map :
int ->
int ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
PPrintEngine.document ->
('a -> PPrintEngine.document) ->
'a list ->
PPrintEngine.document
surround_separate_map n b void opening sep closing f xs
is equivalent to surround_separate n b void opening sep closing (List.map f xs)
.
Short-hands
!^s
is a short-hand for string s
.
x ^/^ y
separates x
and y
with a breakable space. It is a short-hand for x ^^ break 1 ^^ y
.
x ^//^ y
is a short-hand for prefix 2 1 x y
.