    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    {-|
    Module      : Text.Pretty.Simple.Internal.Color
    Copyright   : (c) Dennis Gosnell, 2016
    License     : BSD-style (see LICENSE file)
    Maintainer  : cdep.illabout@gmail.com
    Stability   : experimental
    Portability : POSIX

    -}
    module Text.Pretty.Simple.Internal.Color
      where

    #if __GLASGOW_HASKELL__ < 710
    -- We don't need this import for GHC 7.10 as it exports all required functions
    -- from Prelude
    import Control.Applicative
    #endif

    import Data.Typeable (Typeable)
    import GHC.Generics (Generic)
    import Prettyprinter.Render.Terminal
      (AnsiStyle, Intensity(Dull,Vivid), Color(..))
    import qualified Prettyprinter.Render.Terminal as Ansi

    -- | These options are for colorizing the output of functions like 'pPrint'.
    --
    -- If you don't want to use a color for one of the options, use 'colorNull'.
    data ColorOptions = ColorOptions
      { ColorOptions -> Style
    colorQuote :: Style
      -- ^ Color to use for quote characters (@\"@) around strings.
      , ColorOptions -> Style
    colorString :: Style
      -- ^ Color to use for strings.
      , ColorOptions -> Style
    colorError :: Style
      -- ^ Color for errors, e.g. unmatched brackets.
      , ColorOptions -> Style
    colorNum :: Style
      -- ^ Color to use for numbers.
      , ColorOptions -> [Style]
    colorRainbowParens :: [Style]
      -- ^ A list of colors to use for rainbow parenthesis output.  Use
      -- '[]' if you don't want rainbow parenthesis.  Use just a single item if you
      -- want all the rainbow parenthesis to be colored the same.
      } deriving (ColorOptions -> ColorOptions -> Bool
    (ColorOptions -> ColorOptions -> Bool)
    -> (ColorOptions -> ColorOptions -> Bool) -> Eq ColorOptions
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ColorOptions -> ColorOptions -> Bool
    == :: ColorOptions -> ColorOptions -> Bool
    $c/= :: ColorOptions -> ColorOptions -> Bool
    /= :: ColorOptions -> ColorOptions -> Bool
    Eq, (forall x. ColorOptions -> Rep ColorOptions x)
    -> (forall x. Rep ColorOptions x -> ColorOptions)
    -> Generic ColorOptions
    forall x. Rep ColorOptions x -> ColorOptions
    forall x. ColorOptions -> Rep ColorOptions x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ColorOptions -> Rep ColorOptions x
    from :: forall x. ColorOptions -> Rep ColorOptions x
    $cto :: forall x. Rep ColorOptions x -> ColorOptions
    to :: forall x. Rep ColorOptions x -> ColorOptions
    Generic, Int -> ColorOptions -> ShowS
    [ColorOptions] -> ShowS
    ColorOptions -> String
    (Int -> ColorOptions -> ShowS)
    -> (ColorOptions -> String)
    -> ([ColorOptions] -> ShowS)
    -> Show ColorOptions
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ColorOptions -> ShowS
    showsPrec :: Int -> ColorOptions -> ShowS
    $cshow :: ColorOptions -> String
    show :: ColorOptions -> String
    $cshowList :: [ColorOptions] -> ShowS
    showList :: [ColorOptions] -> ShowS
    Show, Typeable)

    -- | Default color options for use on a dark background.
    defaultColorOptionsDarkBg :: ColorOptions
    defaultColorOptionsDarkBg :: ColorOptions
    defaultColorOptionsDarkBg =
      ColorOptions
      { colorQuote :: Style
    colorQuote = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    White
      , colorString :: Style
    colorString = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Blue
      , colorError :: Style
    colorError = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Red
      , colorNum :: Style
    colorNum = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Green
      , colorRainbowParens :: [Style]
    colorRainbowParens =
        [ Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Magenta
        , Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Cyan
        , Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Yellow
        , Intensity -> Color -> Style
    color Intensity
    Dull Color
    Magenta
        , Intensity -> Color -> Style
    color Intensity
    Dull Color
    Cyan
        , Intensity -> Color -> Style
    color Intensity
    Dull Color
    Yellow
        , Intensity -> Color -> Style
    colorBold Intensity
    Dull Color
    Magenta
        , Intensity -> Color -> Style
    colorBold Intensity
    Dull Color
    Cyan
        , Intensity -> Color -> Style
    colorBold Intensity
    Dull Color
    Yellow
        , Intensity -> Color -> Style
    color Intensity
    Vivid Color
    Magenta
        , Intensity -> Color -> Style
    color Intensity
    Vivid Color
    Cyan
        , Intensity -> Color -> Style
    color Intensity
    Vivid Color
    Yellow
        ]
      }

    -- | Default color options for use on a light background.
    defaultColorOptionsLightBg :: ColorOptions
    defaultColorOptionsLightBg :: ColorOptions
    defaultColorOptionsLightBg =
      ColorOptions
      { colorQuote :: Style
    colorQuote = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Black
      , colorString :: Style
    colorString = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Blue
      , colorError :: Style
    colorError = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Red
      , colorNum :: Style
    colorNum = Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Green
      , colorRainbowParens :: [Style]
    colorRainbowParens =
        [ Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Magenta
        , Intensity -> Color -> Style
    colorBold Intensity
    Vivid Color
    Cyan
        , Intensity -> Color -> Style
    color Intensity
    Dull Color
    Magenta
        , Intensity -> Color -> Style
    color Intensity
    Dull Color
    Cyan
        , Intensity -> Color -> Style
    colorBold Intensity
    Dull Color
    Magenta
        , Intensity -> Color -> Style
    colorBold Intensity
    Dull Color
    Cyan
        , Intensity -> Color -> Style
    color Intensity
    Vivid Color
    Magenta
        , Intensity -> Color -> Style
    color Intensity
    Vivid Color
    Cyan
        ]
      }

    -- | No styling.
    colorNull :: Style
    colorNull :: Style
    colorNull = Style
      { styleColor :: Maybe (Color, Intensity)
    styleColor = Maybe (Color, Intensity)
    forall a. Maybe a
    Nothing
      , styleBold :: Bool
    styleBold = Bool
    False
      , styleItalic :: Bool
    styleItalic = Bool
    False
      , styleUnderlined :: Bool
    styleUnderlined = Bool
    False
      }

    -- | Ways to style terminal output.
    data Style = Style
      { Style -> Maybe (Color, Intensity)
    styleColor :: Maybe (Color, Intensity)
      , Style -> Bool
    styleBold :: Bool
      , Style -> Bool
    styleItalic :: Bool
      , Style -> Bool
    styleUnderlined :: Bool
      }
      deriving (Style -> Style -> Bool
    (Style -> Style -> Bool) -> (Style -> Style -> Bool) -> Eq Style
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Style -> Style -> Bool
    == :: Style -> Style -> Bool
    $c/= :: Style -> Style -> Bool
    /= :: Style -> Style -> Bool
    Eq, (forall x. Style -> Rep Style x)
    -> (forall x. Rep Style x -> Style) -> Generic Style
    forall x. Rep Style x -> Style
    forall x. Style -> Rep Style x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Style -> Rep Style x
    from :: forall x. Style -> Rep Style x
    $cto :: forall x. Rep Style x -> Style
    to :: forall x. Rep Style x -> Style
    Generic, Int -> Style -> ShowS
    [Style] -> ShowS
    Style -> String
    (Int -> Style -> ShowS)
    -> (Style -> String) -> ([Style] -> ShowS) -> Show Style
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Style -> ShowS
    showsPrec :: Int -> Style -> ShowS
    $cshow :: Style -> String
    show :: Style -> String
    $cshowList :: [Style] -> ShowS
    showList :: [Style] -> ShowS
    Show, Typeable)

    color :: Intensity -> Color -> Style
    color :: Intensity -> Color -> Style
    color Intensity
    i Color
    c = Style
    colorNull {styleColor :: Maybe (Color, Intensity)
    styleColor = (Color, Intensity) -> Maybe (Color, Intensity)
    forall a. a -> Maybe a
    Just (Color
    c, Intensity
    i)}

    colorBold :: Intensity -> Color -> Style
    colorBold :: Intensity -> Color -> Style
    colorBold Intensity
    i Color
    c = (Intensity -> Color -> Style
    color Intensity
    i Color
    c) {styleBold :: Bool
    styleBold = Bool
    True}

    convertStyle :: Style -> AnsiStyle
    convertStyle :: Style -> AnsiStyle
    convertStyle Style {Bool
    Maybe (Color, Intensity)
    styleColor :: Style -> Maybe (Color, Intensity)
    styleBold :: Style -> Bool
    styleItalic :: Style -> Bool
    styleUnderlined :: Style -> Bool
    styleColor :: Maybe (Color, Intensity)
    styleBold :: Bool
    styleItalic :: Bool
    styleUnderlined :: Bool
    ..} =
      [AnsiStyle] -> AnsiStyle
    forall a. Monoid a => [a] -> a
    mconcat
        [ AnsiStyle
    -> ((Color, Intensity) -> AnsiStyle)
    -> Maybe (Color, Intensity)
    -> AnsiStyle
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe AnsiStyle
    forall a. Monoid a => a
    mempty ((Color -> Intensity -> AnsiStyle)
    -> (Color, Intensity) -> AnsiStyle
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ((Color -> Intensity -> AnsiStyle)
     -> (Color, Intensity) -> AnsiStyle)
    -> (Color -> Intensity -> AnsiStyle)
    -> (Color, Intensity)
    -> AnsiStyle
    forall a b. (a -> b) -> a -> b
    $ (Intensity -> Color -> AnsiStyle)
    -> Color -> Intensity -> AnsiStyle
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Intensity -> Color -> AnsiStyle
    col) Maybe (Color, Intensity)
    styleColor
        , if Bool
    styleBold then AnsiStyle
    Ansi.bold else AnsiStyle
    forall a. Monoid a => a
    mempty
        , if Bool
    styleItalic then AnsiStyle
    Ansi.italicized else AnsiStyle
    forall a. Monoid a => a
    mempty
        , if Bool
    styleUnderlined then AnsiStyle
    Ansi.underlined else AnsiStyle
    forall a. Monoid a => a
    mempty
        ]
      where
        col :: Intensity -> Color -> AnsiStyle
    col = \case
          Intensity
    Vivid -> Color -> AnsiStyle
    Ansi.color
          Intensity
    Dull -> Color -> AnsiStyle
    Ansi.colorDull