{- | Module : Text.Paint Description : Colorization of command-line output Copyright : (c) 2017 Daniel Lovasko License : BSD2 Maintainer : Daniel Lovasko Stability : stable Portability : portable -} module Text.Paint ( Color(..) -- * , Flag(..) -- * , Paint(..) -- * , paint -- Paint -> Text -> Text ) where import qualified Data.Text as T -- | Foreground and background color. data Color = Black -- ^ black | Red -- ^ red | Green -- ^ green | Yellow -- ^ yellow | Blue -- ^ blue | Magenta -- ^ magenta | Cyan -- ^ cyan | LightGray -- ^ light gray | DarkGray -- ^ dark gray | LightRed -- ^ light red | LightGreen -- ^ light green | LightYellow -- ^ light yellow | LightBlue -- ^ light blue | LightMagenta -- ^ light magenta | LightCyan -- ^ light cyan | White -- ^ white | Default -- ^ default setting deriving (Eq, Ord, Enum, Show) -- | Various flags applicable to the text. data Flag = Bold -- ^ bold text (sometimes lighter) | Underline -- ^ underlined text | Blink -- ^ blinking (<150 BPM) deriving (Eq, Ord, Show) -- | Coloring scheme containing foreground and background layers, and a -- setting for text styling. data Paint = Paint Color Color [Flag] -- | Convert a flag into an ANSI code. flagCode :: Flag -- ^ flag -> Int -- ^ ANSI code flagCode Bold = 1 flagCode Underline = 4 flagCode Blink = 5 -- | Convert a foreground color into an ANSI code. fgCode :: Color -- ^ color -> Int -- ^ ANSI code fgCode Black = 30 fgCode Red = 31 fgCode Green = 32 fgCode Yellow = 33 fgCode Blue = 34 fgCode Magenta = 35 fgCode Cyan = 36 fgCode LightGray = 37 fgCode Default = 39 fgCode DarkGray = 90 fgCode LightRed = 91 fgCode LightGreen = 92 fgCode LightYellow = 93 fgCode LightBlue = 94 fgCode LightMagenta = 95 fgCode LightCyan = 96 fgCode White = 97 -- | Convert a background color into an ANSI code. bgCode :: Color -- ^ color -> Int -- ^ ANSI code bgCode Black = 40 bgCode Red = 41 bgCode Green = 42 bgCode Yellow = 43 bgCode Blue = 44 bgCode Magenta = 45 bgCode Cyan = 46 bgCode LightGray = 47 bgCode Default = 49 bgCode DarkGray = 100 bgCode LightRed = 101 bgCode LightGreen = 102 bgCode LightYellow = 103 bgCode LightBlue = 104 bgCode LightMagenta = 105 bgCode LightCyan = 106 bgCode White = 107 -- | Convert a coloring scheme into an ANSI escape sequence. translate :: Paint -- ^ coloring scheme -> T.Text -- ^ escape sequence translate (Paint fg bg flags) = T.concat [T.pack "\x1b[", codes, T.pack "m"] where codes = T.intercalate (T.singleton ';') $ map (T.pack . show) codes' codes' = map flagCode flags ++ [fgCode fg] ++ [bgCode bg] -- | Apply a color scheme to a text instance. paint :: Paint -- ^ coloring scheme -> T.Text -- ^ plain text -> T.Text -- ^ colorized text paint pnt text = T.concat [translate pnt, text, T.pack "\x1b[0m"]