Library
Module
Module type
Parameter
Class
Class type
The pretty printer and document combinators, parameterized by a cost factory.
module C : Signature.CostFactory
type cost = C.t
The cost
type
Examples in the rest of this section assume that the program begins with
open Pretty_expressive
let cf = Printer.default_cost_factory ~page_width:10 ()
module P = Printer.Make (val cf)
open P
val text : string -> doc
text s
is a document for textual content s
; s
must not contain a newline.
Examples:
# pretty_print (text "Portal") |> print_endline;;
Portal
- : unit = ()
val newline : string option -> doc
a ^^ b
is a document for concatenation of documents a
and b
without alignment. In the paper, the symbol <>
is used for the operator. We use ^^
in the OCaml implementation instead to avoid shadowing the built-in not equal operator. This operator also known as the unaligned concatenation, which is widely used in traditional pretty printers.
See also Printer.MakeCompat
for a functor that provides this operator under the symbol <>
.
Examples:
let left_doc = text "Splatoon" ^^ nl ^^ text "Nier";;
let right_doc = text "Automata" ^^ nl ^^ text "FEZ";;
# pretty_print (left_doc ^^ right_doc) |> print_endline;;
Splatoon
NierAutomata
FEZ
- : unit = ()
By "without alignment," we mean that the right document is not treated as as box with a rigid structure. This makes it easy to format code in C-like languages, whose array expression, function call, and curly braces should not be rigid.
a <|> b
is a document for a choice between document a
and b
.
# let print_doc w =
let cf = Printer.default_cost_factory ~page_width:w () in
let module P = Printer.Make (val cf) in
let open P in
pretty_print (text "Chrono Trigger" <|>
(text "Octopath" ^^ nl ^^ text "Traveler")) |> print_endline;;
val print_doc : int -> unit = <fun>
# print_doc 10;;
Octopath
Traveler
- : unit = ()
# print_doc 15;;
Chrono Trigger
- : unit = ()
See also Best Practice for Document Construction
align d
is a document that aligns d
at the column position.
Examples:
# pretty_print (left_doc ^^ align right_doc) |> print_endline;;
Splatoon
NierAutomata
FEZ
- : unit = ()
The aligned concatenation operator (<+>)
is a derived combinator that composes (^^)
and align
together. It is especially useful for languages that uses the the box model for code styling.
nest n d
is a document that increments the indentation level by n
when rendering d
.
Examples:
# pretty_print (text "when 1 = 2:" ^^ nest 4 (nl ^^ text "print 'oh no!'"))
|> print_endline;;
when 1 = 2:
print 'oh no!'
- : unit = ()
The increment does not affect content on the current line. In the following example, when 1 = 2:
is not further indented.
# pretty_print (nest 4 (text "when 1 = 2:" ^^ nl ^^ text "print 'oh no!'"))
|> print_endline;;
when 1 = 2:
print 'oh no!'
- : unit = ()
reset d
is a document that resets indentation level to 0 in d
. This is especially useful for formatting multi-line strings and multi-line comments.
Examples:
# let s_d = reset (text "#<<EOF" ^^ nl ^^
text "Zelda" ^^ nl ^^
text "Baba is you" ^^ nl ^^
text "EOF");;
val s_d : doc = <abstr>
# pretty_print (text "when 1 = 2:" ^^ nest 4 (nl ^^ text "print " ^^ s_d))
|> print_endline;;
when 1 = 2:
print #<<EOF
Zelda
Baba is you
EOF
- : unit = ()
cost c d
is a document that artificially adds cost c
to d
.
In the below example, we artificially adds overflow to text "CrossCode"
, making it a non-optimal choice, even though text "CrossCode"
would have been the optimal choice had cost
not been used.
Examples:
# pretty_print (cost (1, 0) (text "CrossCode") <|>
(text "Final" ^^ nl ^^ text "Fantasy")) |> print_endline;;
Final
Fantasy
- : unit = ()
# pretty_print (text "CrossCode" <|>
(text "Final" ^^ nl ^^ text "Fantasy")) |> print_endline;;
CrossCode
- : unit = ()
cost
is especially useful in combination with a custom cost factory. See the section for further details.
val fail : doc
A document that always fails. It interacts with (<|>)
: failing branches are pruned away.
Examples:
# pretty_print (text "Sea of Stars" ^^ fail) |> print_endline;;
Exception: Failure "fails to render".
# pretty_print ((text "Sea of Stars" ^^ fail) <|> text "Hades") |> print_endline;;
Hades
- : unit = ()
print d
prints the document d
to an info
record. The optional ~init_c
can be used to indicate that the printing begins at a non-zero column position.
val pretty_print : ?init_c:int -> doc -> string
pretty_print d
prints the document d
to a string. The optional ~init_c
can be used to indicate that the printing begins at a non-zero column position.
Examples:
# print_string "Languages: ";
pretty_print (align (text "Racket" ^^ nl ^^
text "OCaml" ^^ nl ^^
text "Pyret")) |> print_endline;;
Languages: Racket
OCaml
Pyret
- : unit = ()
# print_string "Languages: ";
pretty_print ~init_c:11
(align (text "Racket" ^^ nl ^^
text "OCaml" ^^ nl ^^
text "Pyret")) |> print_endline;;
Languages: Racket
OCaml
Pyret
- : unit = ()
flatten d
is a document that replaces newlines and indentation spaces with what's specified in newline
when rendering d
.
Examples:
# pretty_print (flatten (text "Fire Emblem" ^^ nl ^^ text "Awakening"))
|> print_endline;;
Fire Emblem Awakening
- : unit = ()
# pretty_print (flatten (text "Mario + Rabbids" ^^ break ^^ text "Kingdom Battle"))
|> print_endline;;
Mario + RabbidsKingdom Battle
- : unit = ()
# pretty_print (flatten (text "XCOM 2" ^^ hard_nl ^^ text "War of the Chosen"))
|> print_endline;;
Exception: Failure "fails to render".
# pretty_print (flatten (text "Tactics Ogre" ^^
newline (Some ": ") ^^
text "Reborn"))
|> print_endline;;
Tactics Ogre: Reborn
- : unit = ()
group d
is a shorthand for d <|> flatten d
. This combinator is a part of most traditional pretty printers.
a <+> b
is a shorthand for a ^^ align b
. It is also known as the aligned concatenation.
fold_doc (++) ds
is a shorthand for d_1 ++ d_2 ++ ... ++ d_n
where d_1 d_2 ... d_n
are drawn from ds
.
vcat ds
is a shorthand for d_1 <$> d_2 <$> ... <$> d_n
where d_1 d_2 ... d_n
are drawn from ds
.
vcat ds
is a shorthand for d_1 <-> d_2 <-> ... <-> d_n
where d_1 d_2 ... d_n
are drawn from ds
.
val empty : doc
Equivalent to text ""
val space : doc
Equivalent to text " "
val comma : doc
Equivalent to text ","
val lbrack : doc
Equivalent to text "["
val rbrack : doc
Equivalent to text "]"
val lbrace : doc
Equivalent to text "{"
val rbrace : doc
Equivalent to text "}"
val lparen : doc
Equivalent to text "("
val rparen : doc
Equivalent to text ")"
val dquote : doc
Equivalent to text "\""