Printer.MakeSourceThe pretty printer and doc combinators, parameterized by a cost factory. See Signature.PrinterT for details.
A pretty expressive printer. The rest of this section assumes that the program begins with
open Pretty_expressive
let cf = Printer.default_cost_factory ~page_width:10 ()
module P = Printer.Make (val cf)
open Pmodule C : Signature.CostFactoryThe doc type
text s is a document for textual content s; s must not contain a newline.
Examples:
# pretty_print (text "Portal") |> print_endline;;
Portal
- : unit = ()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
a <> b is a document for concatenation of documents a and b without alignment. It's also known as the unaligned concatenation, which is widely used in traditional pretty printers.
Examples:
# let left_doc = text "Splatoon" <> nl <> text "Nier";;
val left_doc : doc = <abstr>
# let right_doc = text "Automata" <> nl <> text "FEZ";;
val right_doc : doc = <abstr>
# 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.
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 "Chrono Trigger", making it a non-optimal choice, even though text "Chrono Trigger" 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.
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.
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.