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)
Author: Sebastian Fischer, Bjoern Peemoeller, Jan Tikovsky
Version: September 2015
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 "]" .
|
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
|
pretty
:: Int -> Doc -> String
(pretty w d)
pretty prints document d
with a page width of w
characters
|
The abstract data type Doc represents pretty documents.
Constructors:
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 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
|
The document
|