Use Tree Zipper for rendering DTC ToF in HTML5.
authorJulien Moutinho <julm+tct@autogeree.net>
Sun, 10 Dec 2017 10:46:29 +0000 (11:46 +0100)
committerJulien Moutinho <julm+tct@autogeree.net>
Sun, 10 Dec 2017 10:46:29 +0000 (11:46 +0100)
Data/TreeSeq/Strict/Zipper.hs
Language/DTC/Document.hs
Language/DTC/Sym.hs
Language/DTC/Write/HTML5.hs
Language/DTC/Write/XML.hs

index 391a43b6d8bd91135b413a60b77293d45c3e1be8..1df689b9baaf20ac306aa56ba476e05864b821f5 100644 (file)
@@ -1,6 +1,3 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# OPTIONS_GHC -fno-warn-tabs #-}
 module Data.TreeSeq.Strict.Zipper where
 
 import Control.Applicative (Applicative(..), Alternative(..))
@@ -10,15 +7,17 @@ import Data.Eq (Eq)
 import Data.Function (($), (.))
 import Data.Functor ((<$>))
 import Data.Int (Int)
+import Data.List.NonEmpty (NonEmpty(..))
 import Data.Maybe (Maybe(..), maybe)
 import Data.Monoid (Monoid(..))
-import Data.Sequence (ViewL(..), ViewR(..), (<|), (|>))
 import Data.Semigroup (Semigroup(..))
+import Data.Sequence (ViewL(..), ViewR(..), (<|), (|>))
 import Data.Typeable (Typeable)
 import Prelude (undefined)
 import Text.Show (Show(..))
-import qualified Data.Sequence as Seq
 import qualified Data.List as List
+import qualified Data.List.NonEmpty as NonEmpty
+import qualified Data.Sequence as Seq
 
 import Data.TreeSeq.Strict (Trees, Tree(..))
 
@@ -30,198 +29,187 @@ nodesTree :: Tree k a -> Trees k a
 nodesTree Tree0{}       = mempty
 nodesTree (TreeN _k ts) = ts
 
-keyTree :: Tree k a -> k
-keyTree (TreeN k _) = k
-keyTree Tree0{}     = undefined
-
 -- * Type 'Zipper'
-data Zipper k a
- =   Zipper
- {   zipper_path :: [Zipper_Step k a]
- ,   zipper_curr :: Trees k a
- } deriving (Eq, Show, Typeable)
+type Zipper k a = NonEmpty (Node k a)
+
+zipper :: Tree k a -> Zipper k a
+zipper t = Node mempty t mempty :| []
+
+zippers :: Trees k a -> [Zipper k a]
+zippers ts = ns >>= axis_collect axis_following_first
+       where ns =
+               case Seq.viewl ts of
+                EmptyL -> empty
+                l :< ls -> pure $ Node mempty l ls :| []
+
+zipper_root :: Zipper k a -> Tree k a
+zipper_root =
+       zip_self .
+       NonEmpty.head .
+       List.last .
+       axis_ancestor_or_self
+
+path :: Zipper k x -> [k]
+path ns =
+       List.reverse $
+       NonEmpty.toList ns >>= \n ->
+               case zip_self n of
+                TreeN k _ -> [k]
+                Tree0{}   -> []
+
+current :: Zipper k a -> Tree k a
+current (Node _ t _ :| _) = t
+
+at :: Alternative f =>
+      Axis k a -> Int ->
+      (Zipper k a -> f (Zipper k a))
+at axis i n =
+       case List.drop i (axis n) of
+        []  -> empty
+        a:_ -> pure a
+infixl 5 `at`
 
-zipper :: Trees k a -> Zipper k a
-zipper = Zipper []
+null :: Axis k a -> Zipper k a -> Bool
+null axis = List.null . axis
 
-zipper_root :: Zipper k a -> Trees k a
-zipper_root = zipper_curr . List.last . zipper_ancestor_or_self
+-- ** Type 'Node'
+data Node k a
+ =   Node
+ {   zip_prec :: Trees k a
+ ,   zip_self :: Tree  k a
+ ,   zip_foll :: Trees k a
+ } deriving (Eq, Show, Typeable)
 
-path_of_zipper :: Zipper k x -> [k]
-path_of_zipper z =
-       keyTree . zipper_step_self <$>
-       List.reverse (zipper_path z)
+-- * Type 'Axis'
+type Axis k a = Zipper k a -> [Zipper k a]
 
--- * Type 'Zipper_Step'
-data Zipper_Step k a
- =   Zipper_Step
- {   zipper_step_prec :: Trees k a
- ,   zipper_step_self :: Tree  k a
- ,   zipper_step_foll :: Trees k a
- } deriving (Eq, Show, Typeable)
+-- ** Type 'AxisAlt'
+-- | Like 'Axis', but generalized with 'Alternative'.
+--
+-- Useful to return a 'Maybe' instead of a list.
+type AxisAlt f k a = Alternative f => Zipper k a -> f (Zipper k a)
 
--- * Axis
 -- | Collect all 'Zipper's along a given axis,
 --   including the first 'Zipper'.
-zipper_collect :: (z -> Maybe z) -> z -> [z]
-zipper_collect f z = z : maybe [] (zipper_collect f) (f z)
+axis_collect :: (n -> Maybe n) -> n -> [n]
+axis_collect f n = n : maybe [] (axis_collect f) (f n)
 
 -- | Collect all 'Zipper's along a given axis,
 --   excluding the first 'Zipper'.
-zipper_collect_without_self :: (z -> Maybe z) -> z -> [z]
-zipper_collect_without_self f z = maybe [] (zipper_collect f) (f z)
+axis_collect_without_self :: (n -> Maybe n) -> n -> [n]
+axis_collect_without_self f n = maybe [] (axis_collect f) (f n)
 
 -- ** Axis self
-zipper_self :: Zipper k a -> [Tree k a]
-zipper_self (Zipper (Zipper_Step _ t _ : _) _) = [t]
-zipper_self _ = []
+axis_self :: Applicative f => Zipper k a -> f (Tree k a)
+axis_self (Node _ t _ :| _) = pure t
 
 -- ** Axis child
-zipper_child :: Zipper k a -> [Zipper k a]
-zipper_child z =
-       zipper_child_first z >>=
-       zipper_collect zipper_foll
-
-zipper_child_lookup ::
- Alternative f =>
- (k -> Bool) -> Zipper k a -> f (Zipper k a)
-zipper_child_lookup fk z = safeHead $ zipper_childs_lookup fk z
-
-zipper_childs_lookup ::
- (k -> Bool) -> Zipper k a -> [Zipper k a]
-zipper_childs_lookup fk (Zipper path ts) =
-       (<$> Seq.findIndicesL (\case TreeN k _ -> fk k; Tree0{} -> False) ts) $ \i ->
-               let (ps, ps') = Seq.splitAt i ts in
+axis_child :: Axis k a
+axis_child n =
+       axis_child_first n >>=
+       axis_collect axis_following_first
+
+axis_child_lookup_first :: (k -> Bool) -> AxisAlt f k a
+axis_child_lookup_first fk n = safeHead $ axis_child_lookup fk n
+
+axis_child_lookup :: (k -> Bool) -> Axis k a
+axis_child_lookup fk ns@(Node _ps t _fs :| _) =
+       (<$> Seq.findIndicesL flt cs) $ \i ->
+               let (ps, ps') = Seq.splitAt i cs in
                case Seq.viewl ps' of
                 EmptyL -> undefined
-                t :< fs ->
-                       Zipper
-                        { zipper_path = Zipper_Step ps t fs : path
-                        , zipper_curr = nodesTree t
-                        }
-
-zipper_child_first :: Alternative f => Zipper k a -> f (Zipper k a)
-zipper_child_first (Zipper path trees) =
-       case Seq.viewl trees of
+                l :< ls -> Node ps l ls :| NonEmpty.toList ns
+       where
+       cs = nodesTree t
+       flt (TreeN k _) = fk k
+       flt Tree0{}     = False
+
+axis_child_first :: AxisAlt f k a
+axis_child_first ns@(Node _ps t _fs :| _) =
+       case Seq.viewl $ nodesTree t of
         EmptyL -> empty
-        t :< ts -> pure $ Zipper
-                { zipper_path = Zipper_Step mempty t ts : path
-                , zipper_curr = nodesTree t
-                }
-
-zipper_child_last :: Alternative f => Zipper k a -> f (Zipper k a)
-zipper_child_last (Zipper path trees) =
-       case Seq.viewr trees of
+        l :< ls -> pure $ Node mempty l ls :| NonEmpty.toList ns
+
+axis_child_last :: AxisAlt f k a
+axis_child_last ns@(Node _ps t _fs :| _) =
+       case Seq.viewr $ nodesTree t of
         EmptyR -> empty
-        ts :> t -> pure $ Zipper
-                { zipper_path = Zipper_Step ts t mempty : path
-                , zipper_curr = nodesTree t
-                }
+        rs :> r -> pure $ Node rs r mempty :| NonEmpty.toList ns
 
 -- ** Axis ancestor
-zipper_ancestor :: Zipper k a -> [Zipper k a]
-zipper_ancestor = zipper_collect_without_self zipper_parent
+axis_ancestor :: Axis k a
+axis_ancestor = axis_collect_without_self axis_parent
 
-zipper_ancestor_or_self :: Zipper k a -> [Zipper k a]
-zipper_ancestor_or_self = zipper_collect zipper_parent
+axis_ancestor_or_self :: Axis k a
+axis_ancestor_or_self = axis_collect axis_parent
 
 -- ** Axis descendant
-zipper_descendant_or_self :: Zipper k a -> [Zipper k a]
-zipper_descendant_or_self =
+axis_descendant_or_self :: Axis k a
+axis_descendant_or_self =
        collect_child []
        where
-               collect_child acc z =
-                       z : maybe acc
-                        (collect_foll acc)
-                        (zipper_child_first z)
-               collect_foll  acc z =
-                       collect_child
-                        (maybe acc
-                                (collect_foll acc)
-                                (zipper_foll z)
-                        ) z
-
-zipper_descendant_or_self_reverse :: Zipper k a -> [Zipper k a]
-zipper_descendant_or_self_reverse z =
-       z : List.concatMap
-        zipper_descendant_or_self_reverse
-        (List.reverse $ zipper_child z)
-
-zipper_descendant :: Zipper k a -> [Zipper k a]
-zipper_descendant = List.tail . zipper_descendant_or_self
+       collect_child acc n =
+               n : maybe acc
+                (collect_following_first acc)
+                (axis_child_first n)
+       collect_following_first acc n =
+               collect_child
+                (maybe acc
+                        (collect_following_first acc)
+                        (axis_following_first n)
+                ) n
+
+axis_descendant_or_self_reverse :: Axis k a
+axis_descendant_or_self_reverse n =
+       n :
+       List.concatMap
+        axis_descendant_or_self_reverse
+        (List.reverse $ axis_child n)
+
+axis_descendant :: Axis k a
+axis_descendant = List.tail . axis_descendant_or_self
 
 -- ** Axis preceding
-zipper_prec :: Alternative f => Zipper k a -> f (Zipper k a)
-zipper_prec (Zipper [] _curr) = empty
-zipper_prec (Zipper (Zipper_Step ps c fs : path) _curr) =
+axis_preceding_first :: AxisAlt f k a
+axis_preceding_first (Node ps t fs :| ns) =
        case Seq.viewr ps of
         EmptyR -> empty
-        ts :> t -> pure Zipper
-                { zipper_path = Zipper_Step ts t (c <| fs) : path
-                , zipper_curr = nodesTree t
-                }
+        rs :> r -> pure $ Node rs r (t <| fs) :| ns
 
-zipper_preceding :: Zipper k a -> [Zipper k a]
-zipper_preceding =
-       zipper_ancestor_or_self >=>
-       zipper_preceding_sibling >=>
-       zipper_descendant_or_self_reverse
+axis_preceding_sibling :: Axis k a
+axis_preceding_sibling = axis_collect_without_self axis_preceding_first
 
-zipper_preceding_sibling :: Zipper k a -> [Zipper k a]
-zipper_preceding_sibling = zipper_collect_without_self zipper_prec
+axis_preceding :: Axis k a
+axis_preceding =
+       axis_ancestor_or_self >=>
+       axis_preceding_sibling >=>
+       axis_descendant_or_self_reverse
 
 -- ** Axis following
-zipper_foll :: Alternative f => Zipper k a -> f (Zipper k a)
-zipper_foll (Zipper [] _curr) = empty
-zipper_foll (Zipper (Zipper_Step ps c fs:path) _curr) =
+axis_following_first :: AxisAlt f k a
+axis_following_first (Node ps t fs :| ns) =
        case Seq.viewl fs of
         EmptyL -> empty
-        t :< ts -> pure $ Zipper
-                { zipper_path = Zipper_Step (ps |> c) t ts : path
-                , zipper_curr = nodesTree t
-                }
+        l :< ls -> pure $ Node (ps |> t) l ls :| ns
 
-zipper_following :: Zipper k a -> [Zipper k a]
-zipper_following =
-       zipper_ancestor_or_self >=>
-       zipper_following_sibling >=>
-       zipper_descendant_or_self
+axis_following_sibling :: Axis k a
+axis_following_sibling = axis_collect_without_self axis_following_first
 
-zipper_following_sibling :: Zipper k a -> [Zipper k a]
-zipper_following_sibling = zipper_collect_without_self zipper_foll
+axis_following :: Axis k a
+axis_following =
+       axis_ancestor_or_self >=>
+       axis_following_sibling >=>
+       axis_descendant_or_self
 
 -- ** Axis parent
-zipper_parent :: Alternative f => Zipper k a -> f (Zipper k a)
-zipper_parent (Zipper [] _) = empty
-zipper_parent (Zipper (Zipper_Step ps c fs : path) curr) =
-       pure Zipper
-        { zipper_path = path
-        , zipper_curr = (ps |> m) <> fs
-        }
-       where
-       m = case c of
-        TreeN k _ -> TreeN k curr
-        Tree0{} -> undefined
+axis_parent :: AxisAlt f k a
+axis_parent (Node ps t fs :| ns) =
+       case ns of
+        Node ps' (TreeN k _) fs' : ns' ->
+               pure $ Node ps' (TreeN k $ (ps |> t) <> fs) fs' :| ns'
+        _ -> empty
 
 -- ** Filter
-zipper_filter ::
- (Zipper k a -> [Zipper k a]) ->
- (Zipper k a -> Bool) ->
- (Zipper k a -> [Zipper k a])
-zipper_filter axis p z = List.filter p (axis z)
-infixl 5 `zipper_filter`
-
-zipper_at ::
- Alternative f =>
- (Zipper k a -> [Zipper k a]) -> Int ->
- (Zipper k a -> f (Zipper k a))
-zipper_at axis n z =
-       case List.drop n (axis z) of
-        []  -> empty
-        a:_ -> pure a
-infixl 5 `zipper_at`
-
-zipper_null ::
- (Zipper k a -> [Zipper k a]) ->
- Zipper k a -> Bool
-zipper_null axis = List.null . axis
+axis_filter :: Axis k a -> (Zipper k a -> Bool) -> Axis k a
+axis_filter axis p n = List.filter p (axis n)
+infixl 5 `axis_filter`
index 822faf86d37e0dbfc7b0c369b5ef848ab4a625fc..ba3f4c8cbec698a520f59446355231cd4737bb9c 100644 (file)
@@ -11,8 +11,11 @@ import Data.Default.Class (Default(..))
 import Data.Eq (Eq)
 import Data.Int (Int)
 import Data.Maybe (Maybe(..))
+import Data.Monoid (Monoid(..))
 import Data.Semigroup (Semigroup(..))
+import Data.Sequence (Seq)
 import Data.Text (Text)
+import Data.TreeSeq.Strict (Trees)
 import Text.Show (Show)
 
 import Language.XML
@@ -21,12 +24,12 @@ import Language.XML
 data Document
  =   Document
  {   head  :: Head
- ,   body  :: [Body]
+ ,   body  :: Body
  } deriving (Eq,Show)
 instance Default Document where
        def = Document
         { head  = def
-        , body  = def
+        , body  = mempty
         }
 
 -- * Type 'Head'
@@ -78,14 +81,20 @@ instance Semigroup About where
         }
 
 -- * Type 'Body'
-data Body
+type Body = Trees BodyKey (Seq BodyValue)
+
+-- ** Type 'BodyKey'
+data BodyKey
  = Section { attrs   :: CommonAttrs
            , title   :: Title
            , aliases :: [Alias]
-           , body    :: [Body]
            , pos     :: XmlPos
            }
- | ToC     { attrs :: CommonAttrs
+ deriving (Eq,Show)
+
+-- ** Type 'BodyValue'
+data BodyValue
+ = ToC     { attrs :: CommonAttrs
            , depth :: Maybe Nat
            , pos   :: XmlPos
            }
@@ -93,10 +102,16 @@ data Body
            , depth :: Maybe Nat
            , pos   :: XmlPos
            }
+ | Figure  { type_ :: Text
+           , attrs :: CommonAttrs
+           , title :: Title
+           , verts :: Verticals
+           , pos   :: XmlPos
+           }
  | Index   { attrs :: CommonAttrs
            , pos   :: XmlPos
            }
- | Verticals [Vertical]
+ | Vertical Vertical
  deriving (Eq,Show)
 
 -- * Type 'Vertical'
@@ -117,12 +132,6 @@ data Vertical
            , refs  :: [Reference]
            , pos   :: XmlPos
            }
- | Figure  { type_ :: Text
-           , attrs :: CommonAttrs
-           , title :: Title
-           , verts :: Verticals
-           , pos   :: XmlPos
-           }
  | Artwork { attrs :: CommonAttrs
            , art   :: Artwork
            , pos   :: XmlPos
index 89521e420007e3da87a178cab68be869136fd18d..2db066d4c98ce214ba6c7abe5e8a5b586873f989 100644 (file)
@@ -8,9 +8,11 @@ import Control.Applicative (Applicative(..), (<$>), (<$))
 import Control.Monad (void)
 import Data.Default.Class (Default(..))
 import Data.Foldable (Foldable, foldl', foldr)
-import Data.Function (($), flip)
+import Data.Function (($), (.), flip)
 import Data.Maybe (Maybe(..), maybe)
 import Data.Text (Text)
+import Data.TreeSeq.Strict (Tree(..))
+import qualified Data.Sequence as Seq
 import qualified Data.Text as Text
 
 import Language.XML
@@ -39,7 +41,10 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
        reference   :: repr DTC.Reference
        document    :: repr DTC.Document
        head        :: repr DTC.Head
-       body        :: repr [DTC.Body]
+       body        :: repr DTC.Body
+       bodyKey     :: repr DTC.BodyKey
+       bodyValue   :: repr DTC.BodyValue
+       figure      :: repr DTC.BodyValue
        about       :: repr DTC.About
        keyword     :: repr Text
        version     :: repr MayText
@@ -50,7 +55,6 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
        link        :: repr DTC.Link
        serie       :: repr DTC.Serie
        alias       :: repr DTC.Alias
-       figure      :: repr DTC.Vertical
        commonAttrs :: repr DTC.CommonAttrs
        commonAttrs =
                rule "commonAttrs" $
@@ -68,34 +72,39 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                 <$> optional (rule "about" $ element "about" about)
        body =
                rule "body" $
+               (Seq.fromList <$>) $
                many $
                        choice
-                        [ rule "section" $
-                               element "section" $
-                               position $
-                               DTC.Section
-                                <$> commonAttrs
-                                <*> title
-                                <*> many alias
-                                <*> body
-                        , element "toc" $
-                               position $
-                               DTC.ToC
-                                <$> commonAttrs
-                                <*> optional (attribute "depth" nat)
-                        , element "tof" $
-                               position $
-                               DTC.ToF
-                                <$> commonAttrs
-                                <*> optional (attribute "depth" nat)
-                        , element "index" $
-                               position $
-                               DTC.Index
-                                <$> commonAttrs
-                                <*  any
-                        , DTC.Verticals
-                                <$> some vertical
+                        [ rule "section" $ element "section" $ TreeN <$> bodyKey <*> body
+                        , Tree0 . Seq.fromList <$> some bodyValue
                         ]
+       bodyKey =
+               position $
+               DTC.Section
+                <$> commonAttrs
+                <*> title
+                <*> many alias
+       bodyValue =
+               choice
+                [ element "toc" $
+                       position $
+                       DTC.ToC
+                        <$> commonAttrs
+                        <*> optional (attribute "depth" nat)
+                , element "tof" $
+                       position $
+                       DTC.ToF
+                        <$> commonAttrs
+                        <*> optional (attribute "depth" nat)
+                , element "index" $
+                       position $
+                       DTC.Index
+                        <$> commonAttrs
+                        <*  any
+                , figure
+                , DTC.Vertical
+                        <$> vertical
+                ]
        title = rule "title" $ DTC.Title <$> element "title" horizontals
        name  = rule "name"  $ attribute "name" text
        url   = rule "url"   $ URL   <$> text
@@ -138,7 +147,6 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                        DTC.RL
                         <$> commonAttrs
                         <*> many reference
-                , figure
                 {-
                 , anyElem $ \n@XmlName{..} ->
                                case xmlNameSpace of
index 0b600be3525fbff8f00c6ff48a00b77ead1bb49b..9cf2108298d106ee750b3c30fd7051f1b95972c3 100644 (file)
@@ -24,7 +24,7 @@ module Language.DTC.Write.HTML5 where
 -- import Prelude (Num(..), undefined)
 -- import qualified Control.Monad.Trans.State as S
 -- import qualified Data.Map.Strict as Map
-import Control.Monad (forM_, mapM_, when)
+import Control.Monad (forM_, mapM_, when, (>=>))
 import Data.Eq (Eq(..))
 import Data.Ord (Ord(..))
 import Data.Foldable (Foldable(..))
@@ -34,18 +34,22 @@ import Data.Int (Int)
 import Data.Maybe (Maybe(..))
 import Data.Monoid (Monoid(..))
 import Data.Semigroup (Semigroup(..))
+import Data.Sequence (Seq)
 import Data.Text (Text)
 import Data.Tuple (snd)
 import Prelude (Num(..))
 import Text.Blaze ((!))
 import Text.Blaze.Html (Html)
 import Text.Show (Show(..))
+import Data.TreeSeq.Strict (Tree(..))
 import qualified Data.List as List
 import qualified Data.Text as Text
 import qualified Data.Text.Lazy as TL
 import qualified Text.Blaze.Html5 as H
 import qualified Text.Blaze.Html5.Attributes  as HA
 import qualified Text.Blaze.Internal as H
+-- import qualified Data.TreeSeq.Strict as Tree
+import qualified Data.TreeSeq.Strict.Zipper as Tree
 
 import Text.Blaze.Utils
 
@@ -59,6 +63,8 @@ import qualified Language.DTC.Document as DTC
 
 instance H.ToMarkup DTC.Ident where
        toMarkup (DTC.Ident i) = H.toMarkup i
+instance H.ToMarkup DTC.Title where
+       toMarkup (DTC.Title t) = html5Horizontals t
 instance AttrValue XmlPos where
        attrValue = attrValue . textXmlPosAncestors . xmlPosAncestors
 
@@ -135,7 +141,7 @@ html5Document loc DTC.Document{..} = do
                        H.meta ! HA.httpEquiv "Content-Type"
                               ! HA.content "text/html; charset=UTF-8"
                        whenSome (DTC.titles $ DTC.about (head :: DTC.Head)) $ \ts ->
-                               let t = textHorizontals $ List.head $ (DTC.unTitle <$> ts) <> [[DTC.Plain ""]] in
+                               let t = H.toMarkup $ List.head $ ts <> [DTC.Title [DTC.Plain ""]] in
                                H.title $ H.toMarkup t
                        -- link ! rel "Chapter" ! title "SomeTitle">
                        H.link ! HA.rel "stylesheet"
@@ -144,11 +150,23 @@ html5Document loc DTC.Document{..} = do
                H.body $
                        html5Body inh body
 
-html5Body :: InhHtml5 -> [DTC.Body] -> Html
-html5Body _inh [] = mempty
-html5Body inh@InhHtml5{..} (b:bs) =
-       case b of
-        DTC.Section{..} -> do
+-- * Type 'BodyZip'
+type BodyZip = Tree.Zipper DTC.BodyKey (Seq DTC.BodyValue)
+
+html5Body :: InhHtml5 -> DTC.Body -> Html
+html5Body inh body =
+       forM_ (Tree.zippers body) $
+               html5BodyZipper inh
+
+html5BodyZipper :: InhHtml5 -> BodyZip -> Html
+html5BodyZipper inh z =
+       case Tree.current z of
+        TreeN k _ts -> html5BodyKey inh z k
+        Tree0 vs -> forM_ vs $ html5BodyValue inh z
+
+html5BodyKey :: InhHtml5 -> BodyZip -> DTC.BodyKey -> Html
+html5BodyKey inh z = \case
+        DTC.Section{..} ->
                H.section
                 ! HA.class_ "section"
                 ! HA.id (attrValue pos) $ do
@@ -159,14 +177,14 @@ html5Body inh@InhHtml5{..} (b:bs) =
                                                        H.td ! HA.class_ "section-number" $ do
                                                                html5SectionNumber $ xmlPosAncestors pos
                                                        H.td ! HA.class_ "section-title" $ do
-                                                               html5Horizontals $ DTC.unTitle title
-                       html5Body inh body
-               html5Body inh bs
-               {- aliases :: [Alias]
-               -}
-        DTC.Verticals vs -> do
-               html5Verticals vs
-               html5Body inh bs
+                                                               H.toMarkup title
+                       forM_ (Tree.axis_child z) $
+                               html5BodyZipper inh
+
+html5BodyValue :: InhHtml5 -> BodyZip -> DTC.BodyValue -> Html
+html5BodyValue InhHtml5{..} z = \ case
+        DTC.Vertical v -> do
+               html5Vertical v
         DTC.ToC{..} -> do
                H.nav ! HA.class_ "toc"
                      ! HA.id (attrValue pos) $ do
@@ -174,20 +192,36 @@ html5Body inh@InhHtml5{..} (b:bs) =
                                H.a ! HA.href (attrValue pos) $
                                        inhHtml5_localize MsgHTML5_Table_of_Contents
                        H.ul $
-                               html5ToC d bs
-               html5Body inh bs
+                               forM_ (Tree.axis_following_sibling z) $
+                                       html5ToC d
                where d = case depth of { Just (DTC.Nat n) -> n; _ -> 0 }
         DTC.ToF{..} -> do
                H.nav ! HA.class_ "tof"
                      ! HA.id (attrValue pos) $
-                       ""
-               html5Body inh bs
+                       H.table ! HA.class_ "tof" $
+                               H.tbody $
+                                       forM_ (Tree.axis_preceding z) $
+                                               html5ToF d
+               where d = case depth of { Just (DTC.Nat n) -> n; _ -> 0 }
+        DTC.Figure{..} ->
+               html5CommonAttrs attrs $
+               H.div ! HA.class_ (attrValue $ "figure-"<>type_)
+                     ! HA.id (attrValue pos) $ do
+                       H.table ! HA.class_ "figure-caption" $
+                               H.tbody $
+                                       H.tr $ do
+                                               H.td ! HA.class_ "figure-number" $ do
+                                                       H.a ! HA.href "" $ H.toMarkup type_
+                                                       ": "
+                                               H.td ! HA.class_ "figure-name" $
+                                                       H.toMarkup title
+                       H.div ! HA.class_ "figure-content" $ do
+                               html5Verticals verts
 
-html5ToC :: Int -> [DTC.Body] -> Html
-html5ToC _depth [] = mempty
-html5ToC depth (b:bs) =
-       case b of
-        DTC.Section{..} -> do
+html5ToC :: Int -> BodyZip -> Html
+html5ToC depth z =
+       case Tree.current z of
+        TreeN DTC.Section{..} _ts -> do
                H.li $ do
                        H.table ! HA.class_ "toc-entry" $
                                H.tbody $
@@ -195,11 +229,27 @@ html5ToC depth (b:bs) =
                                                H.td $
                                                        html5SectionRef $ xmlPosAncestors pos
                                                H.td $
-                                                       html5Horizontals $ DTC.unTitle title
+                                                       H.toMarkup title
                        when (depth > 0) $
-                               H.ul $ html5ToC (depth - 1) body
-               html5ToC depth bs
-        _ -> html5ToC depth bs
+                               H.ul $
+                                       forM_ (Tree.axis_child z) $
+                                               html5ToC (depth - 1)
+        _ -> mempty
+
+html5ToF :: Int -> BodyZip -> Html
+html5ToF depth z =
+       case Tree.current z of
+        Tree0 bs ->
+               forM_ bs $ \case
+                DTC.Figure{..} ->
+                       H.tr $ do
+                               H.td ! HA.class_ "figure-number" $
+                                       H.a ! HA.href (attrValue pos) $
+                                               H.toMarkup type_
+                               H.td ! HA.class_ "figure-name" $
+                                       H.toMarkup title
+                _ -> mempty
+        _ -> mempty
 
 textXmlPosAncestors :: [(XmlName,Int)] -> Text
 textXmlPosAncestors =
@@ -268,20 +318,6 @@ html5Vertical = \case
                                forM_ refs html5Reference
         DTC.Comment t ->
                H.Comment (H.Text t) ()
-        DTC.Figure{..} ->
-               html5CommonAttrs attrs $
-               H.div ! HA.class_ (attrValue $ "figure-"<>type_)
-                     ! HA.id (attrValue pos) $ do
-                       H.table ! HA.class_ "figure-caption" $
-                               H.tbody $
-                                       H.tr $ do
-                                               H.td ! HA.class_ "figure-number" $ do
-                                                       H.a ! HA.href "" $ H.toMarkup type_
-                                                       ": "
-                                               H.td ! HA.class_ "figure-name" $
-                                                       html5Horizontals $ DTC.unTitle title
-                       H.div ! HA.class_ "figure-content" $ do
-                               html5Verticals verts
        {-
         Index{..} -> 
         Artwork{..} -> 
index 6092b4de2f50b4ca69d34448db73a6b7d93d2d8c..0f0b20011d2ceef64f0fc279caecb3ffaf88c03f 100644 (file)
@@ -14,6 +14,7 @@ import Data.Text (Text)
 import Text.Blaze ((!))
 import Text.Blaze.Utils
 import Text.Blaze.XML (XML)
+import Data.TreeSeq.Strict (Tree(..))
 import qualified Data.Char as Char
 import qualified Data.Map.Strict as Map
 import qualified Data.Text as Text
@@ -44,15 +45,22 @@ xmlHead :: DTC.Head -> XML
 xmlHead DTC.Head{..} =
        XML.about $ xmlAbout about
 
-xmlBody :: [DTC.Body] -> XML
+xmlBody :: DTC.Body -> XML
 xmlBody = mapM_ $ \case
-        DTC.Verticals vs -> xmlVerticals vs
+        TreeN k ts -> xmlBodyKey k $ xmlBody ts
+        Tree0 vs -> xmlBodyValue `mapM_` vs
+
+xmlBodyKey :: DTC.BodyKey -> XML -> XML
+xmlBodyKey k body = case k of
         DTC.Section{..} ->
                xmlCommonAttrs attrs $
                XML.section $ do
                        xmlTitle title
                        forM_ aliases xmlAlias
-                       xmlBody body
+                       body
+
+xmlBodyValue :: DTC.BodyValue -> XML
+xmlBodyValue = \case
         DTC.ToC{..} ->
                xmlCommonAttrs attrs $
                XML.toc
@@ -61,6 +69,13 @@ xmlBody = mapM_ $ \case
                xmlCommonAttrs attrs $
                XML.tof
                 !?? mayAttr XA.depth depth
+        DTC.Figure{..} ->
+               xmlCommonAttrs attrs $
+               XML.figure
+                ! XA.type_ (attrValue type_) $ do
+                       xmlTitle title
+                       xmlVerticals verts
+        DTC.Vertical v -> xmlVertical v
 
 xmlAbout :: DTC.About -> XML
 xmlAbout DTC.About{..} = do
@@ -159,12 +174,6 @@ xmlVertical = \case
                xmlCommonAttrs attrs $
                XML.rl $ forM_ refs $ xmlReference
         -- DTC.Index -> XML.index
-        DTC.Figure{..} ->
-               xmlCommonAttrs attrs $
-               XML.figure
-                ! XA.type_ (attrValue type_) $ do
-                       xmlTitle title
-                       xmlVerticals verts
         DTC.Comment c ->
                XML.comment c
         DTC.Artwork{..} ->