Module

Options.Applicative.Help.Pretty

Package
purescript-optparse
Repository
f-o-a-m/purescript-optparse

#(.$.) Source

Operator alias for Text.PrettyPrint.Leijen.appendWithLine (right-associative / precedence 5)

Re-exports from Text.PrettyPrint.Leijen

#SimpleDoc Source

data SimpleDoc

The data type @SimpleDoc@ represents rendered documents and is used by the display functions.

Whereas values of the data type 'Doc' represent non-empty sets of possible renderings of a document, values of the data type @SimpleDoc@ represent single renderings of a document.

The @Int@ in @SText@ contains the length of the string. The @Int@ in @SLine@ contains the indentation for that line. The library provides two default display functions 'displayS' and 'displayIO'. You can provide your own display function by writing a function from a @SimpleDoc@ to your own output format.

Constructors

Instances

#Docs Source

data Docs

list of indentation/document pairs; saves an indirection over [(Int,Doc)]

Constructors

#Doc Source

data Doc

The abstract data type @Doc@ represents pretty documents.

More specifically, a value of type @Doc@ represents a non-empty set of possible renderings of a document. The rendering functions select one of these possibilities.

@Doc@ is an instance of the 'Show' class. @(show doc)@ pretty prints document @doc@ with a page width of 80 characters and a ribbon width of 32 characters.

show (text "hello" <$> text "world")

Which would return the string "hello\nworld", i.e.

@ hello world @

Constructors

Instances

#width Source

width :: Doc -> (Int -> Doc) -> Doc

#vsep Source

vsep :: Array Doc -> Doc

The document @(vsep xs)@ concatenates all documents @xs@ vertically with @(<$>)@. If a 'group' undoes the line breaks inserted by @vsep@, all documents are separated with a space.

someText = map text (words ("text to lay out"))

test = text "some" <+> vsep someText

This is layed out as:

@ some text to lay out @

The 'align' combinator can be used to align the documents under their first element

test = text "some" <+> align (vsep someText)

Which is printed as:

@ some text to lay out @

#vcat Source

vcat :: Array Doc -> Doc

The document @(vcat xs)@ concatenates all documents @xs@ vertically with @(<$$>)@. If a 'group' undoes the line breaks inserted by @vcat@, all documents are directly concatenated.

#tupled Source

tupled :: Array Doc -> Doc

The document @(tupled xs)@ comma separates the documents @xs@ and encloses them in parenthesis. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All comma separators are put in front of the elements.

#text Source

text :: String -> Doc

The document @(text s)@ contains the literal string @s@. The string shouldn't contain any newline (@'\n'@) characters. If the string contains newline characters, the function 'string' should be used.

#string Source

string :: String -> Doc

The document @(string s)@ concatenates all characters in @s@ using @line@ for newline characters and @char@ for all other characters. It is used instead of 'text' whenever the text contains newline characters.

#squotes Source

squotes :: Doc -> Doc

Document @(squotes x)@ encloses document @x@ with single quotes "'".

#squote Source

squote :: Doc

The document @squote@ contains a single quote, "'".

#spaces Source

#space Source

space :: Doc

The document @space@ contains a single space, " ".

x <+> y = x <> space <> y

#softline Source

softline :: Doc

The document @softline@ behaves like 'space' if the resulting output fits the page, otherwise it behaves like 'line'.

softline = group line

#softbreak Source

softbreak :: Doc

The document @softbreak@ behaves like 'empty' if the resulting output fits the page, otherwise it behaves like 'line'.

softbreak = group linebreak

#sep Source

sep :: Array Doc -> Doc

The document @(sep xs)@ concatenates all documents @xs@ either horizontally with @(<+>)@, if it fits the page, or vertically with @(<$>)@.

sep xs = group (vsep xs)

#semiBraces Source

semiBraces :: Array Doc -> Doc

The document @(semiBraces xs)@ separates the documents @xs@ with semicolons and encloses them in braces. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All semicolons are put in front of the elements.

#semi Source

semi :: Doc

The document @semi@ contains a semicolon, ";".

#rparen Source

rparen :: Doc

The document @rparen@ contains a right parenthesis, ")".

#renderSmart Source

renderSmart :: Number -> Int -> Doc -> SimpleDoc

A slightly smarter rendering algorithm with more lookahead. It provides provide earlier breaking on deeply nested structures For example, consider this python-ish pseudocode: @fun(fun(fun(fun(fun([abcdefg, abcdefg])))))@ If we put a softbreak (+ nesting 2) after each open parenthesis, and align the elements of the list to match the opening brackets, this will render with @renderPretty@ and a page width of 20 as: @ fun(fun(fun(fun(fun([ | abcdef, | abcdef, ] ))))) | @ Where the 20c. boundary has been marked with |. Because @renderPretty@ only uses one-line lookahead, it sees that the first line fits, and is stuck putting the second and third lines after the 20-c mark. In contrast, @renderSmart@ will continue to check that the potential document up to the end of the indentation level. Thus, it will format the document as:

@ fun( | fun( | fun( | fun( | fun([ | abcdef, abcdef, ] | ))))) | @ Which fits within the 20c. boundary.

#renderPretty Source

renderPretty :: Number -> Int -> Doc -> SimpleDoc

This is the default pretty printer which is used by 'show', 'putDoc' and 'hPutDoc'. @(renderPretty ribbonfrac width x)@ renders document @x@ with a page width of @width@ and a ribbon width of @(ribbonfrac * width)@ characters. The ribbon width is the maximal amount of non-indentation characters on a line. The parameter @ribbonfrac@ should be between @0.0@ and @1.0@. If it is lower or higher, the ribbon width will be 0 or @width@ respectively.

#renderFits Source

#renderCompact Source

renderCompact :: Doc -> SimpleDoc

@(renderCompact x)@ renders document @x@ without adding any indentation. Since no 'pretty' printing is involved, this renderer is very fast. The resulting output contains fewer characters than a pretty printed version and can be used for output that is read by other programs.

This rendering function does not add any colorisation information.

#rbracket Source

rbracket :: Doc

The document @rbracket@ contains a right square bracket, "]".

#rbrace Source

rbrace :: Doc

The document @rbrace@ contains a right brace, "}".

#rangle Source

rangle :: Doc

The document @rangle@ contains a right angle, ">".

#punctuate Source

punctuate :: Doc -> Array Doc -> Array Doc

@(punctuate p xs)@ concatenates all documents in @xs@ with document @p@ except for the last 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 'tupled' or, in general, 'encloseSep'.)

#parens Source

parens :: Doc -> Doc

Document @(parens x)@ encloses document @x@ in parenthesis, "(" and ")".

#number Source

number :: Number -> Doc

The document @(number f)@ shows the literal number @f@ using 'text'.

#nesting Source

nesting :: (Int -> Doc) -> Doc

#nest Source

nest :: Int -> Doc -> Doc

The document @(nest i x)@ renders document @x@ with the current indentation level increased by i (See also 'hang', 'align' and 'indent').

nest 2 (text "hello" <$> text "world") <$> text "!"

outputs as:

@ hello world ! @

#lparen Source

lparen :: Doc

The document @lparen@ contains a left parenthesis, "(".

#list Source

list :: Array Doc -> Doc

The document @(list xs)@ comma separates the documents @xs@ and encloses them in square brackets. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All comma separators are put in front of the elements.

#linebreak Source

linebreak :: Doc

The @linebreak@ document advances to the next line and indents to the current nesting level. Document @linebreak@ behaves like 'empty' if the line break is undone by 'group'.

#line Source

line :: Doc

The @line@ document advances to the next line and indents to the current nesting level. Document @line@ behaves like @(text " ")@ if the line break is undone by 'group'.

#lbracket Source

lbracket :: Doc

The document @lbracket@ contains a left square bracket, "[".

#lbrace Source

lbrace :: Doc

The document @lbrace@ contains a left brace, "{".

#langle Source

langle :: Doc

The document @langle@ contains a left angle, "<".

#int Source

int :: Int -> Doc

The document @(int i)@ shows the literal integer @i@ using 'text'.

#indentation Source

#indent Source

indent :: Int -> Doc -> Doc

The document @(indent i x)@ indents document @x@ with @i@ spaces.

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 ! @

#hsep Source

hsep :: Array Doc -> Doc

The document @(hsep xs)@ concatenates all documents @xs@ horizontally with @(<+>)@.

#hcat Source

hcat :: Array Doc -> Doc

The document @(hcat xs)@ concatenates all documents @xs@ horizontally with @(<>)@.

#hardline Source

hardline :: Doc

A linebreak that will never be flattened; it is guaranteed to render as a newline.

#hang Source

hang :: Int -> Doc -> Doc

The hang combinator implements hanging indentation. The document @(hang i x)@ renders document @x@ with a nesting level set to the current column plus @i@. The following example uses hanging indentation for some text:

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)

#group Source

group :: Doc -> Doc

The @group@ combinator is used to specify alternative layouts. The document @(group x)@ undoes all line breaks in document @x@. The resulting line is added to the current line if that fits the page. Otherwise, the document @x@ is rendered without any changes.

#foldr1 Source

foldr1 :: forall a. Monoid a => (a -> a -> a) -> Array a -> a

#flatten Source

#flatAlt Source

flatAlt :: Doc -> Doc -> Doc

A document that is normally rendered as the first argument, but when flattened, is rendered as the second document.

#fitsR Source

fitsR :: Int -> Int -> Int -> LazySimpleDoc -> Boolean

@fitsR@ has a little more lookahead: assuming that nesting roughly corresponds to syntactic depth, @fitsR@ checks that not only the current line fits, but the entire syntactic structure being formatted at this level of indentation fits. If we were to remove the second case for @SLine@, we would check that not only the current structure fits, but also the rest of the document, which would be slightly more intelligent but would have exponential runtime (and is prohibitively expensive in practice). p = pagewidth m = minimum nesting level to fit in w = the width in which to fit the first line

#fits1 Source

fits1 :: Int -> Int -> Int -> LazySimpleDoc -> Boolean

@fits1@ does 1 line lookahead.

#fillSep Source

fillSep :: Array 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@.

fillSep xs = foldr (</>) empty xs

#fillCat Source

fillCat :: Array 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@.

fillCat xs = foldr1 (<//>) empty

#fillBreak Source

fillBreak :: Int -> Doc -> Doc

The document @(fillBreak i x)@ first renders document @x@. It than appends @space@s until the width is equal to @i@. If the width of @x@ is already larger than @i@, the nesting level is increased by @i@ and a @line@ is appended. When we redefine @ptype@ in the previous example to use @fillBreak@, we get a useful variation of the previous output:

ptype (name,tp) = fillBreak 6 (text name) <+> text "::" <+> text tp

The output will now be:

@ let empty :: Doc nest :: Int -> Doc -> Doc linebreak :: Doc @

#fill Source

fill :: Int -> Doc -> Doc

The document @(fill i x)@ renders document @x@. It than appends @space@s until the width is equal to @i@. If the width of @x@ is already larger, nothing is appended. This combinator is quite useful in practice to output a list of bindings. The following example demonstrates this.

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 @

#equals Source

equals :: Doc

The document @equals@ contains an equal sign, "=".

#encloseSep Source

encloseSep :: Doc -> Doc -> Doc -> Array Doc -> Doc

The document @(encloseSep l r sep xs)@ concatenates the documents @xs@ separated by @sep@ and encloses the resulting document by @l@ and @r@. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All separators are put in front of the elements. For example, the combinator 'list' can be defined with @encloseSep@:

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] @

#enclose Source

enclose :: Doc -> Doc -> Doc -> Doc

The document @(enclose l r x)@ encloses document @x@ between documents @l@ and @r@ using @(<>)@.

enclose l r x = l <> x <> r

#empty Source

empty :: Doc

The empty document is, indeed, empty. Although @empty@ has no content, it does have a 'height' of 1 and behaves exactly like @(text "")@ (and is therefore not a unit of @<$>@).

#dquotes Source

dquotes :: Doc -> Doc

Document @(dquotes x)@ encloses document @x@ with double quotes '"'.

#dquote Source

dquote :: Doc

The document @dquote@ contains a double quote, '"'.

#dot Source

dot :: Doc

The document @dot@ contains a single dot, ".".

#displayS Source

displayS :: SimpleDoc -> String

@(displayS simpleDoc)@ takes the output @simpleDoc@ from a rendering function and transforms it to a 'ShowS' type (for use in the 'Show' class).

showWidth :: Int -> Doc -> String showWidth w x = displayS (renderPretty 0.4 w x) ""

ANSI color information will be discarded by this function unless you are running on a Unix-like operating system. This is due to a technical limitation in Windows ANSI support.

#comma Source

comma :: Doc

The document @comma@ contains a comma, ",".

#column Source

column :: (Int -> Doc) -> Doc

#colon Source

colon :: Doc

The document @colon@ contains a colon, ":".

#char Source

char :: Char -> Doc

The document @(char c)@ contains the literal character @c@. The character shouldn't be a newline (@'\n'@), the function 'line' should be used for line breaks.

#cat Source

cat :: Array Doc -> Doc

The document @(cat xs)@ concatenates all documents @xs@ either horizontally with @(<>)@, if it fits the page, or vertically with @(<$$>)@.

cat xs = group (vcat xs)

#brackets Source

brackets :: Doc -> Doc

Document @(brackets x)@ encloses document @x@ in square brackets, "[" and "]".

#braces Source

braces :: Doc -> Doc

Document @(braces x)@ encloses document @x@ in braces, "{" and "}".

#bool Source

bool :: Boolean -> Doc

The document @(bool b)@ shows the literal bool @b@ using 'text'.

#beside Source

beside :: Doc -> Doc -> Doc

#backslash Source

backslash :: Doc

The document @backslash@ contains a back slash, "\".

#appendWithSpace Source

appendWithSpace :: Doc -> Doc -> Doc

The document @(x <+> y)@ concatenates document @x@ and @y@ with a @space@ in between. (infixr 6)

#appendWithSoftline Source

appendWithSoftline :: Doc -> Doc -> Doc

The document @(x </> y)@ concatenates document @x@ and @y@ with a 'softline' in between. This effectively puts @x@ and @y@ either next to each other (with a @space@ in between) or underneath each other. (infixr 5)

#appendWithSoftbreak Source

appendWithSoftbreak :: Doc -> Doc -> Doc

The document @(x <//> y)@ concatenates document @x@ and @y@ with a 'softbreak' in between. This effectively puts @x@ and @y@ either right next to each other or underneath each other. (infixr 5)

#appendWithLinebreak Source

appendWithLinebreak :: Doc -> Doc -> Doc

The document @(x <$$> y)@ concatenates document @x@ and @y@ with a @linebreak@ in between. (infixr 5)

#appendWithLine Source

appendWithLine :: Doc -> Doc -> Doc

The document @(x <$> y)@ concatenates document @x@ and @y@ with a 'line' in between. (infixr 5)

#angles Source

angles :: Doc -> Doc

Document @(angles x)@ encloses document @x@ in angles, "<" and ">".

#align Source

align :: Doc -> Doc

The document @(align x)@ renders document @x@ with the nesting level set to the current column. It is used for example to implement 'hang'.

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 @

#(</>) Source

Operator alias for Text.PrettyPrint.Leijen.appendWithSoftline (right-associative / precedence 5)

#(<//>) Source

Operator alias for Text.PrettyPrint.Leijen.appendWithSoftbreak (right-associative / precedence 5)

#(<+>) Source

Operator alias for Text.PrettyPrint.Leijen.appendWithSpace (right-associative / precedence 6)

#(<$$>) Source

Operator alias for Text.PrettyPrint.Leijen.appendWithLinebreak (right-associative / precedence 5)