colour-text-0.0.0.0: library/Colour/Text/CssRgb.hs
module Colour.Text.CssRgb
( readHex,
showHex,
showDecTransparent,
)
where
import Data.Colour.RGBSpace (RGB (..))
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Word (Word8)
import qualified Numeric
import qualified Text.Show as Show
readHex :: forall m. MonadFail m => Text -> m (RGB Word8)
readHex text = case Text.unpack text of
['#', a, b, c, d, e, f] -> pure RGB <*> w a b <*> w c d <*> w e f
where
w :: Char -> Char -> m Word8
w c1 c2 = (maybe (fail ("Invalid characters in CSS RGB value: " <> Text.unpack text)) pure) $ hexWord8Maybe c1 c2
'#' : _ -> fail $ "Invalid CSS RGB value: Must be six hex characters, but is " <> Text.unpack text
[] -> fail "Invalid CSS RGB value: Empty string"
_ -> fail $ "Invalid CSS RGB value: Only hex format is supported (must start with #), but got: " <> Text.unpack text
hexWord8Maybe :: Char -> Char -> Maybe Word8
hexWord8Maybe a b = case Numeric.readHex [a, b] of [(x, "")] -> Just x; _ -> Nothing
showHex :: RGB Word8 -> Text
showHex (RGB r g b) =
Text.singleton '#' <> foldMap (\x -> Text.pack (pad (Numeric.showHex x ""))) [r, g, b]
showDecTransparent :: RGB Word8 -> Text
showDecTransparent (RGB r g b) =
function "rgba" $
(Text.pack . Show.show <$> [r, g, b]) <> ["0"]
function :: Text -> [Text] -> Text
function name args = name <> paren (commaSep args)
paren :: Text -> Text
paren x = Text.singleton '(' <> x <> Text.singleton ')'
commaSep :: [Text] -> Text
commaSep = Text.intercalate (Text.pack ", ")
pad :: String -> String
pad cs = case cs of [] -> "00"; [x] -> ['0', x]; x -> x