@@ 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) =