web-css-0.1.0: src/Web/CSS/Escaping.hs
module Web.CSS.Escaping
( escapeIdentifier
, escapeString
) where
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TLB
import qualified Data.Text.Lazy.Builder.Int as TLBI
-- | Format a character as a hex escape.
escapeChar :: Char -> TL.Text
escapeChar =
TL.cons '\\' .
TL.justifyRight 6 '0' .
TLB.toLazyText .
TLBI.hexadecimal .
fromEnum
-- | Escape a CSS identifier. This function is slightly more
-- permissive than the CSS standard. For example, it does not reject
-- identifiers that begin with two hyphens. The function always
-- escapes 'special' characters such as the tilde (@~@) or left
-- bracket (@[@). As such, they will never be interpreted as special
-- characters.
escapeIdentifier :: TL.Text -> TL.Text
escapeIdentifier = TL.concatMap escape
where
escape c | c >= 'a' && c <= 'z' = TL.singleton c -- No escaping
escape c | c >= 'A' && c <= 'Z' = TL.singleton c -- No escaping
escape c | c >= '0' && c <= '9' = TL.singleton c -- No escaping
escape c @ '_' = TL.singleton c -- No escaping
escape c @ '-' = TL.singleton c -- No escaping
escape c | c >= ' ' && c <= '~' = TL.pack ['\\', c] -- Simple escapes
escape c = escapeChar c -- General escape
-- | Escape a CSS string value. This function is conservative and
-- produces only output characters in the US-ASCII range. This comes
-- at the cost of space usage, so this function should not be used to
-- encode strings expected to contain a disproportionate amount of
-- non-US-ASCII characters.
escapeString :: TL.Text -> TL.Text
escapeString s =
TL.concat [ TL.pack "\""
, TL.concatMap escape s
, TL.pack "\""
]
where
escape c | c < ' ' = escapeChar c -- Control characters
escape c | c > '~' = escapeChar c -- Outside US-ASCII.
escape c @ '"' = TL.pack ['\\', c] -- Quotes
escape c = TL.singleton c -- Non-quote, US-ASCII.