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
|