rainbow-0.34.2.2: lib/Rainbow/Types.hs
{-# LANGUAGE DeriveGeneric, DeriveDataTypeable, DeriveFunctor,
DeriveTraversable, DeriveFoldable, TemplateHaskell #-}
-- | All the main types in Rainbow. Using this module you can specify
-- that you want different formatting for 8- and 256-color terminals.
-- Many of the names in this module conflict with the names in
-- "Rainbow", so it's probably best to @import@ this module
-- @qualified@.
module Rainbow.Types where
-- # Imports
import Control.Lens (makeLenses)
import Data.String (IsString(..))
import Data.Text (Text)
import qualified Data.Text as X
import Data.Traversable ()
import Data.Typeable (Typeable)
import Data.Word (Word8)
import GHC.Generics (Generic)
--
-- Colors
--
-- | A color; a 'Nothing' value means that the terminal's default
-- color is used. The type of the 'Maybe' generally will be an
-- 'Enum8' to represent one of 8 colors, or a 'Word8' to represent one
-- of 256 colors.
newtype Color a = Color (Maybe a)
deriving (Eq, Show, Ord, Generic, Typeable, Functor, Foldable,
Traversable)
instance Semigroup (Color a) where
Color x <> Color y = case y of
Just a -> Color (Just a)
_ -> Color x
-- | Takes the last non-Nothing Color. 'mempty' is no color.
instance Monoid (Color a) where
mempty = Color Nothing
-- | A simple enumeration for eight values. Represents eight colors.
data Enum8
= E0
| E1
| E2
| E3
| E4
| E5
| E6
| E7
deriving (Eq, Ord, Show, Bounded, Enum, Generic, Typeable)
enum8toWord8 :: Enum8 -> Word8
enum8toWord8 e = case e of
E0 -> 0
E1 -> 1
E2 -> 2
E3 -> 3
E4 -> 4
E5 -> 5
E6 -> 6
E7 -> 7
black :: Enum8
black = E0
red :: Enum8
red = E1
green :: Enum8
green = E2
yellow :: Enum8
yellow = E3
blue :: Enum8
blue = E4
magenta :: Enum8
magenta = E5
cyan :: Enum8
cyan = E6
white :: Enum8
white = E7
grey :: Word8
grey = 8
brightRed :: Word8
brightRed = 9
brightGreen :: Word8
brightGreen = 10
brightYellow :: Word8
brightYellow = 11
brightBlue :: Word8
brightBlue = 12
brightMagenta :: Word8
brightMagenta = 13
brightCyan :: Word8
brightCyan = 14
brightWhite :: Word8
brightWhite = 15
--
-- Styles
--
-- | Text formatting such as bold, italic, etc.
data Format = Format
{ _bold :: Bool
, _faint :: Bool
, _italic :: Bool
, _underline :: Bool
, _blink :: Bool
, _inverse :: Bool
, _invisible :: Bool
, _strikeout :: Bool
} deriving (Show, Eq, Ord, Generic, Typeable)
makeLenses ''Format
instance Semigroup Format where
(Format x0 x1 x2 x3 x4 x5 x6 x7) <> (Format y0 y1 y2 y3 y4 y5 y6 y7)
= Format (x0 || y0) (x1 || y1) (x2 || y2) (x3 || y3) (x4 || y4)
(x5 || y5) (x6 || y6) (x7 || y7)
-- | For each field, the resulting field is True if either field is
-- True. For 'mempty', every field is False.
instance Monoid Format where
mempty = Format False False False False False False False False
-- | The foreground and background color, and the 'Format'. This
-- represents all colors and formatting attributes for either an 8- or
-- 256-color terminal.
data Style a = Style
{ _fore :: Color a
, _back :: Color a
, _format :: Format
} deriving (Show, Eq, Ord, Generic, Typeable, Functor, Foldable,
Traversable)
makeLenses ''Style
instance Semigroup (Style a) where
(Style x0 x1 x2) <> (Style y0 y1 y2)
= Style (x0 <> y0) (x1 <> y1) (x2 <> y2)
-- | Uses the underlying 'Monoid' instances for 'Color' and 'Format'.
instance Monoid (Style a) where
mempty = Style mempty mempty mempty
--
-- Scheme
--
-- | Holds the 'Style' for both 8- and 256-color terminals.
data Scheme = Scheme
{ _style8 :: Style Enum8
, _style256 :: Style Word8
} deriving (Eq, Ord, Show, Generic, Typeable)
makeLenses ''Scheme
instance Semigroup Scheme where
(Scheme x0 x1) <> (Scheme y0 y1) = Scheme (x0 <> y0) (x1 <> y1)
instance Monoid Scheme where
mempty = Scheme mempty mempty
--
-- Chunks
--
-- | A chunk is some textual data coupled with a description of what
-- color the text is, attributes like whether it is bold or
-- underlined, etc. The chunk knows what foreground and background
-- colors and what attributes to use for both an 8 color terminal and
-- a 256 color terminal.
data Chunk = Chunk
{ _scheme :: Scheme
, _yarn :: Text
} deriving (Eq, Show, Ord, Generic, Typeable)
-- | Uses the underlying 'Semigroup' instances for both the
-- underlying 'Scheme' and the underlying 'Text'.
instance Semigroup Chunk where
(Chunk x0 x1) <> (Chunk y0 y1)
= Chunk (x0 <> y0) (x1 <> y1)
-- | Creates a 'Chunk' with no formatting and with the given text.
instance IsString Chunk where
fromString = chunk . X.pack
-- | Uses the underlying 'Monoid' instances for the 'Scheme' and for
-- the underlying 'Text'. Therefore 'mempty' will have no
-- formatting, no colors, and no text.
instance Monoid Chunk where
mempty = Chunk mempty mempty
-- | Creates a 'Chunk' with no formatting and with the given text.
-- A 'Chunk' is also an instance of 'Data.String.IsString' so you
-- can create them with the @OverloadedStrings@ extension. Such a
-- 'Chunk' has the text of the string and no formatting.
chunk :: Text -> Chunk
chunk = Chunk mempty
makeLenses ''Chunk
-- | Stores colors that may affect 8-color terminals, 256-color
-- terminals, both, or neither.
data Radiant = Radiant
{ _color8 :: Color Enum8
, _color256 :: Color Word8
} deriving (Eq, Ord, Show, Typeable, Generic)
instance Semigroup Radiant where
(Radiant x0 x1) <> (Radiant y0 y1) = Radiant (x0 <> y0) (x1 <> y1)
-- | Uses the underlying 'Monoid' instance for the 'Color's. Thus the
-- last non-'Nothing' 'Color' is used. This can be useful to specify
-- one color for 8-color terminals and a different color for 256-color
-- terminals.
instance Monoid Radiant where
mempty = Radiant mempty mempty
makeLenses ''Radiant