{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-} module Data.Monoid.Colorful.Nested ( Style(..) , Color(..) , Term(..) , Colored(..) , hGetTerm , getTerm , hPrintColored , printColored , hPrintColoredIO , printColoredIO , hPrintColoredS , printColoredS , showColored , showColoredM , showColoredS ) where import System.IO (Handle) import Data.Monoid.Colorful.Term import Data.Monoid.Colorful.Color import Data.Monoid.Colorful.SGR import Data.Monoid.Colorful.Trustworthy import Data.String (IsString(..)) import Data.Semigroup (Semigroup) import GHC.Generics (Generic, Generic1) import qualified Data.Monoid.Colorful.Flat as Flat import Control.Monad (ap) -- | Colored Monoid data Colored a = Nil | Value a | Style !Style (Colored a) | Unstyle !Style (Colored a) | Fg !Color (Colored a) | Bg !Color (Colored a) | Pair (Colored a) (Colored a) deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable, Generic, Generic1) -- | Free monad! instance Applicative Colored where pure = Value (<*>) = ap -- | Free monad! instance Monad Colored where Nil >>= _ = Nil Value x >>= f = f x Style a x >>= f = Style a (x >>= f) Unstyle a x >>= f = Unstyle a (x >>= f) Fg a x >>= f = Fg a (x >>= f) Bg a x >>= f = Bg a (x >>= f) Pair x y >>= f = Pair (x >>= f) (y >>= f) instance Semigroup (Colored a) instance Monoid (Colored a) where mempty = Nil mappend = Pair instance IsString a => IsString (Colored a) where fromString = Value . fromString instance IsList (Colored a) where type Item (Colored a) = Colored a fromList = foldr Pair Nil toList = (:[]) -- TODO, invalid -- | Flatten the Monoid @Colored a@ and return @[Flat.Colored a]@ -- -- This function is used internally for rendering the Colored monoids. flatten :: Colored a -> [Flat.Colored a] flatten s = go s [] where go (Value a) = (Flat.Value a:) go (Style a b) = (Flat.Push:) . (Flat.Style a:) . go b . (Flat.Pop:) go (Unstyle a b) = (Flat.Push:) . (Flat.Unstyle a:) . go b . (Flat.Pop:) go (Fg a b) = (Flat.Push:) . (Flat.Fg a:) . go b . (Flat.Pop:) go (Bg a b) = (Flat.Push:) . (Flat.Bg a:) . go b . (Flat.Pop:) go Nil = id go (Pair a b) = go a . go b hPrintColoredIO :: Handle -> Term -> Colored (IO ()) -> IO () hPrintColoredIO h t = Flat.hPrintColoredIO h t . flatten printColoredIO :: Term -> Colored (IO ()) -> IO () printColoredIO t = Flat.printColoredIO t . flatten hPrintColored :: (Handle -> a -> IO ()) -> Handle -> Term -> Colored a -> IO () hPrintColored f h t = Flat.hPrintColored f h t . flatten printColored :: (a -> IO ()) -> Term -> Colored a -> IO () printColored f t = Flat.printColored f t . flatten hPrintColoredS :: Handle -> Term -> Colored String -> IO () hPrintColoredS h t = Flat.hPrintColoredS h t . flatten printColoredS :: Term -> Colored String -> IO () printColoredS t = Flat.printColoredS t . flatten showColoredM :: (Monad f, Monoid o) => (a -> f o) -> (SGRCode -> f o) -> Term -> Colored a -> f o showColoredM f g t = Flat.showColoredM f g t . flatten showColored :: Monoid o => (a -> o) -> (SGRCode -> o) -> Term -> Colored a -> o showColored f g t = Flat.showColored f g t . flatten showColoredS :: Term -> Colored String -> ShowS showColoredS t = Flat.showColoredS t . flatten