1#include "Common-Safe-Haskell.hs" 2 3{-| The \'ANSI\' standards refer to the visual style of displaying characters as 4their \'graphic rendition\'. The style includes the color of a character or its 5background, the intensity (bold, normal or faint) of a character, or whether the 6character is italic or underlined (single or double), blinking (slowly or 7rapidly) or visible or not. The \'ANSI\' codes to establish the graphic 8rendition for subsequent text are referred to as SELECT GRAPHIC RENDITION (SGR). 9 10This module exports types and functions used to represent SGR aspects. See also 11'System.Console.ANSI.setSGR' and related functions. 12-} 13module System.Console.ANSI.Types 14 ( 15 -- * Types used to represent SGR aspects 16 SGR (..) 17 , ConsoleLayer (..) 18 , Color (..) 19 , ColorIntensity (..) 20 , ConsoleIntensity (..) 21 , Underlining (..) 22 , BlinkSpeed (..) 23 -- * Constructors of xterm 256-color palette indices 24 , xterm6LevelRGB 25 , xterm24LevelGray 26 , xtermSystem 27 ) where 28 29import Data.Ix (Ix) 30import Data.Word (Word8) 31 32import Data.Colour (Colour) 33 34-- | ANSI's eight standard colors. They come in two intensities, which are 35-- controlled by 'ColorIntensity'. Many terminals allow the colors of the 36-- standard palette to be customised, so that, for example, 37-- @setSGR [ SetColor Foreground Vivid Green ]@ may not result in bright green 38-- characters. 39data Color = Black 40 | Red 41 | Green 42 | Yellow 43 | Blue 44 | Magenta 45 | Cyan 46 | White 47 deriving (Eq, Ord, Bounded, Enum, Show, Read, Ix) 48 49-- | ANSI's standard colors come in two intensities 50data ColorIntensity = Dull 51 | Vivid 52 deriving (Eq, Ord, Bounded, Enum, Show, Read, Ix) 53 54-- | ANSI colors can be set on two different layers 55data ConsoleLayer = Foreground 56 | Background 57 deriving (Eq, Ord, Bounded, Enum, Show, Read, Ix) 58 59-- | ANSI blink speeds: values other than 'NoBlink' are not widely supported 60data BlinkSpeed = SlowBlink -- ^ Less than 150 blinks per minute 61 | RapidBlink -- ^ More than 150 blinks per minute 62 | NoBlink 63 deriving (Eq, Ord, Bounded, Enum, Show, Read, Ix) 64 65-- | ANSI text underlining 66data Underlining 67 = SingleUnderline 68 -- | Not widely supported. Not supported natively on Windows 10 69 | DoubleUnderline 70 | NoUnderline 71 deriving (Eq, Ord, Bounded ,Enum, Show, Read, Ix) 72 73-- | ANSI general console intensity: usually treated as setting the font style 74-- (e.g. 'BoldIntensity' causes text to be bold) 75data ConsoleIntensity 76 = BoldIntensity 77 -- | Not widely supported: sometimes treated as concealing text. Not supported 78 -- natively on Windows 10 79 | FaintIntensity 80 | NormalIntensity 81 deriving (Eq, Ord, Bounded, Enum, Show, Read, Ix) 82 83-- | ANSI Select Graphic Rendition (SGR) command 84-- 85-- In respect of colors, there are three alternative commands: 86-- 87-- (1) the \'ANSI\' standards allow for eight standard colors (with two 88-- intensities). Windows and many other terminals (including xterm) allow the 89-- user to redefine the standard colors (so, for example 'Vivid' 'Green' may not 90-- correspond to bright green; 91-- 92-- (2) an extension of the standard that allows true colors (24 bit color depth) 93-- in RGB space. This is usually the best alternative for more colors; and 94-- 95-- (3) another extension that allows a palette of 256 colors, each color 96-- specified by an index. Xterm provides a protocol for a palette of 256 colors 97-- that many other terminals, including Windows 10, follow. Some terminals 98-- (including xterm) allow the user to redefine some or all of the palette 99-- colors. 100data SGR 101 -- | Default rendition, cancels the effect of any preceding occurrence of SGR 102 -- (implementation-defined) 103 = Reset 104 -- | Set the character intensity. Partially supported natively on Windows 10 105 | SetConsoleIntensity !ConsoleIntensity 106 -- | Set italicized. Not widely supported: sometimes treated as swapping 107 -- foreground and background. Not supported natively on Windows 10 108 | SetItalicized !Bool 109 -- | Set or clear underlining. Partially supported natively on Windows 10 110 | SetUnderlining !Underlining 111 -- | Set or clear character blinking. Not supported natively on Windows 10 112 | SetBlinkSpeed !BlinkSpeed 113 -- | Set revealed or concealed. Not widely supported. Not supported natively 114 -- on Windows 10 115 | SetVisible !Bool 116 -- | Set negative or positive image. Supported natively on Windows 10 117 | SetSwapForegroundBackground !Bool 118 -- | Set a color from the standard palette of 16 colors (8 colors by 2 119 -- color intensities). Many terminals allow the palette colors to be 120 -- customised 121 | SetColor !ConsoleLayer !ColorIntensity !Color 122 -- | Set a true color (24 bit color depth). Supported natively on Windows 10 123 -- from the Creators Update (April 2017) 124 -- 125 -- @since 0.7 126 | SetRGBColor !ConsoleLayer !(Colour Float) 127 -- | Set a color from a palette of 256 colors using a numerical index 128 -- (0-based). Supported natively on Windows 10 from the Creators Update (April 129 -- 2017) but not on legacy Windows native terminals. See 'xtermSystem', 130 -- 'xterm6LevelRGB' and 'xterm24LevelGray' to construct indices based on 131 -- xterm's standard protocol for a 256-color palette. 132 -- 133 -- @since 0.9 134 | SetPaletteColor !ConsoleLayer !Word8 135 -- | Set a color to the default (implementation-defined) 136 -- 137 -- @since 0.10 138 | SetDefaultColor !ConsoleLayer 139 deriving (Eq, Show, Read) 140 141-- | Given xterm's standard protocol for a 256-color palette, returns the index 142-- to that part of the palette which is a 6 level (6x6x6) color cube of 216 RGB 143-- colors. Throws an error if any of the red, green or blue channels is outside 144-- the range 0 to 5. An example of use is: 145-- 146-- >>> setSGR [ SetPaletteColor $ xterm6LevelRGB 5 2 0 ] -- Dark Orange 147-- 148-- @since 0.9 149xterm6LevelRGB :: Int -> Int -> Int -> Word8 150xterm6LevelRGB r g b 151 -- RGB colors are represented by index: 152 -- 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5) 153 | r >= 0 && r < 6 && g >= 0 && g < 6 && b >= 0 && b < 6 154 = fromIntegral $ 16 + 36 * r + 6 * g + b 155 | otherwise 156 = error $ show r ++ " " ++ show g ++ " " ++ show b ++ " (r g b) is " ++ 157 "outside of a 6 level (6x6x6) color cube." 158 159-- | Given xterm's standard protocol for a 256-color palette, returns the index 160-- to that part of the palette which is a spectrum of 24 grays, from dark 161-- gray (0) to near white (23) (black and white are themselves excluded). Throws 162-- an error if the gray is outside of the range 0 to 23. An example of use is: 163-- 164-- >>> setSGR [ SetPaletteColor $ xterm24LevelGray 12 ] -- Gray50 165-- 166-- @since 0.9 167xterm24LevelGray :: Int -> Word8 168xterm24LevelGray y 169 -- Grayscale colors are represented by index: 170 -- 232 + g (0 ≤ g ≤ 23) 171 | y >= 0 && y < 24 = fromIntegral $ 232 + y 172 | otherwise 173 = error $ show y ++ " (gray) is outside of the range 0 to 23." 174 175-- | Given xterm's standard protocol for a 256-color palette, returns the index 176-- to that part of the palette which corresponds to the \'ANSI\' standards' 16 177-- standard, or \'system\', colors (eight colors in two intensities). An example 178-- of use is: 179-- 180-- >>> setSGR [ SetPaletteColor $ xtermSystem Vivid Green ] 181-- 182-- @since 0.9 183xtermSystem :: ColorIntensity -> Color -> Word8 184xtermSystem intensity color 185 | intensity == Dull = index 186 | otherwise = index + 8 187 where 188 index = fromIntegral $ fromEnum color 189