PP
Module
signature PP
structure PP
:> PP
The module implements a simple form of pretty-printing.
val newline : string
type pp
val toString : pp -> string
val empty : pp
val block : bool * pp list -> pp
val decorate : string * pp * string -> pp
val quote : pp -> pp
val comma : pp -> pp
val colon : pp -> pp
val semicolon : pp -> pp
val fromString : string -> pp
val fromStringSplitEscape : string -> pp
newline
"\n"
, but on Windows it is "\r\n"
.
type pp
pp
were implemented as
datatype pp = Block of bool * pp list | Decorate of string * pp * stringbut it's actually implemented in a way allowing more efficient processing.
toString pp
pp
into a string where, if possible, all of the string's lines are no longer than the current printing line length (see Params
.getPrintingLineLength
). This translation is carried out using a recursive function that is supplied a value pp
of pp
to be turned into a string, together with the current indentation ind
and the after size aft
, i.e., the size of the string that will immediately follow the final line of the translation of pp
. A recursive call is not responsible for generating the ind
spaces that will preceed pp
's translation in the overall translation.
Block(spaceNoBreak, pps)
is turned into a string consisting of one of more lines, all but the first of which begin with ind
spaces. This is done by recursively translating the elements of pps
, in sequence, with appropriate indentations and after sizes. If the translations of a sequence of elements of pps
—separated by blanks iff spaceNoBreak
is true—fit on a single line (including the ind
initial spaces, and leaving room for aft
additional characters, if the final element of pps
is included), then the elements' translations are combined in this way. But when an element's translation requires multiples lines, it is never combined with other translations, either before or after. The translation of the final element of pp
, whether combined with other translations or not, must always be computed by taking into account that aft
additional characters will immediately follow its last line.
Decorate(s1, pp, s2)
is turned into the string consisting of the concatenation of:
s1
,
pp
with indentation ind + size s1
, and after size size s2 + aft
, and
s2
.
empty
Block(true, nil)
.
block
Block
.
decorate
Decorate
.
quote pp
Decorate("\"", pp, "\"")
.
comma pp
Decorate("", pp, ",")
.
colon pp
Decorate("", pp, ":")
.
semicolon pp
Decorate("", pp, ";")
.
fromString s
Decorate(s, empty, "")
.
fromStringSplitEscape s
Block(false, map (fn c => fromString(Char.toString c)) (explode s))where
Char.toString
escapes non-printable characters (as well as double quotes and backslashes) using SML escape sequences.
For example, if the current printing line length is 30
, running
val pp = PP.decorate ("(", PP.block (true, [PP.fromString "once", PP.fromString "upon", PP.fromString "a", PP.fromString "time"]), ")"); val pp' = PP.decorate ("[", PP.block(false, [pp, pp, pp]), "]"); print(PP.toString pp' ^ "\n");results in the output
[(once upon a time) (once upon a time) (once upon a time)]And, if the current printing line length is
60
, running the same code results in
[(once upon a time)(once upon a time)(once upon a time)]
Forlan Version 4.15
Copyright © 2022 Alley Stoughton