    {-# LANGUAGE CPP               #-}

    module Heist.Splices
      ( ifISplice
      , ifCSplice
      , ifElseISplice
      , ifElseCSplice
      , module Heist.Splices.Apply
      , module Heist.Splices.Bind
      , module Heist.Splices.Cache
      , module Heist.Splices.Html
      , module Heist.Splices.Ignore
      , module Heist.Splices.Markdown
      ) where

    #if !MIN_VERSION_base(4,8,0)
    import           Data.Monoid (Monoid(..))
    #endif

    import qualified Heist.Compiled as C
    import qualified Heist.Interpreted as I
    import           Heist.Splices.Apply
    import           Heist.Splices.Bind
    import           Heist.Splices.Cache
    import           Heist.Splices.Html
    import           Heist.Splices.Ignore
    import           Heist.Splices.Markdown
    import           Heist.Internal.Types.HeistState
    import qualified Text.XmlHtml as X

    ------------------------------------------------------------------------------
    -- | Run the splice contents if given condition is True, make splice disappear
    -- if not.
    ifISplice :: Monad m => Bool -> I.Splice m
    ifISplice :: forall (m :: * -> *). Monad m => Bool -> Splice m
    ifISplice Bool
    cond =
        case Bool
    cond of
          Bool
    False -> Template -> Splice m
    forall a. a -> HeistT m m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
          Bool
    True -> Splice m
    forall (n :: * -> *). Monad n => Splice n
    I.runChildren

    ------------------------------------------------------------------------------
    -- | Function for constructing if splices that use a runtime predicate
    -- function to determine whether the node's children should be rendered.
    ifCSplice :: Monad m
              => (t -> Bool)
              -> RuntimeSplice m t
              -> C.Splice m
    ifCSplice :: forall (m :: * -> *) t.
    Monad m =>
    (t -> Bool) -> RuntimeSplice m t -> Splice m
    ifCSplice t -> Bool
    predicate RuntimeSplice m t
    runtime = do
        DList (Chunk m)
    chunks <- Splice m
    forall (n :: * -> *). Monad n => Splice n
    C.runChildren
        DList (Chunk m) -> Splice m
    forall a. a -> HeistT m IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DList (Chunk m) -> Splice m) -> DList (Chunk m) -> Splice m
    forall a b. (a -> b) -> a -> b
    $ RuntimeSplice m Builder -> DList (Chunk m)
    forall (n :: * -> *). RuntimeSplice n Builder -> DList (Chunk n)
    C.yieldRuntime (RuntimeSplice m Builder -> DList (Chunk m))
    -> RuntimeSplice m Builder -> DList (Chunk m)
    forall a b. (a -> b) -> a -> b
    $ do
            t
    a <- RuntimeSplice m t
    runtime
            if t -> Bool
    predicate t
    a
              then
                DList (Chunk m) -> RuntimeSplice m Builder
    forall (n :: * -> *).
    Monad n =>
    DList (Chunk n) -> RuntimeSplice n Builder
    C.codeGen DList (Chunk m)
    chunks
              else
                Builder -> RuntimeSplice m Builder
    forall a. a -> RuntimeSplice m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Builder
    forall a. Monoid a => a
    mempty

    ------------------------------------------------------------------------------
    -- | Implements an if\/then\/else conditional splice.  It splits its children
    -- around the \<else\/\> element to get the markup to be used for the two cases.
    ifElseISplice :: Monad m => Bool -> I.Splice m
    ifElseISplice :: forall (m :: * -> *). Monad m => Bool -> Splice m
    ifElseISplice Bool
    cond = HeistT m m Node
    forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m Node
    getParamNode HeistT m m Node
    -> (Node -> HeistT m m Template) -> HeistT m m Template
    forall a b. HeistT m m a -> (a -> HeistT m m b) -> HeistT m m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Template -> HeistT m m Template
    forall {n :: * -> *}. Monad n => Template -> Splice n
    rewrite (Template -> HeistT m m Template)
    -> (Node -> Template) -> Node -> HeistT m m Template
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Node -> Template
    X.childNodes)
      where
        rewrite :: Template -> Splice n
    rewrite Template
    nodes =
          let (Template
    ns, Template
    ns') = (Node -> Bool) -> Template -> (Template, Template)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break (\Node
    n -> Node -> Maybe Text
    X.tagName Node
    nMaybe Text -> Maybe Text -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "else") Template
    nodes
          in Template -> Splice n
    forall {n :: * -> *}. Monad n => Template -> Splice n
    I.runNodeList (Template -> Splice n) -> Template -> Splice n
    forall a b. (a -> b) -> a -> b
    $ if Bool
    cond then Template
    ns else (Int -> Template -> Template
    forall a. Int -> [a] -> [a]
    drop Int
    1 Template
    ns')

    ------------------------------------------------------------------------------
    -- | Implements an if\/then\/else conditional splice.  It splits its children
    -- around the \<else\/\> element to get the markup to be used for the two cases.
    ifElseCSplice :: Monad m => Bool -> C.Splice m
    ifElseCSplice :: forall (m :: * -> *). Monad m => Bool -> Splice m
    ifElseCSplice Bool
    cond = HeistT m IO Node
    forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m Node
    getParamNode HeistT m IO Node
    -> (Node -> HeistT m IO (DList (Chunk m)))
    -> HeistT m IO (DList (Chunk m))
    forall a b. HeistT m IO a -> (a -> HeistT m IO b) -> HeistT m IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Template -> HeistT m IO (DList (Chunk m))
    forall {n :: * -> *}. Monad n => Template -> Splice n
    rewrite (Template -> HeistT m IO (DList (Chunk m)))
    -> (Node -> Template) -> Node -> HeistT m IO (DList (Chunk m))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Node -> Template
    X.childNodes)
      where rewrite :: Template -> Splice n
    rewrite Template
    nodes =
              let (Template
    ns, Template
    ns') = (Node -> Bool) -> Template -> (Template, Template)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break (\Node
    n -> Node -> Maybe Text
    X.tagName Node
    nMaybe Text -> Maybe Text -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "else") Template
    nodes
              in Template -> Splice n
    forall {n :: * -> *}. Monad n => Template -> Splice n
    C.runNodeList (Template -> Splice n) -> Template -> Splice n
    forall a b. (a -> b) -> a -> b
    $ if Bool
    cond then Template
    ns else (Int -> Template -> Template
    forall a. Int -> [a] -> [a]
    drop Int
    1 Template
    ns')