Moduleoptparse-applicative-0.19.0.0Haskell98
Options.Applicative.Help.Pretty
- 12 types
- 2 classes
- 93 values
- Packageoptparse-applicative-0.19.0.0
- Exports108
- LanguageHaskell98
- LicenceBSD-3-Clause
- SourceInternal.hs
(align x) lays out the 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. Without alignment, the second line is put simply below everything we've had so far:
"lorem" <+> vsep ["ipsum", "dolor"]lorem ipsumdolor
If we add an align to the mix, the vsep's contents all start in the
same column:
"lorem" <+> align (vsep ["ipsum", "dolor"])lorem ipsum dolor
Change the annotations of a Document. Individual annotations can be removed, changed, or replaced by multiple ones.
This is a general function that combines unAnnotate and reAnnotate, and it is useful for mapping semantic annotations (such as »this is a keyword«) to display annotations (such as »this is red and underlined«), because some backends may not care about certain annotations, while others may.
Annotations earlier in the new list will be applied earlier, i.e. returning
[Bold, Green] will result in a bold document that contains green text, and
not vice-versa.
Since this traverses the entire Doc tree, including parts that are not
rendered due to other layouts fitting better, it is preferable to reannotate
after producing the layout by using alterAnnotationsS.
Change the annotation of a document to a different annotation, or none at all. alterAnnotations for SimpleDocStream.
Note that the Doc version is more flexible, since it allows changing a single annotation to multiple ones. (SimpleDocTree restores this flexibility again.)
Add an annotation to a Doc. This annotation can then be used by the
renderer to e.g. add color to certain parts of the output. For a full
tutorial example on how to use it, see the
Prettyprinter.Render.Tutorials.StackMachineTutorial or
Prettyprinter.Render.Tutorials.TreeRenderingTutorial modules.
This function is only relevant for custom formats with their own annotations, and not relevant for basic prettyprinting. The predefined renderers, e.g. Prettyprinter.Render.Text, should be enough for the most common needs.
(cat xs) tries laying out the documents xs separated with nothing,
and if this does not fit the page, separates them with newlines. This is what
differentiates it from vcat, which always lays out its contents beneath
each other.
let docs = Util.words "lorem ipsum dolor"putDocW 80 ("Docs:" <+> cat docs)Docs: loremipsumdolor
When there is enough space, the documents are put above one another:
putDocW 10 ("Docs:" <+> cat docs)Docs: loremipsumdolor
cat = group . vcat
Layout a document depending on which column it starts at. align is implemented in terms of column.
column (\l -> "Columns are" <+> pretty l <> "-based.")Columns are 0-based.
let doc = "prefix" <+> column (\l -> "| <- column" <+> pretty l)vsep [indent n doc | n <- [0,4,8]]prefix | <- column 7 prefix | <- column 11 prefix | <- column 15
Concatenate all documents element-wise with a binary function.
concatWith _ [] = mempty
concatWith (**) [x,y,z] = x ** y ** z
Multiple convenience definitions based on concatWith are already predefined, for example:
hsep = concatWith (<+>)
fillSep = concatWith (\x y -> x <> softline <> y)
This is also useful to define customized joiners:
concatWith (surround dot) ["Prettyprinter", "Render", "Text"]Prettyprinter.Render.Text
The default layout options, suitable when you just want some output, and don’t particularly care about the details. Used by the Show instance, for example.
defaultLayoutOptionsLayoutOptions {layoutPageWidth = AvailablePerLine 80 1.0}
The empty document behaves like (pretty ""), so it has a height of 1.
This may lead to surprising behaviour if we expect it to bear no weight
inside e.g. vcat, where we get an empty line of output from it (parens
for visibility only):
vsep ["hello", parens emptyDoc, "world"]hello()world
encloseSep (encloseSep l r sep xs) concatenates the documents xs separated by
sep, and encloses the resulting document by l and r.
The documents are laid out horizontally if that fits the page:
let doc = "list" <+> align (encloseSep lbracket rbracket comma (map pretty [1,20,300,4000]))putDocW 80 doclist [1,20,300,4000]
If there is not enough space, then the input is split into lines entry-wise otherwise they are laid out vertically, with separators put in the front:
putDocW 10 doclist [1 ,20 ,300 ,4000]
Note that doc contains an explicit call to align so that the list items
are aligned vertically.
For putting separators at the end of entries instead, have a look at punctuate.
(fill i x) lays out the document x. It then appends spaces until
the width is equal to i. If the width of x is already larger, nothing is
appended.
This function is quite useful in practice to output a list of bindings:
let types = [("empty","Doc"), ("nest","Int -> Doc -> Doc"), ("fillSep","[Doc] -> Doc")]let ptype (name, tp) = fill 5 (pretty name) <+> "::" <+> pretty tp"let" <+> align (vcat (map ptype types))let empty :: Doc nest :: Int -> Doc -> Doc fillSep :: [Doc] -> Doc
(fillBreak i x) first lays out the document x. It then appends spaces
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 example given in fill to use fillBreak, we get
a useful variation of the output:
let types = [("empty","Doc"), ("nest","Int -> Doc -> Doc"), ("fillSep","[Doc] -> Doc")]let ptype (name, tp) = fillBreak 5 (pretty name) <+> "::" <+> pretty tp"let" <+> align (vcat (map ptype types))let empty :: Doc nest :: Int -> Doc -> Doc fillSep :: [Doc] -> Doc
(fillCat xs) concatenates documents xs horizontally with <> as
long as it fits the page, then inserts a line' and continues doing that
for all documents in xs. This is similar to how an ordinary word processor
lays out the text if you just keep typing after you hit the maximum line
length.
(line' means that if grouped, the documents are separated with nothing
instead of newlines. See fillSep if you want a space instead.)
Observe the difference between fillSep and fillCat. fillSep
concatenates the entries spaced when grouped:
let docs = take 20 (cycle (["lorem", "ipsum", "dolor", "sit", "amet"]))putDocW 40 ("Grouped:" <+> group (fillSep docs))Grouped: lorem ipsum dolor sit ametlorem ipsum dolor sit amet lorem ipsumdolor sit amet lorem ipsum dolor sitamet
On the other hand, fillCat concatenates the entries directly when grouped:
putDocW 40 ("Grouped:" <+> group (fillCat docs))Grouped: loremipsumdolorsitametloremipsumdolorsitametloremipsumdolorsitametloremipsumdolorsitamet
(fillSep xs) concatenates the documents xs horizontally with <+>
as long as it fits the page, then inserts a line and continues doing that
for all documents in xs. (line means that if grouped, the documents
are separated with a space instead of newlines. Use fillCat if you do not
want a space.)
Let's print some words to fill the line:
let docs = take 20 (cycle ["lorem", "ipsum", "dolor", "sit", "amet"])putDocW 80 ("Docs:" <+> fillSep docs)Docs: lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dolorsit amet lorem ipsum dolor sit amet
The same document, printed at a width of only 40, yields
putDocW 40 ("Docs:" <+> fillSep docs)Docs: lorem ipsum dolor sit amet loremipsum dolor sit amet lorem ipsum dolorsit amet lorem ipsum dolor sit amet
By default, (flatAlt x y) renders as x. However when grouped,
y will be preferred, with x as the fallback for the case when y
doesn't fit.
let doc = flatAlt "a" "b"putDoc docaputDoc (group doc)bputDocW 0 (group doc)a
flatAlt is particularly useful for defining conditional separators such as
softline = group (flatAlt hardline " ")
let hello = "Hello" <> softline <> "world!"putDocW 12 helloHello world!putDocW 11 helloHelloworld!
Example: Haskell's do-notation
We can use this to render Haskell's do-notation nicely:
let open = flatAlt "" "{ "let close = flatAlt "" " }"let separator = flatAlt "" "; "let prettyDo xs = group ("do" <+> align (encloseSep open close separator xs))let statements = ["name:_ <- getArgs", "let greet = \"Hello, \" <> name", "putStrLn greet"]
This is put into a single line with {;} style if it fits:
putDocW 80 (prettyDo statements)do { name:_ <- getArgs; let greet = "Hello, " <> name; putStrLn greet }
When there is not enough space the statements are broken up into lines nicely:
putDocW 10 (prettyDo statements)do name:_ <- getArgs let greet = "Hello, " <> name putStrLn greet
Notes
Users should be careful to choose x to be less wide than y.
Otherwise, if y turns out not to fit the page, we fall back on an even
wider layout:
let ugly = group (flatAlt "even wider" "too wide")putDocW 7 uglyeven wider
Also note that group will flatten y:
putDoc (group (flatAlt "x" ("y" <> line <> "y")))y y
This also means that an "unflattenable" y which contains a hard linebreak
will never be rendered:
putDoc (group (flatAlt "x" ("y" <> hardline <> "y")))x
(fuse depth doc) combines text nodes so they can be rendered more
efficiently. A fused document is always laid out identical to its unfused
version.
When laying a Document out to a SimpleDocStream, every component of the input is translated directly to the simpler output format. This sometimes yields undesirable chunking when many pieces have been concatenated together.
For example
"a" <> "b" <> pretty 'c' <> "d"abcd
results in a chain of four entries in a SimpleDocStream, although this is fully equivalent to the tightly packed
"abcd" :: Doc annabcd
which is only a single SimpleDocStream entry, and can be processed faster.
It is therefore a good idea to run fuse on concatenations of lots of small strings that are used many times:
let oftenUsed = fuse Shallow ("a" <> "b" <> pretty 'c' <> "d")hsep (replicate 5 oftenUsed)abcd abcd abcd abcd abcd
(group x) tries laying out x into a single line by removing the
contained line breaks; if this does not fit the page, or when a hardline
within x prevents it from being flattened, x is laid out without any
changes.
The group function is key to layouts that adapt to available space nicely.
See vcat, line, or flatAlt for examples that are related, or make good use of it.
hang (hang i x) lays out the document x with a nesting level set to the
current column plus i. Negative values are allowed, and decrease the
nesting level accordingly.
let doc = reflow "Indenting these words with hang"putDocW 24 ("prefix" <+> hang 4 doc)prefix Indenting these words with hang
This differs from nest, which is based on the current nesting level plus
i. When you're not sure, try the more efficient nest first. In our
example, this would yield
let doc = reflow "Indenting these words with nest"putDocW 24 ("prefix" <+> nest 4 doc)prefix Indenting these words with nest
hang i doc = align (nest i doc)
A hardline is always laid out as a line break, even when grouped or
when there is plenty of space. Note that it might still be simply discarded
if it is part of a flatAlt inside a group.
let doc = "lorem ipsum" <> hardline <> "dolor sit amet"putDocW 1000 doclorem ipsumdolor sit amet
group doclorem ipsumdolor sit amet
(hsep xs) concatenates all documents xs horizontally with <+>,
i.e. it puts a space between all entries.
let docs = Util.words "lorem ipsum dolor sit amet"hsep docslorem ipsum dolor sit amet
hsep does not introduce line breaks on its own, even when the page is too
narrow:
putDocW 5 (hsep docs)lorem ipsum dolor sit amet
For automatic line breaks, consider using fillSep instead.
(layoutCompact x) lays out the document x without adding any
indentation and without preserving annotations.
Since no 'pretty' printing is involved, this layouter is very
fast. The resulting output contains fewer characters than a prettyprinted
version and can be used for output that is read by other programs.
let doc = hang 4 (vsep ["lorem", "ipsum", hang 4 (vsep ["dolor", "sit"])])doclorem ipsum dolor sit
let putDocCompact = renderIO System.IO.stdout . layoutCompactputDocCompact docloremipsumdolorsit
This is the default layout algorithm, and it is used by show, putDoc
and hPutDoc.
layoutPretty commits to rendering something in a certain way if the
remainder of the current line fits the layout constraints; in other words,
it has up to one line of lookahead when rendering. Consider using the
smarter, but a bit less performant, layoutSmart algorithm if the results
seem to run off to the right before having lots of line breaks.
A layout algorithm with more lookahead than layoutPretty, that introduces line breaks earlier if the content does not (or will not, rather) fit within the page width.
Consider the following python-ish document,
let fun x = hang 2 ("fun(" <> softline' <> x) <> ")"let doc = (fun . fun . fun . fun . fun) (align (list ["abcdef", "ghijklm"]))
which we’ll be rendering using the following pipeline (where the layout algorithm has been left open):
import Data.Text.IO as Timport Prettyprinter.Render.Textlet hr = pipe <> pretty (replicate (26-2) '-') <> pipelet go layouter x = (T.putStrLn . renderStrict . layouter (LayoutOptions (AvailablePerLine 26 1))) (vsep [hr, x, hr])
If we render this using layoutPretty with a page width of 26 characters
per line, all the fun calls fit into the first line so they will be put
there:
go layoutPretty doc|------------------------|fun(fun(fun(fun(fun( [ abcdef , ghijklm ])))))|------------------------|
Note that this exceeds the desired 26 character page width. The same
document, rendered with layoutSmart, fits the layout constraints:
go layoutSmart doc|------------------------|fun( fun( fun( fun( fun( [ abcdef , ghijklm ])))))|------------------------|
The key difference between layoutPretty and layoutSmart is that the latter will check the potential document until it encounters a line with the same indentation or less than the start of the document. Any line encountered earlier is assumed to belong to the same syntactic structure. layoutPretty checks only the first line.
Consider for example the question of whether the As fit into the document
below:
1 A
2 A
3 A
4 B
5 BlayoutPretty will check only line 1, ignoring whether e.g. line 2 might
already be too wide.
By contrast, layoutSmart stops only once it reaches line 4, where the B
has the same indentation as the first A.
Haskell-inspired variant of encloseSep with braces and comma as separator.
let doc = list (map pretty [1,20,300,4000])putDocW 80 doc[1, 20, 300, 4000]
putDocW 10 doc[ 1, 20, 300, 4000 ]
(nest i x) lays out the document x with the current nesting level
(indentation of the following lines) increased by i. Negative values are
allowed, and decrease the nesting level accordingly.
vsep [nest 4 (vsep ["lorem", "ipsum", "dolor"]), "sit", "amet"]lorem ipsum dolorsitamet
See also
Layout a document depending on the page width, if one has been specified.
let prettyPageWidth (AvailablePerLine l r) = "Width:" <+> pretty l <> ", ribbon fraction:" <+> pretty rlet doc = "prefix" <+> pageWidth (brackets . prettyPageWidth)putDocW 32 (vsep [indent n doc | n <- [0,4,8]])prefix [Width: 32, ribbon fraction: 1.0] prefix [Width: 32, ribbon fraction: 1.0] prefix [Width: 32, ribbon fraction: 1.0]
(plural n one many) is one if n is 1, and many otherwise. A
typical use case is adding a plural "s".
let things = [True]let amount = length thingspretty things <+> "has" <+> pretty amount <+> plural "entry" "entries" amount[True] has 1 entry
(punctuate p xs) appends p to all but the last document in xs.
let docs = punctuate comma (Util.words "lorem ipsum dolor sit amet")putDocW 80 (hsep docs)lorem, ipsum, dolor, sit, amet
The separators are put at the end of the entries, which we can see if we position the result vertically:
putDocW 20 (vsep docs)lorem,ipsum,dolor,sit,amet
If you want put the commas in front of their elements instead of at the end, you should use tupled or, in general, encloseSep.
Change the annotation of a Document.
Useful in particular to embed documents with one form of annotation in a more generally annotated document.
Since this traverses the entire Doc tree, including parts that are not
rendered due to other layouts fitting better, it is preferable to reannotate
after producing the layout by using reAnnotateS.
Since reAnnotate has the right type and satisfies 'reAnnotate id = id',
it is used to define the Functor instance of Doc.
Change the annotation of a document. reAnnotate for SimpleDocStream.
Remove all trailing space characters.
This has some performance impact, because it does an entire additional pass over the SimpleDocStream.
No trimming will be done inside annotations, which are considered to contain
no (trimmable) whitespace, since the annotation might actually be about the
whitespace, for example a renderer that colors the background of trailing
whitespace, as e.g. git diff can be configured to do.
Historical note: Since v1.7.0, layoutPretty and layoutSmart avoid producing the trailing whitespace that was the original motivation for creating removeTrailingWhitespace. See https://github.com/quchen/prettyprinter/pull/139 for some background info.
(sep xs) tries laying out the documents xs separated with spaces,
and if this does not fit the page, separates them with newlines. This is what
differentiates it from vsep, which always lays out its contents beneath
each other.
let doc = "prefix" <+> sep ["text", "to", "lay", "out"]putDocW 80 docprefix text to lay out
With a narrower layout, the entries are separated by newlines:
putDocW 20 docprefix texttolayout
sep = group . vsep
softline behaves like if the resulting output fits the page,
otherwise like spaceline.
Here, we have enough space to put everything in one line:
let doc = "lorem ipsum" <> softline <> "dolor sit amet"putDocW 80 doclorem ipsum dolor sit amet
If we narrow the page to width 10, the layouter produces a line break:
putDocW 10 doclorem ipsumdolor sit amet
softline = group line
softline' is like softline, but behaves like mempty if the
resulting output does not fit on the page (instead of ). In other
words, spaceline is to line' how softline is to softline'.
With enough space, we get direct concatenation:
let doc = "ThisWord" <> softline' <> "IsWayTooLong"putDocW 80 docThisWordIsWayTooLong
If we narrow the page to width 10, the layouter produces a line break:
putDocW 10 docThisWordIsWayTooLong
softline' = group line'
Haskell-inspired variant of encloseSep with parentheses and comma as separator.
let doc = tupled (map pretty [1,20,300,4000])putDocW 80 doc(1, 20, 300, 4000)
putDocW 10 doc( 1, 20, 300, 4000 )
Remove all annotations.
Although unAnnotate is idempotent with respect to rendering,
unAnnotate . unAnnotate = unAnnotate
it should not be used without caution, for each invocation traverses the entire contained document. If possible, it is preferable to unannotate after producing the layout by using unAnnotateS.
Remove all annotations. unAnnotate for SimpleDocStream.
(vcat xs) vertically concatenates the documents xs. If it is
grouped, the line breaks are removed.
In other words vcat is like vsep, with newlines removed instead of
replaced by spaces.
let docs = Util.words "lorem ipsum dolor"vcat docsloremipsumdolorgroup (vcat docs)loremipsumdolor
Since grouping a vcat is rather common, cat is a built-in shortcut for it.
Convenience function to convert a Showable value to a Doc. If the String does not contain newlines, consider using the more performant unsafeViaShow.
(vsep xs) concatenates all documents xs above each other. If a
group undoes the line breaks inserted by vsep, the documents are
separated with a space instead.
Using vsep alone yields
"prefix" <+> vsep ["text", "to", "lay", "out"]prefix texttolayout
grouping a vsep separates the documents with a space if it fits the
page (and does nothing otherwise). See the sep convenience function for
this use case.
The align function can be used to align the documents under their first element:
"prefix" <+> align (vsep ["text", "to", "lay", "out"])prefix text to lay out
Since grouping a vsep is rather common, sep is a built-in for doing that.
(width doc f) lays out the document doc, and makes the column width
of it available to a function.
let annotate doc = width (brackets doc) (\w -> " <- width:" <+> pretty w)align (vsep (map annotate ["---", "------", indent 3 "---", vsep ["---", indent 4 "---"]]))[---] <- width: 5[------] <- width: 8[ ---] <- width: 8[--- ---] <- width: 8
angles "·"<·>
backslash\
braces "·"{·}
brackets "·"[·]
colon:
comma,
dot.
dquote"
dquotes "·""·"
equals=
langle<
lbrace{
lbracket[
lparen(
parens "·"(·)
pipe|
rangle>
rbrace}
rbracket]
rparen)
semi;
slash/
"a" <> space <> "b"a b
This is mostly used via <+>,
"a" <+> "b"a b
squote'
squotes "·"'·'
An associative operation.
Examples
[1,2,3] <> [4,5,6][1,2,3,4,5,6]
Just [1, 2, 3] <> Just [4, 5, 6]Just [1,2,3,4,5,6]
putStr "Hello, " <> putStrLn "World!"Hello, World!
Fusion depth parameter, used by fuse.
Constructors
ShallowDo not dive deep into nested documents, fusing mostly concatenations of text nodes together.
DeepRecurse into all parts of the Doc, including different layout alternatives, and location-sensitive values such as created by nesting which cannot be fused before, but only during, the layout process. As a result, the performance cost of using deep fusion is often hard to predict, and depends on the interplay between page layout and document to prettyprint.
This value should only be used if profiling shows it is significantly faster than using Shallow.
Instances3Eq, Ord, Show
Eq FusionDepthDefined in prettyprinter-1.7.2 · Prettyprinter.InternalOrd FusionDepthDefined in prettyprinter-1.7.2 · Prettyprinter.InternalShow FusionDepthDefined in prettyprinter-1.7.2 · Prettyprinter.Internal
Options to influence the layout algorithms.
Constructors
Instances3Eq, Ord, Show
Eq LayoutOptionsDefined in prettyprinter-1.7.2 · Prettyprinter.InternalOrd LayoutOptionsDefined in prettyprinter-1.7.2 · Prettyprinter.InternalShow LayoutOptionsDefined in prettyprinter-1.7.2 · Prettyprinter.Internal
Maximum number of characters that fit in one line. The layout algorithms will try not to exceed the set limit by inserting line breaks when applicable (e.g. via softline').
Constructors
AvailablePerLine !Int !DoubleLayouters should not exceed the specified space per line.
The Int is the number of characters, including whitespace, that fit in a line. A typical value is 80.
The Double is the ribbon with, i.e. the fraction of the total page width that can be printed on. This allows limiting the length of printable text per line. Values must be between 0 and 1, and 0.4 to 1 is typical.
UnboundedLayouters should not introduce line breaks on their own.
Methods
pretty :: a -> Doc annExample1 expression pretty 1 <+> pretty "hello" <+> pretty 1.2341 hello 1.234
prettyList :: [a] -> Doc annprettyListis only used to define theinstance Pretty a => Pretty [a]. In normal circumstances only theprettyfunction is used.Example1 expression prettyList [1, 23, 456][1, 23, 456]
Instances32Pretty, …
Pretty VoidDefined in prettyprinter-1.7.2 · Prettyprinter.InternalFinding a good example for printing something that does not exist is hard, so here is an example of printing a list full of nothing.
Example1 expression pretty ([] :: [Void])[]
Pretty IntegerDefined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (2^123 :: Integer)10633823966279326983230456482242756608
Pretty NaturalDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Int16Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Int32Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Int64Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Int8Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty BoolDefined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty TrueTrue
Pretty CharDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty DoubleDefined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (exp 1 :: Double)2.71828182845904...
Pretty FloatDefined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (pi :: Float)3.1415927
Pretty IntDefined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123 :: Int)123
Pretty WordDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Word16Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Word32Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Word64Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty Word8Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty TextDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty TextDefined in prettyprinter-1.7.2 · Prettyprinter.Internal(lazy Text instance, identical to the strict version)
Pretty ()Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty ()()
The argument is not used:
Example1 expression pretty (error "Strict?" :: ())()
Pretty a => Pretty (NonEmpty a)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty a => Pretty (Identity a)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (Identity 1)1
Pretty a => Pretty (Maybe a)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPretty a => Pretty [a]Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty [1,2,3][1, 2, 3]
ann ~ Void => Pretty (Doc ann)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(Pretty a1, Pretty a2) => Pretty (a1, a2)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123, "hello")(123, hello)
Pretty a => Pretty (Const a b)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(Pretty a1, Pretty a2, Pretty a3) => Pretty (a1, a2, a3)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123, "hello", False)(123, hello, False)
(Pretty a1, Pretty a2, Pretty a3, Pretty a4) => Pretty (a1, a2, a3, a4)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123, "hello", False, ())(123, hello, False, ())
(Pretty a1, Pretty a2, Pretty a3, Pretty a4, Pretty a5) => Pretty (a1, a2, a3, a4, a5)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123, "hello", False, (), 3.14)(123, hello, False, (), 3.14)
(Pretty a1, Pretty a2, Pretty a3, Pretty a4, Pretty a5, Pretty a6) => Pretty (a1, a2, a3, a4, a5, a6)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123, "hello", False, (), 3.14, Just 2.71)(123, hello, False, (), 3.14, 2.71)
(Pretty a1, Pretty a2, Pretty a3, Pretty a4, Pretty a5, Pretty a6, Pretty a7) => Pretty (a1, a2, a3, a4, a5, a6, a7)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalExample1 expression pretty (123, "hello", False, (), 3.14, Just 2.71, [1,2,3])(123, hello, False, (), 3.14, 2.71, [1, 2, 3])
Methods
prettyAnn :: a -> Doc annprettyAnnList :: [a] -> Doc ann
Instances32PrettyAnn, …
PrettyAnn ann VoidDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann IntegerDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann NaturalDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Int16Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Int32Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Int64Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Int8Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann BoolDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann CharDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann DoubleDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann FloatDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann IntDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann WordDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Word16Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Word32Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Word64Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann Word8Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann TextDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann TextDefined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann ()Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann (Doc ann)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann a => PrettyAnn ann (NonEmpty a)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann a => PrettyAnn ann (Identity a)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann a => PrettyAnn ann (Maybe a)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann a => PrettyAnn ann [a]Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(PrettyAnn ann a1, PrettyAnn ann a2) => PrettyAnn ann (a1, a2)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalPrettyAnn ann a => PrettyAnn ann (Const a b)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(PrettyAnn ann a1, PrettyAnn ann a2, PrettyAnn ann a3) => PrettyAnn ann (a1, a2, a3)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(PrettyAnn ann a1, PrettyAnn ann a2, PrettyAnn ann a3, PrettyAnn ann a4) => PrettyAnn ann (a1, a2, a3, a4)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(PrettyAnn ann a1, PrettyAnn ann a2, PrettyAnn ann a3, PrettyAnn ann a4, PrettyAnn ann a5) => PrettyAnn ann (a1, a2, a3, a4, a5)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(PrettyAnn ann a1, PrettyAnn ann a2, PrettyAnn ann a3, PrettyAnn ann a4, PrettyAnn ann a5, PrettyAnn ann a6) => PrettyAnn ann (a1, a2, a3, a4, a5, a6)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal(PrettyAnn ann a1, PrettyAnn ann a2, PrettyAnn ann a3, PrettyAnn ann a4, PrettyAnn ann a5, PrettyAnn ann a6, PrettyAnn ann a7) => PrettyAnn ann (a1, a2, a3, a4, a5, a6, a7)Defined in prettyprinter-1.7.2 · Prettyprinter.Internal
The data type SimpleDocStream represents laid out documents and is used
by the display functions.
A simplified view is that Doc = [SimpleDocStream], and the layout
functions pick one of the SimpleDocStreams based on which one fits the
layout constraints best. This means that SimpleDocStream has all complexity
contained in Doc resolved, making it very easy to convert it to other
formats, such as plain text or terminal output.
To write your own Doc to X converter, it is therefore sufficient to
convert from SimpleDocStream. The »Render« submodules provide some
built-in converters to do so, and helpers to create own ones.
Constructors
SFailSEmptySChar !Char (SimpleDocStream ann)SText !Int !Text (SimpleDocStream ann)SLine !Int (SimpleDocStream ann)Int= indentation level for the (next) lineSAnnPush ann (SimpleDocStream ann)Add an annotation to the remaining document.
SAnnPop (SimpleDocStream ann)Remove a previously pushed annotation.
Instances8Functor, Foldable, Traversable, Eq, Ord, Show, …
Functor SimpleDocStreamDefined in prettyprinter-1.7.2 · Prettyprinter.InternalAlter the document’s annotations.
This instance makes SimpleDocStream more flexible (because it can be used in Functor-polymorphic values), but
fmapis much less readable compared to usingin code that only works forreAnnotateSTSimpleDocStreamanyway. Consider using the latter when the type does not matter.Foldable SimpleDocStreamDefined in prettyprinter-1.7.2 · Prettyprinter.InternalCollect all annotations from a document.
Traversable SimpleDocStreamDefined in prettyprinter-1.7.2 · Prettyprinter.InternalTransform a document based on its annotations, possibly leveraging Applicative effects.
Eq ann => Eq (SimpleDocStream ann)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalOrd ann => Ord (SimpleDocStream ann)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalShow ann => Show (SimpleDocStream ann)Defined in prettyprinter-1.7.2 · Prettyprinter.InternalGeneric (SimpleDocStream ann)Defined in prettyprinter-1.7.2 · Prettyprinter.Internaltype Rep (SimpleDocStream ann) = D1 ('MetaDataDefined in prettyprinter-1.7.2 · Prettyprinter.Internal"SimpleDocStream"
"Prettyprinter.Internal"
"prettyprinter-1.7.2-SPFFk7WrbZ5dowUcxRlzD"
'False) ((C1 ('MetaCons"SFail"
'PrefixI 'False) U1 :+: (C1 ('MetaCons"SEmpty"
'PrefixI 'False) U1 :+: C1 ('MetaCons"SChar"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Char) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (SimpleDocStream ann))))) :+: ((C1 ('MetaCons"SText"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Int) :*: (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (SimpleDocStream ann)))) :+: C1 ('MetaCons"SLine"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Int) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (SimpleDocStream ann)))) :+: (C1 ('MetaCons"SAnnPush"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ann) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (SimpleDocStream ann))) :+: C1 ('MetaCons"SAnnPop"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (SimpleDocStream ann))))))
Style the background with a vivid color.
Style the background with a dull color.
Render in bold.
Style the foreground with a vivid color.
Style the foreground with a dull color.
Like putDoc, but instead of using stdout, print to a user-provided handle, e.g. a file or a socket using defaultLayoutOptions.
main = withFile "someFile.txt" (\h -> hPutDoc h (vcat ["vertical", "text"]))hPutDoc h doc = renderIO h (layoutPretty defaultLayoutOptions doc)
Render in italics.
(putDoc doc) prettyprints document doc to standard output using
defaultLayoutOptions.
putDoc ("hello" <+> "world")hello world
putDoc = hPutDoc stdout
(renderIO h sdoc) writes sdoc to the handle h.
let render = renderIO System.IO.stdout . layoutPretty defaultLayoutOptionslet doc = annotate (color Red) ("red" <+> align (vsep [annotate (color Blue <> underlined) ("blue+u" <+> annotate bold "bold" <+> "blue+u"), "red"]))
We render the unAnnotated version here, since the ANSI codes don’t display well in Haddock,
render (unAnnotate doc)red blue+u bold blue+u red
This function behaves just like
renderIO h sdoc = TL.hPutStr h (renderLazy sdoc)
but will not generate any intermediate text, rendering directly to the handle.
(renderLazy doc) takes the output doc from a rendering function
and transforms it to lazy text, including ANSI styling directives for things
like colorization.
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.
With a bit of trickery to make the ANSI codes printable, here is an example that would render colored in an ANSI terminal:
let render = TL.putStrLn . TL.replace "\ESC" "\\e" . renderLazy . layoutPretty defaultLayoutOptionslet doc = annotate (color Red) ("red" <+> align (vsep [annotate (color Blue <> underlined) ("blue+u" <+> annotate bold "bold" <+> "blue+u"), "red"]))render (unAnnotate doc)red blue+u bold blue+u redrender doc\e[0;91mred \e[0;94;4mblue+u \e[0;94;1;4mbold\e[0;94;4m blue+u\e[0;91m red\e[0m
Run the above via echo -e in your terminal to see the coloring....
(renderStrict sdoc) takes the output sdoc from a rendering and
transforms it to strict text.
Render underlined.
Instances5Eq, Ord, Show, Semigroup, Monoid
Eq AnsiStyleDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalOrd AnsiStyleDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalShow AnsiStyleDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalSemigroup AnsiStyleDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalKeep the first decision for each of foreground color, background color, boldness, italication, and underlining. If a certain style is not set, the terminal’s default will be used.
Example:
color Red <> color Greenis red because the first color wins, and not bold because (or if) that’s the terminal’s default.
Monoid AnsiStyleDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.Internalmempty does nothing, which is equivalent to inheriting the style of the surrounding doc, or the terminal’s default if no style has been set yet.
Instances3Eq, Ord, Show
Instances3Eq, Ord, Show
Instances3Eq, Ord, Show
Instances3Eq, Ord, Show
Eq ItalicizedDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalOrd ItalicizedDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalShow ItalicizedDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.Internal
Instances3Eq, Ord, Show
Eq UnderlinedDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalOrd UnderlinedDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.InternalShow UnderlinedDefined in prettyprinter-ansi-terminal-1.1.4 · Prettyprinter.Render.Terminal.Internal
Render flattened text on this line, or start a new line before rendering any text.
This will also nest subsequent lines in the group.
Separate items in an alternative with a pipe.
If the first document and the pipe don't fit on the line, then mandatorily flow the next entry onto the following line.
The (//) softbreak ensures that if the document does fit on the line, there is at least a space, but it's possible for y to still appear on the next line.
Printer hacks to get nice indentation for long commands and subcommands.
If we're starting this section over the desired width (usually 1/3 of the ribbon), then we will make a line break, indent all of the usage, and go.
The ifAtRoot is an interesting clause. If this whole operation is put under a group then the linebreak will disappear; then item d will therefore not be at the starting column, and it won't be indented more.