{-# LANGUAGE OverloadedStrings #-}
-- | Lowers certain CSS properties to plain text.
module Data.CSS.Preprocessor.Text(
    TextStyle, resolve, resolveWithCounterStyles, CounterStore'(..)) where

import Data.CSS.Syntax.Tokens (Token(..), NumericValue(..))
import Stylist (parseUnorderedShorthand, PropertyParser(..))
import Stylist.Parse (scanBlock)
import Data.CSS.StyleTree
import qualified Data.Text as Txt
import Data.Text (Text)
import Data.CSS.Preprocessor.Text.CounterStyle
        (parseCounter, counterRender, CounterStore'(..), decimalCounter,
        defaultCounterStore, CounterStore, CounterStyle(..), speakAs')

import Data.Maybe (fromMaybe, isJust)
import qualified Data.HashMap.Lazy as M
import Data.Function ((&))

import Data.Char (isSpace)

type Counters = [(Text, Int)]
-- | `PropertyParser` decorator that parses & lowers certain CSS properties to plain text.
data TextStyle p = TextStyle {
    TextStyle p -> p
inner :: p,
    TextStyle p -> [(Text, [Token])]
counterProps :: [(Text, [Token])],

    TextStyle p -> Counters
counterReset :: Counters,
    TextStyle p -> Counters
counterIncrement :: Counters,
    TextStyle p -> Counters
counterSet :: Counters,

    TextStyle p -> Bool
whiteSpaceCollapse :: Bool,
    TextStyle p -> Bool
newlineCollapse :: Bool,

    TextStyle p -> Bool
isListItem :: Bool,
    TextStyle p -> [Token]
listStyleImage :: [Token],
    TextStyle p -> [Token]
listStyleType :: [Token],
    TextStyle p -> Bool
listPosInside :: Bool,
    TextStyle p -> Maybe Bool
markerIsRight :: Maybe Bool,
    TextStyle p -> Bool
isRTL :: Bool,

    TextStyle p -> Maybe (TextStyle p)
beforePseudo :: Maybe (TextStyle p),
    TextStyle p -> Maybe (TextStyle p)
afterPseudo  :: Maybe (TextStyle p),
    TextStyle p -> Maybe (TextStyle p)
markerPseudo :: Maybe (TextStyle p)
}

instance PropertyParser p => PropertyParser (TextStyle p) where
    temp :: TextStyle p
temp = TextStyle :: forall p.
p
-> [(Text, [Token])]
-> Counters
-> Counters
-> Counters
-> Bool
-> Bool
-> Bool
-> [Token]
-> [Token]
-> Bool
-> Maybe Bool
-> Bool
-> Maybe (TextStyle p)
-> Maybe (TextStyle p)
-> Maybe (TextStyle p)
-> TextStyle p
TextStyle {
            inner :: p
inner = p
forall a. PropertyParser a => a
temp,
            counterProps :: [(Text, [Token])]
counterProps = [],
            counterReset :: Counters
counterReset = [],
            counterIncrement :: Counters
counterIncrement = [],
            counterSet :: Counters
counterSet = [],
            whiteSpaceCollapse :: Bool
whiteSpaceCollapse = Bool
True,
            newlineCollapse :: Bool
newlineCollapse = Bool
True,
            isListItem :: Bool
isListItem = Bool
False,
            listStyleImage :: [Token]
listStyleImage = [],
            listStyleType :: [Token]
listStyleType = [Text -> Token
Ident "disc"],
            listPosInside :: Bool
listPosInside = Bool
False,
            markerIsRight :: Maybe Bool
markerIsRight = Maybe Bool
forall a. Maybe a
Nothing,
            isRTL :: Bool
isRTL = Bool
False,
            beforePseudo :: Maybe (TextStyle p)
beforePseudo = Maybe (TextStyle p)
forall a. Maybe a
Nothing,
            afterPseudo :: Maybe (TextStyle p)
afterPseudo  = Maybe (TextStyle p)
forall a. Maybe a
Nothing,
            markerPseudo :: Maybe (TextStyle p)
markerPseudo = Maybe (TextStyle p)
forall a. Maybe a
Nothing
        }
    inherit :: TextStyle p -> TextStyle p
inherit parent :: TextStyle p
parent = TextStyle :: forall p.
p
-> [(Text, [Token])]
-> Counters
-> Counters
-> Counters
-> Bool
-> Bool
-> Bool
-> [Token]
-> [Token]
-> Bool
-> Maybe Bool
-> Bool
-> Maybe (TextStyle p)
-> Maybe (TextStyle p)
-> Maybe (TextStyle p)
-> TextStyle p
TextStyle {
            inner :: p
inner = p -> p
forall a. PropertyParser a => a -> a
inherit (p -> p) -> p -> p
forall a b. (a -> b) -> a -> b
$ TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
parent,
            counterProps :: [(Text, [Token])]
counterProps = [],
            counterReset :: Counters
counterReset = [],
            counterIncrement :: Counters
counterIncrement = [],
            counterSet :: Counters
counterSet = [],
            whiteSpaceCollapse :: Bool
whiteSpaceCollapse = TextStyle p -> Bool
forall p. TextStyle p -> Bool
whiteSpaceCollapse TextStyle p
parent,
            newlineCollapse :: Bool
newlineCollapse = TextStyle p -> Bool
forall p. TextStyle p -> Bool
newlineCollapse TextStyle p
parent,
            isListItem :: Bool
isListItem = Bool
False,
            listStyleImage :: [Token]
listStyleImage = TextStyle p -> [Token]
forall p. TextStyle p -> [Token]
listStyleImage TextStyle p
parent,
            listStyleType :: [Token]
listStyleType = TextStyle p -> [Token]
forall p. TextStyle p -> [Token]
listStyleType TextStyle p
parent,
            listPosInside :: Bool
listPosInside = TextStyle p -> Bool
forall p. TextStyle p -> Bool
listPosInside TextStyle p
parent,
            markerIsRight :: Maybe Bool
markerIsRight = if Maybe Bool -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe Bool
forall p. TextStyle p -> Maybe Bool
markerIsRight TextStyle p
parent
                then Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Bool -> Maybe Bool) -> Bool -> Maybe Bool
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Bool
forall p. TextStyle p -> Bool
isRTL TextStyle p
parent else Maybe Bool
forall a. Maybe a
Nothing,
            isRTL :: Bool
isRTL = TextStyle p -> Bool
forall p. TextStyle p -> Bool
isRTL TextStyle p
parent,
            beforePseudo :: Maybe (TextStyle p)
beforePseudo = Maybe (TextStyle p)
forall a. Maybe a
Nothing,
            afterPseudo :: Maybe (TextStyle p)
afterPseudo  = Maybe (TextStyle p)
forall a. Maybe a
Nothing,
            markerPseudo :: Maybe (TextStyle p)
markerPseudo = Maybe (TextStyle p)
forall a. Maybe a
Nothing
        }
    priority :: TextStyle p -> [Text]
priority self :: TextStyle p
self = p -> [Text]
forall a. PropertyParser a => a -> [Text]
priority (p -> [Text]) -> p -> [Text]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
self

    shorthand :: TextStyle p -> Text -> [Token] -> [(Text, [Token])]
shorthand _ key :: Text
key value :: [Token]
value
        | Text
key Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["counter-reset", "counter-increment", "counter-set"],
            Just _ <- Int -> [Token] -> Maybe Counters
parseCounters 0 [Token]
value = [(Text
key, [Token]
value)]
    shorthand self :: TextStyle p
self "white-space" [Ident val :: Text
val]
        | Text
val Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["normal", "pre", "pre-wrap", "pre-line"] = [("white-space", [Text -> Token
Ident Text
val])]
        | Bool
otherwise = p -> Text -> [Token] -> [(Text, [Token])]
forall a.
PropertyParser a =>
a -> Text -> [Token] -> [(Text, [Token])]
shorthand (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
self) "white-space" [Text -> Token
Ident Text
val]
    shorthand self :: TextStyle p
self "list-style" toks :: [Token]
toks = TextStyle p -> [Text] -> [Token] -> [(Text, [Token])]
forall a.
PropertyParser a =>
a -> [Text] -> [Token] -> [(Text, [Token])]
parseUnorderedShorthand TextStyle p
self [Text]
subprops [Token]
toks
      where subprops :: [Text]
subprops = ["list-style-image", "list-style-type", "list-style-position"]
    shorthand TextStyle { inner :: forall p. TextStyle p -> p
inner = p
s } k :: Text
k v :: [Token]
v
        | Just _ <- p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand p
s p
s Text
k ([Token] -> Maybe p) -> [Token] -> Maybe p
forall a b. (a -> b) -> a -> b
$ [Token] -> [Token]
removeCounters [Token]
v = [(Text
k, [Token]
v)]
        | Bool
otherwise = p -> Text -> [Token] -> [(Text, [Token])]
forall a.
PropertyParser a =>
a -> Text -> [Token] -> [(Text, [Token])]
shorthand p
s Text
k [Token]
v

    longhand :: TextStyle p
-> TextStyle p -> Text -> [Token] -> Maybe (TextStyle p)
longhand _ self :: TextStyle p
self "counter-reset" value :: [Token]
value = (\v :: Counters
v -> TextStyle p
self {counterReset :: Counters
counterReset = Counters
v}) (Counters -> TextStyle p) -> Maybe Counters -> Maybe (TextStyle p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Token] -> Maybe Counters
parseCounters 0 [Token]
value
    longhand _ self :: TextStyle p
self "counter-increment" value :: [Token]
value = (\v :: Counters
v -> TextStyle p
self {counterIncrement :: Counters
counterIncrement = Counters
v}) (Counters -> TextStyle p) -> Maybe Counters -> Maybe (TextStyle p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Token] -> Maybe Counters
parseCounters 1 [Token]
value
    longhand _ self :: TextStyle p
self "counter-set" value :: [Token]
value = (\v :: Counters
v -> TextStyle p
self {counterSet :: Counters
counterSet = Counters
v}) (Counters -> TextStyle p) -> Maybe Counters -> Maybe (TextStyle p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Token] -> Maybe Counters
parseCounters 0 [Token]
value

    longhand p :: TextStyle p
p self :: TextStyle p
self "white-space" [Ident "initial"] = TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
forall p.
PropertyParser p =>
TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace TextStyle p
p TextStyle p
self Bool
True Bool
True "normal"
    longhand p :: TextStyle p
p self :: TextStyle p
self "white-space" [Ident "normal"] = TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
forall p.
PropertyParser p =>
TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace TextStyle p
p TextStyle p
self Bool
True Bool
True "normal"
    longhand p :: TextStyle p
p self :: TextStyle p
self "white-space" [Ident "pre"] = TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
forall p.
PropertyParser p =>
TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace TextStyle p
p TextStyle p
self Bool
False Bool
False "nowrap"
    longhand p :: TextStyle p
p self :: TextStyle p
self "white-space" [Ident "nowrap"] = TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
forall p.
PropertyParser p =>
TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace TextStyle p
p TextStyle p
self Bool
True Bool
True "nowrap"
    longhand p :: TextStyle p
p self :: TextStyle p
self "white-space" [Ident "pre-wrap"] = TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
forall p.
PropertyParser p =>
TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace TextStyle p
p TextStyle p
self Bool
False Bool
False "normal"
    longhand p :: TextStyle p
p self :: TextStyle p
self "white-space" [Ident "pre-line"] = TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
forall p.
PropertyParser p =>
TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace TextStyle p
p TextStyle p
self Bool
True Bool
False "normal"

    longhand p :: TextStyle p
p self :: TextStyle p
self@TextStyle {inner :: forall p. TextStyle p -> p
inner=p
self'} "display" [Ident "list-item"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
            isListItem :: Bool
isListItem = Bool
True,
            inner :: p
inner = p -> Maybe p -> p
forall a. a -> Maybe a -> a
fromMaybe p
self' (Maybe p -> p) -> Maybe p -> p
forall a b. (a -> b) -> a -> b
$
                p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
p) p
self' "display" [Text -> Token
Ident "block"]
        }
    longhand TextStyle {inner :: forall p. TextStyle p -> p
inner=p
p'} self :: TextStyle p
self@TextStyle {inner :: forall p. TextStyle p -> p
inner = p
self'} "display" value :: [Token]
value
        | Just ret :: p
ret <- p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand p
p' p
self' "display" [Token]
value = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
            isListItem :: Bool
isListItem = Bool
False,
            inner :: p
inner = p
ret
          }
        | Bool
otherwise = Maybe (TextStyle p)
forall a. Maybe a
Nothing

    longhand _ self :: TextStyle p
self "list-style-image" [Ident kw :: Text
kw] | Text
kw Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["initial", "none"]
        = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { listStyleImage :: [Token]
listStyleImage = [] }
    longhand TextStyle { inner :: forall p. TextStyle p -> p
inner = p
p' } self :: TextStyle p
self@TextStyle { inner :: forall p. TextStyle p -> p
inner = p
self' }
            "list-style-image" value :: [Token]
value
        | Just _ <- p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand p
p' p
self' "background-image" [Token]
value = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
            listStyleImage :: [Token]
listStyleImage = [Token]
value -- This is a valid image according to caller.
          }
        | Bool
otherwise = Maybe (TextStyle p)
forall a. Maybe a
Nothing
    longhand _ self :: TextStyle p
self "list-style-type" [Ident "initial"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { listStyleType :: [Token]
listStyleType = [Text -> Token
Ident "disc"] }
    longhand _ self :: TextStyle p
self "list-style-type" toks :: [Token]
toks | Just _ <- CounterStore -> [Token] -> Maybe (CounterStyle, [Token])
parseCounter CounterStore
forall k v. HashMap k v
M.empty [Token]
toks =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { listStyleType :: [Token]
listStyleType = [Token]
toks }
    longhand _ self :: TextStyle p
self "list-style-position" [Ident "inside"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { listPosInside :: Bool
listPosInside = Bool
True }
    longhand _ self :: TextStyle p
self "list-style-position" [Ident "outside"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { listPosInside :: Bool
listPosInside = Bool
False }
    longhand _ self :: TextStyle p
self "list-style-position" [Ident "initial"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { listPosInside :: Bool
listPosInside = Bool
False }

    longhand _ self :: TextStyle p
self "marker-side" [Ident "match-self"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { markerIsRight :: Maybe Bool
markerIsRight = Maybe Bool
forall a. Maybe a
Nothing }
    longhand parent :: TextStyle p
parent self :: TextStyle p
self "marker-side" [Ident "match-parent"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { markerIsRight :: Maybe Bool
markerIsRight = Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Bool -> Maybe Bool) -> Bool -> Maybe Bool
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Bool
forall p. TextStyle p -> Bool
isRTL TextStyle p
parent }
    longhand _ self :: TextStyle p
self "marker-side" [Ident "initial"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self { markerIsRight :: Maybe Bool
markerIsRight = Maybe Bool
forall a. Maybe a
Nothing }
    longhand _ self :: TextStyle p
self k :: Text
k@Text
"direction" v :: [Token]
v@[Ident "ltr"] = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
        isRTL :: Bool
isRTL = Bool
False, counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList Text
k [Token]
v ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self }
    longhand _ self :: TextStyle p
self k :: Text
k@Text
"direction" v :: [Token]
v@[Ident "rtl"] = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
        isRTL :: Bool
isRTL = Bool
True, counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList Text
k [Token]
v ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self }
    longhand _ self :: TextStyle p
self k :: Text
k@Text
"direction" v :: [Token]
v@[Ident "initial"] = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
        isRTL :: Bool
isRTL = Bool
False, counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList Text
k [Token]
v ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self }

    -- Capture `content` properties & anything else using counter(s) functions.
    -- This is important in Rhapsode for the sake of navigational markers.
    -- Ignoring invalid properties.
    longhand TextStyle { inner :: forall p. TextStyle p -> p
inner = p
p' } TextStyle { inner :: forall p. TextStyle p -> p
inner = p
self' } key :: Text
key value :: [Token]
value
        | Maybe p
Nothing <- p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand p
p' p
self' Text
key ([Token] -> Maybe p) -> [Token] -> Maybe p
forall a b. (a -> b) -> a -> b
$ [Token] -> [Token]
removeCounters [Token]
value = Maybe (TextStyle p)
forall a. Maybe a
Nothing
    longhand _ self :: TextStyle p
self "content" [Ident "normal"] =
        TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
self {
            counterProps :: [(Text, [Token])]
counterProps =
                [(Text
k, [Token]
val) | (k :: Text
k, val :: [Token]
val) <- TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self, Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= "content"]
          }
    longhand parent :: TextStyle p
parent self :: TextStyle p
self key :: Text
key value :: [Token]
value
        | Text
key Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "content" Bool -> Bool -> Bool
|| Text -> Token
Function "counter" Token -> [Token] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Token]
value Bool -> Bool -> Bool
|| Text -> Token
Function "counters" Token -> [Token] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Token]
value =
            TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just (TextStyle p -> Maybe (TextStyle p))
-> TextStyle p -> Maybe (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p
self { counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList Text
key [Token]
value ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self }
        | Bool
otherwise = (\v :: p
v -> TextStyle p
self {inner :: p
inner = p
v}) (p -> TextStyle p) -> Maybe p -> Maybe (TextStyle p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
            p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
parent ) (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
self) Text
key [Token]
value

    pseudoEl :: TextStyle p
-> Text
-> (TextStyle p -> Maybe (TextStyle p) -> TextStyle p)
-> TextStyle p
pseudoEl self :: TextStyle p
self "before" calc :: TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc = TextStyle p
self { beforePseudo :: Maybe (TextStyle p)
beforePseudo = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just (TextStyle p -> Maybe (TextStyle p))
-> TextStyle p -> Maybe (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc TextStyle p
self Maybe (TextStyle p)
forall a. Maybe a
Nothing }
    pseudoEl self :: TextStyle p
self "after" calc :: TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc  = TextStyle p
self { afterPseudo :: Maybe (TextStyle p)
afterPseudo  = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just (TextStyle p -> Maybe (TextStyle p))
-> TextStyle p -> Maybe (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc TextStyle p
self Maybe (TextStyle p)
forall a. Maybe a
Nothing }
    pseudoEl self :: TextStyle p
self "marker" calc :: TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc = TextStyle p
self { markerPseudo :: Maybe (TextStyle p)
markerPseudo = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just (TextStyle p -> Maybe (TextStyle p))
-> TextStyle p -> Maybe (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc TextStyle p
self Maybe (TextStyle p)
forall a. Maybe a
Nothing }
    pseudoEl self :: TextStyle p
self sel :: Text
sel calc :: TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc = TextStyle p
self {
        inner :: p
inner = p -> Text -> (p -> Maybe p -> p) -> p
forall a. PropertyParser a => a -> Text -> (a -> Maybe a -> a) -> a
pseudoEl (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
self) Text
sel p -> Maybe p -> p
calc'
      } where
        calc' :: p -> Maybe p -> p
calc' parent :: p
parent (Just base :: p
base) =
            TextStyle p -> p
forall p. TextStyle p -> p
inner (TextStyle p -> p) -> TextStyle p -> p
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc TextStyle p
forall a. PropertyParser a => a
temp { inner :: p
inner = p
parent } (Maybe (TextStyle p) -> TextStyle p)
-> Maybe (TextStyle p) -> TextStyle p
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
forall a. PropertyParser a => a
temp { inner :: p
inner = p
base }
        calc' parent :: p
parent Nothing = TextStyle p -> p
forall p. TextStyle p -> p
inner (TextStyle p -> p) -> TextStyle p -> p
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Maybe (TextStyle p) -> TextStyle p
calc TextStyle p
forall a. PropertyParser a => a
temp { inner :: p
inner = p
parent } Maybe (TextStyle p)
forall a. Maybe a
Nothing

insertList :: Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList :: a -> b -> [(a, b)] -> [(a, b)]
insertList key :: a
key value :: b
value list :: [(a, b)]
list | Maybe b
Nothing <- a -> [(a, b)] -> Maybe b
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup a
key [(a, b)]
list = (a
key, b
value) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: [(a, b)]
list
    | Bool
otherwise = [(a
k, if a
k a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
key then b
value else b
v) | (k :: a
k, v :: b
v) <- [(a, b)]
list]

removeCounters :: [Token] -> [Token]
removeCounters :: [Token] -> [Token]
removeCounters (Function "counter":Ident _:RightParen:toks :: [Token]
toks) = Text -> Token
String "" Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token] -> [Token]
removeCounters [Token]
toks
removeCounters (Function "counter":Ident _:Comma:toks :: [Token]
toks)
    | Just (_, RightParen:toks' :: [Token]
toks') <- [Token] -> Maybe (CounterStyle, [Token])
parseCounter0 [Token]
toks = Text -> Token
String "" Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token] -> [Token]
removeCounters [Token]
toks'
removeCounters (Function "counters":Ident _:Comma:String _:RightParen:toks :: [Token]
toks) =
    Text -> Token
String "" Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token] -> [Token]
removeCounters [Token]
toks
removeCounters (Function "counters":Ident _:Comma:String _:Comma:toks :: [Token]
toks)
    | Just (_, RightParen:toks' :: [Token]
toks') <- [Token] -> Maybe (CounterStyle, [Token])
parseCounter0 [Token]
toks = Text -> Token
String "" Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token] -> [Token]
removeCounters [Token]
toks'
removeCounters (tok :: Token
tok:toks :: [Token]
toks) = Token
tok Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token] -> [Token]
removeCounters [Token]
toks
removeCounters [] = []

parseCounter0 :: [Token] -> Maybe (CounterStyle, [Token])
parseCounter0 :: [Token] -> Maybe (CounterStyle, [Token])
parseCounter0 = CounterStore -> [Token] -> Maybe (CounterStyle, [Token])
parseCounter CounterStore
forall k v. HashMap k v
M.empty

setWhiteSpace :: PropertyParser p => TextStyle p -> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace :: TextStyle p
-> TextStyle p -> Bool -> Bool -> Text -> Maybe (TextStyle p)
setWhiteSpace parent :: TextStyle p
parent self :: TextStyle p
self collapse :: Bool
collapse noNewlines :: Bool
noNewlines lowered :: Text
lowered = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just (TextStyle p -> Maybe (TextStyle p))
-> TextStyle p -> Maybe (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p
self {
        inner :: p
inner = TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
self p -> Maybe p -> p
forall a. a -> Maybe a -> a
`fromMaybe` p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
parent) (TextStyle p -> p
forall p. TextStyle p -> p
inner TextStyle p
self) "white-space" [Text -> Token
Ident Text
lowered],
        whiteSpaceCollapse :: Bool
whiteSpaceCollapse = Bool
collapse,
        newlineCollapse :: Bool
newlineCollapse = Bool
noNewlines
    }
parseCounters :: Int -> [Token] -> Maybe [(Text, Int)]
parseCounters :: Int -> [Token] -> Maybe Counters
parseCounters _ [Ident "none"] = Counters -> Maybe Counters
forall a. a -> Maybe a
Just []
parseCounters _ [Ident "initial"] = Counters -> Maybe Counters
forall a. a -> Maybe a
Just []
parseCounters _ [] = Counters -> Maybe Counters
forall a. a -> Maybe a
Just []
parseCounters x :: Int
x (Ident counter :: Text
counter : Number _ (NVInteger count' :: Integer
count') : toks :: [Token]
toks) =
    (:) (Text
counter, Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
count') (Counters -> Counters) -> Maybe Counters -> Maybe Counters
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Token] -> Maybe Counters
parseCounters Int
x [Token]
toks
parseCounters x :: Int
x (Ident counter :: Text
counter : toks :: [Token]
toks) = (:) (Text
counter, Int
x) (Counters -> Counters) -> Maybe Counters -> Maybe Counters
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Token] -> Maybe Counters
parseCounters Int
x [Token]
toks
parseCounters _ _ = Maybe Counters
forall a. Maybe a
Nothing

-- | Returns inner `PropertyParser` with text properties applied.
resolve :: PropertyParser p => StyleTree (TextStyle p) -> StyleTree p
resolve :: StyleTree (TextStyle p) -> StyleTree p
resolve = CounterStore' -> StyleTree (TextStyle p) -> StyleTree p
forall p.
PropertyParser p =>
CounterStore' -> StyleTree (TextStyle p) -> StyleTree p
resolveWithCounterStyles CounterStore'
defaultCounterStore
resolveWithCounterStyles :: PropertyParser p =>
    CounterStore' -> StyleTree (TextStyle p) -> StyleTree p
resolveWithCounterStyles :: CounterStore' -> StyleTree (TextStyle p) -> StyleTree p
resolveWithCounterStyles (CounterStore counters :: CounterStore
counters) =
    StyleTree (TextStyle p) -> StyleTree p
forall p.
PropertyParser p =>
StyleTree (TextStyle p) -> StyleTree p
resolve' (StyleTree (TextStyle p) -> StyleTree p)
-> (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p)
-> StyleTree p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p. StyleTree (TextStyle p) -> StyleTree (TextStyle p)
collapseWS (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p)
-> StyleTree (TextStyle p)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
applyCounters CounterStore
counters (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p)
-> StyleTree (TextStyle p)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
counters
resolve' :: PropertyParser p => StyleTree (TextStyle p) -> StyleTree p
resolve' :: StyleTree (TextStyle p) -> StyleTree p
resolve' = (TextStyle p -> p) -> StyleTree (TextStyle p) -> StyleTree p
forall p p'. (p -> p') -> StyleTree p -> StyleTree p'
treeMap ((TextStyle p -> p) -> StyleTree (TextStyle p) -> StyleTree p)
-> (TextStyle p -> p) -> StyleTree (TextStyle p) -> StyleTree p
forall a b. (a -> b) -> a -> b
$ \TextStyle {inner :: forall p. TextStyle p -> p
inner = p
inner', counterProps :: forall p. TextStyle p -> [(Text, [Token])]
counterProps = [(Text, [Token])]
props} -> (p -> (Text, [Token]) -> p) -> p -> [(Text, [Token])] -> p
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl p -> (Text, [Token]) -> p
forall p. PropertyParser p => p -> (Text, [Token]) -> p
resolveProp p
inner' [(Text, [Token])]
props
resolveProp :: PropertyParser p => p -> (Text, [Token]) -> p
resolveProp :: p -> (Text, [Token]) -> p
resolveProp sty :: p
sty (key :: Text
key, value :: [Token]
value) = p
sty p -> Maybe p -> p
forall a. a -> Maybe a -> a
`fromMaybe` p -> p -> Text -> [Token] -> Maybe p
forall a. PropertyParser a => a -> a -> Text -> [Token] -> Maybe a
longhand p
forall a. PropertyParser a => a
temp p
sty Text
key [Token]
value

--------
---- Lists & pseudo-elements
--------

insertPseudos :: PropertyParser p =>
    CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos :: CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos s :: CounterStore
s (StyleTree self :: TextStyle p
self@TextStyle { afterPseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
afterPseudo = Just child :: TextStyle p
child } childs :: [StyleTree (TextStyle p)]
childs) =
    CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
s (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$
        TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self { afterPseudo :: Maybe (TextStyle p)
afterPseudo = Maybe (TextStyle p)
forall a. Maybe a
Nothing } ([StyleTree (TextStyle p)]
childs [StyleTree (TextStyle p)]
-> [StyleTree (TextStyle p)] -> [StyleTree (TextStyle p)]
forall a. [a] -> [a] -> [a]
++ [Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
forall p.
Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t Maybe CounterStyle
forall a. Maybe a
Nothing TextStyle p
child])
insertPseudos s :: CounterStore
s (StyleTree self :: TextStyle p
self@TextStyle { beforePseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
beforePseudo = Just child :: TextStyle p
child } childs :: [StyleTree (TextStyle p)]
childs) =
    CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
s (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self { beforePseudo :: Maybe (TextStyle p)
beforePseudo = Maybe (TextStyle p)
forall a. Maybe a
Nothing }
        (Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
forall p.
Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t Maybe CounterStyle
forall a. Maybe a
Nothing TextStyle p
childStyleTree (TextStyle p)
-> [StyleTree (TextStyle p)] -> [StyleTree (TextStyle p)]
forall a. a -> [a] -> [a]
:[StyleTree (TextStyle p)]
childs)

insertPseudos s :: CounterStore
s (StyleTree self :: TextStyle p
self@TextStyle { markerPseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
markerPseudo = Maybe (TextStyle p)
Nothing } childs :: [StyleTree (TextStyle p)]
childs) =
    CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
s (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self { markerPseudo :: Maybe (TextStyle p)
markerPseudo = TextStyle p -> Maybe (TextStyle p)
forall a. a -> Maybe a
Just TextStyle p
forall a. PropertyParser a => a
temp } [StyleTree (TextStyle p)]
childs
insertPseudos s :: CounterStore
s self :: StyleTree (TextStyle p)
self@(StyleTree TextStyle { markerPseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
markerPseudo = Just child :: TextStyle p
child} _)
    | Just text :: [Token]
text <- Text -> [(Text, [Token])] -> Maybe [Token]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup "content" ([(Text, [Token])] -> Maybe [Token])
-> [(Text, [Token])] -> Maybe [Token]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
child =
        StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
addBullet StyleTree (TextStyle p)
self CounterStore
s Maybe CounterStyle
forall a. Maybe a
Nothing [Token]
text
insertPseudos s :: CounterStore
s self :: StyleTree (TextStyle p)
self@(StyleTree TextStyle { listStyleImage :: forall p. TextStyle p -> [Token]
listStyleImage = bullet :: [Token]
bullet@(_:_) } _) =
    StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
addBullet StyleTree (TextStyle p)
self CounterStore
s Maybe CounterStyle
forall a. Maybe a
Nothing ([Token]
bullet [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ [Text -> Token
String " "])
insertPseudos s :: CounterStore
s self :: StyleTree (TextStyle p)
self@(StyleTree TextStyle { listStyleType :: forall p. TextStyle p -> [Token]
listStyleType = bullet :: [Token]
bullet@(_:_) } _)
    | Just (cstyle :: CounterStyle
cstyle, _) <- CounterStore -> [Token] -> Maybe (CounterStyle, [Token])
parseCounter CounterStore
s [Token]
bullet =
        StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
addBullet StyleTree (TextStyle p)
self CounterStore
s (CounterStyle -> Maybe CounterStyle
forall a. a -> Maybe a
Just CounterStyle
cstyle) ([Token] -> StyleTree (TextStyle p))
-> [Token] -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$ CounterStyle -> [Token]
text CounterStyle
cstyle
  where
    text :: CounterStyle -> [Token]
text counter :: CounterStyle
counter = Text -> Token
String (CounterStyle -> Text
prefix CounterStyle
counter)Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:
        Text -> Token
Function "counter"Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:Text -> Token
Ident "list-item"Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:Token
CommaToken -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:[Token]
bullet [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++
        [Text -> Token
String (Text -> Token) -> Text -> Token
forall a b. (a -> b) -> a -> b
$ CounterStyle -> Text
suffix CounterStyle
counter]

insertPseudos store :: CounterStore
store (StyleTree self :: TextStyle p
self childs :: [StyleTree (TextStyle p)]
childs) =
    TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self ([StyleTree (TextStyle p)] -> StyleTree (TextStyle p))
-> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$ (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> [StyleTree (TextStyle p)] -> [StyleTree (TextStyle p)]
forall a b. (a -> b) -> [a] -> [b]
map (CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
store) [StyleTree (TextStyle p)]
childs

addBullet :: PropertyParser p => StyleTree (TextStyle p) ->
    CounterStore -> Maybe CounterStyle -> [Token] -> StyleTree (TextStyle p)
addBullet :: StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
addBullet (StyleTree self :: TextStyle p
self@TextStyle {
        counterIncrement :: forall p. TextStyle p -> Counters
counterIncrement = Counters
counters, isListItem :: forall p. TextStyle p -> Bool
isListItem = Bool
True
    } childs :: [StyleTree (TextStyle p)]
childs) store :: CounterStore
store cstyle :: Maybe CounterStyle
cstyle txt :: [Token]
txt | Maybe Int
Nothing <- Text -> Counters -> Maybe Int
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup "list-item" Counters
counters =
        StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
addBullet (TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self {
            counterIncrement :: Counters
counterIncrement = ("list-item", 1)(Text, Int) -> Counters -> Counters
forall a. a -> [a] -> [a]
:TextStyle p -> Counters
forall p. TextStyle p -> Counters
counterIncrement TextStyle p
self
        } [StyleTree (TextStyle p)]
childs) CounterStore
store Maybe CounterStyle
cstyle [Token]
txt
addBullet (StyleTree self :: TextStyle p
self@TextStyle {
        isListItem :: forall p. TextStyle p -> Bool
isListItem = Bool
True, listPosInside :: forall p. TextStyle p -> Bool
listPosInside = Bool
True, markerPseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
markerPseudo = Just child :: TextStyle p
child
    } childs :: [StyleTree (TextStyle p)]
childs) store :: CounterStore
store cstyle :: Maybe CounterStyle
cstyle txt :: [Token]
txt = CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
store (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$
        TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self { isListItem :: Bool
isListItem = Bool
False } (Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
forall p.
Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t Maybe CounterStyle
cstyle TextStyle p
child {
            counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList "content" [Token]
txt ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
child
        } StyleTree (TextStyle p)
-> [StyleTree (TextStyle p)] -> [StyleTree (TextStyle p)]
forall a. a -> [a] -> [a]
: [StyleTree (TextStyle p)]
childs)
addBullet (StyleTree s :: TextStyle p
s@TextStyle {markerIsRight :: forall p. TextStyle p -> Maybe Bool
markerIsRight=Maybe Bool
Nothing} childs :: [StyleTree (TextStyle p)]
childs) store :: CounterStore
store cstyle :: Maybe CounterStyle
cstyle txt :: [Token]
txt
    = StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
StyleTree (TextStyle p)
-> CounterStore
-> Maybe CounterStyle
-> [Token]
-> StyleTree (TextStyle p)
addBullet (TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
s { markerIsRight :: Maybe Bool
markerIsRight = Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Bool -> Maybe Bool) -> Bool -> Maybe Bool
forall a b. (a -> b) -> a -> b
$ TextStyle p -> Bool
forall p. TextStyle p -> Bool
isRTL TextStyle p
s } [StyleTree (TextStyle p)]
childs)
        CounterStore
store Maybe CounterStyle
cstyle [Token]
txt
addBullet (StyleTree self :: TextStyle p
self@TextStyle { markerIsRight :: forall p. TextStyle p -> Maybe Bool
markerIsRight = Just False,
        isListItem :: forall p. TextStyle p -> Bool
isListItem = Bool
True, listPosInside :: forall p. TextStyle p -> Bool
listPosInside = Bool
False, markerPseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
markerPseudo = Just child :: TextStyle p
child
    } childs :: [StyleTree (TextStyle p)]
childs) store :: CounterStore
store cstyle :: Maybe CounterStyle
cstyle txt :: [Token]
txt = CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
store (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$
        TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self {
            isListItem :: Bool
isListItem = Bool
False,
            -- Flex lays out children horizontally at min size.
            counterProps :: [(Text, [Token])]
counterProps=Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList "display" [Text -> Token
Ident "flex"] ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
child
        } [
            Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
forall p.
Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t Maybe CounterStyle
cstyle TextStyle p
child {
                counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList "content" [Token]
txt ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
child
            },
            -- Generate a new layout box for the bullet to sit outside of.
            TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
forall a. PropertyParser a => a
temp [StyleTree (TextStyle p)]
childs
        ]
addBullet (StyleTree self :: TextStyle p
self@TextStyle { markerIsRight :: forall p. TextStyle p -> Maybe Bool
markerIsRight = Just True,
        isListItem :: forall p. TextStyle p -> Bool
isListItem = Bool
True, listPosInside :: forall p. TextStyle p -> Bool
listPosInside = Bool
False, markerPseudo :: forall p. TextStyle p -> Maybe (TextStyle p)
markerPseudo = Just child :: TextStyle p
child
    } childs :: [StyleTree (TextStyle p)]
childs) store :: CounterStore
store cstyle :: Maybe CounterStyle
cstyle txt :: [Token]
txt = CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
store (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$
        TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self {
            isListItem :: Bool
isListItem = Bool
False,
            counterProps :: [(Text, [Token])]
counterProps=Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList "display" [Text -> Token
Ident "flex"] ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
child
        } [
            TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
forall a. PropertyParser a => a
temp [StyleTree (TextStyle p)]
childs,
            Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
forall p.
Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t Maybe CounterStyle
cstyle TextStyle p
child {
                counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList "content" [Token]
txt ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
child
            }
        ]
addBullet (StyleTree self :: TextStyle p
self childs :: [StyleTree (TextStyle p)]
childs) store :: CounterStore
store _ _ =
    CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall p.
PropertyParser p =>
CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
insertPseudos CounterStore
store (StyleTree (TextStyle p) -> StyleTree (TextStyle p))
-> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self {
        isListItem :: Bool
isListItem = Bool
False,
        listStyleImage :: [Token]
listStyleImage = [], listStyleType :: [Token]
listStyleType = []
    } [StyleTree (TextStyle p)]
childs

t :: Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t :: Maybe CounterStyle -> TextStyle p -> StyleTree (TextStyle p)
t (Just cstyle :: CounterStyle
cstyle) self :: TextStyle p
self = TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self {
    counterProps :: [(Text, [Token])]
counterProps = Text -> [Token] -> [(Text, [Token])] -> [(Text, [Token])]
forall a b. Eq a => a -> b -> [(a, b)] -> [(a, b)]
insertList "speak-as" [Text -> Token
Ident (Text -> Token) -> Text -> Token
forall a b. (a -> b) -> a -> b
$ CounterStyle -> Text
speakAs' CounterStyle
cstyle] ([(Text, [Token])] -> [(Text, [Token])])
-> [(Text, [Token])] -> [(Text, [Token])]
forall a b. (a -> b) -> a -> b
$
        TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self } []
t Nothing self :: TextStyle p
self = TextStyle p -> [StyleTree (TextStyle p)] -> StyleTree (TextStyle p)
forall p. p -> [StyleTree p] -> StyleTree p
StyleTree TextStyle p
self []

--------
---- Counters
--------
type Context = M.HashMap Text [([Integer], Int)]

inheritCounters :: Context -> Context -> Context
inheritCounters :: Context -> Context -> Context
inheritCounters counterSource :: Context
counterSource valueSource :: Context
valueSource = ([([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)])
-> Context -> Context -> Context
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
M.unionWith [([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)]
forall a b b. Eq a => [(a, b)] -> [(a, b)] -> [(a, b)]
cb Context
valueSource Context
counterSource -- indexed by name & el-path
    where cb :: [(a, b)] -> [(a, b)] -> [(a, b)]
cb val :: [(a, b)]
val source :: [(a, b)]
source = [(a, b)
counter | counter :: (a, b)
counter@(path :: a
path, _) <- [(a, b)]
val,
                            a
path a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
p | (p :: a
p, _) <- [(a, b)]
source]]

instantiateCounter :: Context -> Path -> Text -> Int -> Context
instantiateCounter :: Context -> [Integer] -> Text -> Int -> Context
instantiateCounter counters :: Context
counters path :: [Integer]
path name :: Text
name val :: Int
val =
        ([([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)])
-> Text -> [([Integer], Int)] -> Context -> Context
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
M.insertWith [([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)]
forall b. [([Integer], b)] -> [([Integer], b)] -> [([Integer], b)]
appendCounter Text
name [([Integer]
path, Int
val)] Context
counters
    where
        appendCounter :: [([Integer], b)] -> [([Integer], b)] -> [([Integer], b)]
appendCounter new :: [([Integer], b)]
new (old :: ([Integer], b)
old@((_:oldPath :: [Integer]
oldPath), _):olds :: [([Integer], b)]
olds)
            | [Integer]
oldPath [Integer] -> [Integer] -> Bool
forall a. Eq a => a -> a -> Bool
== [Integer] -> [Integer]
forall a. [a] -> [a]
tail [Integer]
path = [([Integer], b)]
new [([Integer], b)] -> [([Integer], b)] -> [([Integer], b)]
forall a. [a] -> [a] -> [a]
++ [([Integer], b)]
olds
            | Bool
otherwise =  [([Integer], b)]
new [([Integer], b)] -> [([Integer], b)] -> [([Integer], b)]
forall a. [a] -> [a] -> [a]
++ (([Integer], b)
old([Integer], b) -> [([Integer], b)] -> [([Integer], b)]
forall a. a -> [a] -> [a]
:[([Integer], b)]
olds)
        appendCounter new :: [([Integer], b)]
new [] = [([Integer], b)]
new
        appendCounter new :: [([Integer], b)]
new (_:olds :: [([Integer], b)]
olds) = [([Integer], b)]
new [([Integer], b)] -> [([Integer], b)] -> [([Integer], b)]
forall a. [a] -> [a] -> [a]
++ [([Integer], b)]
olds
instantiateCounters :: Path -> Counters -> Context -> Context
instantiateCounters :: [Integer] -> Counters -> Context -> Context
instantiateCounters path :: [Integer]
path instruct :: Counters
instruct counters :: Context
counters = (Context -> (Text, Int) -> Context)
-> Context -> Counters -> Context
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Context -> (Text, Int) -> Context
cb Context
counters Counters
instruct
    where cb :: Context -> (Text, Int) -> Context
cb counters' :: Context
counters' (name :: Text
name, value :: Int
value) = Context -> [Integer] -> Text -> Int -> Context
instantiateCounter Context
counters' [Integer]
path Text
name Int
value

incrementCounter :: Context -> Path -> Text -> Int -> Context
incrementCounter :: Context -> [Integer] -> Text -> Int -> Context
incrementCounter counters :: Context
counters path :: [Integer]
path name :: Text
name val :: Int
val =
        ([([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)])
-> Text -> [([Integer], Int)] -> Context -> Context
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
M.insertWith [([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)]
forall b a. Num b => [(a, b)] -> [(a, b)] -> [(a, b)]
addCounter Text
name [([Integer]
path, Int
val)] Context
counters
    where
        addCounter :: [(a, b)] -> [(a, b)] -> [(a, b)]
addCounter ((_, new :: b
new):_) ((path' :: a
path', old :: b
old):rest :: [(a, b)]
rest) = (a
path', b
new b -> b -> b
forall a. Num a => a -> a -> a
+ b
old)(a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
:[(a, b)]
rest
        addCounter [] old :: [(a, b)]
old = [(a, b)]
old
        addCounter new :: [(a, b)]
new [] = [(a, b)]
new
incrementCounters :: Path -> Counters -> Context -> Context
incrementCounters :: [Integer] -> Counters -> Context -> Context
incrementCounters path :: [Integer]
path instruct :: Counters
instruct counters :: Context
counters = (Context -> (Text, Int) -> Context)
-> Context -> Counters -> Context
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Context -> (Text, Int) -> Context
cb Context
counters Counters
instruct
    where cb :: Context -> (Text, Int) -> Context
cb counters' :: Context
counters' (name :: Text
name, value :: Int
value) = Context -> [Integer] -> Text -> Int -> Context
incrementCounter Context
counters' [Integer]
path Text
name Int
value

setCounter :: Context -> Path -> Text -> Int -> Context
setCounter :: Context -> [Integer] -> Text -> Int -> Context
setCounter counters :: Context
counters path :: [Integer]
path name :: Text
name val :: Int
val = ([([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)])
-> Text -> [([Integer], Int)] -> Context -> Context
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
M.insertWith [([Integer], Int)] -> [([Integer], Int)] -> [([Integer], Int)]
forall a b. [(a, b)] -> [(a, b)] -> [(a, b)]
setCounter' Text
name [([Integer]
path, Int
val)] Context
counters
    where
        setCounter' :: [(a, b)] -> [(a, b)] -> [(a, b)]
setCounter' ((_, val' :: b
val'):_) ((path' :: a
path', _):rest :: [(a, b)]
rest) = (a
path', b
val')(a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
:[(a, b)]
rest
        setCounter' [] old :: [(a, b)]
old = [(a, b)]
old
        setCounter' new :: [(a, b)]
new [] = [(a, b)]
new
setCounters :: Path -> Counters -> Context -> Context
setCounters :: [Integer] -> Counters -> Context -> Context
setCounters path :: [Integer]
path instruct :: Counters
instruct counters :: Context
counters = (Context -> (Text, Int) -> Context)
-> Context -> Counters -> Context
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Context -> (Text, Int) -> Context
cb Context
counters Counters
instruct
    where cb :: Context -> (Text, Int) -> Context
cb counters' :: Context
counters' (name :: Text
name, value :: Int
value) = Context -> [Integer] -> Text -> Int -> Context
setCounter Context
counters' [Integer]
path Text
name Int
value


renderCounters :: CounterStore -> Context -> [Token] -> [Token]
renderCounters :: CounterStore -> Context -> [Token] -> [Token]
renderCounters store :: CounterStore
store counters :: Context
counters (Function "counter":Ident name :: Text
name:RightParen:toks :: [Token]
toks)
    | Just ((_, count :: Int
count):_) <- Text
name Text -> Context -> Maybe [([Integer], Int)]
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
`M.lookup` Context
counters =
        Text -> Token
String (CounterStyle -> Int -> Text
counterRender CounterStyle
decimalCounter Int
count) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks
    | Bool
otherwise = CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks
renderCounters store :: CounterStore
store counters :: Context
counters (Function "counter":Ident name :: Text
name:Comma:toks :: [Token]
toks)
    | Just ((_, count :: Int
count):_) <- Text
name Text -> Context -> Maybe [([Integer], Int)]
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
`M.lookup` Context
counters,
            Just (cstyle :: CounterStyle
cstyle, RightParen:toks' :: [Token]
toks') <- CounterStore -> [Token] -> Maybe (CounterStyle, [Token])
parseCounter CounterStore
store [Token]
toks =
        Text -> Token
String (CounterStyle -> Int -> Text
counterRender CounterStyle
cstyle Int
count) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks'
    | Bool
otherwise = CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters ([Token] -> [Token]) -> [Token] -> [Token]
forall a b. (a -> b) -> a -> b
$ [Token] -> [Token]
skipBlock [Token]
toks
renderCounters store :: CounterStore
store counters :: Context
counters (Function "counters":Ident name :: Text
name:Comma:String sep :: Text
sep:RightParen:toks :: [Token]
toks)
    | Just counter :: [([Integer], Int)]
counter <- Text
name Text -> Context -> Maybe [([Integer], Int)]
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
`M.lookup` Context
counters = Text -> Token
String (Text -> [Text] -> Text
Txt.intercalate Text
sep [
        CounterStyle -> Int -> Text
counterRender CounterStyle
decimalCounter Int
count | (_, count :: Int
count) <- [([Integer], Int)] -> [([Integer], Int)]
forall a. [a] -> [a]
reverse [([Integer], Int)]
counter
    ]) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks
    | Bool
otherwise = CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks
renderCounters store :: CounterStore
store counters :: Context
counters (Function "counters":Ident name :: Text
name:Comma:String sep :: Text
sep:Comma:toks :: [Token]
toks)
    | Just counter :: [([Integer], Int)]
counter <- Text
name Text -> Context -> Maybe [([Integer], Int)]
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
`M.lookup` Context
counters,
            Just (cstyle :: CounterStyle
cstyle, RightParen:toks' :: [Token]
toks') <- CounterStore -> [Token] -> Maybe (CounterStyle, [Token])
parseCounter CounterStore
store [Token]
toks =
        Text -> Token
String (Text -> [Text] -> Text
Txt.intercalate Text
sep [
            CounterStyle -> Int -> Text
counterRender CounterStyle
cstyle Int
count | (_, count :: Int
count) <- [([Integer], Int)] -> [([Integer], Int)]
forall a. [a] -> [a]
reverse [([Integer], Int)]
counter
        ]) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks'
    | Bool
otherwise = CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks
renderCounters store :: CounterStore
store counters :: Context
counters (tok :: Token
tok:toks :: [Token]
toks) = Token
tok Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
toks
renderCounters _ _ [] = []

skipBlock :: [Token] -> [Token]
skipBlock :: [Token] -> [Token]
skipBlock = ([Token], [Token]) -> [Token]
forall a b. (a, b) -> b
snd (([Token], [Token]) -> [Token])
-> ([Token] -> ([Token], [Token])) -> [Token] -> [Token]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Token] -> ([Token], [Token])
scanBlock

applyCounters :: CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
applyCounters :: CounterStore -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
applyCounters counters :: CounterStore
counters = (Context
 -> Context -> [Integer] -> TextStyle p -> (Context, TextStyle p))
-> Context -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall c p p'.
(c -> c -> [Integer] -> p -> (c, p'))
-> c -> StyleTree p -> StyleTree p'
treeOrder (CounterStore
-> Context
-> Context
-> [Integer]
-> TextStyle p
-> (Context, TextStyle p)
forall p.
CounterStore
-> Context
-> Context
-> [Integer]
-> TextStyle p
-> (Context, TextStyle p)
applyCounters0 CounterStore
counters) Context
forall k v. HashMap k v
M.empty
applyCounters0 :: CounterStore -> Context -> Context -> Path -> TextStyle p ->
        (Context, TextStyle p)
applyCounters0 :: CounterStore
-> Context
-> Context
-> [Integer]
-> TextStyle p
-> (Context, TextStyle p)
applyCounters0 store :: CounterStore
store counterSource :: Context
counterSource valueSource :: Context
valueSource path :: [Integer]
path node :: TextStyle p
node =
    let counters :: Context
counters = Context -> Context -> Context
inheritCounters Context
counterSource Context
valueSource Context -> (Context -> Context) -> Context
forall a b. a -> (a -> b) -> b
&
            [Integer] -> Counters -> Context -> Context
instantiateCounters [Integer]
path (TextStyle p -> Counters
forall p. TextStyle p -> Counters
counterReset TextStyle p
node) Context -> (Context -> Context) -> Context
forall a b. a -> (a -> b) -> b
&
            [Integer] -> Counters -> Context -> Context
incrementCounters [Integer]
path (TextStyle p -> Counters
forall p. TextStyle p -> Counters
counterIncrement TextStyle p
node) Context -> (Context -> Context) -> Context
forall a b. a -> (a -> b) -> b
&
            [Integer] -> Counters -> Context -> Context
setCounters [Integer]
path (TextStyle p -> Counters
forall p. TextStyle p -> Counters
counterSet TextStyle p
node)
    in (Context
counters, TextStyle p
node {
        counterProps :: [(Text, [Token])]
counterProps = [(Text
k, CounterStore -> Context -> [Token] -> [Token]
renderCounters CounterStore
store Context
counters [Token]
v) | (k :: Text
k, v :: [Token]
v) <- TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
node]
    })

--------
---- white-space
--------
content :: TextStyle p -> [Token]
content :: TextStyle p -> [Token]
content = [Token] -> Maybe [Token] -> [Token]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [Token] -> [Token])
-> (TextStyle p -> Maybe [Token]) -> TextStyle p -> [Token]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [(Text, [Token])] -> Maybe [Token]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup "content" ([(Text, [Token])] -> Maybe [Token])
-> (TextStyle p -> [(Text, [Token])])
-> TextStyle p
-> Maybe [Token]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps
setContent :: [Token] -> TextStyle p -> TextStyle p
setContent :: [Token] -> TextStyle p -> TextStyle p
setContent value :: [Token]
value self :: TextStyle p
self = TextStyle p
self {
        counterProps :: [(Text, [Token])]
counterProps = [(Text
k, if Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "content" then [Token]
value else [Token]
v) | (k :: Text
k, v :: [Token]
v) <- TextStyle p -> [(Text, [Token])]
forall p. TextStyle p -> [(Text, [Token])]
counterProps TextStyle p
self]
    }

collapseWS :: StyleTree (TextStyle p) -> StyleTree (TextStyle p)
collapseWS :: StyleTree (TextStyle p) -> StyleTree (TextStyle p)
collapseWS = (Bool -> Bool -> [Integer] -> TextStyle p -> (Bool, TextStyle p))
-> Bool -> StyleTree (TextStyle p) -> StyleTree (TextStyle p)
forall c p p'.
(c -> c -> [Integer] -> p -> (c, p'))
-> c -> StyleTree p -> StyleTree p'
treeOrder Bool -> Bool -> [Integer] -> TextStyle p -> (Bool, TextStyle p)
forall p.
Bool -> Bool -> [Integer] -> TextStyle p -> (Bool, TextStyle p)
collapseWS0 Bool
True
collapseWS0 :: Bool -> Bool -> Path -> TextStyle p -> (Bool, TextStyle p)
collapseWS0 :: Bool -> Bool -> [Integer] -> TextStyle p -> (Bool, TextStyle p)
collapseWS0 _ _ _ node :: TextStyle p
node@(TextStyle {
    whiteSpaceCollapse :: forall p. TextStyle p -> Bool
whiteSpaceCollapse = Bool
False, newlineCollapse :: forall p. TextStyle p -> Bool
newlineCollapse = Bool
False }) = (Bool
False, TextStyle p
node)
collapseWS0 _ inSpace :: Bool
inSpace _ node :: TextStyle p
node@(TextStyle {
        whiteSpaceCollapse :: forall p. TextStyle p -> Bool
whiteSpaceCollapse = Bool
wsCollapse,
        newlineCollapse :: forall p. TextStyle p -> Bool
newlineCollapse = Bool
nlCollapse
    }) = (Bool
trailingSpace, [Token] -> TextStyle p -> TextStyle p
forall p. [Token] -> TextStyle p -> TextStyle p
setContent [Token]
content' TextStyle p
node)
  where (trailingSpace :: Bool
trailingSpace, content' :: [Token]
content') =
            Bool -> Bool -> Bool -> [Token] -> (Bool, [Token])
collapseWSToks Bool
inSpace Bool
wsCollapse Bool
nlCollapse ([Token] -> (Bool, [Token])) -> [Token] -> (Bool, [Token])
forall a b. (a -> b) -> a -> b
$ TextStyle p -> [Token]
forall p. TextStyle p -> [Token]
content TextStyle p
node

collapseWSToks :: Bool -> Bool -> Bool -> [Token] -> (Bool, [Token])
collapseWSToks :: Bool -> Bool -> Bool -> [Token] -> (Bool, [Token])
collapseWSToks stripStart :: Bool
stripStart wsCollapse :: Bool
wsCollapse nlCollapse :: Bool
nlCollapse (String txt :: Text
txt:toks :: [Token]
toks) =
    let (trailingSpace :: Bool
trailingSpace, str' :: String
str') =
            Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr Bool
stripStart Bool
wsCollapse Bool
nlCollapse (String -> (Bool, String)) -> String -> (Bool, String)
forall a b. (a -> b) -> a -> b
$ Text -> String
Txt.unpack Text
txt
        (trailingSpace' :: Bool
trailingSpace', toks' :: [Token]
toks') =
            Bool -> Bool -> Bool -> [Token] -> (Bool, [Token])
collapseWSToks Bool
trailingSpace Bool
wsCollapse Bool
nlCollapse [Token]
toks
    in (Bool
trailingSpace', Text -> Token
String (String -> Text
Txt.pack String
str')Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:[Token]
toks')
collapseWSToks _ wsCollapse :: Bool
wsCollapse nlCollapse :: Bool
nlCollapse (tok :: Token
tok:toks :: [Token]
toks) =
    let (trailingSpace :: Bool
trailingSpace, toks' :: [Token]
toks') = Bool -> Bool -> Bool -> [Token] -> (Bool, [Token])
collapseWSToks Bool
False Bool
wsCollapse Bool
nlCollapse [Token]
toks
    in (Bool
trailingSpace, Token
tokToken -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:[Token]
toks')
collapseWSToks trailingWS :: Bool
trailingWS _ _ [] = (Bool
trailingWS, [])

collapseWSStr, collapseWSStr' :: Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr :: Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr _ wsCollapse :: Bool
wsCollapse False str :: String
str@('\n':_) =
    Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr' Bool
True Bool
wsCollapse Bool
False String
str
collapseWSStr True True nlCollapse :: Bool
nlCollapse (ch :: Char
ch:str :: String
str) | Char -> Bool
isSpace Char
ch =
    Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr Bool
True Bool
True Bool
nlCollapse String
str
collapseWSStr False True nlCollapse :: Bool
nlCollapse str :: String
str@(ch :: Char
ch:_) | Char -> Bool
isSpace Char
ch =
    Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr' Bool
True Bool
True Bool
nlCollapse String
str
collapseWSStr _ wsCollapse :: Bool
wsCollapse nlCollapse :: Bool
nlCollapse str :: String
str =
    Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr' Bool
False Bool
wsCollapse Bool
nlCollapse String
str
collapseWSStr' :: Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr' a :: Bool
a b :: Bool
b c :: Bool
c (d :: Char
d:ds :: String
ds) =
    let (trailing :: Bool
trailing, ds' :: String
ds') = Bool -> Bool -> Bool -> String -> (Bool, String)
collapseWSStr Bool
a Bool
b Bool
c String
ds in (Bool
trailing, Char
dChar -> String -> String
forall a. a -> [a] -> [a]
:String
ds')
collapseWSStr' a :: Bool
a _ _ [] = (Bool
a, [])