-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Pretty-printing library -- -- This package contains a pretty-printing library, a set of API's that -- provides a way to easily print out text in a consistent format of your -- choosing. This is useful for compilers and related tools. . This -- library produces more compact outputs than both Wadler-Leijen or -- Hughes-PJ algorithms, at the expense of computational ressources. The -- core API is based on Hughes-PJ, but some combinators of the Leijen API -- are implemented as well. @package pretty-compact @version 3.1 module Text.PrettyPrint.Compact.Core type Annotation a = (Monoid a) class Layout d text :: (Layout d, Monoid a) => String -> d a flush :: (Layout d, Monoid a) => d a -> d a -- | <> new annotation to the Doc. -- -- Example: 'Any True' annotation will transform the rendered Doc -- into uppercase: -- --
--   >>> let r = putStrLn . renderWith defaultOptions { optsAnnotate = \a x -> if a == Any True then map toUpper x else x }
--   
--   >>> r $ text "hello" <$$> annotate (Any True) (text "world")
--   hello
--   WORLD
--   
annotate :: forall a. (Layout d, Monoid a) => a -> d a -> d a renderWith :: (Monoid r, Annotation a) => Options a r -> ODoc a -> r data Options a r Options :: !Int -> (a -> String -> r) -> Options a r -- | maximum page width [optsPageWidth] :: Options a r -> !Int -- | how to annotate the string. Note: the annotation should -- preserve the visible length of the string. [optsAnnotate] :: Options a r -> a -> String -> r groupingBy :: Monoid a => String -> [(Int, Doc a)] -> Doc a type Doc = ODoc -- | The document (x $$> y) concatenates document x -- and y with a linebreak in between. (infixr 5) ($$) :: (Layout d, Monoid a, Semigroup (d a)) => d a -> d a -> d a instance Data.Traversable.Traversable Text.PrettyPrint.Compact.Core.AS instance Data.Foldable.Foldable Text.PrettyPrint.Compact.Core.AS instance GHC.Base.Functor Text.PrettyPrint.Compact.Core.AS instance GHC.Show.Show a => GHC.Show.Show (Text.PrettyPrint.Compact.Core.AS a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Text.PrettyPrint.Compact.Core.AS a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.PrettyPrint.Compact.Core.AS a) instance Data.Traversable.Traversable Text.PrettyPrint.Compact.Core.L instance Data.Foldable.Foldable Text.PrettyPrint.Compact.Core.L instance GHC.Base.Functor Text.PrettyPrint.Compact.Core.L instance GHC.Show.Show a => GHC.Show.Show (Text.PrettyPrint.Compact.Core.L a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Text.PrettyPrint.Compact.Core.L a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.PrettyPrint.Compact.Core.L a) instance Data.Traversable.Traversable Text.PrettyPrint.Compact.Core.M instance Data.Foldable.Foldable Text.PrettyPrint.Compact.Core.M instance GHC.Base.Functor Text.PrettyPrint.Compact.Core.M instance GHC.Classes.Ord (Text.PrettyPrint.Compact.Core.M a) instance GHC.Classes.Eq (Text.PrettyPrint.Compact.Core.M a) instance GHC.Show.Show (Text.PrettyPrint.Compact.Core.M a) instance (Data.Traversable.Traversable f, Data.Traversable.Traversable g) => Data.Traversable.Traversable (Text.PrettyPrint.Compact.Core.Pair f g) instance (Data.Foldable.Foldable f, Data.Foldable.Foldable g) => Data.Foldable.Foldable (Text.PrettyPrint.Compact.Core.Pair f g) instance (GHC.Base.Functor f, GHC.Base.Functor g) => GHC.Base.Functor (Text.PrettyPrint.Compact.Core.Pair f g) instance GHC.Base.Functor Text.PrettyPrint.Compact.Core.ODoc instance GHC.Base.Monoid a => Data.String.IsString (Text.PrettyPrint.Compact.Core.Doc a) instance GHC.Base.Monoid a => GHC.Base.Semigroup (Text.PrettyPrint.Compact.Core.ODoc a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Text.PrettyPrint.Compact.Core.ODoc a) instance Text.PrettyPrint.Compact.Core.Layout Text.PrettyPrint.Compact.Core.ODoc instance (GHC.Base.Semigroup (f a), GHC.Base.Semigroup (g a)) => GHC.Base.Semigroup (Text.PrettyPrint.Compact.Core.Pair f g a) instance (GHC.Base.Monoid (f a), GHC.Base.Monoid (g a)) => GHC.Base.Monoid (Text.PrettyPrint.Compact.Core.Pair f g a) instance (Text.PrettyPrint.Compact.Core.Layout a, Text.PrettyPrint.Compact.Core.Layout b) => Text.PrettyPrint.Compact.Core.Layout (Text.PrettyPrint.Compact.Core.Pair a b) instance Text.PrettyPrint.Compact.Core.Poset (Text.PrettyPrint.Compact.Core.M a) instance GHC.Base.Semigroup (Text.PrettyPrint.Compact.Core.M a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Text.PrettyPrint.Compact.Core.M a) instance Text.PrettyPrint.Compact.Core.Layout Text.PrettyPrint.Compact.Core.M instance Text.PrettyPrint.Compact.Core.Layout Text.PrettyPrint.Compact.Core.L instance GHC.Base.Monoid a => GHC.Base.Semigroup (Text.PrettyPrint.Compact.Core.L a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Text.PrettyPrint.Compact.Core.L a) instance GHC.Base.Semigroup (Text.PrettyPrint.Compact.Core.AS a) -- | Compact pretty-printer. -- --

Examples

-- -- Assume that we want to pretty print S-Expressions, which can either be -- atom or a list of S-Expressions. -- --
--   >>> data SExpr = SExpr [SExpr] | Atom String deriving Show
--   
--   >>> let pretty :: SExpr -> Doc (); pretty (Atom s) = text s; pretty (SExpr xs) = text "(" <> (sep $ map pretty xs) <> text ")"
--   
-- -- Using the above representation, the S-Expression (a b c d) -- has the following encoding: -- --
--   >>> let abcd = SExpr [Atom "a",Atom "b",Atom "c",Atom "d"]
--   
-- -- The legible layouts of the abcd S-Expression defined above -- would be either -- --
--   >>> putStrLn $ render $ pretty abcd
--   (a b c d)
--   
-- -- or -- --
--   >>> putStrLn $ renderWith defaultOptions { optsPageWidth = 5 } $ pretty abcd
--   (a
--    b
--    c
--    d)
--   
-- -- The testData S-Expression is specially crafted to demonstrate -- general shortcomings of both Hughes and Wadler libraries. -- --
--   >>> let abcd4 = SExpr [abcd,abcd,abcd,abcd]
--   
--   >>> let testData = SExpr [ SExpr [Atom "abcde", abcd4], SExpr [Atom "abcdefgh", abcd4]]
--   
--   >>> putStrLn $ render $ pretty testData
--   ((abcde ((a b c d) (a b c d) (a b c d) (a b c d)))
--    (abcdefgh ((a b c d) (a b c d) (a b c d) (a b c d))))
--   
-- -- on 20-column-wide page -- --
--   >>> putStrLn $ renderWith defaultOptions { optsPageWidth = 20 } $ pretty testData
--   ((abcde ((a b c d)
--            (a b c d)
--            (a b c d)
--            (a b c d)))
--    (abcdefgh
--     ((a b c d)
--      (a b c d)
--      (a b c d)
--      (a b c d))))
--   
-- -- Yet, neither Hughes' nor Wadler's library can deliver those results. -- --

Annotations

-- -- For example we can annotate every car element of S-Expressions, -- and in the rendering phase emphasise them by rendering them in -- uppercase. -- --
--   >>> let pretty' :: SExpr -> Doc Any; pretty' (Atom s) = text s; pretty' (SExpr []) = text "()"; pretty' (SExpr (x:xs)) = text "(" <> (sep $ annotate (Any True) (pretty' x) : map pretty' xs) <> text ")"
--   
--   >>> let render' = renderWith defaultOptions { optsAnnotate  = \a x -> if a == Any True then map toUpper x else x }
--   
--   >>> putStrLn $ render' $ pretty' testData
--   ((ABCDE ((A B C D) (A B C D) (A B C D) (A B C D)))
--    (ABCDEFGH ((A B C D) (A b c d) (A b c d) (A b c d))))
--   
module Text.PrettyPrint.Compact type Doc = ODoc text :: (Layout d, Monoid a) => String -> d a flush :: (Layout d, Monoid a) => d a -> d a char :: Annotation a => Char -> Doc a -- | The hang combinator implements hanging indentation. The document -- (hang i x y) either x and y concatenated -- with <+> or y below x with an -- additional indentation of i. hang :: Annotation a => Int -> Doc a -> Doc a -> Doc a -- | The hang combinator implements hanging indentation. The document -- (hang separator i x y) either x and y -- concatenated with <> text separator <> or -- y below x with an additional indentation of -- i. hangWith :: Annotation a => String -> Int -> Doc a -> Doc a -> Doc a -- | The document (enclosure 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 -- enclosure: -- --
--   list xs = enclosure 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]
--   
encloseSep :: Annotation a => Doc a -> Doc a -> Doc a -> [Doc a] -> Doc a -- | 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. list :: Annotation a => [Doc a] -> Doc a -- | 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. tupled :: Annotation a => [Doc a] -> Doc a -- | The document (semiBraces xs) separates the documents -- xs with semi colons and encloses them in braces. The -- documents are rendered horizontally if that fits the page. Otherwise -- they are aligned vertically. All semi colons are put in front of the -- elements. semiBraces :: Annotation a => [Doc a] -> Doc a -- | The document (x <+> y) concatenates document x -- and y with a space in between. (infixr 6) (<+>) :: Annotation a => Doc a -> Doc a -> Doc a -- | The document (x $$> y) concatenates document x -- and y with a linebreak in between. (infixr 5) ($$) :: (Layout d, Monoid a, Semigroup (d a)) => d a -> d a -> d a -- | The document (x </> y) puts x and y -- either next to each other (with a space in between) or -- underneath each other. (infixr 5) () :: Annotation a => Doc a -> Doc a -> Doc a -- | The document (x <//> y) puts x and y -- either right next to each other (if x fits on a single line) -- or underneath each other. (infixr 5) () :: Annotation a => Doc a -> Doc a -> Doc a -- | The document (x <$$> y) concatenates document -- x and y with a linebreak in between. (infixr 5) (<$$>) :: Annotation a => Doc a -> Doc a -> Doc a -- | The document (hsep xs) concatenates all documents xs -- horizontally with (<+>). hsep :: Annotation a => [Doc a] -> Doc a -- | The document (sep xs) concatenates all documents xs -- either horizontally with (<+>), if it fits the page, or -- vertically with (<$$>). Documents on the left of -- horizontal concatenation must fit on a single line. sep :: Annotation a => [Doc a] -> Doc a -- | The document (hcat xs) concatenates all documents xs -- horizontally with (<>). hcat :: Annotation a => [Doc a] -> Doc a -- | The document (vcat xs) concatenates all documents xs -- vertically with ($$). vcat :: Annotation a => [Doc a] -> Doc a -- | The document (cat xs) concatenates all documents xs -- either horizontally with (<>), if it fits the page, or -- vertically with (<$$>). cat :: Annotation a => [Doc a] -> Doc a -- | (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.) punctuate :: Annotation a => Doc a -> [Doc a] -> [Doc a] -- | The document (enclose l r x) encloses document x -- between documents l and r using (<>). enclose :: Annotation a => Doc a -> Doc a -> Doc a -> Doc a -- | Document (squotes x) encloses document x with single -- quotes "'". squotes :: Annotation a => Doc a -> Doc a -- | Document (dquotes x) encloses document x with double -- quotes '"'. dquotes :: Annotation a => Doc a -> Doc a -- | Document (parens x) encloses document x in -- parenthesis, "(" and ")". parens :: Annotation a => Doc a -> Doc a -- | Document (angles x) encloses document x in angles, -- "<" and ">". angles :: Annotation a => Doc a -> Doc a -- | Document (braces x) encloses document x in braces, -- "{" and "}". braces :: Annotation a => Doc a -> Doc a -- | Document (brackets x) encloses document x in square -- brackets, "[" and "]". brackets :: Annotation a => Doc a -> Doc a -- | The document lparen contains a left parenthesis, "(". lparen :: Annotation a => Doc a -- | The document rparen contains a right parenthesis, ")". rparen :: Annotation a => Doc a -- | The document langle contains a left angle, "<". langle :: Annotation a => Doc a -- | The document rangle contains a right angle, ">". rangle :: Annotation a => Doc a -- | The document lbrace contains a left brace, "{". lbrace :: Annotation a => Doc a -- | The document rbrace contains a right brace, "}". rbrace :: Annotation a => Doc a -- | The document lbracket contains a left square bracket, "[". lbracket :: Annotation a => Doc a -- | The document rbracket contains a right square bracket, "]". rbracket :: Annotation a => Doc a -- | The document squote contains a single quote, "'". squote :: Annotation a => Doc a -- | The document dquote contains a double quote, '"'. dquote :: Annotation a => Doc a -- | The document semi contains a semi colon, ";". semi :: Annotation a => Doc a -- | The document colon contains a colon, ":". colon :: Annotation a => Doc a -- | The document comma contains a comma, ",". comma :: Annotation a => Doc a space :: Annotation a => Doc a -- | The document dot contains a single dot, ".". dot :: Annotation a => Doc a -- | The document backslash contains a back slash, "\". backslash :: Annotation a => Doc a -- | The document equals contains an equal sign, "=". equals :: Annotation a => Doc a -- | 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. string :: Annotation a => String -> Doc a -- | The document (int i) shows the literal integer i -- using text. int :: Annotation a => Int -> Doc a -- | The document (integer i) shows the literal integer i -- using text. integer :: Annotation a => Integer -> Doc a -- | The document (float f) shows the literal float f -- using text. float :: Annotation a => Float -> Doc a -- | The document (double d) shows the literal double d -- using text. double :: Annotation a => Double -> Doc a -- | The document (rational r) shows the literal rational -- r using text. rational :: Annotation a => Rational -> Doc a bool :: Annotation a => Bool -> Doc a renderWith :: (Monoid r, Annotation a) => Options a r -> ODoc a -> r -- | Render the Doc into String omitting all annotations. render :: Annotation a => Doc a -> String data Options a r Options :: !Int -> (a -> String -> r) -> Options a r -- | maximum page width [optsPageWidth] :: Options a r -> !Int -- | how to annotate the string. Note: the annotation should -- preserve the visible length of the string. [optsAnnotate] :: Options a r -> a -> String -> r defaultOptions :: Options a String -- | <> new annotation to the Doc. -- -- Example: 'Any True' annotation will transform the rendered Doc -- into uppercase: -- --
--   >>> let r = putStrLn . renderWith defaultOptions { optsAnnotate = \a x -> if a == Any True then map toUpper x else x }
--   
--   >>> r $ text "hello" <$$> annotate (Any True) (text "world")
--   hello
--   WORLD
--   
annotate :: forall a. (Layout d, Monoid a) => a -> d a -> d a