From 186cbffac5c4f775ce015d7ed2a92279c4449644 Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Wed, 1 Apr 2020 16:30:41 +1300 Subject: [PATCH] Improve documentation, release version 1.2 --- src/Data/CSS/Preprocessor/Conditions.hs | 6 ++++ src/Data/CSS/Preprocessor/Conditions/Expr.hs | 21 +++++++++++-- src/Data/CSS/Style.hs | 2 ++ src/Data/CSS/Style/Cascade.hs | 6 ++++ src/Data/CSS/Style/Common.hs | 10 ++++++- src/Data/CSS/Style/Importance.hs | 3 ++ src/Data/CSS/Style/Selector/Index.hs | 4 +++ src/Data/CSS/Style/Selector/Interpret.hs | 5 ++++ src/Data/CSS/Style/Selector/Specificity.hs | 3 ++ src/Data/CSS/Syntax/Selector.hs | 31 +++++++++++++++----- src/Data/CSS/Syntax/StyleSheet.hs | 19 ++++++++++++ src/Data/CSS/Syntax/StyleSheet/ByteString.hs | 9 ------ src/Data/CSS/Syntax/StylishUtil.hs | 9 ++++++ stylist.cabal | 4 +-- xml-conduit-stylist/src/Data/HTML2CSS.hs | 10 +++++++ 15 files changed, 120 insertions(+), 22 deletions(-) delete mode 100644 src/Data/CSS/Syntax/StyleSheet/ByteString.hs diff --git a/src/Data/CSS/Preprocessor/Conditions.hs b/src/Data/CSS/Preprocessor/Conditions.hs index b04ab2d..64debc5 100644 --- a/src/Data/CSS/Preprocessor/Conditions.hs +++ b/src/Data/CSS/Preprocessor/Conditions.hs @@ -1,4 +1,8 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Evaluates conditional CSS @rules. +-- Parse a CSS stylesheet to `ConditionalStyles` to evaluate @document & @supports rules. +-- Call `loadImports` to resolve any @import rules to @media rules. +-- And call `resolve` to convert into another `StyleSheet` instance whilst resolving @media rules. module Data.CSS.Preprocessor.Conditions( ConditionalStyles(..), conditionalStyles, ConditionalRule(..), extractImports, resolveImports, loadImports, resolve, testIsStyled, @@ -102,6 +106,8 @@ instance PropertyParser p => StyleSheet (ConditionalStyles p) where addAtRule self rule tokens = let (block, rest) = scanAtRule tokens in (addRule' self $ AtRule rule block, rest) +-- | Flags whether any style rules have been applied yet, +-- for the sake of evaluating "@document unstyled {...}". testIsStyled :: ConditionalStyles p -> ConditionalStyles p testIsStyled styles = styles { isUnstyled = null $ rules styles } diff --git a/src/Data/CSS/Preprocessor/Conditions/Expr.hs b/src/Data/CSS/Preprocessor/Conditions/Expr.hs index d45ef72..99dd7ad 100644 --- a/src/Data/CSS/Preprocessor/Conditions/Expr.hs +++ b/src/Data/CSS/Preprocessor/Conditions/Expr.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Evaluates CSS media queries for @import & @media. +-- INTERNAL MODULE module Data.CSS.Preprocessor.Conditions.Expr( Expr, Op(..), parse, parse', eval, Datum(..) ) where @@ -7,16 +9,30 @@ import Data.CSS.Syntax.Tokens(Token(..)) import Data.Text.Internal (Text(..)) import Data.Text (stripPrefix) +-- | A parsed (post-order) expression. type Expr = [Op] -data Op = And | Or | Not | Var Text | Tok Token | MkRatio | Func Text [Token] - | Less | LessEq | Equal | Greater | GreaterEq deriving (Show, Eq) +-- | Operators understood by media queries. +data Op = And -- ^ Is true if both operands are true + | Or -- ^ Is true if either operand is true + | Not -- ^ Is true if it's operand isn't. + | Var Text -- ^ Queries the value of an externally-specified parameter. + | Tok Token -- ^ Tokens to be evaluated as specified by caller. + | MkRatio -- ^ Pushes a ratio value to stack, for querying screensize. + | Less -- ^ Is the left operand smaller than right? + | LessEq -- ^ Is the left operand smaller or the same as right? + | Equal -- ^ Are the operands the same? + | Greater -- ^ Is the left operand bigger than right? + | GreaterEq -- ^ Is the left operand bigger or the same as right? + deriving (Show, Eq) +-- | Parses a media query to postorder form, returning the tokens after the given delimiter. parse :: Token -> [Token] -> (Expr, [Token]) parse end toks = let (toks', rest) = break (== end) toks in (parse' toks' [], rest) -------- ---- Shunting Yard parser -------- +-- | Parses a media query to postorder form, given an operator stack. parse' :: [Token] -> [(Op, Int)] -> Expr parse' (Whitespace:toks) ops = parse' toks ops @@ -58,6 +74,7 @@ pushOp toks op b ops = parse' toks ((op, b):ops) -- | Dynamic types for evaluating media queries. data Datum = B Bool | N Float | Ratio Float Float deriving Eq +-- | Evaluates a media query with the given functions for evaluating vars & tokens. eval :: (Text -> Datum) -> (Token -> Datum) -> Expr -> Bool eval = eval' [] diff --git a/src/Data/CSS/Style.hs b/src/Data/CSS/Style.hs index ce42eec..30381e7 100644 --- a/src/Data/CSS/Style.hs +++ b/src/Data/CSS/Style.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Queries computed styles out of a specially-parsed CSS stylesheet. +-- See in particular `QueryableStyleSheet`, `queryRules`, & `cascade'`. module Data.CSS.Style( QueryableStyleSheet, QueryableStyleSheet'(..), queryableStyleSheet, queryRules, diff --git a/src/Data/CSS/Style/Cascade.hs b/src/Data/CSS/Style/Cascade.hs index d410946..698da67 100644 --- a/src/Data/CSS/Style/Cascade.hs +++ b/src/Data/CSS/Style/Cascade.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Applies CSS selection, cascade, & inheritance. +-- INTERNAL MODULE. module Data.CSS.Style.Cascade( query, cascade, TrivialPropertyParser(..), PropertyParser(..), Props @@ -41,12 +43,14 @@ instance PropertyParser TrivialPropertyParser where longhand _ (TrivialPropertyParser self) key value = Just $ TrivialPropertyParser $ insert (unpack key) value self +-- | "key: value;" entries to be parsed into an output type. type Props = [(Text, [Token])] -------- ---- Query/Psuedo-elements -------- +-- | Looks up style rules for an element, grouped by psuedoelement. query :: RuleStore s => s -> Element -> HashMap Text [StyleRule'] query self el = Prelude.foldr yield empty $ lookupRules self el where yield rule store = insertWith (++) (psuedoElement rule) [resolveAttr rule el] store @@ -55,6 +59,8 @@ query self el = Prelude.foldr yield empty $ lookupRules self el ---- Cascade/Inheritance -------- +-- | Applies cascade for the given `StyleRule'`s & explicit styles, +-- parsed to a value of the same `PropertyParser` type passed in & inheriting from it. cascade :: PropertyParser p => [StyleRule'] -> Props -> p -> p cascade styles overrides base = construct base $ toList $ cascadeRules (getVars base ++ overrides) styles diff --git a/src/Data/CSS/Style/Common.hs b/src/Data/CSS/Style/Common.hs index ad6b3d8..febc894 100644 --- a/src/Data/CSS/Style/Common.hs +++ b/src/Data/CSS/Style/Common.hs @@ -1,3 +1,5 @@ +-- | Central infrastructure for implementing queryable stylesheets. +-- NOTE: This internal module isn't intended to be fully documented. module Data.CSS.Style.Common( RuleStore(..), StyleRule'(..), selector, properties, psuedoElement, styleRule', Element(..), Attribute(..), @@ -10,12 +12,18 @@ import Data.CSS.Syntax.Selector import Data.CSS.Syntax.Tokens import Data.Text.Internal (Text(..)) +-- | An inversely-linked tree of elements, to apply CSS selectors to. data Element = ElementNode { + -- | The element's parent in the tree. parent :: Maybe Element, + -- | The element's previous sibling in the tree. previous :: Maybe Element, + -- | The element's name. name :: Text, - attributes :: [Attribute] -- in sorted order. + -- | The element's attributes, in sorted order. + attributes :: [Attribute] } +-- | A key-value attribute. data Attribute = Attribute Text String deriving (Eq, Ord) class RuleStore a where diff --git a/src/Data/CSS/Style/Importance.hs b/src/Data/CSS/Style/Importance.hs index b9508e4..5683cc2 100644 --- a/src/Data/CSS/Style/Importance.hs +++ b/src/Data/CSS/Style/Importance.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Evaluates !important. +-- INTERNAL MODULE. module Data.CSS.Style.Importance ( ImportanceSplitter(..) ) where @@ -18,6 +20,7 @@ splitProperties [] = ([], []) --- NOTE: Prorities are defined with lower numbers being more important, --- so negate to be consistant with other priority sources. --- This API decision started out being accidental, but I find it more intuitive. +-- | Evaluates "!important" by splitting all `StyleRule'` in two. data ImportanceSplitter a = ImportanceSplitter a instance RuleStore inner => RuleStore (ImportanceSplitter inner) where new = ImportanceSplitter new diff --git a/src/Data/CSS/Style/Selector/Index.hs b/src/Data/CSS/Style/Selector/Index.hs index 006606c..2df7b4d 100644 --- a/src/Data/CSS/Style/Selector/Index.hs +++ b/src/Data/CSS/Style/Selector/Index.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Fast lookup & storage for style rules. +-- INTERNAL MODULE. module Data.CSS.Style.Selector.Index ( StyleIndex(..), rulesForElement @@ -13,6 +15,7 @@ import Data.Hashable import Data.Text (unpack, pack) import Data.CSS.Syntax.Tokens (serialize) -- for easy hashing +-- | Fast lookup & storage for style rules. data StyleIndex = StyleIndex { indexed :: HashMap SimpleSelector [StyleRule'], unindexed :: [StyleRule'] @@ -31,6 +34,7 @@ instance RuleStore StyleIndex where index = indexed self rules = unindexed self : Prelude.map get (testsForElement element) +-- | LEGACY TESTING API. rulesForElement :: StyleIndex -> Element -> [StyleRule] -- For testing rulesForElement self element = Prelude.map inner $ lookupRules self element diff --git a/src/Data/CSS/Style/Selector/Interpret.hs b/src/Data/CSS/Style/Selector/Interpret.hs index 1942158..fd621de 100644 --- a/src/Data/CSS/Style/Selector/Interpret.hs +++ b/src/Data/CSS/Style/Selector/Interpret.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Evaluates CSS selectors over an element. +-- INTERNAL MODULE. module Data.CSS.Style.Selector.Interpret( compile, SelectorFunc, InterpretedRuleStore(..) @@ -10,9 +12,11 @@ import Data.Text (unpack) import Data.List import Data.Maybe +-- | A compiled(?) CSS selector. type SelectorFunc = Element -> Bool type AttrsFunc = [Attribute] -> Bool +-- | Converts a parsed CSS selector into a callable function. compile :: Selector -> SelectorFunc compile (Element sel) = compileInner sel compile (Child upSel sel) = direct parent (compile upSel) $ compileInner sel @@ -88,6 +92,7 @@ hasLang expected value = expected == value || isPrefixOf (expected ++ "-") value -------- ---- RuleStore wrapper -------- +-- | Compiles & fully evaluates CSS selectors. data InterpretedRuleStore inner = InterpretedRuleStore inner instance RuleStore inner => RuleStore (InterpretedRuleStore inner) where new = InterpretedRuleStore new diff --git a/src/Data/CSS/Style/Selector/Specificity.hs b/src/Data/CSS/Style/Selector/Specificity.hs index 9b3a667..8201858 100644 --- a/src/Data/CSS/Style/Selector/Specificity.hs +++ b/src/Data/CSS/Style/Selector/Specificity.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Sorts `StyleRule'`s by specificity. +-- INTERNAL MODULE. module Data.CSS.Style.Selector.Specificity( OrderedRuleStore(..) ) where @@ -27,6 +29,7 @@ computeSpecificity' [] = (0, 0, 0) add :: Vec -> Vec -> Vec add (a, b, c) (x, y, z) = (a + x, b + y, c + z) +-- | Sorts `StyleRule'`s by their selector specificity. data OrderedRuleStore inner = OrderedRuleStore inner Int instance RuleStore inner => RuleStore (OrderedRuleStore inner) where diff --git a/src/Data/CSS/Syntax/Selector.hs b/src/Data/CSS/Syntax/Selector.hs index b4daf62..4da2e60 100644 --- a/src/Data/CSS/Syntax/Selector.hs +++ b/src/Data/CSS/Syntax/Selector.hs @@ -1,3 +1,5 @@ +-- | Parses CSS selectors +-- See `parseSelectors` module Data.CSS.Syntax.Selector( Selector(..), SimpleSelector(..), PropertyTest(..), parseSelectors @@ -8,18 +10,31 @@ import Data.CSS.Syntax.StylishUtil import Data.Text.Internal (Text(..)) --- type Selector = [SimpleSelector] -data Selector = Element [SimpleSelector] | - Child Selector [SimpleSelector] | Descendant Selector [SimpleSelector] | - Adjacent Selector [SimpleSelector] | Sibling Selector [SimpleSelector] +-- | A CSS "selector" indicating which elements should be effected by CSS. +data Selector = Element [SimpleSelector] -- ^ Selects a single element. + | Child Selector [SimpleSelector] -- ^ Represents "a > b" operator. + | Descendant Selector [SimpleSelector] -- ^ Represents "a b" operator. + | Adjacent Selector [SimpleSelector] -- ^ Represents "a + b" operator. + | Sibling Selector [SimpleSelector] -- ^ Represents "a ~ b" operator. deriving (Show, Eq) -data SimpleSelector = Tag Text | Id Text | Class Text | Property Text PropertyTest | - Psuedoclass Text [Token] +-- | An individual test comprising a CSS stylesheet. +data SimpleSelector = Tag Text -- ^ Matches a tagname, e.g. "a" + | Id Text -- ^ Matches the "id" attribute, e.g. "#header" + | Class Text -- ^ Matches the "class" attribute, e.g. ".ad" + | Property Text PropertyTest -- ^ Matches a specified property + | Psuedoclass Text [Token] -- ^ Matches psuedoclasses provided by the caller (via a nameless property). deriving (Show, Eq) -data PropertyTest = Exists | Equals Text | Suffix Text | Prefix Text | Substring Text | - Include Text | Dash Text +-- | How should a property be matched. +data PropertyTest = Exists -- ^ Matches whether an attribute actually exists, e.g. "[title]" + | Equals Text -- ^ Matches whether the attribute is exactly equal to the value, e.g. "=" + | Suffix Text -- ^ Matches whether attribute ends with the given value, e.g. "$=" + | Prefix Text -- ^ Matches whether attribute starts with the given value, e.g. "^=" + | Substring Text -- ^ Matches whether the attribute contains the given value, e.g. "*=" + | Include Text -- ^ Is one of the whitespace-seperated values the one specified? e.g. "~=" + | Dash Text -- ^ Matches whitespace seperated values, or their "-"-seperated prefixes. e.g. "|=" deriving (Show, Eq) +-- | Parses a CSS selector. parseSelectors :: Parser [Selector] parseSelectors tokens = concatP (:) parseCompound parseSelectorsTail $ skipSpace tokens parseSelectorsTail :: Parser [Selector] diff --git a/src/Data/CSS/Syntax/StyleSheet.hs b/src/Data/CSS/Syntax/StyleSheet.hs index 7a3e28b..e88a69a 100644 --- a/src/Data/CSS/Syntax/StyleSheet.hs +++ b/src/Data/CSS/Syntax/StyleSheet.hs @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Parses a CSS stylesheet +-- See `StyleSheet` & `parseForURL`. module Data.CSS.Syntax.StyleSheet ( parse, parse', parseForURL, TrivialStyleSheet(..), StyleSheet(..), skipAtRule, scanAtRule, scanBlock, skipSpace, @@ -20,20 +22,28 @@ import Network.URI (parseRelativeReference, relativeTo, uriToString, URI(..)) -------- ---- Output type class -------- +-- | Describes how to store, and to some extent parse, CSS stylesheets. +-- These methods are used to construct the results from `parse`, etc. class StyleSheet s where + -- | Sets the stylesheet priority (useragent vs user vs author), optional. setPriority :: Int -> s -> s setPriority _ = id + -- | Stores a parsed selector+properties rule. addRule :: s -> StyleRule -> s + -- | Stores and parses an identified at-rule. addAtRule :: s -> Text -> [Token] -> (s, [Token]) addAtRule self _ tokens = (self, skipAtRule tokens) +-- | Stores the parsed selector*s*+proeprties rule. addRules :: StyleSheet ss => ss -> ([Selector], ([(Text, [Token])], Text)) -> ss addRules self (selector:selectors, val@(props, psuedoel)) = addRules self' (selectors, val) where self' = addRule self $ StyleRule selector props psuedoel addRules self ([], _) = self +-- | The properties to set for elements matching the given selector. data StyleRule = StyleRule Selector [(Text, [Token])] Text deriving (Show, Eq) +-- | Gathers StyleRules into a list, mainly for testing. data TrivialStyleSheet = TrivialStyleSheet [StyleRule] deriving (Show, Eq) instance StyleSheet TrivialStyleSheet where addRule (TrivialStyleSheet self) rule = TrivialStyleSheet $ rule:self @@ -41,9 +51,11 @@ instance StyleSheet TrivialStyleSheet where -------- ---- Basic parsing -------- +-- | Parse a CSS stylesheet parse :: StyleSheet s => s -> Text -> s parse stylesheet source = parse' stylesheet $ tokenize source +-- | Parse a CSS stylesheet, resolving all URLs to absolute form. parseForURL :: StyleSheet s => s -> URI -> Text -> s parseForURL stylesheet base source = parse' stylesheet $ rewriteURLs $ tokenize source where @@ -54,6 +66,7 @@ parseForURL stylesheet base source = parse' stylesheet $ rewriteURLs $ tokenize rewriteURLs (tok:toks) = tok : rewriteURLs toks rewriteURLs [] = [] +-- | Parse a tokenized (via `css-syntax`) CSS stylesheet parse' :: StyleSheet t => t -> [Token] -> t -- Things to skip. parse' stylesheet (Whitespace:tokens) = parse' stylesheet tokens @@ -71,6 +84,7 @@ parse' stylesheet tokens = parse' (addRules stylesheet rule) tokens' -------- ---- Property parsing -------- +-- | Parse "{key: value; ...}" property values, with a psuedoelement. parseProperties :: Parser ([(Text, [Token])], Text) parseProperties (LeftCurlyBracket:tokens) = noPsuedoel $ parseProperties' tokens parseProperties (Whitespace:tokens) = parseProperties tokens @@ -83,6 +97,7 @@ parseProperties [] = noPsuedoel ([], []) noPsuedoel :: (x, y) -> ((x, Text), y) noPsuedoel (val, tokens) = ((val, ""), tokens) +-- | Parse "key: value;"... property values, as per the HTML "style" property. parseProperties' :: Parser [(Text, [Token])] parseProperties' (Whitespace:tokens) = parseProperties' tokens parseProperties' (Ident name:tokens) @@ -96,6 +111,7 @@ parseProperties' tokens = parseProperties' (skipValue tokens) -------- ---- Skipping/Scanning utilities -------- +-- | Returns tokens before & after an at-rule value, terminated after a curly-bracketed block or a semicolon. scanAtRule :: Parser [Token] scanAtRule (Semicolon:tokens) = ([Semicolon], tokens) scanAtRule tokens@(LeftCurlyBracket:_) = scanInner tokens $ \rest -> ([], rest) @@ -110,9 +126,11 @@ scanAtRule (RightSquareBracket:tokens) = ([], RightSquareBracket:tokens) scanAtRule tokens = capture scanAtRule tokens +-- | Returns tokens after an at-rule, as per `scanAtRule`. skipAtRule :: [Token] -> [Token] skipAtRule tokens = snd $ scanAtRule tokens +-- | Returns tokens before & after a semicolon. scanValue :: Parser [Token] scanValue (Semicolon:tokens) = ([], tokens) scanValue (Whitespace:tokens) = scanValue tokens @@ -128,5 +146,6 @@ scanValue (RightSquareBracket:tokens) = ([], RightSquareBracket:tokens) scanValue tokens = capture scanValue tokens +-- | Returns tokens after a semicolon. skipValue :: [Token] -> [Token] skipValue tokens = snd $ scanValue tokens diff --git a/src/Data/CSS/Syntax/StyleSheet/ByteString.hs b/src/Data/CSS/Syntax/StyleSheet/ByteString.hs deleted file mode 100644 index a0729d5..0000000 --- a/src/Data/CSS/Syntax/StyleSheet/ByteString.hs +++ /dev/null @@ -1,9 +0,0 @@ --- To determine the text encoding, attempt each text encoding to look for an initial @charset, falling back to UTF8 --- An abstraction would do the test itself. --- text (Data.Text.Encoding) module includes: --- decodeLatin1 --- decodeUtf8 --- decodeUtf16LE --- decodeUtf16BE --- decodeUtf32LE --- decodeUtf32BE diff --git a/src/Data/CSS/Syntax/StylishUtil.hs b/src/Data/CSS/Syntax/StylishUtil.hs index 8af8684..fb69575 100644 --- a/src/Data/CSS/Syntax/StylishUtil.hs +++ b/src/Data/CSS/Syntax/StylishUtil.hs @@ -1,3 +1,4 @@ +-- | Utility parser combinators for parsing CSS stylesheets. module Data.CSS.Syntax.StylishUtil( concatP, capture, skipSpace, scanBlock, skipBlock, scanInner, @@ -6,22 +7,28 @@ module Data.CSS.Syntax.StylishUtil( import Data.CSS.Syntax.Tokens +-- | A simple parser combinator type. type Parser x = [Token] -> (x, [Token]) + +-- | Chains two parser combinators together. concatP :: (a -> b -> c) -> Parser a -> Parser b -> Parser c concatP join left right tokens = (join x y, remainder) where (x, tokens') = left tokens (y, remainder) = right tokens' +-- | "captures" the token being parsed into the returned output. capture :: Parser [Token] -> Parser [Token] capture cb (token:tokens) = (token:captured, tokens') where (captured, tokens') = cb tokens capture _ [] = ([], []) +-- | Removes preceding `Whitespace` tokens. skipSpace :: [Token] -> [Token] skipSpace (Whitespace:tokens) = skipSpace tokens skipSpace tokens = tokens +-- | Returns tokens until the next unbalanced closing brace. scanBlock :: Parser [Token] -- TODO assert closing tags are correct -- But what should the error recovery be? @@ -36,9 +43,11 @@ scanBlock tokens@(LeftSquareBracket:_) = scanInner tokens scanBlock scanBlock tokens = capture scanBlock tokens +-- | Returns tokens after the next unbalanced closing brace. skipBlock :: [Token] -> [Token] skipBlock tokens = snd $ scanBlock tokens +-- | Parses a block followed by the given combinator, returning the tokens the matched. scanInner :: [Token] -> Parser [Token] -> ([Token], [Token]) scanInner (token:tokens) cb = concatP gather scanBlock cb tokens where gather x y = token : x ++ y diff --git a/stylist.cabal b/stylist.cabal index 59fc390..830df12 100644 --- a/stylist.cabal +++ b/stylist.cabal @@ -10,7 +10,7 @@ name: stylist -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change -version: 1.1.1.0 +version: 1.2.0.0 -- A short (one-line) description of the package. synopsis: Apply CSS styles to a document tree. @@ -84,6 +84,6 @@ test-suite test-stylist other-modules: Data.CSS.Syntax.StyleSheet, Data.CSS.Syntax.Selector, Data.CSS.Style build-depends: base >=4.9 && <=4.12, css-syntax >=0.1 && <0.2, text, unordered-containers >= 0.2 && <0.3, hashable, - network-uri >= 2.6 && <2.7, hspec, QuickCheck, + network-uri >= 2.6 && <2.7, async >= 2.1 && <2.3, hspec, QuickCheck, scientific >= 0.3 && <1.0 ghc-options: -Wall diff --git a/xml-conduit-stylist/src/Data/HTML2CSS.hs b/xml-conduit-stylist/src/Data/HTML2CSS.hs index 7ac1177..fa111f1 100644 --- a/xml-conduit-stylist/src/Data/HTML2CSS.hs +++ b/xml-conduit-stylist/src/Data/HTML2CSS.hs @@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Bindings from `xml-conduit` to `haskell-stylist`. module Data.HTML2CSS( externalStyles, externalStylesForURL, internalStyles, internalStylesForURL, -- legacy html2css, cssPriorityAgent, cssPriorityUser, cssPriorityAuthor, -- parsing @@ -50,9 +51,11 @@ parseMediaQuery attrs | otherwise = [] ---- Parsing (legacy) +-- | LEGACY: Extract relative links to external stylesheets. externalStyles :: StyleSheet s => s -> (M.Map XML.Name Txt.Text -> Bool) -> XML.Element -> (URI -> IO Txt.Text) -> IO s externalStyles a b c d = externalStylesForURL a b c nullURI d +-- | LEGACY: Extract absolutized links to external stylesheets. externalStylesForURL stylesheet testMedia html base loadURL = do css <- externalStyles' testMedia html base loadURL return $ foldl (\a (b, c) -> parseForURL a b c) (cssPriorityAuthor stylesheet) css @@ -72,7 +75,9 @@ linkedStyles' testMedia (XML.Element (XML.Name "link" _ _) attrs _) linkedStyles' testMedia (XML.Element _ _ children) = concat [linkedStyles' testMedia el | XML.NodeElement el <- children] +-- | LEGACY: Extract internally embedded CSS stylesheets. internalStyles a b c = internalStylesForURL a b nullURI c +-- | LEGACY: Extract internally embedded CSS stylesheets, with absolutized URLs. internalStylesForURL testMedia stylesheet base html = foldl (\s -> parseForURL s base) (cssPriorityAuthor stylesheet) $ internalStyles' testMedia html @@ -92,12 +97,16 @@ strContent (_:rest) = strContent rest strContent [] = "" ---- Styling +-- | Converts a parsed XML or HTML document to a specified style tree type. traverseStyles :: PropertyParser s => (s -> [o] -> o) -> (s -> Txt.Text -> o) -> QueryableStyleSheet s -> XML.Element -> o traverseStyles = traverseStyles' Nothing temp Nothing (\x y -> Nothing) +-- | Converts a parsed XML or HTML document to a specified style tree type, +-- with a routine to compute alternative contents based on the raw element or computed styles. traversePrepopulatedStyles :: PropertyParser s => (s -> XML.Element -> Maybe [o]) -> (s -> [o] -> o) -> (s -> Txt.Text -> o) -> QueryableStyleSheet s -> XML.Element -> o traversePrepopulatedStyles = traverseStyles' Nothing temp Nothing +-- | Full routine for converting a parsed XML or HTML document to a specified style tree type. traverseStyles' :: PropertyParser s => Maybe Element -> s -> Maybe Element -> (s -> XML.Element -> Maybe [o]) -> (s -> [o] -> o) -> (s -> Txt.Text -> o) -> QueryableStyleSheet s -> XML.Element -> o @@ -128,6 +137,7 @@ traversePsuedo rules psuedo parentStyle builder | Just rules' <- HM.lookup psuedo rules = [builder (cascade' rules' [] parentStyle) []] | otherwise = [] +-- | Converts a xml-conduit Element to a stylist Element. elToStylish (XML.Element (XML.Name name _ _) attrs _) parent previous = ElementNode { name = name, -- 2.30.2