packages feed

prettyprinter-ansi-terminal 1.1.1.2 → 1.1.2

raw patch · 8 files changed

+618/−368 lines, 8 filesdep +QuickCheckdep +base-compatdep +containersdep ~basedep ~prettyprinterdep ~textnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: QuickCheck, base-compat, containers, deepseq, gauge, prettyprinter-ansi-terminal

Dependency ranges changed: base, prettyprinter, text

API changes (from Hackage documentation)

- Data.Text.Prettyprint.Doc.Render.Terminal: Black :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Blue :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Bold :: Bold
- Data.Text.Prettyprint.Doc.Render.Terminal: Cyan :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Dull :: Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal: Green :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Italicized :: Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal: Magenta :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Red :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Underlined :: Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal: Vivid :: Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal: White :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: Yellow :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal: bgColor :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: bgColorDull :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: bold :: AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: color :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: colorDull :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: data AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: data Bold
- Data.Text.Prettyprint.Doc.Render.Terminal: data Color
- Data.Text.Prettyprint.Doc.Render.Terminal: data Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal: data Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal: data Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal: hPutDoc :: Handle -> Doc AnsiStyle -> IO ()
- Data.Text.Prettyprint.Doc.Render.Terminal: italicized :: AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal: putDoc :: Doc AnsiStyle -> IO ()
- Data.Text.Prettyprint.Doc.Render.Terminal: renderIO :: Handle -> SimpleDocStream AnsiStyle -> IO ()
- Data.Text.Prettyprint.Doc.Render.Terminal: renderLazy :: SimpleDocStream AnsiStyle -> Text
- Data.Text.Prettyprint.Doc.Render.Terminal: renderStrict :: SimpleDocStream AnsiStyle -> Text
- Data.Text.Prettyprint.Doc.Render.Terminal: underlined :: AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Background :: Layer
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Black :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Blue :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Bold :: Bold
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Cyan :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Dull :: Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Foreground :: Layer
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Green :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Italicized :: Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Magenta :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Red :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: SetAnsiStyle :: Maybe (Intensity, Color) -> Maybe (Intensity, Color) -> Maybe Bold -> Maybe Italicized -> Maybe Underlined -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Underlined :: Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Vivid :: Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: White :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: Yellow :: Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: [ansiBackground] :: AnsiStyle -> Maybe (Intensity, Color)
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: [ansiBold] :: AnsiStyle -> Maybe Bold
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: [ansiForeground] :: AnsiStyle -> Maybe (Intensity, Color)
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: [ansiItalics] :: AnsiStyle -> Maybe Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: [ansiUnderlining] :: AnsiStyle -> Maybe Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: bgColor :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: bgColorDull :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: bold :: AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: color :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: colorDull :: Color -> AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data Bold
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data Layer
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: data Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: hPutDoc :: Handle -> Doc AnsiStyle -> IO ()
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance Data.Semigroup.Semigroup Data.Text.Prettyprint.Doc.Render.Terminal.Internal.AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Base.Monoid Data.Text.Prettyprint.Doc.Render.Terminal.Internal.AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Bold
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Layer
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Eq Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Bold
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Layer
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Classes.Ord Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Bold
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Color
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Intensity
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Italicized
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Layer
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: instance GHC.Show.Show Data.Text.Prettyprint.Doc.Render.Terminal.Internal.Underlined
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: italicized :: AnsiStyle
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: panicStyleStackFullyConsumed :: void
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: panicStyleStackNotFullyConsumed :: Int -> void
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: putDoc :: Doc AnsiStyle -> IO ()
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: renderIO :: Handle -> SimpleDocStream AnsiStyle -> IO ()
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: renderLazy :: SimpleDocStream AnsiStyle -> Text
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: renderStrict :: SimpleDocStream AnsiStyle -> Text
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: styleToRawText :: AnsiStyle -> Text
- Data.Text.Prettyprint.Doc.Render.Terminal.Internal: underlined :: AnsiStyle
+ Prettyprinter.Render.Terminal: Black :: Color
+ Prettyprinter.Render.Terminal: Blue :: Color
+ Prettyprinter.Render.Terminal: Bold :: Bold
+ Prettyprinter.Render.Terminal: Cyan :: Color
+ Prettyprinter.Render.Terminal: Dull :: Intensity
+ Prettyprinter.Render.Terminal: Green :: Color
+ Prettyprinter.Render.Terminal: Italicized :: Italicized
+ Prettyprinter.Render.Terminal: Magenta :: Color
+ Prettyprinter.Render.Terminal: Red :: Color
+ Prettyprinter.Render.Terminal: Underlined :: Underlined
+ Prettyprinter.Render.Terminal: Vivid :: Intensity
+ Prettyprinter.Render.Terminal: White :: Color
+ Prettyprinter.Render.Terminal: Yellow :: Color
+ Prettyprinter.Render.Terminal: bgColor :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal: bgColorDull :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal: bold :: AnsiStyle
+ Prettyprinter.Render.Terminal: color :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal: colorDull :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal: data AnsiStyle
+ Prettyprinter.Render.Terminal: data Bold
+ Prettyprinter.Render.Terminal: data Color
+ Prettyprinter.Render.Terminal: data Intensity
+ Prettyprinter.Render.Terminal: data Italicized
+ Prettyprinter.Render.Terminal: data Underlined
+ Prettyprinter.Render.Terminal: hPutDoc :: Handle -> Doc AnsiStyle -> IO ()
+ Prettyprinter.Render.Terminal: italicized :: AnsiStyle
+ Prettyprinter.Render.Terminal: putDoc :: Doc AnsiStyle -> IO ()
+ Prettyprinter.Render.Terminal: renderIO :: Handle -> SimpleDocStream AnsiStyle -> IO ()
+ Prettyprinter.Render.Terminal: renderLazy :: SimpleDocStream AnsiStyle -> Text
+ Prettyprinter.Render.Terminal: renderStrict :: SimpleDocStream AnsiStyle -> Text
+ Prettyprinter.Render.Terminal: underlined :: AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: Black :: Color
+ Prettyprinter.Render.Terminal.Internal: Blue :: Color
+ Prettyprinter.Render.Terminal.Internal: Bold :: Bold
+ Prettyprinter.Render.Terminal.Internal: Cyan :: Color
+ Prettyprinter.Render.Terminal.Internal: Dull :: Intensity
+ Prettyprinter.Render.Terminal.Internal: Green :: Color
+ Prettyprinter.Render.Terminal.Internal: Italicized :: Italicized
+ Prettyprinter.Render.Terminal.Internal: Magenta :: Color
+ Prettyprinter.Render.Terminal.Internal: Red :: Color
+ Prettyprinter.Render.Terminal.Internal: SetAnsiStyle :: Maybe (Intensity, Color) -> Maybe (Intensity, Color) -> Maybe Bold -> Maybe Italicized -> Maybe Underlined -> AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: Underlined :: Underlined
+ Prettyprinter.Render.Terminal.Internal: Vivid :: Intensity
+ Prettyprinter.Render.Terminal.Internal: White :: Color
+ Prettyprinter.Render.Terminal.Internal: Yellow :: Color
+ Prettyprinter.Render.Terminal.Internal: [ansiBackground] :: AnsiStyle -> Maybe (Intensity, Color)
+ Prettyprinter.Render.Terminal.Internal: [ansiBold] :: AnsiStyle -> Maybe Bold
+ Prettyprinter.Render.Terminal.Internal: [ansiForeground] :: AnsiStyle -> Maybe (Intensity, Color)
+ Prettyprinter.Render.Terminal.Internal: [ansiItalics] :: AnsiStyle -> Maybe Italicized
+ Prettyprinter.Render.Terminal.Internal: [ansiUnderlining] :: AnsiStyle -> Maybe Underlined
+ Prettyprinter.Render.Terminal.Internal: bgColor :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: bgColorDull :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: bold :: AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: color :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: colorDull :: Color -> AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: data AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: data Bold
+ Prettyprinter.Render.Terminal.Internal: data Color
+ Prettyprinter.Render.Terminal.Internal: data Intensity
+ Prettyprinter.Render.Terminal.Internal: data Italicized
+ Prettyprinter.Render.Terminal.Internal: data Underlined
+ Prettyprinter.Render.Terminal.Internal: hPutDoc :: Handle -> Doc AnsiStyle -> IO ()
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Base.Monoid Prettyprinter.Render.Terminal.Internal.AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Base.Semigroup Prettyprinter.Render.Terminal.Internal.AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.Bold
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.Color
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.Intensity
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.Italicized
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.Layer
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Eq Prettyprinter.Render.Terminal.Internal.Underlined
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.Bold
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.Color
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.Intensity
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.Italicized
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.Layer
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Classes.Ord Prettyprinter.Render.Terminal.Internal.Underlined
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.Bold
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.Color
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.Intensity
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.Italicized
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.Layer
+ Prettyprinter.Render.Terminal.Internal: instance GHC.Show.Show Prettyprinter.Render.Terminal.Internal.Underlined
+ Prettyprinter.Render.Terminal.Internal: italicized :: AnsiStyle
+ Prettyprinter.Render.Terminal.Internal: putDoc :: Doc AnsiStyle -> IO ()
+ Prettyprinter.Render.Terminal.Internal: renderIO :: Handle -> SimpleDocStream AnsiStyle -> IO ()
+ Prettyprinter.Render.Terminal.Internal: renderLazy :: SimpleDocStream AnsiStyle -> Text
+ Prettyprinter.Render.Terminal.Internal: renderStrict :: SimpleDocStream AnsiStyle -> Text
+ Prettyprinter.Render.Terminal.Internal: underlined :: AnsiStyle

Files

CHANGELOG.md view
@@ -1,3 +1,17 @@+# [1.1.2]++- [Add shallower `Prettyprinter` module hierarchy exposing the same API.](https://github.com/quchen/prettyprinter/pull/174)+  * The current plan for the existing `Data.Text.Prettyprint.Doc*` modules is:+    * Start deprecation in early 2021.+    * Remove the modules after a deprecation period of at least one year.+- [Make `renderLazy` lazy, and speed it up.](https://github.com/quchen/prettyprinter/pull/176)+- [Add export list for Prettyprinter.Render.Terminal.Internal.](https://github.com/quchen/prettyprinter/pull/148)+- [Optimize generating spaces for indentation.](https://github.com/quchen/prettyprinter/pull/132)+- [Enable `-O2`.](https://github.com/quchen/prettyprinter/pull/144)+- [Extend GHC support to 7.6 and 7.4.](https://github.com/quchen/prettyprinter/pull/74)++[1.1.2]: https://github.com/quchen/prettyprinter/compare/ansi-terminal-v1.1.1.2...ansi-terminal-v1.1.2+ # 1.1.1.2  - Fix documentation claiming there would be a trailing newline in `renderIO`
+ bench/LargeOutput.hs view
@@ -0,0 +1,159 @@+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE LambdaCase        #-}+{-# LANGUAGE OverloadedStrings #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++-- | This benchmark is derived from the large-output benchmark in prettyprinter, but contains additional annotations.+module Main (main) where++import Prelude        ()+import Prelude.Compat++import           Control.DeepSeq+import           Control.Monad.Compat+import           Data.Char+import           Data.Map                              (Map)+import qualified Data.Map                              as M+import           Data.Text                             (Text)+import qualified Data.Text                             as T+import qualified Data.Text.IO                          as T+import qualified Data.Text.Lazy                        as TL+import           Gauge+import           GHC.Generics+import           Prettyprinter+import           Prettyprinter.Render.Terminal         as Terminal+import qualified Prettyprinter.Render.Text             as Text+import           Test.QuickCheck+import           Test.QuickCheck.Gen+import           Test.QuickCheck.Random++++newtype Program = Program Binds deriving (Show, Generic)+newtype Binds = Binds (Map Text LambdaForm) deriving (Show, Generic)+data LambdaForm = LambdaForm ![Text] ![Text] !Expr deriving (Show, Generic)+data Expr+    = Let Binds Expr+    | Case Expr [Alt]+    | AppF Text [Text]+    | AppC Text [Text]+    | AppP Text Text Text+    | LitE Int+    deriving (Show, Generic)+data Alt = Alt Text [Text] Expr deriving (Show, Generic)++instance NFData Program+instance NFData Binds+instance NFData LambdaForm+instance NFData Expr+instance NFData Alt++instance Arbitrary Program where arbitrary = fmap Program arbitrary+instance Arbitrary Binds where+    arbitrary = do+        NonEmpty xs <- arbitrary+        pure (Binds (M.fromList xs))+instance Arbitrary LambdaForm where+    arbitrary = LambdaForm <$> fromTo 0 2 arbitrary <*> fromTo 0 2 arbitrary <*> arbitrary++instance Arbitrary Expr where+    arbitrary = (oneof . map scaled)+        [ Let <$> arbitrary <*> arbitrary+        , Case <$> arbitrary <*> (do NonEmpty xs <- arbitrary; pure xs)+        , AppF <$> arbitrary <*> fromTo 0 3 arbitrary+        , AppC <$> ucFirst arbitrary <*> fromTo 0 3 arbitrary+        , AppP <$> arbitrary <*> arbitrary <*> arbitrary+        , LitE <$> arbitrary ]+instance Arbitrary Alt where arbitrary = Alt <$> ucFirst arbitrary <*> fromTo 0 3 arbitrary <*> arbitrary+instance Arbitrary Text where+    arbitrary = do+        n <- choose (3,6)+        str <- replicateM n (elements ['a'..'z'])+        if str `elem` ["let", "in", "case", "of"]+            then arbitrary+            else pure (T.pack str)++ucFirst :: Gen Text -> Gen Text+ucFirst gen = do+    x <- gen+    case T.uncons x of+        Nothing -> pure x+        Just (t,ext) -> pure (T.cons (toUpper t) ext)++anCol :: Color -> Doc AnsiStyle -> Doc AnsiStyle+anCol = annotate . color++prettyProgram :: Program -> Doc AnsiStyle+prettyProgram (Program binds) = annotate italicized $ prettyBinds binds++prettyBinds :: Binds -> Doc AnsiStyle+prettyBinds (Binds bs) = align (vsep (map prettyBinding (M.assocs bs)))+  where+    prettyBinding (var, lambda) = pretty var <+> anCol Red "=" <+> prettyLambdaForm lambda++prettyLambdaForm :: LambdaForm -> Doc AnsiStyle+prettyLambdaForm (LambdaForm free bound body) = prettyExp . (<+> anCol Blue "->") . prettyBound . prettyFree $ anCol Blue "\\"+  where+    prettyFree | null free = id+               | otherwise = (<> anCol Blue lparen <> hsep (map pretty free) <> anCol Blue rparen)+    prettyBound | null bound = id+                | null free = (<> hsep (map pretty bound))+                | otherwise = (<+> hsep (map pretty bound))+    prettyExp = (<+> prettyExpr body)++prettyExpr :: Expr -> Doc AnsiStyle+prettyExpr = \case+    Let binds body ->+        align (vsep [ anCol Red "let" <+> align (prettyBinds binds)+                    , anCol Red "in" <+> prettyExpr body ])++    Case scrutinee alts -> vsep+        [ anCol Yellow "case" <+> prettyExpr scrutinee <+> anCol Yellow "of"+        , indent 4 (align (vsep (map prettyAlt alts))) ]++    AppF f [] -> annotate bold . anCol Green $ pretty f+    AppF f args -> annotate bold . anCol Green $ pretty f <+> hsep (map pretty args)++    AppC c [] -> annotate bold . anCol Green $ pretty c+    AppC c args -> annotate bold . anCol Green $ pretty c <+> hsep (map pretty args)++    AppP op x y -> annotate bold . anCol Green $ pretty op <+> pretty x <+> pretty y++    LitE lit -> annotate bold . anCol Green $ pretty lit++prettyAlt :: Alt -> Doc AnsiStyle+prettyAlt (Alt con [] body) = pretty con <+> anCol Yellow "->" <+> prettyExpr body+prettyAlt (Alt con args body) = pretty con <+> hsep (map pretty args) <+> anCol Yellow "->" <+> prettyExpr body++scaled :: Gen a -> Gen a+scaled = scale (\n -> n * 2 `quot` 3)++fromTo :: Int -> Int -> Gen b -> Gen b+fromTo a b gen = do+    n <- choose (min a b, max a b)+    resize n gen++randomProgram+    :: Int -- ^ Seed+    -> Int -- ^ Generator size+    -> Program+randomProgram seed size = let MkGen gen = arbitrary in gen (mkQCGen seed) size++main :: IO ()+main = do+    let prog = randomProgram 1 60+        layoutOpts = defaultLayoutOptions { layoutPageWidth = Unbounded }+        renderedProg = (renderLazy . layoutPretty layoutOpts . prettyProgram) prog+        (progLines, progWidth) = let l = TL.lines renderedProg in (length l, maximum (map TL.length l))+    putDoc ("Program size:" <+> pretty progLines <+> "lines, maximum width:" <+> pretty progWidth)++    let render :: (SimpleDocStream AnsiStyle -> TL.Text) -> Program -> TL.Text+        render r = r . layoutPretty layoutOpts . prettyProgram++    rnf prog `seq` T.putStrLn "Starting benchmark…"++    defaultMain+        [ bench "prettyprinter-ansi-terminal" $ nf (render Terminal.renderLazy) prog+        , bench "prettyprinter" $ nf (render Text.renderLazy) prog+        ]
misc/version-compatibility-macros.h view
@@ -10,10 +10,14 @@  #define APPLICATIVE_MONAD               MIN_VERSION_base(4,8,0) #define FOLDABLE_TRAVERSABLE_IN_PRELUDE MIN_VERSION_base(4,8,0)+#define FUNCTOR_IDENTITY_IN_BASE        MIN_VERSION_base(4,8,0) #define MONOID_IN_PRELUDE               MIN_VERSION_base(4,8,0) #define NATURAL_IN_BASE                 MIN_VERSION_base(4,8,0)  #define SEMIGROUP_IN_BASE               MIN_VERSION_base(4,9,0)-#define MONAD_FAIL                      MIN_VERSION_base(4,9,0)++#define SEMIGROUP_MONOID_SUPERCLASS     MIN_VERSION_base(4,11,0)++#define FAIL_IN_MONAD                   !(MIN_VERSION_base(4,13,0))  #endif
prettyprinter-ansi-terminal.cabal view
@@ -1,5 +1,5 @@ name:                prettyprinter-ansi-terminal-version:             1.1.1.2+version:             1.1.2 cabal-version:       >= 1.10 category:            User Interfaces, Text synopsis:            ANSI terminal backend for the »prettyprinter« package.@@ -10,11 +10,16 @@                    , misc/version-compatibility-macros.h                    , CHANGELOG.md author:              David Luposchainsky-maintainer:          David Luposchainsky <dluposchainsky at google>+maintainer:          Simon Jakobi <simon.jakobi@gmail.com>, David Luposchainsky <dluposchainsky at google> bug-reports:         http://github.com/quchen/prettyprinter/issues homepage:            http://github.com/quchen/prettyprinter build-type:          Simple-tested-with:         GHC==7.8.4, GHC==7.10.2, GHC==7.10.3, GHC==8.0.1, GHC==8.0.2+tested-with:         GHC == 7.8.4+                   , GHC == 7.10.2+                   , GHC == 7.10.3+                   , GHC == 8.0.1+                   , GHC == 8.0.2+                   , GHC == 8.2.2  source-repository head   type: git@@ -23,18 +28,19 @@ library     exposed-modules:  Data.Text.Prettyprint.Doc.Render.Terminal                     , Data.Text.Prettyprint.Doc.Render.Terminal.Internal-    ghc-options:      -Wall+                    , Prettyprinter.Render.Terminal+                    , Prettyprinter.Render.Terminal.Internal+    ghc-options:      -Wall -O2     hs-source-dirs:   src     include-dirs:     misc     default-language: Haskell2010     other-extensions:           CPP-        , LambdaCase         , OverloadedStrings       build-depends:-          base          >= 4.7 && < 5+          base          >= 4.5 && < 5         , ansi-terminal >= 0.4.0         , text          >= 1.2         , prettyprinter >= 1.1.1@@ -56,3 +62,21 @@     if impl (ghc < 7.10)         buildable: False         -- Doctest cannot search folders in old versions it seems :-(++benchmark large-output+    build-depends:+          base >= 4.5 && < 5+        , base-compat >=0.9.3 && <0.12+        , containers+        , deepseq+        , gauge >= 0.2+        , prettyprinter+        , prettyprinter-ansi-terminal+        , QuickCheck >= 2.7+        , text++    hs-source-dirs:      bench+    main-is:             LargeOutput.hs+    ghc-options:         -O2 -threaded -rtsopts -with-rtsopts=-N -Wall+    default-language:    Haskell2010+    type:                exitcode-stdio-1.0
src/Data/Text/Prettyprint/Doc/Render/Terminal.hs view
@@ -1,35 +1,13 @@--- | Render 'SimpleDocStream' in a terminal.+-- | This module is part of the old @Data.Text.Prettyprint.Doc@ module hierarchy+-- which is being replaced by a shallower @Prettyprinter@ module hierarchy+-- offering the same API.+--+-- This module will be deprecated and eventually removed.+--+-- Use "Prettyprinter.Render.Terminal" instead. module Data.Text.Prettyprint.Doc.Render.Terminal (-    -- * Styling-    AnsiStyle,-    Color(..),--    -- ** Font color-    color, colorDull,--    -- ** Background color-    bgColor, bgColorDull,--    -- ** Font style-    bold, italicized, underlined,--    -- ** Internal markers-    ---    -- | These should only be used for writing adaptors to other libraries; for-    -- the average use case, use 'bold', 'bgColorDull', etc.-    Intensity(..),-    Bold(..),-    Underlined(..),-    Italicized(..),--    -- * Conversion to ANSI-infused 'Text'-    renderLazy, renderStrict,--    -- * Render directly to 'stdout'-    renderIO,--    -- ** Convenience functions-    putDoc, hPutDoc,+    module Prettyprinter.Render.Terminal ) where -import Data.Text.Prettyprint.Doc.Render.Terminal.Internal+import Prettyprinter.Render.Terminal+
src/Data/Text/Prettyprint/Doc/Render/Terminal/Internal.hs view
@@ -1,334 +1,14 @@-{-# LANGUAGE CPP               #-}-{-# LANGUAGE LambdaCase        #-}-{-# LANGUAGE OverloadedStrings #-}--#include "version-compatibility-macros.h"---- | __Warning:__ Internal module. May change arbitrarily between versions.-module Data.Text.Prettyprint.Doc.Render.Terminal.Internal where----import           Control.Applicative-import           Control.Monad.ST-import           Data.IORef-import           Data.Maybe-import           Data.Semigroup-import           Data.STRef-import           Data.Text              (Text)-import qualified Data.Text              as T-import qualified Data.Text.IO           as T-import qualified Data.Text.Lazy         as TL-import qualified Data.Text.Lazy.Builder as TLB-import qualified System.Console.ANSI    as ANSI-import           System.IO              (Handle, hPutChar, stdout)--import Data.Text.Prettyprint.Doc-import Data.Text.Prettyprint.Doc.Render.Util.Panic------ $setup------ (Definitions for the doctests)------ >>> :set -XOverloadedStrings--- >>> import qualified Data.Text.Lazy.IO as TL--- >>> import qualified Data.Text.Lazy as TL--- >>> import Data.Text.Prettyprint.Doc.Render.Terminal------ | The 8 ANSI terminal colors.-data Color = Black | Red | Green | Yellow | Blue | Magenta | Cyan | White-    deriving (Eq, Ord, Show)---- | Dull or vivid coloring, as supported by ANSI terminals.-data Intensity = Vivid | Dull-    deriving (Eq, Ord, Show)---- | Foreground (text) or background (paper) color-data Layer = Foreground | Background-    deriving (Eq, Ord, Show)--data Bold       = Bold       deriving (Eq, Ord, Show)-data Underlined = Underlined deriving (Eq, Ord, Show)-data Italicized = Italicized deriving (Eq, Ord, Show)---- | Style the foreground with a vivid color.-color :: Color -> AnsiStyle-color c = mempty { ansiForeground = Just (Vivid, c) }---- | Style the background with a vivid color.-bgColor :: Color -> AnsiStyle-bgColor c =  mempty { ansiBackground = Just (Vivid, c) }---- | Style the foreground with a dull color.-colorDull :: Color -> AnsiStyle-colorDull c =  mempty { ansiForeground = Just (Dull, c) }---- | Style the background with a dull color.-bgColorDull :: Color -> AnsiStyle-bgColorDull c =  mempty { ansiBackground = Just (Dull, c) }---- | Render in __bold__.-bold :: AnsiStyle-bold = mempty { ansiBold = Just Bold }---- | Render in /italics/.-italicized :: AnsiStyle-italicized = mempty { ansiItalics = Just Italicized }---- | Render underlined.-underlined :: AnsiStyle-underlined = mempty { ansiUnderlining = Just Underlined }---- | @('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 defaultLayoutOptions--- >>> let 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---     red--- >>> render 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.-renderLazy :: SimpleDocStream AnsiStyle -> TL.Text-renderLazy sdoc = runST (do-    styleStackRef <- newSTRef [mempty]-    outputRef <- newSTRef mempty--    let push x = modifySTRef' styleStackRef (x :)-        unsafePeek = readSTRef styleStackRef >>= \case-            []  -> panicPeekedEmpty-            x:_ -> pure x-        unsafePop = readSTRef styleStackRef >>= \case-            []   -> panicPeekedEmpty-            x:xs -> writeSTRef styleStackRef xs >> pure x-        writeOutput x = modifySTRef outputRef (<> x)--    let go = \case-            SFail -> panicUncaughtFail-            SEmpty -> pure ()-            SChar c rest -> do-                writeOutput (TLB.singleton c)-                go rest-            SText _ t rest -> do-                writeOutput (TLB.fromText t)-                go rest-            SLine i rest -> do-                writeOutput (TLB.singleton '\n' <> TLB.fromText (T.replicate i " "))-                go rest-            SAnnPush style rest -> do-                currentStyle <- unsafePeek-                let newStyle = style <> currentStyle-                push newStyle-                writeOutput (TLB.fromText (styleToRawText newStyle))-                go rest-            SAnnPop rest -> do-                _currentStyle <- unsafePop-                newStyle <- unsafePeek-                writeOutput (TLB.fromText (styleToRawText newStyle))-                go rest-    go sdoc-    readSTRef styleStackRef >>= \case-        []  -> panicStyleStackFullyConsumed-        [_] -> fmap TLB.toLazyText (readSTRef outputRef)-        xs  -> panicStyleStackNotFullyConsumed (length xs) )---- | @('renderIO' h sdoc)@ writes @sdoc@ to the handle @h@.------ >>> let render = renderIO System.IO.stdout . layoutPretty defaultLayoutOptions--- >>> let doc = annotate (color Red) ("red" <+> align (vsep [annotate (color Blue <> underlined) ("blue+u" <+> annotate bold "bold" <+> "blue+u"), "red"]))------ We render the 'unAnnotate'd 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.-renderIO :: Handle -> SimpleDocStream AnsiStyle -> IO ()-renderIO h sdoc = do-    styleStackRef <- newIORef [mempty]--    let push x = modifyIORef' styleStackRef (x :)-        unsafePeek = readIORef styleStackRef >>= \case-            [] -> panicPeekedEmpty-            x:_ -> pure x-        unsafePop = readIORef styleStackRef >>= \case-            [] -> panicPeekedEmpty-            x:xs -> writeIORef styleStackRef xs >> pure x--    let go = \case-            SFail -> panicUncaughtFail-            SEmpty -> pure ()-            SChar c rest -> do-                hPutChar h c-                go rest-            SText _ t rest -> do-                T.hPutStr h t-                go rest-            SLine i rest -> do-                hPutChar h '\n'-                T.hPutStr h (T.replicate i " ")-                go rest-            SAnnPush style rest -> do-                currentStyle <- unsafePeek-                let newStyle = style <> currentStyle-                push newStyle-                T.hPutStr h (styleToRawText newStyle)-                go rest-            SAnnPop rest -> do-                _currentStyle <- unsafePop-                newStyle <- unsafePeek-                T.hPutStr h (styleToRawText newStyle)-                go rest-    go sdoc-    readIORef styleStackRef >>= \case-        []  -> panicStyleStackFullyConsumed-        [_] -> pure ()-        xs  -> panicStyleStackNotFullyConsumed (length xs)--panicStyleStackFullyConsumed :: void-panicStyleStackFullyConsumed-  = error ("There is no empty style left at the end of rendering" ++-           " (but there should be). Please report this as a bug.")--panicStyleStackNotFullyConsumed :: Int -> void-panicStyleStackNotFullyConsumed len-  = error ("There are " <> show len <> " styles left at the" ++-           "end of rendering (there should be only 1). Please report" ++-           " this as a bug.")---- $--- >>> let render = renderIO System.IO.stdout . layoutPretty defaultLayoutOptions--- >>> let 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---     red------ This test won’t work since I don’t know how to type \ESC for doctest :-/--- -- >>> render doc--- -- \ESC[0;91mred \ESC[0;94;4mblue+u \ESC[0;94;1;4mbold\ESC[0;94;4m blue+u\ESC[0;91m--- --     red\ESC[0m---- | Render the annotated document in a certain style. Styles not set in the--- annotation will use the style of the surrounding document, or the terminal’s--- default if none has been set yet.------ @--- style = 'color' 'Green' '<>' 'bold'--- styledDoc = 'annotate' style "hello world"--- @-data AnsiStyle = SetAnsiStyle-    { ansiForeground  :: Maybe (Intensity, Color) -- ^ Set the foreground color, or keep the old one.-    , ansiBackground  :: Maybe (Intensity, Color) -- ^ Set the background color, or keep the old one.-    , ansiBold        :: Maybe Bold               -- ^ Switch on boldness, or don’t do anything.-    , ansiItalics     :: Maybe Italicized         -- ^ Switch on italics, or don’t do anything.-    , ansiUnderlining :: Maybe Underlined         -- ^ Switch on underlining, or don’t do anything.-    } deriving (Eq, Ord, Show)---- | Keep 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:+-- | This module is part of the old @Data.Text.Prettyprint.Doc@ module hierarchy+-- which is being replaced by a shallower @Prettyprinter@ module hierarchy+-- offering the same API. ----- @--- 'color' 'Red' '<>' 'color' 'Green'--- @+-- This module will be deprecated and eventually removed. ----- is red because the first color wins, and not bold because (or if) that’s the--- terminal’s default.-instance Semigroup AnsiStyle where-    cs1 <> cs2 = SetAnsiStyle-        { ansiForeground  = ansiForeground  cs1 <|> ansiForeground  cs2-        , ansiBackground  = ansiBackground  cs1 <|> ansiBackground  cs2-        , ansiBold        = ansiBold        cs1 <|> ansiBold        cs2-        , ansiItalics     = ansiItalics     cs1 <|> ansiItalics     cs2-        , ansiUnderlining = ansiUnderlining cs1 <|> ansiUnderlining cs2 }---- | 'mempty' 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.-instance Monoid AnsiStyle where-    mempty = SetAnsiStyle Nothing Nothing Nothing Nothing Nothing-    mappend = (<>)--styleToRawText :: AnsiStyle -> Text-styleToRawText = T.pack . ANSI.setSGRCode . stylesToSgrs-  where-    stylesToSgrs :: AnsiStyle -> [ANSI.SGR]-    stylesToSgrs (SetAnsiStyle fg bg b i u) = catMaybes-        [ Just ANSI.Reset-        , fmap (\(intensity, c) -> ANSI.SetColor ANSI.Foreground (convertIntensity intensity) (convertColor c)) fg-        , fmap (\(intensity, c) -> ANSI.SetColor ANSI.Background (convertIntensity intensity) (convertColor c)) bg-        , fmap (\_              -> ANSI.SetConsoleIntensity ANSI.BoldIntensity) b-        , fmap (\_              -> ANSI.SetItalicized True) i-        , fmap (\_              -> ANSI.SetUnderlining ANSI.SingleUnderline) u-        ]--    convertIntensity :: Intensity -> ANSI.ColorIntensity-    convertIntensity = \case-        Vivid -> ANSI.Vivid-        Dull  -> ANSI.Dull--    convertColor :: Color -> ANSI.Color-    convertColor = \case-        Black   -> ANSI.Black-        Red     -> ANSI.Red-        Green   -> ANSI.Green-        Yellow  -> ANSI.Yellow-        Blue    -> ANSI.Blue-        Magenta -> ANSI.Magenta-        Cyan    -> ANSI.Cyan-        White   -> ANSI.White+-- Use "Prettyprinter.Render.Terminal.Internal" instead.+module Data.Text.Prettyprint.Doc.Render.Terminal.Internal (+    module Prettyprinter.Render.Terminal.Internal+) where +import Prettyprinter.Render.Terminal.Internal  --- | @('renderStrict' sdoc)@ takes the output @sdoc@ from a rendering and--- transforms it to strict text.-renderStrict :: SimpleDocStream AnsiStyle -> Text-renderStrict = TL.toStrict . renderLazy---- | @('putDoc' doc)@ prettyprints document @doc@ to standard output using--- 'defaultLayoutOptions'.------ >>> putDoc ("hello" <+> "world")--- hello world------ @--- 'putDoc' = 'hPutDoc' 'stdout'--- @-putDoc :: Doc AnsiStyle -> IO ()-putDoc = hPutDoc stdout---- | 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)--- @-hPutDoc :: Handle -> Doc AnsiStyle -> IO ()-hPutDoc h doc = renderIO h (layoutPretty defaultLayoutOptions doc)
+ src/Prettyprinter/Render/Terminal.hs view
@@ -0,0 +1,35 @@+-- | Render 'SimpleDocStream' in a terminal.+module Prettyprinter.Render.Terminal (+    -- * Styling+    AnsiStyle,+    Color(..),++    -- ** Font color+    color, colorDull,++    -- ** Background color+    bgColor, bgColorDull,++    -- ** Font style+    bold, italicized, underlined,++    -- ** Internal markers+    --+    -- | These should only be used for writing adaptors to other libraries; for+    -- the average use case, use 'bold', 'bgColorDull', etc.+    Intensity(..),+    Bold(..),+    Underlined(..),+    Italicized(..),++    -- * Conversion to ANSI-infused 'Text'+    renderLazy, renderStrict,++    -- * Render directly to 'stdout'+    renderIO,++    -- ** Convenience functions+    putDoc, hPutDoc,+) where++import Prettyprinter.Render.Terminal.Internal
+ src/Prettyprinter/Render/Terminal/Internal.hs view
@@ -0,0 +1,356 @@+{-# LANGUAGE CPP               #-}+{-# LANGUAGE OverloadedStrings #-}++{-# OPTIONS_HADDOCK not-home #-}++#include "version-compatibility-macros.h"++-- | __Warning:__ Internal module. May change arbitrarily between versions.+module Prettyprinter.Render.Terminal.Internal (+    -- * Styling+    AnsiStyle(..),+    Color(..),++    -- ** Font color+    color, colorDull,++    -- ** Background color+    bgColor, bgColorDull,++    -- ** Font style+    bold, italicized, underlined,++    -- ** Internal markers+    Intensity(..),+    Bold(..),+    Underlined(..),+    Italicized(..),++    -- * Conversion to ANSI-infused 'Text'+    renderLazy, renderStrict,++    -- * Render directly to 'stdout'+    renderIO,++    -- ** Convenience functions+    putDoc, hPutDoc,+) where++++import           Control.Applicative+import           Data.IORef+import           Data.Maybe+import           Data.Text              (Text)+import qualified Data.Text              as T+import qualified Data.Text.IO           as T+import qualified Data.Text.Lazy         as TL+import qualified Data.Text.Lazy.Builder as TLB+import qualified System.Console.ANSI    as ANSI+import           System.IO              (Handle, hPutChar, stdout)++import Data.Text.Prettyprint.Doc+import Data.Text.Prettyprint.Doc.Render.Util.Panic++#if !(SEMIGROUP_MONOID_SUPERCLASS)+import Data.Semigroup+#endif++#if !(MIN_VERSION_base(4,6,0))+modifyIORef' :: IORef a -> (a -> a) -> IO ()+modifyIORef' ref f = do+    x <- readIORef ref+    let x' = f x+    x' `seq` writeIORef ref x'+#endif++-- $setup+--+-- (Definitions for the doctests)+--+-- >>> :set -XOverloadedStrings+-- >>> import qualified Data.Text.Lazy.IO as TL+-- >>> import qualified Data.Text.Lazy as TL+-- >>> import Prettyprinter.Render.Terminal++++-- | The 8 ANSI terminal colors.+data Color = Black | Red | Green | Yellow | Blue | Magenta | Cyan | White+    deriving (Eq, Ord, Show)++-- | Dull or vivid coloring, as supported by ANSI terminals.+data Intensity = Vivid | Dull+    deriving (Eq, Ord, Show)++-- | Foreground (text) or background (paper) color+data Layer = Foreground | Background+    deriving (Eq, Ord, Show)++data Bold       = Bold       deriving (Eq, Ord, Show)+data Underlined = Underlined deriving (Eq, Ord, Show)+data Italicized = Italicized deriving (Eq, Ord, Show)++-- | Style the foreground with a vivid color.+color :: Color -> AnsiStyle+color c = mempty { ansiForeground = Just (Vivid, c) }++-- | Style the background with a vivid color.+bgColor :: Color -> AnsiStyle+bgColor c =  mempty { ansiBackground = Just (Vivid, c) }++-- | Style the foreground with a dull color.+colorDull :: Color -> AnsiStyle+colorDull c =  mempty { ansiForeground = Just (Dull, c) }++-- | Style the background with a dull color.+bgColorDull :: Color -> AnsiStyle+bgColorDull c =  mempty { ansiBackground = Just (Dull, c) }++-- | Render in __bold__.+bold :: AnsiStyle+bold = mempty { ansiBold = Just Bold }++-- | Render in /italics/.+italicized :: AnsiStyle+italicized = mempty { ansiItalics = Just Italicized }++-- | Render underlined.+underlined :: AnsiStyle+underlined = mempty { ansiUnderlining = Just Underlined }++-- | @('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 defaultLayoutOptions+-- >>> let 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+--     red+-- >>> render 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.+renderLazy :: SimpleDocStream AnsiStyle -> TL.Text+renderLazy =+    let push x = (x :)++        unsafePeek []    = panicPeekedEmpty+        unsafePeek (x:_) = x++        unsafePop []     = panicPoppedEmpty+        unsafePop (x:xs) = (x, xs)++        go :: [AnsiStyle] -> SimpleDocStream AnsiStyle -> TLB.Builder+        go s sds = case sds of+            SFail -> panicUncaughtFail+            SEmpty -> mempty+            SChar c rest -> TLB.singleton c <> go s rest+            SText _ t rest -> TLB.fromText t <> go s rest+            SLine i rest -> TLB.singleton '\n' <> TLB.fromText (T.replicate i " ") <> go s rest+            SAnnPush style rest ->+                let currentStyle = unsafePeek s+                    newStyle = style <> currentStyle+                in  TLB.fromText (styleToRawText newStyle) <> go (push style s) rest+            SAnnPop rest ->+                let (_currentStyle, s') = unsafePop s+                    newStyle = unsafePeek s'+                in  TLB.fromText (styleToRawText newStyle) <> go s' rest++    in  TLB.toLazyText . go [mempty]+++-- | @('renderIO' h sdoc)@ writes @sdoc@ to the handle @h@.+--+-- >>> let render = renderIO System.IO.stdout . layoutPretty defaultLayoutOptions+-- >>> let doc = annotate (color Red) ("red" <+> align (vsep [annotate (color Blue <> underlined) ("blue+u" <+> annotate bold "bold" <+> "blue+u"), "red"]))+--+-- We render the 'unAnnotate'd 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.+renderIO :: Handle -> SimpleDocStream AnsiStyle -> IO ()+renderIO h sdoc = do+    styleStackRef <- newIORef [mempty]++    let push x = modifyIORef' styleStackRef (x :)+        unsafePeek = readIORef styleStackRef >>= \tok -> case tok of+            [] -> panicPeekedEmpty+            x:_ -> pure x+        unsafePop = readIORef styleStackRef >>= \tok -> case tok of+            [] -> panicPoppedEmpty+            x:xs -> writeIORef styleStackRef xs >> pure x++    let go = \sds -> case sds of+            SFail -> panicUncaughtFail+            SEmpty -> pure ()+            SChar c rest -> do+                hPutChar h c+                go rest+            SText _ t rest -> do+                T.hPutStr h t+                go rest+            SLine i rest -> do+                hPutChar h '\n'+                T.hPutStr h (T.replicate i (T.singleton ' '))+                go rest+            SAnnPush style rest -> do+                currentStyle <- unsafePeek+                let newStyle = style <> currentStyle+                push newStyle+                T.hPutStr h (styleToRawText newStyle)+                go rest+            SAnnPop rest -> do+                _currentStyle <- unsafePop+                newStyle <- unsafePeek+                T.hPutStr h (styleToRawText newStyle)+                go rest+    go sdoc+    readIORef styleStackRef >>= \stack -> case stack of+        []  -> panicStyleStackFullyConsumed+        [_] -> pure ()+        xs  -> panicStyleStackNotFullyConsumed (length xs)++panicStyleStackFullyConsumed :: void+panicStyleStackFullyConsumed+  = error ("There is no empty style left at the end of rendering" +++           " (but there should be). Please report this as a bug.")++panicStyleStackNotFullyConsumed :: Int -> void+panicStyleStackNotFullyConsumed len+  = error ("There are " <> show len <> " styles left at the" +++           "end of rendering (there should be only 1). Please report" +++           " this as a bug.")++-- $+-- >>> let render = renderIO System.IO.stdout . layoutPretty defaultLayoutOptions+-- >>> let 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+--     red+--+-- This test won’t work since I don’t know how to type \ESC for doctest :-/+-- -- >>> render doc+-- -- \ESC[0;91mred \ESC[0;94;4mblue+u \ESC[0;94;1;4mbold\ESC[0;94;4m blue+u\ESC[0;91m+-- --     red\ESC[0m++-- | Render the annotated document in a certain style. Styles not set in the+-- annotation will use the style of the surrounding document, or the terminal’s+-- default if none has been set yet.+--+-- @+-- style = 'color' 'Green' '<>' 'bold'+-- styledDoc = 'annotate' style "hello world"+-- @+data AnsiStyle = SetAnsiStyle+    { ansiForeground  :: Maybe (Intensity, Color) -- ^ Set the foreground color, or keep the old one.+    , ansiBackground  :: Maybe (Intensity, Color) -- ^ Set the background color, or keep the old one.+    , ansiBold        :: Maybe Bold               -- ^ Switch on boldness, or don’t do anything.+    , ansiItalics     :: Maybe Italicized         -- ^ Switch on italics, or don’t do anything.+    , ansiUnderlining :: Maybe Underlined         -- ^ Switch on underlining, or don’t do anything.+    } deriving (Eq, Ord, Show)++-- | Keep 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' 'Green'+-- @+--+-- is red because the first color wins, and not bold because (or if) that’s the+-- terminal’s default.+instance Semigroup AnsiStyle where+    cs1 <> cs2 = SetAnsiStyle+        { ansiForeground  = ansiForeground  cs1 <|> ansiForeground  cs2+        , ansiBackground  = ansiBackground  cs1 <|> ansiBackground  cs2+        , ansiBold        = ansiBold        cs1 <|> ansiBold        cs2+        , ansiItalics     = ansiItalics     cs1 <|> ansiItalics     cs2+        , ansiUnderlining = ansiUnderlining cs1 <|> ansiUnderlining cs2 }++-- | 'mempty' 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.+instance Monoid AnsiStyle where+    mempty = SetAnsiStyle Nothing Nothing Nothing Nothing Nothing+    mappend = (<>)++styleToRawText :: AnsiStyle -> Text+styleToRawText = T.pack . ANSI.setSGRCode . stylesToSgrs+  where+    stylesToSgrs :: AnsiStyle -> [ANSI.SGR]+    stylesToSgrs (SetAnsiStyle fg bg b i u) = catMaybes+        [ Just ANSI.Reset+        , fmap (\(intensity, c) -> ANSI.SetColor ANSI.Foreground (convertIntensity intensity) (convertColor c)) fg+        , fmap (\(intensity, c) -> ANSI.SetColor ANSI.Background (convertIntensity intensity) (convertColor c)) bg+        , fmap (\_              -> ANSI.SetConsoleIntensity ANSI.BoldIntensity) b+        , fmap (\_              -> ANSI.SetItalicized True) i+        , fmap (\_              -> ANSI.SetUnderlining ANSI.SingleUnderline) u+        ]++    convertIntensity :: Intensity -> ANSI.ColorIntensity+    convertIntensity = \i -> case i of+        Vivid -> ANSI.Vivid+        Dull  -> ANSI.Dull++    convertColor :: Color -> ANSI.Color+    convertColor = \c -> case c of+        Black   -> ANSI.Black+        Red     -> ANSI.Red+        Green   -> ANSI.Green+        Yellow  -> ANSI.Yellow+        Blue    -> ANSI.Blue+        Magenta -> ANSI.Magenta+        Cyan    -> ANSI.Cyan+        White   -> ANSI.White++++-- | @('renderStrict' sdoc)@ takes the output @sdoc@ from a rendering and+-- transforms it to strict text.+renderStrict :: SimpleDocStream AnsiStyle -> Text+renderStrict = TL.toStrict . renderLazy++-- | @('putDoc' doc)@ prettyprints document @doc@ to standard output using+-- 'defaultLayoutOptions'.+--+-- >>> putDoc ("hello" <+> "world")+-- hello world+--+-- @+-- 'putDoc' = 'hPutDoc' 'stdout'+-- @+putDoc :: Doc AnsiStyle -> IO ()+putDoc = hPutDoc stdout++-- | 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)+-- @+hPutDoc :: Handle -> Doc AnsiStyle -> IO ()+hPutDoc h doc = renderIO h (layoutPretty defaultLayoutOptions doc)