    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {- |
       Module      : Text.Pandoc.Chunks
       Copyright   : Copyright (C) 2022-2024 John MacFarlane
       License     : GNU GPL, version 2 or above

       Maintainer  : John MacFarlane <jgm@berkeley.edu>
       Stability   : alpha
       Portability : portable

    Functions and types for splitting a Pandoc into subdocuments,
    e.g. for conversion into a set of HTML pages.
    -}
    module Text.Pandoc.Chunks
      ( Chunk(..)
      , ChunkedDoc(..)
      , PathTemplate(..)
      , splitIntoChunks
      , toTOCTree
      , tocToList
      , SecInfo(..)
      ) where

    import Text.Pandoc.Definition
    import Text.Pandoc.Shared (makeSections, stringify, inlineListToIdentifier,
                               tshow, uniqueIdent)
    import Text.Pandoc.Walk (Walkable(..), query)
    import Data.Aeson (FromJSON, ToJSON)
    import Data.Text (Text)
    import Text.Printf (printf)
    import Data.Maybe (fromMaybe, isNothing)
    import qualified Data.Map as M
    import qualified Data.Text as T
    import Data.String (IsString)
    import GHC.Generics (Generic)
    import Text.HTML.TagSoup (Tag (TagOpen), fromAttrib, parseTags)
    import Data.Tree (Tree(..))
    import Data.Data (Data)
    import Data.Typeable (Typeable)
    import qualified Data.Set as Set
    import Control.Monad.State

    -- | Split 'Pandoc' into 'Chunk's, e.g. for conversion into
    -- a set of HTML pages or EPUB chapters.
    splitIntoChunks :: PathTemplate -- ^ Template for filepath
                    -> Bool -- ^ Number sections
                    -> Maybe Int -- ^ Base heading level
                    -> Int -- ^ Chunk level -- level of section to split at
                    -> Pandoc
                    -> ChunkedDoc
    splitIntoChunks :: PathTemplate -> Bool -> Maybe Int -> Int -> Pandoc -> ChunkedDoc
    splitIntoChunks PathTemplate
    pathTemplate Bool
    numberSections Maybe Int
    mbBaseLevel
                    Int
    chunklev (Pandoc Meta
    meta [Block]
    blocks) =
       ChunkedDoc -> ChunkedDoc
    addNav (ChunkedDoc -> ChunkedDoc)
    -> (ChunkedDoc -> ChunkedDoc) -> ChunkedDoc -> ChunkedDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
       ChunkedDoc -> ChunkedDoc
    fixInternalReferences (ChunkedDoc -> ChunkedDoc)
    -> (ChunkedDoc -> ChunkedDoc) -> ChunkedDoc -> ChunkedDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
       (Block -> Block) -> ChunkedDoc -> ChunkedDoc
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Block -> Block
    rmNavAttrs (ChunkedDoc -> ChunkedDoc) -> ChunkedDoc -> ChunkedDoc
    forall a b. (a -> b) -> a -> b
    $
       ChunkedDoc{ chunkedMeta :: Meta
    chunkedMeta = Meta
    meta
                 , chunkedChunks :: [Chunk]
    chunkedChunks = [Chunk]
    chunks
                 , chunkedTOC :: Tree SecInfo
    chunkedTOC = Tree SecInfo
    tocTree }
     where
      tocTree :: Tree SecInfo
    tocTree = [Chunk] -> Tree SecInfo -> Tree SecInfo
    fixTOCTreePaths [Chunk]
    chunks (Tree SecInfo -> Tree SecInfo) -> Tree SecInfo -> Tree SecInfo
    forall a b. (a -> b) -> a -> b
    $ [Block] -> Tree SecInfo
    toTOCTree [Block]
    sections
      chunks :: [Chunk]
    chunks = Int -> PathTemplate -> Meta -> [Block] -> [Chunk]
    makeChunks Int
    chunklev PathTemplate
    pathTemplate Meta
    meta ([Block] -> [Chunk]) -> [Block] -> [Chunk]
    forall a b. (a -> b) -> a -> b
    $ [Block]
    sections
      sections :: [Block]
    sections = [Block] -> [Block]
    ensureIds ([Block] -> [Block]) -> [Block] -> [Block]
    forall a b. (a -> b) -> a -> b
    $ Bool -> Maybe Int -> [Block] -> [Block]
    makeSections Bool
    numberSections Maybe Int
    mbBaseLevel [Block]
    blocks

    -- The TOC won't work if we don't have unique identifiers for all sections.
    ensureIds :: [Block] -> [Block]
    ensureIds :: [Block] -> [Block]
    ensureIds [Block]
    bs = State (Set Text) [Block] -> Set Text -> [Block]
    forall s a. State s a -> s -> a
    evalState ((Block -> StateT (Set Text) Identity Block)
    -> [Block] -> State (Set Text) [Block]
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Block -> m Block) -> [Block] -> m [Block]
    walkM Block -> StateT (Set Text) Identity Block
    go [Block]
    bs) Set Text
    forall a. Monoid a => a
    mempty
     where
       go :: Block -> State (Set.Set Text) Block
       go :: Block -> StateT (Set Text) Identity Block
    go b :: Block
    b@(Div (Text
    ident,Text
    "section":[Text]
    cls,[(Text, Text)]
    kvs) bs' :: [Block]
    bs'@(Header Int
    _ (Text, [Text], [(Text, Text)])
    _ [Inline]
    ils : [Block]
    _))
         | Text -> Bool
    T.null Text
    ident
           = do ids <- StateT (Set Text) Identity (Set Text)
    forall s (m :: * -> *). MonadState s m => m s
    get
                let newid = Extensions -> [Inline] -> Set Text -> Text
    uniqueIdent Extensions
    forall a. Monoid a => a
    mempty [Inline]
    ils Set Text
    ids
                modify $ Set.insert newid
                pure $ Div (newid,"section":cls,kvs) bs'
         | Bool
    otherwise
           = do (Set Text -> Set Text) -> StateT (Set Text) Identity ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((Set Text -> Set Text) -> StateT (Set Text) Identity ())
    -> (Set Text -> Set Text) -> StateT (Set Text) Identity ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Set Text -> Set Text
    forall a. Ord a => a -> Set a -> Set a
    Set.insert Text
    ident
                Block -> StateT (Set Text) Identity Block
    forall a. a -> StateT (Set Text) Identity a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Block
    b
       go Block
    b = Block -> StateT (Set Text) Identity Block
    forall a. a -> StateT (Set Text) Identity a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Block
    b

    -- | Add chunkNext, chunkPrev, chunkUp
    addNav :: ChunkedDoc -> ChunkedDoc
    addNav :: ChunkedDoc -> ChunkedDoc
    addNav ChunkedDoc
    chunkedDoc =
      ChunkedDoc
    chunkedDoc{ chunkedChunks =
         addNext . addPrev . addUp $ chunkedChunks chunkedDoc }

    addUp :: [Chunk] -> [Chunk]
    addUp :: [Chunk] -> [Chunk]
    addUp (Chunk
    c : Chunk
    d : [Chunk]
    ds)
      | Chunk -> Int
    chunkLevel Chunk
    c Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Chunk -> Int
    chunkLevel Chunk
    d
        = Chunk
    c Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk] -> [Chunk]
    addUp (Chunk
    d{ chunkUp = Just c } Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk]
    ds)
      | Chunk -> Int
    chunkLevel Chunk
    c Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Chunk -> Int
    chunkLevel Chunk
    d
        = Chunk
    c Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk] -> [Chunk]
    addUp (Chunk
    d{ chunkUp = chunkUp c} Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk]
    ds)
    addUp (Chunk
    c:[Chunk]
    cs) = Chunk
    c Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    : [Chunk] -> [Chunk]
    addUp [Chunk]
    cs
    addUp [] = []

    addNext :: [Chunk] -> [Chunk]
    addNext :: [Chunk] -> [Chunk]
    addNext [Chunk]
    cs = (Chunk -> Maybe Chunk -> Chunk)
    -> [Chunk] -> [Maybe Chunk] -> [Chunk]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith Chunk -> Maybe Chunk -> Chunk
    go [Chunk]
    cs ((Chunk -> Maybe Chunk) -> [Chunk] -> [Maybe Chunk]
    forall a b. (a -> b) -> [a] -> [b]
    map Chunk -> Maybe Chunk
    forall a. a -> Maybe a
    Just (Int -> [Chunk] -> [Chunk]
    forall a. Int -> [a] -> [a]
    drop Int
    1 [Chunk]
    cs) [Maybe Chunk] -> [Maybe Chunk] -> [Maybe Chunk]
    forall a. [a] -> [a] -> [a]
    ++ [Maybe Chunk
    forall a. Maybe a
    Nothing])
     where
      go :: Chunk -> Maybe Chunk -> Chunk
    go Chunk
    c Maybe Chunk
    nxt = Chunk
    c{ chunkNext = nxt }

    addPrev :: [Chunk] -> [Chunk]
    addPrev :: [Chunk] -> [Chunk]
    addPrev [Chunk]
    cs = (Chunk -> Maybe Chunk -> Chunk)
    -> [Chunk] -> [Maybe Chunk] -> [Chunk]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith Chunk -> Maybe Chunk -> Chunk
    go [Chunk]
    cs (Maybe Chunk
    forall a. Maybe a
    Nothing Maybe Chunk -> [Maybe Chunk] -> [Maybe Chunk]
    forall a. a -> [a] -> [a]
    : (Chunk -> Maybe Chunk) -> [Chunk] -> [Maybe Chunk]
    forall a b. (a -> b) -> [a] -> [b]
    map Chunk -> Maybe Chunk
    forall a. a -> Maybe a
    Just [Chunk]
    cs)
     where
      go :: Chunk -> Maybe Chunk -> Chunk
    go Chunk
    c Maybe Chunk
    prev = Chunk
    c{ chunkPrev = prev }

    -- | Fix internal references so they point to the path of the chunk.
    fixInternalReferences :: ChunkedDoc -> ChunkedDoc
    fixInternalReferences :: ChunkedDoc -> ChunkedDoc
    fixInternalReferences ChunkedDoc
    chunkedDoc = (Inline -> Inline) -> ChunkedDoc -> ChunkedDoc
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Inline -> Inline
    fixInternalRefs ChunkedDoc
    chunkedDoc
     where
      fixInternalRefs :: Inline -> Inline
      fixInternalRefs :: Inline -> Inline
    fixInternalRefs il :: Inline
    il@(Link (Text, [Text], [(Text, Text)])
    attr [Inline]
    ils (Text
    src,Text
    tit))
        = case Text -> Maybe (Char, Text)
    T.uncons Text
    src of
            Just (Char
    '#', Text
    ident) -> (Text, [Text], [(Text, Text)])
    -> [Inline] -> (Text, Text) -> Inline
    Link (Text, [Text], [(Text, Text)])
    attr [Inline]
    ils (Text
    src', Text
    tit)
              where src' :: Text
    src' = case Text -> Map Text Chunk -> Maybe Chunk
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup Text
    ident Map Text Chunk
    refMap of
                             Just Chunk
    chunk -> String -> Text
    T.pack (Chunk -> String
    chunkPath Chunk
    chunk) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src
                             Maybe Chunk
    Nothing -> Text
    src
            Maybe (Char, Text)
    _ -> Inline
    il
      fixInternalRefs Inline
    il = Inline
    il

      refMap :: Map Text Chunk
    refMap = (Chunk -> Map Text Chunk -> Map Text Chunk)
    -> Map Text Chunk -> [Chunk] -> Map Text Chunk
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Chunk -> Map Text Chunk -> Map Text Chunk
    chunkToRefs Map Text Chunk
    forall a. Monoid a => a
    mempty (ChunkedDoc -> [Chunk]
    chunkedChunks ChunkedDoc
    chunkedDoc)

      chunkToRefs :: Chunk -> Map Text Chunk -> Map Text Chunk
    chunkToRefs Chunk
    chunk Map Text Chunk
    m =
        let idents :: [Text]
    idents = Chunk -> Text
    chunkId Chunk
    chunk Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    : [Block] -> [Text]
    forall {b}. (Walkable Block b, Walkable Inline b) => b -> [Text]
    getIdents (Chunk -> [Block]
    chunkContents Chunk
    chunk)
        in  (Text -> Map Text Chunk -> Map Text Chunk)
    -> Map Text Chunk -> [Text] -> Map Text Chunk
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Text
    ident -> Text -> Chunk -> Map Text Chunk -> Map Text Chunk
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert Text
    ident Chunk
    chunk) Map Text Chunk
    m [Text]
    idents

      getIdents :: b -> [Text]
    getIdents b
    bs = (Block -> [Text]) -> b -> [Text]
    forall c. Monoid c => (Block -> c) -> b -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Block -> [Text]
    getBlockIdent b
    bs [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ (Inline -> [Text]) -> b -> [Text]
    forall c. Monoid c => (Inline -> c) -> b -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Inline -> [Text]
    getInlineIdent b
    bs

      getBlockIdent :: Block -> [Text]
      getBlockIdent :: Block -> [Text]
    getBlockIdent (Div (Text
    ident, [Text]
    _, [(Text, Text)]
    _) [Block]
    _)
        | Bool -> Bool
    not (Text -> Bool
    T.null Text
    ident) = [Text
    ident]
      getBlockIdent (Header Int
    _ (Text
    ident, [Text]
    _, [(Text, Text)]
    _) [Inline]
    _)
        | Bool -> Bool
    not (Text -> Bool
    T.null Text
    ident) = [Text
    ident]
      getBlockIdent (Table (Text
    ident,[Text]
    _,[(Text, Text)]
    _) Caption
    _ [ColSpec]
    _ TableHead
    _ [TableBody]
    _ TableFoot
    _)
        | Bool -> Bool
    not (Text -> Bool
    T.null Text
    ident) = [Text
    ident]
      getBlockIdent (RawBlock Format
    fmt Text
    raw)
        | Format -> Bool
    isHtmlFormat Format
    fmt
        = (Tag Text -> [Text] -> [Text]) -> [Text] -> [Tag Text] -> [Text]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Tag Text
    tag ->
                    case Tag Text
    tag of
                      TagOpen{} ->
                        case Text -> Tag Text -> Text
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib Text
    "id" Tag Text
    tag of
                          Text
    "" -> [Text] -> [Text]
    forall a. a -> a
    id
                          Text
    x  -> (Text
    xText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :)
                      Tag Text
    _ -> [Text] -> [Text]
    forall a. a -> a
    id)
            [] (Text -> [Tag Text]
    forall str. StringLike str => str -> [Tag str]
    parseTags Text
    raw)
      getBlockIdent Block
    _ = []

      getInlineIdent :: Inline -> [Text]
      getInlineIdent :: Inline -> [Text]
    getInlineIdent (Span (Text
    ident, [Text]
    _, [(Text, Text)]
    _) [Inline]
    _)
        | Bool -> Bool
    not (Text -> Bool
    T.null Text
    ident) = [Text
    ident]
      getInlineIdent (Link (Text
    ident, [Text]
    _, [(Text, Text)]
    _) [Inline]
    _ (Text, Text)
    _)
        | Bool -> Bool
    not (Text -> Bool
    T.null Text
    ident) = [Text
    ident]
      getInlineIdent (Image (Text
    ident, [Text]
    _, [(Text, Text)]
    _) [Inline]
    _ (Text, Text)
    _)
        | Bool -> Bool
    not (Text -> Bool
    T.null Text
    ident) = [Text
    ident]
      getInlineIdent (RawInline Format
    fmt Text
    raw)
        | Format -> Bool
    isHtmlFormat Format
    fmt
        = (Tag Text -> [Text] -> [Text]) -> [Text] -> [Tag Text] -> [Text]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Tag Text
    tag ->
                    case Tag Text
    tag of
                      TagOpen{} ->
                        case Text -> Tag Text -> Text
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib Text
    "id" Tag Text
    tag of
                          Text
    "" -> [Text] -> [Text]
    forall a. a -> a
    id
                          Text
    x  -> (Text
    xText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :)
                      Tag Text
    _ -> [Text] -> [Text]
    forall a. a -> a
    id)
            [] (Text -> [Tag Text]
    forall str. StringLike str => str -> [Tag str]
    parseTags Text
    raw)
      getInlineIdent Inline
    _ = []

      isHtmlFormat :: Format -> Bool
      isHtmlFormat :: Format -> Bool
    isHtmlFormat (Format Text
    "html") = Bool
    True
      isHtmlFormat (Format Text
    "html4") = Bool
    True
      isHtmlFormat (Format Text
    "html5") = Bool
    True
      isHtmlFormat Format
    _ = Bool
    False

    makeChunks :: Int -> PathTemplate -> Meta -> [Block] -> [Chunk]
    makeChunks :: Int -> PathTemplate -> Meta -> [Block] -> [Chunk]
    makeChunks Int
    chunklev PathTemplate
    pathTemplate Meta
    meta = Int -> [Block] -> [Chunk]
    secsToChunks Int
    1
     where
      isChunkHeader :: Block -> Bool
      isChunkHeader :: Block -> Bool
    isChunkHeader (Div (Text
    _,Text
    "section":[Text]
    _,[(Text, Text)]
    _) (Header Int
    n (Text, [Text], [(Text, Text)])
    _ [Inline]
    _:[Block]
    _)) = Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    chunklev
      isChunkHeader Block
    _ = Bool
    False

      secsToChunks :: Int -> [Block] -> [Chunk]
      secsToChunks :: Int -> [Block] -> [Chunk]
    secsToChunks Int
    chunknum [Block]
    bs =
        case (Block -> Bool) -> [Block] -> ([Block], [Block])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Block -> Bool
    isChunkHeader [Block]
    bs of
          ([], []) -> []
          ([], (d :: Block
    d@(Div attr :: (Text, [Text], [(Text, Text)])
    attr@(Text
    _,Text
    "section":[Text]
    _,[(Text, Text)]
    _) (h :: Block
    h@(Header Int
    lvl (Text, [Text], [(Text, Text)])
    _ [Inline]
    _) : [Block]
    bs')) : [Block]
    rest))
            | Int
    chunklev Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    lvl ->
              -- If the header is of the same level as chunks, create a chunk
              Int -> Block -> Chunk
    toChunk Int
    chunknum Block
    d Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    :
                Int -> [Block] -> [Chunk]
    secsToChunks (Int
    chunknum Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) [Block]
    rest
            | Int
    chunklev Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    lvl ->
              case (Block -> Bool) -> [Block] -> ([Block], [Block])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Block -> Bool
    isChunkHeader [Block]
    bs' of
                ([Block]
    xs, [Block]
    ys) -> Int -> Block -> Chunk
    toChunk Int
    chunknum ((Text, [Text], [(Text, Text)]) -> [Block] -> Block
    Div (Text, [Text], [(Text, Text)])
    attr (Block
    hBlock -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    :[Block]
    xs)) Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    :
                              Int -> [Block] -> [Chunk]
    secsToChunks (Int
    chunknum Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) ([Block]
    ys [Block] -> [Block] -> [Block]
    forall a. [a] -> [a] -> [a]
    ++ [Block]
    rest)
          ([Block]
    xs, [Block]
    ys) -> Int -> Block -> Chunk
    toChunk Int
    chunknum
                         ((Text, [Text], [(Text, Text)]) -> [Block] -> Block
    Div (Text
    "",[Text
    "preamble"],[]) [Block]
    xs) Chunk -> [Chunk] -> [Chunk]
    forall a. a -> [a] -> [a]
    :
                        Int -> [Block] -> [Chunk]
    secsToChunks (Int
    chunknum Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) [Block]
    ys

      toChunk :: Int -> Block -> Chunk
      toChunk :: Int -> Block -> Chunk
    toChunk Int
    chunknum
        (Div (Text
    divid,Text
    "section":[Text]
    classes,[(Text, Text)]
    kvs) (h :: Block
    h@(Header Int
    lvl (Text, [Text], [(Text, Text)])
    _ [Inline]
    ils) : [Block]
    bs)) =
        Chunk
          { chunkHeading :: [Inline]
    chunkHeading = [Inline]
    ils
          , chunkId :: Text
    chunkId = Text
    divid
          , chunkLevel :: Int
    chunkLevel = Int
    lvl
          , chunkNumber :: Int
    chunkNumber = Int
    chunknum
          , chunkSectionNumber :: Maybe Text
    chunkSectionNumber = Maybe Text
    secnum
          , chunkPath :: String
    chunkPath = String
    chunkpath
          , chunkUp :: Maybe Chunk
    chunkUp = Maybe Chunk
    forall a. Maybe a
    Nothing
          , chunkNext :: Maybe Chunk
    chunkNext = Maybe Chunk
    forall a. Maybe a
    Nothing
          , chunkPrev :: Maybe Chunk
    chunkPrev = Maybe Chunk
    forall a. Maybe a
    Nothing
          , chunkUnlisted :: Bool
    chunkUnlisted = Text
    "unlisted" Text -> [Text] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    classes
          , chunkContents :: [Block]
    chunkContents =
             [(Text, [Text], [(Text, Text)]) -> [Block] -> Block
    Div (Text
    divid,Text
    "section"Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    classes,[(Text, Text)]
    kvs') (Block
    h Block -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    : [Block]
    bs)]
          }
         where kvs' :: [(Text, Text)]
    kvs' = [(Text, Text)]
    kvs [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. [a] -> [a] -> [a]
    ++ [(Text
    "nav-path", String -> Text
    T.pack String
    chunkpath)]
               secnum :: Maybe Text
    secnum = Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    "number" [(Text, Text)]
    kvs
               chunkpath :: String
    chunkpath = PathTemplate -> Int -> Text -> Text -> Text -> String
    resolvePathTemplate PathTemplate
    pathTemplate Int
    chunknum
                            ([Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Inline]
    ils)
                            Text
    divid
                            (Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    "" Maybe Text
    secnum)
      toChunk Int
    chunknum (Div (Text
    "",[Text
    "preamble"],[]) [Block]
    bs) =
          Chunk
          { chunkHeading :: [Inline]
    chunkHeading = Meta -> [Inline]
    docTitle Meta
    meta
          , chunkId :: Text
    chunkId = Text
    chunkid
          , chunkLevel :: Int
    chunkLevel = Int
    0
          , chunkNumber :: Int
    chunkNumber = Int
    chunknum
          , chunkSectionNumber :: Maybe Text
    chunkSectionNumber = Maybe Text
    forall a. Maybe a
    Nothing
          , chunkPath :: String
    chunkPath = String
    chunkpath
          , chunkUp :: Maybe Chunk
    chunkUp = Maybe Chunk
    forall a. Maybe a
    Nothing
          , chunkPrev :: Maybe Chunk
    chunkPrev = Maybe Chunk
    forall a. Maybe a
    Nothing
          , chunkNext :: Maybe Chunk
    chunkNext = Maybe Chunk
    forall a. Maybe a
    Nothing
          , chunkUnlisted :: Bool
    chunkUnlisted = Bool
    False
          , chunkContents :: [Block]
    chunkContents = [Block]
    bs
          }
        where
          chunkpath :: String
    chunkpath = PathTemplate -> Int -> Text -> Text -> Text -> String
    resolvePathTemplate PathTemplate
    pathTemplate Int
    chunknum
                            ([Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify (Meta -> [Inline]
    docTitle Meta
    meta))
                            Text
    chunkid
                            Text
    "0"
          chunkid :: Text
    chunkid = Extensions -> [Inline] -> Text
    inlineListToIdentifier Extensions
    forall a. Monoid a => a
    mempty (Meta -> [Inline]
    docTitle Meta
    meta) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                          Text
    "-" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    chunknum
      toChunk Int
    _ Block
    b = String -> Chunk
    forall a. HasCallStack => String -> a
    error (String -> Chunk) -> String -> Chunk
    forall a b. (a -> b) -> a -> b
    $ String
    "toChunk called on inappropriate block " String -> String -> String
    forall a. Semigroup a => a -> a -> a
    <> Block -> String
    forall a. Show a => a -> String
    show Block
    b
      -- should not happen

    -- Remove some attributes we added just to construct chunkNext etc.
    rmNavAttrs :: Block -> Block
    rmNavAttrs :: Block -> Block
    rmNavAttrs (Div (Text
    ident,[Text]
    classes,[(Text, Text)]
    kvs) [Block]
    bs) =
      (Text, [Text], [(Text, Text)]) -> [Block] -> Block
    Div (Text
    ident,[Text]
    classes,((Text, Text) -> Bool) -> [(Text, Text)] -> [(Text, Text)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> ((Text, Text) -> Bool) -> (Text, Text) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Text, Text) -> Bool
    forall {b}. (Text, b) -> Bool
    isNavAttr) [(Text, Text)]
    kvs) [Block]
    bs
     where
      isNavAttr :: (Text, b) -> Bool
    isNavAttr (Text
    k,b
    _) = Text
    "nav-" Text -> Text -> Bool
    `T.isPrefixOf` Text
    k
    rmNavAttrs Block
    b = Block
    b

    resolvePathTemplate :: PathTemplate
                        -> Int -- ^ Chunk number
                        -> Text -- ^ Stringified heading text
                        -> Text -- ^ Section identifier
                        -> Text -- ^ Section number
                        -> FilePath
    resolvePathTemplate :: PathTemplate -> Int -> Text -> Text -> Text -> String
    resolvePathTemplate (PathTemplate Text
    templ) Int
    chunknum Text
    headingText Text
    ident Text
    secnum =
      Text -> String
    T.unpack (Text -> String) -> (Text -> Text) -> Text -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      (Char -> Bool) -> Text -> Text
    T.filter (\Char
    c -> Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    '/' Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    '\\') (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      HasCallStack => Text -> Text -> Text -> Text
    Text -> Text -> Text -> Text
    T.replace Text
    "%n" (String -> Text
    T.pack (String -> Text) -> String -> Text
    forall a b. (a -> b) -> a -> b
    $ String -> Int -> String
    forall r. PrintfType r => String -> r
    printf String
    "%03d" Int
    chunknum) (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      HasCallStack => Text -> Text -> Text -> Text
    Text -> Text -> Text -> Text
    T.replace Text
    "%s" Text
    secnum (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      HasCallStack => Text -> Text -> Text -> Text
    Text -> Text -> Text -> Text
    T.replace Text
    "%h" Text
    headingText (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      HasCallStack => Text -> Text -> Text -> Text
    Text -> Text -> Text -> Text
    T.replace Text
    "%i" Text
    ident (Text -> String) -> Text -> String
    forall a b. (a -> b) -> a -> b
    $
      Text
    templ

    -- | A 'PathTemplate' is a FilePath in which certain codes
    -- will be substituted with information from a 'Chunk'.
    -- @%n@ will be replaced with the chunk number
    -- (padded with leading 0s to 3 digits),
    -- @%s@ with the section number of the heading,
    -- @%h@ with the (stringified) heading text,
    -- @%i@ with the section identifier.
    -- For example, @"section-%s-%i.html"@ might be resolved to
    -- @"section-1.2-introduction.html"@.
    newtype PathTemplate =
      PathTemplate { PathTemplate -> Text
    unPathTemplate :: Text }
      deriving (Int -> PathTemplate -> String -> String
    [PathTemplate] -> String -> String
    PathTemplate -> String
    (Int -> PathTemplate -> String -> String)
    -> (PathTemplate -> String)
    -> ([PathTemplate] -> String -> String)
    -> Show PathTemplate
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> PathTemplate -> String -> String
    showsPrec :: Int -> PathTemplate -> String -> String
    $cshow :: PathTemplate -> String
    show :: PathTemplate -> String
    $cshowList :: [PathTemplate] -> String -> String
    showList :: [PathTemplate] -> String -> String
    Show, String -> PathTemplate
    (String -> PathTemplate) -> IsString PathTemplate
    forall a. (String -> a) -> IsString a
    $cfromString :: String -> PathTemplate
    fromString :: String -> PathTemplate
    IsString, Typeable PathTemplate
    Typeable PathTemplate =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> PathTemplate -> c PathTemplate)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c PathTemplate)
    -> (PathTemplate -> Constr)
    -> (PathTemplate -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c PathTemplate))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c PathTemplate))
    -> ((forall b. Data b => b -> b) -> PathTemplate -> PathTemplate)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r)
    -> (forall u. (forall d. Data d => d -> u) -> PathTemplate -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> PathTemplate -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate)
    -> Data PathTemplate
    PathTemplate -> Constr
    PathTemplate -> DataType
    (forall b. Data b => b -> b) -> PathTemplate -> PathTemplate
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> PathTemplate -> u
    forall u. (forall d. Data d => d -> u) -> PathTemplate -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PathTemplate
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PathTemplate -> c PathTemplate
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PathTemplate)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c PathTemplate)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PathTemplate -> c PathTemplate
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PathTemplate -> c PathTemplate
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PathTemplate
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PathTemplate
    $ctoConstr :: PathTemplate -> Constr
    toConstr :: PathTemplate -> Constr
    $cdataTypeOf :: PathTemplate -> DataType
    dataTypeOf :: PathTemplate -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PathTemplate)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PathTemplate)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c PathTemplate)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c PathTemplate)
    $cgmapT :: (forall b. Data b => b -> b) -> PathTemplate -> PathTemplate
    gmapT :: (forall b. Data b => b -> b) -> PathTemplate -> PathTemplate
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PathTemplate -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> PathTemplate -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> PathTemplate -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PathTemplate -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PathTemplate -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PathTemplate -> m PathTemplate
    Data, Typeable, (forall x. PathTemplate -> Rep PathTemplate x)
    -> (forall x. Rep PathTemplate x -> PathTemplate)
    -> Generic PathTemplate
    forall x. Rep PathTemplate x -> PathTemplate
    forall x. PathTemplate -> Rep PathTemplate x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. PathTemplate -> Rep PathTemplate x
    from :: forall x. PathTemplate -> Rep PathTemplate x
    $cto :: forall x. Rep PathTemplate x -> PathTemplate
    to :: forall x. Rep PathTemplate x -> PathTemplate
    Generic, [PathTemplate] -> Value
    [PathTemplate] -> Encoding
    PathTemplate -> Bool
    PathTemplate -> Value
    PathTemplate -> Encoding
    (PathTemplate -> Value)
    -> (PathTemplate -> Encoding)
    -> ([PathTemplate] -> Value)
    -> ([PathTemplate] -> Encoding)
    -> (PathTemplate -> Bool)
    -> ToJSON PathTemplate
    forall a.
    (a -> Value)
    -> (a -> Encoding)
    -> ([a] -> Value)
    -> ([a] -> Encoding)
    -> (a -> Bool)
    -> ToJSON a
    $ctoJSON :: PathTemplate -> Value
    toJSON :: PathTemplate -> Value
    $ctoEncoding :: PathTemplate -> Encoding
    toEncoding :: PathTemplate -> Encoding
    $ctoJSONList :: [PathTemplate] -> Value
    toJSONList :: [PathTemplate] -> Value
    $ctoEncodingList :: [PathTemplate] -> Encoding
    toEncodingList :: [PathTemplate] -> Encoding
    $comitField :: PathTemplate -> Bool
    omitField :: PathTemplate -> Bool
    ToJSON, Maybe PathTemplate
    Value -> Parser [PathTemplate]
    Value -> Parser PathTemplate
    (Value -> Parser PathTemplate)
    -> (Value -> Parser [PathTemplate])
    -> Maybe PathTemplate
    -> FromJSON PathTemplate
    forall a.
    (Value -> Parser a)
    -> (Value -> Parser [a]) -> Maybe a -> FromJSON a
    $cparseJSON :: Value -> Parser PathTemplate
    parseJSON :: Value -> Parser PathTemplate
    $cparseJSONList :: Value -> Parser [PathTemplate]
    parseJSONList :: Value -> Parser [PathTemplate]
    $comittedField :: Maybe PathTemplate
    omittedField :: Maybe PathTemplate
    FromJSON)

    -- | A part of a document (typically a chapter or section, or
    -- the part of a section before its subsections).
    data Chunk =
      Chunk
      { Chunk -> [Inline]
    chunkHeading :: [Inline]
      , Chunk -> Text
    chunkId :: Text
      , Chunk -> Int
    chunkLevel :: Int
      , Chunk -> Int
    chunkNumber :: Int
      , Chunk -> Maybe Text
    chunkSectionNumber :: Maybe Text
      , Chunk -> String
    chunkPath :: FilePath
      , Chunk -> Maybe Chunk
    chunkUp :: Maybe Chunk
      , Chunk -> Maybe Chunk
    chunkPrev :: Maybe Chunk
      , Chunk -> Maybe Chunk
    chunkNext :: Maybe Chunk
      , Chunk -> Bool
    chunkUnlisted :: Bool
      , Chunk -> [Block]
    chunkContents :: [Block]
      }
      deriving (Int -> Chunk -> String -> String
    [Chunk] -> String -> String
    Chunk -> String
    (Int -> Chunk -> String -> String)
    -> (Chunk -> String) -> ([Chunk] -> String -> String) -> Show Chunk
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> Chunk -> String -> String
    showsPrec :: Int -> Chunk -> String -> String
    $cshow :: Chunk -> String
    show :: Chunk -> String
    $cshowList :: [Chunk] -> String -> String
    showList :: [Chunk] -> String -> String
    Show, Chunk -> Chunk -> Bool
    (Chunk -> Chunk -> Bool) -> (Chunk -> Chunk -> Bool) -> Eq Chunk
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Chunk -> Chunk -> Bool
    == :: Chunk -> Chunk -> Bool
    $c/= :: Chunk -> Chunk -> Bool
    /= :: Chunk -> Chunk -> Bool
    Eq, (forall x. Chunk -> Rep Chunk x)
    -> (forall x. Rep Chunk x -> Chunk) -> Generic Chunk
    forall x. Rep Chunk x -> Chunk
    forall x. Chunk -> Rep Chunk x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Chunk -> Rep Chunk x
    from :: forall x. Chunk -> Rep Chunk x
    $cto :: forall x. Rep Chunk x -> Chunk
    to :: forall x. Rep Chunk x -> Chunk
    Generic)

    instance Walkable Inline Chunk where
      query :: forall c. Monoid c => (Inline -> c) -> Chunk -> c
    query Inline -> c
    f Chunk
    chunk = (Inline -> c) -> [Block] -> c
    forall c. Monoid c => (Inline -> c) -> [Block] -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Inline -> c
    f (Chunk -> [Block]
    chunkContents Chunk
    chunk)
      walk :: (Inline -> Inline) -> Chunk -> Chunk
    walk Inline -> Inline
    f Chunk
    chunk = Chunk
    chunk{ chunkContents = walk f (chunkContents chunk) }
      walkM :: forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> Chunk -> m Chunk
    walkM Inline -> m Inline
    f Chunk
    chunk = do
        contents <- (Inline -> m Inline) -> [Block] -> m [Block]
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> [Block] -> m [Block]
    walkM Inline -> m Inline
    f (Chunk -> [Block]
    chunkContents Chunk
    chunk)
        return chunk{ chunkContents = contents }

    instance Walkable Block Chunk where
      query :: forall c. Monoid c => (Block -> c) -> Chunk -> c
    query Block -> c
    f Chunk
    chunk = (Block -> c) -> [Block] -> c
    forall c. Monoid c => (Block -> c) -> [Block] -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Block -> c
    f (Chunk -> [Block]
    chunkContents Chunk
    chunk)
      walk :: (Block -> Block) -> Chunk -> Chunk
    walk Block -> Block
    f Chunk
    chunk = Chunk
    chunk{ chunkContents = walk f (chunkContents chunk) }
      walkM :: forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Block -> m Block) -> Chunk -> m Chunk
    walkM Block -> m Block
    f Chunk
    chunk = do
        contents <- (Block -> m Block) -> [Block] -> m [Block]
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Block -> m Block) -> [Block] -> m [Block]
    walkM Block -> m Block
    f (Chunk -> [Block]
    chunkContents Chunk
    chunk)
        return chunk{ chunkContents = contents }

    -- | A 'Pandoc' broken into 'Chunk's for writing to separate files.
    data ChunkedDoc =
      ChunkedDoc
      { ChunkedDoc -> Meta
    chunkedMeta :: Meta
      , ChunkedDoc -> Tree SecInfo
    chunkedTOC :: Tree SecInfo
      , ChunkedDoc -> [Chunk]
    chunkedChunks :: [Chunk]
      } deriving (Int -> ChunkedDoc -> String -> String
    [ChunkedDoc] -> String -> String
    ChunkedDoc -> String
    (Int -> ChunkedDoc -> String -> String)
    -> (ChunkedDoc -> String)
    -> ([ChunkedDoc] -> String -> String)
    -> Show ChunkedDoc
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> ChunkedDoc -> String -> String
    showsPrec :: Int -> ChunkedDoc -> String -> String
    $cshow :: ChunkedDoc -> String
    show :: ChunkedDoc -> String
    $cshowList :: [ChunkedDoc] -> String -> String
    showList :: [ChunkedDoc] -> String -> String
    Show, ChunkedDoc -> ChunkedDoc -> Bool
    (ChunkedDoc -> ChunkedDoc -> Bool)
    -> (ChunkedDoc -> ChunkedDoc -> Bool) -> Eq ChunkedDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ChunkedDoc -> ChunkedDoc -> Bool
    == :: ChunkedDoc -> ChunkedDoc -> Bool
    $c/= :: ChunkedDoc -> ChunkedDoc -> Bool
    /= :: ChunkedDoc -> ChunkedDoc -> Bool
    Eq, (forall x. ChunkedDoc -> Rep ChunkedDoc x)
    -> (forall x. Rep ChunkedDoc x -> ChunkedDoc) -> Generic ChunkedDoc
    forall x. Rep ChunkedDoc x -> ChunkedDoc
    forall x. ChunkedDoc -> Rep ChunkedDoc x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ChunkedDoc -> Rep ChunkedDoc x
    from :: forall x. ChunkedDoc -> Rep ChunkedDoc x
    $cto :: forall x. Rep ChunkedDoc x -> ChunkedDoc
    to :: forall x. Rep ChunkedDoc x -> ChunkedDoc
    Generic)

    instance Walkable Inline ChunkedDoc where
      query :: forall c. Monoid c => (Inline -> c) -> ChunkedDoc -> c
    query Inline -> c
    f ChunkedDoc
    doc = (Inline -> c) -> [Chunk] -> c
    forall c. Monoid c => (Inline -> c) -> [Chunk] -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Inline -> c
    f (ChunkedDoc -> [Chunk]
    chunkedChunks ChunkedDoc
    doc) c -> c -> c
    forall a. Semigroup a => a -> a -> a
    <> (Inline -> c) -> Meta -> c
    forall c. Monoid c => (Inline -> c) -> Meta -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Inline -> c
    f (ChunkedDoc -> Meta
    chunkedMeta ChunkedDoc
    doc)
      walk :: (Inline -> Inline) -> ChunkedDoc -> ChunkedDoc
    walk Inline -> Inline
    f ChunkedDoc
    doc = ChunkedDoc
    doc{ chunkedMeta = walk f (chunkedMeta doc)
                      , chunkedChunks = walk f (chunkedChunks doc)
                      }
      walkM :: forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> ChunkedDoc -> m ChunkedDoc
    walkM Inline -> m Inline
    f ChunkedDoc
    doc = do
        meta' <- (Inline -> m Inline) -> Meta -> m Meta
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> Meta -> m Meta
    walkM Inline -> m Inline
    f (ChunkedDoc -> Meta
    chunkedMeta ChunkedDoc
    doc)
        chunks' <- walkM f (chunkedChunks doc)
        return $ doc{ chunkedMeta = meta'
                    , chunkedChunks = chunks' }

    instance Walkable Block ChunkedDoc where
      query :: forall c. Monoid c => (Block -> c) -> ChunkedDoc -> c
    query Block -> c
    f ChunkedDoc
    doc = (Block -> c) -> [Chunk] -> c
    forall c. Monoid c => (Block -> c) -> [Chunk] -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Block -> c
    f (ChunkedDoc -> [Chunk]
    chunkedChunks ChunkedDoc
    doc) c -> c -> c
    forall a. Semigroup a => a -> a -> a
    <> (Block -> c) -> Meta -> c
    forall c. Monoid c => (Block -> c) -> Meta -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Block -> c
    f (ChunkedDoc -> Meta
    chunkedMeta ChunkedDoc
    doc)
      walk :: (Block -> Block) -> ChunkedDoc -> ChunkedDoc
    walk Block -> Block
    f ChunkedDoc
    doc = ChunkedDoc
    doc{ chunkedMeta = walk f (chunkedMeta doc)
                      , chunkedChunks = walk f (chunkedChunks doc)
                      }
      walkM :: forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Block -> m Block) -> ChunkedDoc -> m ChunkedDoc
    walkM Block -> m Block
    f ChunkedDoc
    doc = do
        meta' <- (Block -> m Block) -> Meta -> m Meta
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Block -> m Block) -> Meta -> m Meta
    walkM Block -> m Block
    f (ChunkedDoc -> Meta
    chunkedMeta ChunkedDoc
    doc)
        chunks' <- walkM f (chunkedChunks doc)
        return $ doc{ chunkedMeta = meta'
                    , chunkedChunks = chunks' }

    -- | Data for a section in a hierarchical document.
    data SecInfo =
      SecInfo
      { SecInfo -> [Inline]
    secTitle :: [Inline]
      , SecInfo -> Maybe Text
    secNumber :: Maybe Text
      , SecInfo -> Text
    secId :: Text
      , SecInfo -> Text
    secPath :: Text -- including fragment, e.g. chunk001.html#section-one
      , SecInfo -> Int
    secLevel :: Int
      } deriving (Int -> SecInfo -> String -> String
    [SecInfo] -> String -> String
    SecInfo -> String
    (Int -> SecInfo -> String -> String)
    -> (SecInfo -> String)
    -> ([SecInfo] -> String -> String)
    -> Show SecInfo
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> SecInfo -> String -> String
    showsPrec :: Int -> SecInfo -> String -> String
    $cshow :: SecInfo -> String
    show :: SecInfo -> String
    $cshowList :: [SecInfo] -> String -> String
    showList :: [SecInfo] -> String -> String
    Show, SecInfo -> SecInfo -> Bool
    (SecInfo -> SecInfo -> Bool)
    -> (SecInfo -> SecInfo -> Bool) -> Eq SecInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SecInfo -> SecInfo -> Bool
    == :: SecInfo -> SecInfo -> Bool
    $c/= :: SecInfo -> SecInfo -> Bool
    /= :: SecInfo -> SecInfo -> Bool
    Eq, (forall x. SecInfo -> Rep SecInfo x)
    -> (forall x. Rep SecInfo x -> SecInfo) -> Generic SecInfo
    forall x. Rep SecInfo x -> SecInfo
    forall x. SecInfo -> Rep SecInfo x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. SecInfo -> Rep SecInfo x
    from :: forall x. SecInfo -> Rep SecInfo x
    $cto :: forall x. Rep SecInfo x -> SecInfo
    to :: forall x. Rep SecInfo x -> SecInfo
    Generic)

    instance Walkable Inline SecInfo where
      query :: forall c. Monoid c => (Inline -> c) -> SecInfo -> c
    query Inline -> c
    f SecInfo
    sec = (Inline -> c) -> [Inline] -> c
    forall c. Monoid c => (Inline -> c) -> [Inline] -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Inline -> c
    f (SecInfo -> [Inline]
    secTitle SecInfo
    sec)
      walk :: (Inline -> Inline) -> SecInfo -> SecInfo
    walk Inline -> Inline
    f SecInfo
    sec = SecInfo
    sec{ secTitle = walk f (secTitle sec) }
      walkM :: forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> SecInfo -> m SecInfo
    walkM Inline -> m Inline
    f SecInfo
    sec = do
        st <- (Inline -> m Inline) -> [Inline] -> m [Inline]
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> [Inline] -> m [Inline]
    walkM Inline -> m Inline
    f (SecInfo -> [Inline]
    secTitle SecInfo
    sec)
        return sec{ secTitle = st }

    -- | Create tree of sections with titles, links, and numbers,
    -- in a form that can be turned into a table of contents.
    -- Presupposes that the '[Block]' is the output of 'makeSections'.
    toTOCTree :: [Block] -> Tree SecInfo
    toTOCTree :: [Block] -> Tree SecInfo
    toTOCTree =
      SecInfo -> [Tree SecInfo] -> Tree SecInfo
    forall a. a -> [Tree a] -> Tree a
    Node SecInfo{ secTitle :: [Inline]
    secTitle = []
                  , secNumber :: Maybe Text
    secNumber = Maybe Text
    forall a. Maybe a
    Nothing
                  , secId :: Text
    secId = Text
    ""
                  , secPath :: Text
    secPath = Text
    ""
                  , secLevel :: Int
    secLevel = Int
    0 } ([Tree SecInfo] -> Tree SecInfo)
    -> ([Block] -> [Tree SecInfo]) -> [Block] -> Tree SecInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Block -> [Tree SecInfo] -> [Tree SecInfo])
    -> [Tree SecInfo] -> [Block] -> [Tree SecInfo]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Block -> [Tree SecInfo] -> [Tree SecInfo]
    go []
     where
      go :: Block -> [Tree SecInfo] -> [Tree SecInfo]
      go :: Block -> [Tree SecInfo] -> [Tree SecInfo]
    go (Div (Text
    ident,[Text]
    _,[(Text, Text)]
    _) (Header Int
    lev (Text
    _,[Text]
    classes,[(Text, Text)]
    kvs) [Inline]
    ils : [Block]
    subsecs))
        | Bool -> Bool
    not (Maybe Text -> Bool
    forall a. Maybe a -> Bool
    isNothing (Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    "number" [(Text, Text)]
    kvs) Bool -> Bool -> Bool
    && Text
    "unlisted" Text -> [Text] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    classes)
        = ((SecInfo -> [Tree SecInfo] -> Tree SecInfo
    forall a. a -> [Tree a] -> Tree a
    Node SecInfo{ secTitle :: [Inline]
    secTitle = [Inline]
    ils
                        , secNumber :: Maybe Text
    secNumber = Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    "number" [(Text, Text)]
    kvs
                        , secId :: Text
    secId = Text
    ident
                        , secPath :: Text
    secPath = Text
    ""
                        , secLevel :: Int
    secLevel = Int
    lev } ((Block -> [Tree SecInfo] -> [Tree SecInfo])
    -> [Tree SecInfo] -> [Block] -> [Tree SecInfo]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Block -> [Tree SecInfo] -> [Tree SecInfo]
    go [] [Block]
    subsecs)) Tree SecInfo -> [Tree SecInfo] -> [Tree SecInfo]
    forall a. a -> [a] -> [a]
    :)
      go (Div (Text, [Text], [(Text, Text)])
    _ [d :: Block
    d@Div{}]) = Block -> [Tree SecInfo] -> [Tree SecInfo]
    go Block
    d -- #8402
      go Block
    _ = [Tree SecInfo] -> [Tree SecInfo]
    forall a. a -> a
    id

    -- | Adjusts paths in the TOC tree generated by 'toTOCTree'
    -- to reflect division into Chunks.
    fixTOCTreePaths :: [Chunk] -> Tree SecInfo -> Tree SecInfo
    fixTOCTreePaths :: [Chunk] -> Tree SecInfo -> Tree SecInfo
    fixTOCTreePaths [Chunk]
    chunks = String -> Tree SecInfo -> Tree SecInfo
    go String
    ""
     where
      idMap :: Map Text String
    idMap = (Chunk -> Map Text String -> Map Text String)
    -> Map Text String -> [Chunk] -> Map Text String
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Chunk
    chunk Map Text String
    m ->
                       let ids :: [Text]
    ids = (Text -> Bool) -> [Text] -> [Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Bool
    T.null)
                                   (Chunk -> Text
    chunkId Chunk
    chunk Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :
                                      (Block -> [Text]) -> [Block] -> [Text]
    forall c. Monoid c => (Block -> c) -> [Block] -> c
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query Block -> [Text]
    getIds (Chunk -> [Block]
    chunkContents Chunk
    chunk))
                        in (Text -> Map Text String -> Map Text String)
    -> Map Text String -> [Text] -> Map Text String
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Text
    i -> Text -> String -> Map Text String -> Map Text String
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert Text
    i (Chunk -> String
    chunkPath Chunk
    chunk)) Map Text String
    m [Text]
    ids)
                    Map Text String
    forall a. Monoid a => a
    mempty [Chunk]
    chunks
      getIds :: Block -> [Text]
      getIds :: Block -> [Text]
    getIds (Div (Text
    i,Text
    "section":[Text]
    _,[(Text, Text)]
    _) [Block]
    _) = [Text
    i]
      getIds Block
    _ = []
      go :: FilePath -> Tree SecInfo -> Tree SecInfo
      go :: String -> Tree SecInfo -> Tree SecInfo
    go String
    fp (Node SecInfo
    secinfo [Tree SecInfo]
    subtrees) =
        let newpath :: Maybe String
    newpath = Text -> Map Text String -> Maybe String
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup (SecInfo -> Text
    secId SecInfo
    secinfo) Map Text String
    idMap
            fp' :: String
    fp' = String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe String
    fp Maybe String
    newpath
            fragment :: Text
    fragment = Text
    "#" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> SecInfo -> Text
    secId SecInfo
    secinfo
         in SecInfo -> [Tree SecInfo] -> Tree SecInfo
    forall a. a -> [Tree a] -> Tree a
    Node SecInfo
    secinfo{ secPath = T.pack fp' <> fragment }
                 ((Tree SecInfo -> Tree SecInfo) -> [Tree SecInfo] -> [Tree SecInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> Tree SecInfo -> Tree SecInfo
    go String
    fp') [Tree SecInfo]
    subtrees)

    -- | Creates a TOC link to the respective document section.
    tocEntryToLink :: Bool -> SecInfo -> [Inline]
    tocEntryToLink :: Bool -> SecInfo -> [Inline]
    tocEntryToLink Bool
    includeNumbers SecInfo
    secinfo = [Inline]
    headerLink
     where
      addNumber :: [Inline] -> [Inline]
    addNumber  = case SecInfo -> Maybe Text
    secNumber SecInfo
    secinfo of
                     Just Text
    num | Bool
    includeNumbers
                            -> ((Text, [Text], [(Text, Text)]) -> [Inline] -> Inline
    Span (Text
    "",[Text
    "toc-section-number"],[])
                                   [Text -> Inline
    Str Text
    num] Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    :) ([Inline] -> [Inline])
    -> ([Inline] -> [Inline]) -> [Inline] -> [Inline]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Inline
    Space Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    :)
                     Maybe Text
    _ -> [Inline] -> [Inline]
    forall a. a -> a
    id
      clean :: Inline -> [Inline]
    clean (Link (Text, [Text], [(Text, Text)])
    _ [Inline]
    xs (Text, Text)
    _) = [Inline]
    xs
      clean (Note [Block]
    _) = []
      clean Inline
    x = [Inline
    x]
      anchor :: Text
    anchor = if Text -> Bool
    T.null (SecInfo -> Text
    secPath SecInfo
    secinfo)
                  then if Text -> Bool
    T.null (SecInfo -> Text
    secId SecInfo
    secinfo)
                          then Text
    ""
                          else Text
    "#" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> SecInfo -> Text
    secId SecInfo
    secinfo
                  else SecInfo -> Text
    secPath SecInfo
    secinfo
      headerText :: [Inline]
    headerText = [Inline] -> [Inline]
    addNumber ([Inline] -> [Inline]) -> [Inline] -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ ([Inline] -> [Inline]) -> [Inline] -> [Inline]
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk ((Inline -> [Inline]) -> [Inline] -> [Inline]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Inline -> [Inline]
    clean) (SecInfo -> [Inline]
    secTitle SecInfo
    secinfo)
      headerLink :: [Inline]
    headerLink = if Text -> Bool
    T.null Text
    anchor
                      then [Inline]
    headerText
                      else [(Text, [Text], [(Text, Text)])
    -> [Inline] -> (Text, Text) -> Inline
    Link ((if Text -> Bool
    T.null (SecInfo -> Text
    secId SecInfo
    secinfo)
                                      then Text
    ""
                                      else Text
    "toc-" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> SecInfo -> Text
    secId SecInfo
    secinfo), [], [])
                             [Inline]
    headerText (Text
    anchor, Text
    "")]

    -- | Generate a table of contents of the given depth.
    tocToList :: Bool -> Int -> Tree SecInfo -> Block
    tocToList :: Bool -> Int -> Tree SecInfo -> Block
    tocToList Bool
    includeNumbers Int
    tocDepth (Node SecInfo
    _ [Tree SecInfo]
    subtrees) = [[Block]] -> Block
    BulletList ([Tree SecInfo] -> [[Block]]
    toItems [Tree SecInfo]
    subtrees)
     where
      toItems :: [Tree SecInfo] -> [[Block]]
    toItems = (Tree SecInfo -> [Block]) -> [Tree SecInfo] -> [[Block]]
    forall a b. (a -> b) -> [a] -> [b]
    map Tree SecInfo -> [Block]
    go ([Tree SecInfo] -> [[Block]])
    -> ([Tree SecInfo] -> [Tree SecInfo])
    -> [Tree SecInfo]
    -> [[Block]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Tree SecInfo -> Bool) -> [Tree SecInfo] -> [Tree SecInfo]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Tree SecInfo -> Bool
    isBelowTocDepth
      isBelowTocDepth :: Tree SecInfo -> Bool
    isBelowTocDepth (Node SecInfo
    sec [Tree SecInfo]
    _) = SecInfo -> Int
    secLevel SecInfo
    sec Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    tocDepth
      go :: Tree SecInfo -> [Block]
    go (Node SecInfo
    secinfo [Tree SecInfo]
    xs) =
        [Inline] -> Block
    Plain (Bool -> SecInfo -> [Inline]
    tocEntryToLink Bool
    includeNumbers SecInfo
    secinfo) Block -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    :
          case [Tree SecInfo] -> [[Block]]
    toItems [Tree SecInfo]
    xs of
            [] -> []
            [[Block]]
    ys -> [[[Block]] -> Block
    BulletList [[Block]]
    ys]