From 90cf1ea6e0d277a6dd30cc5f9599d43984068cc5 Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Mon, 20 Apr 2020 19:27:31 +1200 Subject: [PATCH] Substitute in counters for any CSS textual property, not just `content`. Will be required by Rhapsode for navigational markers. --- src/Data/CSS/Preprocessor/Text.hs | 43 +++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/Data/CSS/Preprocessor/Text.hs b/src/Data/CSS/Preprocessor/Text.hs index dc8c35e..493e8a4 100644 --- a/src/Data/CSS/Preprocessor/Text.hs +++ b/src/Data/CSS/Preprocessor/Text.hs @@ -18,7 +18,7 @@ type Counters = [(Text, Integer)] -- | `PropertyParser` decorator that parses & lowers certain CSS properties to plain text. data TextStyle p = TextStyle { inner :: p, - content :: [Token], + counterProps :: [(Text, [Token])], counterReset :: Counters, counterIncrement :: Counters, @@ -31,7 +31,7 @@ data TextStyle p = TextStyle { instance PropertyParser p => PropertyParser (TextStyle p) where temp = TextStyle { inner = temp, - content = [], + counterProps = [], counterReset = [], counterIncrement = [], counterSet = [], @@ -40,7 +40,7 @@ instance PropertyParser p => PropertyParser (TextStyle p) where } inherit parent = TextStyle { inner = inherit $ inner parent, - content = [], + counterProps = [], counterReset = [], counterIncrement = [], counterSet = [], @@ -48,14 +48,13 @@ instance PropertyParser p => PropertyParser (TextStyle p) where newlineCollapse = newlineCollapse parent } - shorthand self "content" value = shorthand (inner self) "content" $ removeCounters value shorthand _ key value | key `elem` ["counter-reset", "counter-increment", "counter-set"], Just _ <- parseCounters 0 value = [(key, value)] shorthand self "white-space" [Ident val] | val `elem` ["normal", "pre", "pre-wrap", "pre-line"] = [("white-space", [Ident val])] | otherwise = shorthand (inner self) "white-space" [Ident val] - shorthand self key value = shorthand (inner self) key value + shorthand self key value = shorthand (inner self) key $ removeCounters value longhand _ self "counter-reset" value = (\v -> self {counterReset = v}) <$> parseCounters 0 value longhand _ self "counter-increment" value = (\v -> self {counterIncrement = v}) <$> parseCounters 1 value @@ -68,8 +67,16 @@ instance PropertyParser p => PropertyParser (TextStyle p) where longhand p self "white-space" [Ident "pre-wrap"] = setWhiteSpace p self False False "normal" longhand p self "white-space" [Ident "pre-line"] = setWhiteSpace p self True False "normal" - longhand _ self "content" value = Just $ self {content = value} - longhand parent self key value = (\v -> self {inner = v}) <$> longhand (inner parent ) (inner self) key value + -- Capture `content` properties & anything else using counter(s) functions. + -- This is important in Rhapsode for the sake of navigational markers. + longhand parent self key value + | key == "content" || Function "counter" `elem` value || Function "counters" `elem` value = + Just $ self { counterProps = insertList key value $ counterProps self } + | otherwise = (\v -> self {inner = v}) <$> longhand (inner parent ) (inner self) key value + +insertList :: Eq a => a -> b -> [(a, b)] -> [(a, b)] +insertList key value list | Nothing <- lookup key list = (key, value) : list + | otherwise = [(k, if k == key then value else v) | (k, v) <- list] removeCounters :: [Token] -> [Token] removeCounters (Function "counter":Ident _:RightParen:toks) = String "" : removeCounters toks @@ -96,9 +103,9 @@ parseCounters _ _ = Nothing resolve :: PropertyParser p => StyleTree (TextStyle p) -> StyleTree p resolve = resolve' . collapseWS . applyCounters resolve' :: PropertyParser p => StyleTree (TextStyle p) -> StyleTree p -resolve' = treeMap $ \TextStyle {inner = inner', content = content'} -> ( - fromMaybe inner' $ longhand temp inner' "content" content' - ) +resolve' = treeMap $ \TextStyle {inner = inner', counterProps = props} -> foldl resolveProp inner' props +resolveProp :: PropertyParser p => p -> (Text, [Token]) -> p +resolveProp sty (key, value) = sty `fromMaybe` longhand temp sty key value -------- ---- Counters @@ -163,21 +170,29 @@ applyCounters0 counterSource valueSource path node = instantiateCounters path (counterReset node) & incrementCounters path (counterIncrement node) & setCounters path (counterSet node) - in (counters, node {content = renderCounters counters $ content node}) + in (counters, node { + counterProps = [(k, renderCounters counters v) | (k, v) <- counterProps node] + }) -------- ---- white-space -------- +content :: TextStyle p -> [Token] +content = fromMaybe [] . lookup "content" . counterProps +setContent :: [Token] -> TextStyle p -> TextStyle p +setContent value self = self { + counterProps = [(k, if k == "content" then value else v) | (k, v) <- counterProps self] + } + collapseWS :: StyleTree (TextStyle p) -> StyleTree (TextStyle p) collapseWS = treeOrder collapseWS0 True collapseWS0 :: Bool -> Bool -> Path -> TextStyle p -> (Bool, TextStyle p) collapseWS0 _ _ _ node@(TextStyle {whiteSpaceCollapse = False, newlineCollapse = False}) = (False, node) collapseWS0 _ inSpace _ node@(TextStyle { - content = content0, whiteSpaceCollapse = wsCollapse, newlineCollapse = nlCollapse - }) = (trailingSpace, node {content = content'}) - where (trailingSpace, content') = collapseWSToks inSpace wsCollapse nlCollapse content0 + }) = (trailingSpace, setContent content' node) + where (trailingSpace, content') = collapseWSToks inSpace wsCollapse nlCollapse $ content node collapseWSToks :: Bool -> Bool -> Bool -> [Token] -> (Bool, [Token]) collapseWSToks stripStart wsCollapse nlCollapse (String txt:toks) = -- 2.30.2