language-css-0.0.1: src/Language/Css/Syntax.hs
-- | Css2.1 syntax
--
-- haskell translation of css 2.1 grammar.
--
-- See <http://www.w3.org/TR/CSS2/grammar.html> and <http://www.w3.org/TR/CSS2/syndata.html>
module Language.Css.Syntax (
-- * Stylesheet
StyleSheet(..), StyleBody(..),
-- * AtRule
AtCharSet(..),
AtImport(..), ImportHead(..),
AtMedia(..),
AtPage(..), PseudoPage,
AtFontFace(..),
-- * RuleSet
RuleSet(..), Decl(..), Prop, Prio(..), Expr(..),
-- * Selectors
Sel(..), SimpleSel(..), SubSel(..),
Element, Attr(..), Class, Id, AttrIdent, AttrVal, PseudoVal(..),
-- * Values
Value(..),
-- * Primitives
Ident(..), Func(..),
Deg(..),
Rad(..),
Grad(..),
Color(..),
Hz(..),
KHz(..),
Em(..),
Ex(..),
Px(..),
In(..),
Cm(..),
Mm(..),
Pc(..),
Pt(..),
Percentage(..),
Ms(..),
S(..),
Uri(..)
) where
import Text.PrettyPrint
data Ident = Ident String
deriving (Eq)
--------------------------------------------------------
-- Stylesheet
data StyleSheet = StyleSheet (Maybe AtCharSet) [AtImport] [StyleBody]
deriving (Eq)
data StyleBody = SRuleSet RuleSet
| SAtMedia AtMedia
| SAtPage AtPage
| SAtFontFace AtFontFace
deriving (Eq)
---------------------------------------------------------
-- AtRules
-- | \@charset
data AtCharSet = AtCharSet String
deriving (Eq)
-- | \@import
data AtImport = AtImport ImportHead [Ident]
deriving (Eq)
data ImportHead = IStr String | IUri Uri
deriving (Eq)
-- | \@media
data AtMedia = AtMedia [Ident] [RuleSet]
deriving (Eq)
-- | \@page
data AtPage = AtPage (Maybe Ident) (Maybe PseudoPage) [Decl]
deriving (Eq)
type PseudoPage = Ident
-- | \@font-face
data AtFontFace = AtFontFace [Decl]
deriving (Eq)
---------------------------------------------------------
-- Rules
data RuleSet = RuleSet [Sel] [Decl]
deriving (Eq)
-- | Declaration
data Decl = Decl (Maybe Prio) Prop Expr
deriving (Eq)
-- | Property
type Prop = Ident
-- | sets @!important@ declaration
data Prio = Important
deriving (Eq)
---------------------------------------------------------
-- Selectors
-- | Selector
data Sel = SSel SimpleSel -- ^ single selector
| DescendSel Sel Sel -- ^ ' '
| ChildSel Sel Sel -- ^ \'>\'
| AdjSel Sel Sel -- ^ \'+\'
deriving (Eq)
-- | Simple selector
data SimpleSel = UnivSel [SubSel] -- ^ Universal selector
| TypeSel Element [SubSel] -- ^ Type selector
deriving (Eq)
data SubSel = AttrSel Attr -- ^ attribute selector
| ClassSel Class -- ^ \'.\'
| IdSel Id -- ^ \'#\'
| PseudoSel PseudoVal -- ^ pseudo classes/elements
deriving (Eq)
-- | attribute selector
data Attr = Attr AttrIdent
| AttrIs AttrIdent AttrVal -- ^ \'=\'
| AttrIncl AttrIdent AttrVal -- ^ \'~=\'
| AttrBegins AttrIdent AttrVal -- ^ \'|=\'
deriving (Eq)
type Element = String
type Class = String
type Id = String
type AttrIdent = String
type AttrVal = String
data PseudoVal = PIdent Ident
| PFunc Func
deriving (Eq)
-------------------------------------------------------------------
-- Values
data Expr = EVal Value -- ^ single value
| SlashSep Expr Expr -- ^ slash separated expressions
| CommaSep Expr Expr -- ^ comma separated expressions
| SpaceSep Expr Expr -- ^ space separated expressions
deriving (Eq)
data Value = VDeg Deg |
VRad Rad |
VGrad Grad |
VColor Color |
VHz Hz |
VKHz KHz |
VFunc Func |
VIdent Ident |
VInt Int |
VEm Em |
VEx Ex |
VPx Px |
VIn In |
VCm Cm |
VMm Mm |
VPc Pc |
VPt Pt |
VDouble Double |
VPercentage Percentage |
VString String |
VMs Ms |
VS S |
VUri Uri
deriving (Eq)
data Func = Func Ident Expr
deriving (Eq)
-- | \<angle\>
data Deg = Deg Double
deriving (Eq)
-- | \<angle\>
data Rad = Rad Double
deriving (Eq)
-- | \<angle\>
data Grad = Grad Double
deriving (Eq)
-- | \<color\>
data Color = Cword String |
Crgb Int Int Int
deriving (Eq)
-- | \<frequency\>
data Hz = Hz Double
deriving (Eq)
-- | \<frequency\>
data KHz = KHz Double
deriving (Eq)
-- | \<length\>
data Em = Em Double
deriving (Eq)
-- | \<length\>
data Ex = Ex Double
deriving (Eq)
-- | \<length\>
data Px = Px Int
deriving (Eq)
-- | \<length\>
data In = In Double
deriving (Eq)
-- | \<length\>
data Cm = Cm Double
deriving (Eq)
-- | \<length\>
data Mm = Mm Double
deriving (Eq)
-- | \<length\>
data Pc = Pc Double
deriving (Eq)
-- | \<length\>
data Pt = Pt Int
deriving (Eq)
-- | \<percentage\>
data Percentage = Percentage Double
deriving (Eq)
-- | \<time\>
data Ms = Ms Double
deriving (Eq)
-- | \<time\>
data S = S Double
deriving (Eq)
-- | \<uri\>
data Uri = Uri String
deriving (Eq)
-------------------------------------------------
-- Show instances
ppMaybe :: Show a => Maybe a -> Doc
ppMaybe = maybe empty (text . show)
punctuateShows :: Show a => Doc -> [a] -> Doc
punctuateShows sep = hcat . punctuate sep . map (text . show)
vsep = vcat . punctuate (text "\n")
-- StyleSheet
instance Show StyleSheet where
show (StyleSheet ch imp body) = show $
ppMaybe ch
$$ (vsep $ map (text . show) imp)
$$ (vsep $ map (text . show) body)
instance Show StyleBody where
show x = case x of
SRuleSet x -> show x
SAtMedia x -> show x
SAtPage x -> show x
SAtFontFace x -> show x
-- AtRules
-- @charset
instance Show AtCharSet where
show (AtCharSet str) = "@charset " ++ str ++ " ;"
-- @import
instance Show AtImport where
show (AtImport head ms) =
show $ text "@import" <+> (text $ show head) <+>
punctuateShows comma ms <+> semi
instance Show ImportHead where
show x = case x of
IStr x -> x
IUri x -> show x
-- @page
instance Show AtPage where
show (AtPage id pp ds) = show $ text "@page"
<+> ppMaybe id <+> ppMaybe pp
<+> (braces $ punctuateShows semi ds)
-- @media
instance Show AtMedia where
show (AtMedia ms rs) = show $ text "@media"
<+> punctuateShows comma ms
<+> punctuateShows comma rs
-- @font-face
instance Show AtFontFace where
show (AtFontFace ds) = show $ text "@font-face"
<+> (braces $ punctuateShows semi ds)
-- RuleSets
instance Show RuleSet where
show (RuleSet sels decls) = show $ (vcat $ punctuate comma $ map (text . show) sels)
<+> lbrace
$$ (nest 4 $ vcat $ punctuate semi $ map (text . show)decls)
<+> rbrace
-- Declarations
instance Show Decl where
show (Decl prio p v) =
case prio of
Just x -> decl ++ " " ++ show x
Nothing -> decl
where decl = show p ++ " : " ++ show v
instance Show Prio where
show = const "!important"
-- Selectors
instance Show Sel where
show x = case x of
SSel x -> show x
DescendSel x xs -> show x ++ " " ++ show xs
ChildSel x xs -> show x ++ " > " ++ show xs
AdjSel x xs -> show x ++ " + " ++ show xs
instance Show SimpleSel where
show x = case x of
UnivSel xs -> "*" ++ showSubs xs
TypeSel el xs -> el ++ showSubs xs
showSubs :: [SubSel] -> String
showSubs = show . hcat . map (text . show)
instance Show PseudoVal where
show x = case x of
PIdent a -> show a
PFunc a -> show a
instance Show SubSel where
show x = case x of
AttrSel a -> show $ brackets $ text $ show a
ClassSel v -> "." ++ v
IdSel v -> "#" ++ v
PseudoSel v -> ":" ++ show v
instance Show Attr where
show x = case x of
Attr a -> show $ text a
AttrIs a v -> show $ text a <> equals <> (doubleQuotes $ text v)
AttrIncl a v -> show $ text a <> text "~=" <> (doubleQuotes $ text v)
AttrBegins a v -> show $ text a <> text "|=" <> (doubleQuotes $ text v)
-- Values
instance Show Expr where
show x = case x of
EVal x -> show x
SlashSep x e -> show x ++ " / " ++ show e
CommaSep x e -> show x ++ " , " ++ show e
SpaceSep x e -> show x ++ " " ++ show e
instance Show Func where
show (Func name arg) = show $ text (show name) <+> parens (text $ show arg)
instance Show Ident where
show (Ident a) = a
-- Measure Units
-- Value
instance Show Value where
show x = case x of
VDeg a -> show a
VRad a -> show a
VGrad a -> show a
VColor a -> show a
VHz a -> show a
VKHz a -> show a
VFunc a -> show a
VIdent a -> show a
VInt a -> show a
VEm a -> show a
VEx a -> show a
VPx a -> show a
VIn a -> show a
VCm a -> show a
VMm a -> show a
VPc a -> show a
VPt a -> show a
VDouble a -> show a
VPercentage a -> show a
VString a -> show a
VMs a -> show a
VS a -> show a
VUri a -> show a
-- Value elems
instance Show Deg where
show (Deg x) = show x ++ "deg"
instance Show Rad where
show (Rad x) = show x ++ "rad"
instance Show Grad where
show (Grad x) = show x ++ "grad"
instance Show Color where
show x = case x of { Cword a -> a ;
Crgb r g b -> show $ (text "rgb" <> ) $ parens $ hsep $ punctuate comma $ map (text. show) [r, g, b]}
instance Show Hz where
show (Hz x) = show x ++ "Hz"
instance Show KHz where
show (KHz x) = show x ++ "kHz"
instance Show Em where
show (Em x) = show x ++ "em"
instance Show Ex where
show (Ex x) = show x ++ "ex"
instance Show Px where
show (Px x) = show x ++ "px"
instance Show In where
show (In x) = show x ++ "in"
instance Show Cm where
show (Cm x) = show x ++ "cm"
instance Show Mm where
show (Mm x) = show x ++ "mm"
instance Show Pc where
show (Pc x) = show x ++ "pc"
instance Show Pt where
show (Pt x) = show x ++ "pt"
instance Show Percentage where
show (Percentage x) = show x ++ "%"
instance Show Ms where
show (Ms x) = show x ++ "ms"
instance Show S where
show (S x) = show x ++ "s"
instance Show Uri where
show (Uri x) = "url(" ++ show x ++ ")"