hasmin-1.0.2: src/Hasmin/Parser/Color.hs
{-# LANGUAGE OverloadedStrings #-}
-----------------------------------------------------------------------------
-- |
-- Module : Hasmin.Parser.Color
-- Copyright : (c) 2017 Cristian Adrián Ontivero
-- License : BSD3
-- Stability : experimental
-- Portability : unknown
--
-- Parsers for CSS \<color> values.
--
-----------------------------------------------------------------------------
module Hasmin.Parser.Color where
import Control.Applicative ((<|>), optional)
import Control.Monad (mzero)
import Data.Attoparsec.Text (Parser)
import Data.Maybe (fromMaybe)
import qualified Data.Attoparsec.Text as A
import Data.Text (Text)
import qualified Data.Text as T
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Hasmin.Parser.Utils
import Hasmin.Parser.Numeric
import Hasmin.Types.Color
hex :: Parser Color
hex = do
_ <- A.char '#'
a <- hexadecimal
b <- hexadecimal
c <- hexadecimal
x <- optional hexadecimal
case x of
Nothing -> pure $ mkHex3 a b c
Just d -> do y <- optional hexadecimal
case y of
Nothing -> pure $ mkHex4 a b c d
Just e -> do f <- hexadecimal
z <- optional hexadecimal
case z of
Nothing -> pure $ mkHex6 [a,b] [c,d] [e,f]
Just g -> do h <- hexadecimal
pure $ mkHex8 [a,b] [c,d] [e,f] [g,h]
-- Assumes "rgb(" has already been read
rgb :: Parser Color
rgb = functionParser (rgbInt <|> rgbPer)
where rgbInt = mkRGBInt <$> word8 <* comma <*> word8 <* comma <*> word8
rgbPer = mkRGBPer <$> percentage <* comma
<*> percentage <* comma <*> percentage
-- Assumes "rgba(" has already been read
rgba :: Parser Color
rgba = functionParser (rgbaInt <|> rgbaPer)
where rgbaInt = mkRGBAInt <$> word8 <* comma <*> word8 <* comma
<*> word8 <* comma <*> alphavalue
rgbaPer = mkRGBAPer <$> percentage <* comma <*> percentage <* comma
<*> percentage <* comma <*> alphavalue
-- Assumes "hsl(" has already been read
hsl :: Parser Color
hsl = functionParser p
where p = mkHSL <$> int <* comma <*> percentage <* comma <*> percentage
-- Assumes "hsla(" has already been read
hsla :: Parser Color
hsla = functionParser p
where p = mkHSLA <$> int <* comma <*> percentage <* comma
<*> percentage <* comma <*> alphavalue
-- | Parser for <https://drafts.csswg.org/css-color-3/#colorunits \<color\>>.
color :: Parser Color
color = hex <|> othercolor
where
othercolor = do
i <- ident
let t = T.toLower i
fromMaybe (colorFunctionParser t) (Map.lookup t namedColorsParsersMap)
namedColorsParsersMap :: Map Text (Parser Color)
namedColorsParsersMap = Map.fromList $ foldr f [] keywordColors
where f x xs = let a = fst x
in (a, pure $ Named a) : xs
colorFunctionsParsers :: [(Text, Parser Color)]
colorFunctionsParsers =
[("rgb", rgb)
,("rgba", rgba)
,("hsl", hsl)
,("hsla", hsla)
]
functionPar :: Map Text (Parser a) -> Text -> Parser a
functionPar m i = A.char '(' *> fromMaybe mzero (Map.lookup t m)
where t = T.toLower i
colorFunctionParser :: Text -> Parser Color
colorFunctionParser = functionPar (Map.fromList colorFunctionsParsers)