This library provides pretty printing combinators.
The interface is that of
Daan Leijen's library
linear-time, bounded implementation
by Olaf Chitil.
Note that the implementation of fill
and fillBreak
is not linear-time bounded
Support of ANSI escape codes for formatting and colorisation of documents
in text terminals (see https://en.wikipedia.org/wiki/ANSIescapecode)
This library corresponds to the library provided by the PAKCS and KiCS2 compilers. But it was partially rewritten and reorganized to make use of type classes and provide pretty printing combinators in a package.
Author: Sebastian Fischer, Bjoern Peemoeller, Jan Tikovsky
Version: October 2017
pPrint
:: Doc -> String Standard printing with a column length of 80. |
empty
:: Doc The empty document |
isEmpty
:: Doc -> Bool Is the document empty? |
text
:: String -> Doc The document (text s)
contains the literal string s .
|
linesep
:: String -> Doc The document (linesep s)
advances to the next line and indents
to the current nesting level.
|
hardline
:: Doc The document hardline
advances to the next line and indents
to the current nesting level.
|
line
:: Doc The document line
advances to the next line and indents to the current
nesting level.
|
linebreak
:: Doc The document linebreak
advances to the next line and indents to
the current nesting level.
|
softline
:: Doc The document softline
behaves like space
if the resulting output
fits the page, otherwise it behaves like line .
|
softbreak
:: Doc The document softbreak
behaves like (text "")
if the resulting output
fits the page, otherwise it behaves like line .
|
group
:: Doc -> Doc The combinator group
is used to specify alternative layouts.
|
nest
:: Int -> Doc -> Doc The document (nest i d)
renders document d
with the current
indentation level increased by i
(See also hang ,
align
and indent ).
|
hang
:: Int -> Doc -> Doc The combinator hang
implements hanging indentation.
|
align
:: Doc -> Doc The document (align d)
renders document `d with the nesting level
set to the current column.
|
indent
:: Int -> Doc -> Doc The document (indent i d)
indents document d
with i
spaces.
|
combine
:: Doc -> Doc -> Doc -> Doc The document (combine c d1 d2)
combines document d1
and d2
with
document c
in between using (<>)
with identity empty .
|
(<>)
:: Doc -> Doc -> Doc The document (x <> y)
concatenates document x
and document y .
|
(<+>)
:: Doc -> Doc -> Doc The document (x <+> y)
concatenates document x
and y
with a
space
in between with identity empty .
|
($$)
:: Doc -> Doc -> Doc The document (x $$ y)
concatenates document x and y with a
line
in between with identity empty .
|
(<$+$>)
:: Doc -> Doc -> Doc The document (x <$+$> y)
concatenates document x
and y
with a
blank line in between with identity empty .
|
(</>)
:: Doc -> Doc -> Doc The document (x </> y)
concatenates document x
and y
with
a softline
in between with identity empty .
|
(<$$>)
:: Doc -> Doc -> Doc The document (x <$$> y)
concatenates document x
and y
with a
linebreak
in between with identity empty .
|
(<//>)
:: Doc -> Doc -> Doc The document (x <//> y)
concatenates document x
and y
with a
softbreak
in between with identity empty .
|
(<$!$>)
:: Doc -> Doc -> Doc The document (x <$!$> y)
concatenates document x
and y
with a
hardline
in between with identity empty .
|
compose
:: (Doc -> Doc -> Doc) -> [Doc] -> Doc The document (compose f xs)
concatenates all documents xs
with function f .
|
hsep
:: [Doc] -> Doc The document (hsep xs)
concatenates all documents xs
horizontally with (<+>) .
|
vsep
:: [Doc] -> Doc The document (vsep xs)
concatenates all documents xs
vertically with
($$) .
|
vsepBlank
:: [Doc] -> Doc The document vsep xs
concatenates all documents xs
vertically with
(<$+$>) .
|
fillSep
:: [Doc] -> Doc The document (fillSep xs)
concatenates documents xs
horizontally with
(</>)
as long as its fits the page, than inserts a
line
and continues doing that for all documents in xs .
|
sep
:: [Doc] -> Doc The document (sep xs)
concatenates all documents xs
either horizontally
with (<+>) , if it fits the page, or vertically
with ($$) .
|
hcat
:: [Doc] -> Doc The document (hcat xs)
concatenates all documents xs
horizontally
with (<>) .
|
vcat
:: [Doc] -> Doc The document (vcat xs)
concatenates all documents xs
vertically
with (<$$>) .
|
fillCat
:: [Doc] -> Doc The document (fillCat xs)
concatenates documents xs
horizontally
with (<//>)
as long as its fits the page, than inserts a linebreak
and continues doing that for all documents in xs .
|
cat
:: [Doc] -> Doc The document (cat xs)
concatenates all documents xs
either horizontally
with (<>) , if it fits the page, or vertically with
(<$$>) .
|
punctuate
:: Doc -> [Doc] -> [Doc] (punctuate p xs)
concatenates all documents xs
with document p
except
for the last document.
|
encloseSep
:: Doc -> Doc -> Doc -> [Doc] -> Doc The document (encloseSep l r s xs)
concatenates the documents xs
seperated by s
and encloses the resulting document by l
and r .
|
encloseSepSpaced
:: Doc -> Doc -> Doc -> [Doc] -> Doc The document (encloseSepSpaced l r s xs)
concatenates the documents xs
seperated by s
and encloses the resulting document by l
and r .
|
hEncloseSep
:: Doc -> Doc -> Doc -> [Doc] -> Doc The document (hEncloseSep l r s xs)
concatenates the documents xs
seperated by s
and encloses the resulting document by l
and r .
|
fillEncloseSep
:: Doc -> Doc -> Doc -> [Doc] -> Doc The document (fillEncloseSep l r s xs)
concatenates the documents xs
seperated by s
and encloses the resulting document by l
and r .
|
fillEncloseSepSpaced
:: Doc -> Doc -> Doc -> [Doc] -> Doc The document (fillEncloseSepSpaced l r s xs)
concatenates the documents
xs
seperated by s
and encloses the resulting document by l
and r .
|
list
:: [Doc] -> Doc The document (list xs)
comma seperates the documents xs
and encloses
them in square brackets.
|
listSpaced
:: [Doc] -> Doc Spaced version of list
|
set
:: [Doc] -> Doc The document (set xs)
comma seperates the documents xs
and encloses
them in braces.
|
setSpaced
:: [Doc] -> Doc Spaced version of set
|
tupled
:: [Doc] -> Doc The document (tupled xs)
comma seperates the documents xs
and encloses
them in parenthesis.
|
tupledSpaced
:: [Doc] -> Doc Spaced version of tupled
|
semiBraces
:: [Doc] -> Doc The document (semiBraces xs)
seperates the documents xs
with semi colons
and encloses them in braces.
|
semiBracesSpaced
:: [Doc] -> Doc Spaced version of semiBraces
|
enclose
:: Doc -> Doc -> Doc -> Doc The document (enclose l r x)
encloses document x
between
documents l
and r
using (<>) .
|
squotes
:: Doc -> Doc Document (squotes x)
encloses document x
with single quotes "'" .
|
dquotes
:: Doc -> Doc Document (dquotes x)
encloses document x
with double quotes.
|
bquotes
:: Doc -> Doc Document (bquotes x)
encloses document x
with back quotes "\`" .
|
parens
:: Doc -> Doc Document (parens x)
encloses document x
in parenthesis,
"("
and ")" .
|
parensIf
:: Bool -> Doc -> Doc Document (parensIf x)
encloses document x
in parenthesis,"("
and ")" ,
iff the condition is true.
|
angles
:: Doc -> Doc Document (angles x)
encloses document x
in angles, "<"
and ">" .
|
braces
:: Doc -> Doc Document (braces x)
encloses document x
in braces, "{"
and "}" .
|
brackets
:: Doc -> Doc Document (brackets x)
encloses document x
in square brackets,
"["
and "]" .
|
bool
:: Bool -> Doc The document (bool b)
shows the boolean b
using text .
|
char
:: Char -> Doc The document (char c)
contains the literal character c .
|
string
:: String -> Doc The document (string s)
concatenates all characters in s
using
line
for newline characters and char
for all other characters.
|
int
:: Int -> Doc The document (int i)
shows the literal integer i
using text .
|
float
:: Float -> Doc The document (float f)
shows the literal float f
using text .
|
lparen
:: Doc The document lparen
contains a left parenthesis, "(" .
|
rparen
:: Doc The document rparen
contains a right parenthesis, ")" .
|
langle
:: Doc The document langle
contains a left angle, "<" .
|
rangle
:: Doc The document rangle
contains a right angle, ">" .
|
lbrace
:: Doc The document lbrace
contains a left brace, "{" .
|
rbrace
:: Doc The document rbrace
contains a right brace, "}" .
|
lbracket
:: Doc The document lbracket
contains a left square bracket, "[" .
|
rbracket
:: Doc The document rbracket
contains a right square bracket, "]" .
|
squote
:: Doc The document squote
contains a single quote, "'" .
|
dquote
:: Doc The document dquote
contains a double quote.
|
semi
:: Doc The document semi
contains a semi colon, ";" .
|
colon
:: Doc The document colon
contains a colon, ":" .
|
comma
:: Doc The document comma
contains a comma, "," .
|
space
:: Doc The document space
contains a single space, " " .
|
dot
:: Doc The document dot
contains a single dot, "." .
|
backslash
:: Doc The document backslash
contains a back slash, "\\" .
|
equals
:: Doc The document equals
contains an equal sign, "=" .
|
larrow
:: Doc The document larrow
contains a left arrow sign, "<-" .
|
rarrow
:: Doc The document rarrow
contains a right arrow sign, "->" .
|
doubleArrow
:: Doc The document doubleArrow
contains an double arrow sign, "=>" .
|
doubleColon
:: Doc The document doubleColon
contains a double colon sign, "::" .
|
bar
:: Doc The document bar
contains a vertical bar sign, "|" .
|
at
:: Doc The document at
contains an at sign, "@" .
|
tilde
:: Doc The document tilde
contains a tilde sign, "~" .
|
fill
:: Int -> Doc -> Doc The document (fill i d)
renders document d .
|
fillBreak
:: Int -> Doc -> Doc The document (fillBreak i d)
first renders document d .
|
bold
:: Doc -> Doc The document (bold d)
displays document d
with bold text
|
faint
:: Doc -> Doc The document (faint d)
displays document d
with faint text
|
blinkSlow
:: Doc -> Doc The document (blinkSlow d)
displays document d
with slowly blinking text
(rarely supported)
|
blinkRapid
:: Doc -> Doc The document (blinkRapid d)
displays document d
with rapidly blinking
text (rarely supported)
|
italic
:: Doc -> Doc The document (italic d)
displays document d
with italicized text
(rarely supported)
|
underline
:: Doc -> Doc The document (underline d)
displays document d
with underlined text
|
crossout
:: Doc -> Doc The document (crossout d)
displays document d
with crossed out text
|
inverse
:: Doc -> Doc The document (inverse d)
displays document d
with inversed coloring,
i.e.
|
black
:: Doc -> Doc The document (black d)
displays document d
with black text color
|
red
:: Doc -> Doc The document (red d)
displays document d
with red text color
|
green
:: Doc -> Doc The document (green d)
displays document d
with green text color
|
yellow
:: Doc -> Doc The document (yellow d)
displays document d
with yellow text color
|
blue
:: Doc -> Doc The document (blue d)
displays document d
with blue text color
|
magenta
:: Doc -> Doc The document (magenta d)
displays document d
with magenta text color
|
cyan
:: Doc -> Doc The document (cyan d)
displays document d
with cyan text color
|
white
:: Doc -> Doc The document (white d)
displays document d
with white text color
|
bgBlack
:: Doc -> Doc The document (bgBlack d)
displays document d
with black background color
|
bgRed
:: Doc -> Doc The document (bgRed d)
displays document d
with red background color
|
bgGreen
:: Doc -> Doc The document (bgGreen d)
displays document d
with green background color
|
bgYellow
:: Doc -> Doc The document (bgYellow d)
displays document d
with yellow background
color
|
bgBlue
:: Doc -> Doc The document (bgBlue d)
displays document d
with blue background color
|
bgMagenta
:: Doc -> Doc The document (bgMagenta d)
displays document d
with magenta background
color
|
bgCyan
:: Doc -> Doc The document (bgCyan d)
displays document d
with cyan background color
|
bgWhite
:: Doc -> Doc The document (bgWhite d)
displays document d
with white background color
|
The empty document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The combinator
|
The document nest 2 (text "hello" $$ text "world") $$ text "!" outputs as: hello world !
|
The combinator test = hang 4 (fillSep (map text (words "the hang combinator indents these words !"))) Which lays out on a page with a width of 20 characters as: the hang combinator indents these words ! The hang combinator is implemented as: hang i x = align (nest i x)
|
The document As an example, we will put a document right above another one, regardless of the current nesting level: x $$ y = align (x $$ y) test = text "hi" <+> (text "nice" $$ text "world") which will be layed out as: hi nice world
|
The document test = indent 4 (fillSep (map text (words "the indent combinator indents these words !"))) Which lays out with a page width of 20 as: the indent combinator indents these words !
|
The document combine c d1 empty == d1 combine c empty d2 == d2 combine c d1 d2 == d1 <> c <> d2 if neither d1 nor d2 are empty
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document someText = map text (words ("text to lay out")) test = text "some" <+> vsep someText This is layed out as: some text to lay out
The test = text "some" <+> align (vsep someText) This is printed as: some text to lay out
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
someText = map text ["words","in","a","tuple"] test = parens (align (cat (punctuate comma someText))) This is layed out on a page width of 20 as: (words,in,a,tuple) But when the page width is 15, it is layed out as: (words, in, a, tuple)
(If you want put the commas in front of their elements instead of at the
end, you should use
|
The document
For example, the combinator list xs = encloseSep lbracket rbracket comma xs test = text "list" <+> (list (map int [10,200,3000])) Which is layed out with a page width of 20 as: list [10,200,3000] But when the page width is 15, it is layed out as: list [10 ,200 ,3000]
|
The document
|
The document The documents are rendered horizontally.
|
The document The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All seperators are put in front of the elements.
|
The document The documents are rendered horizontally if that fits the page. Otherwise, they are aligned vertically. All seperators are put in front of the elements.
|
The document
|
Spaced version of |
The document
|
The document
|
Spaced version of |
The document
|
Spaced version of |
The document
|
Document
|
Document
|
Document
|
Document
|
Document
|
Document
|
Document
|
Document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document x <+> y = x <> space <> y
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document types = [("empty","Doc") ,("nest","Int -> Doc -> Doc") ,("linebreak","Doc")] ptype (name,tp) = fill 6 (text name) <+> text "::" <+> text tp test = text "let" <+> align (vcat (map ptype types)) Which is layed out as: let empty :: Doc nest :: Int -> Doc -> Doc linebreak :: Doc
Note that |
The document ptype (name,tp) = fillBreak 6 (text name) <+> text "::" <+> text tp The output will now be: let empty :: Doc nest :: Int -> Doc -> Doc linebreak :: Doc
Note that |
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|
The document
|