@@ 0,0 1,28 @@
+-- | Abstracts away tree traversals.
+-- Mostly used by callers including (soon) XML Conduit Stylist,
+-- but also used internally for generating counter text.
+module Data.CSS.StyleTree(StyleTree(..), treeOrder, treeOrder', Path, treeMap) where
+
+data StyleTree p = StyleTree {
+ style :: p,
+ children :: [StyleTree p]
+}
+
+type Path = [Integer]
+treeOrder :: (c -> c -> Path -> p -> (c, p')) ->
+ c -> StyleTree p -> StyleTree p'
+treeOrder cb ctxt tree = StyleTree
+ (snd $ cb ctxt ctxt [] $ style tree)
+ (snd $ treeOrder' cb ctxt ctxt [0] $ children tree)
+treeOrder' :: (c -> c -> Path -> p -> (c, p')) ->
+ c -> c -> Path -> [StyleTree p] -> (c, [StyleTree p'])
+treeOrder' cb prevContext context (num:path) (node:nodes) = (tailContext, StyleTree node' children' : nodes')
+ where
+ (selfContext, node') = cb prevContext context (num:path) $ style node
+ (childContext, children') = treeOrder' cb selfContext selfContext (0:num:path) $ children node
+ (tailContext, nodes') = treeOrder' cb selfContext childContext (num + 1:path) nodes
+treeOrder' _ _ context _ [] = (context, [])
+treeOrder' _ _ _ [] _ = error "Invalid path during tree traversal!"
+
+treeMap :: (p -> p') -> StyleTree p -> StyleTree p'
+treeMap cb = treeOrder (\_ _ _ p -> ((), cb p)) ()