    {-# 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 :: Bool -> Splice m
    ifISplice cond :: Bool
    cond =
        case Bool
    cond of
          False -> [Node] -> Splice m
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
          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 :: (t -> Bool) -> RuntimeSplice m t -> Splice m
    ifCSplice predicate :: t -> Bool
    predicate runtime :: 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 (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 (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 :: Bool -> Splice m
    ifElseISplice cond :: Bool
    cond = HeistT m m Node
    forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m Node
    getParamNode HeistT m m Node -> (Node -> Splice m) -> Splice m
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= ([Node] -> Splice m
    forall (n :: * -> *). Monad n => [Node] -> Splice n
    rewrite ([Node] -> Splice m) -> (Node -> [Node]) -> Node -> Splice m
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Node -> [Node]
    X.childNodes)
      where
        rewrite :: [Node] -> Splice n
    rewrite nodes :: [Node]
    nodes =
          let (ns :: [Node]
    ns, ns' :: [Node]
    ns') = (Node -> Bool) -> [Node] -> ([Node], [Node])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break (\n :: 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 "else") [Node]
    nodes
          in [Node] -> Splice n
    forall (n :: * -> *). Monad n => [Node] -> Splice n
    I.runNodeList ([Node] -> Splice n) -> [Node] -> Splice n
    forall a b. (a -> b) -> a -> b
    $ if Bool
    cond then [Node]
    ns else (Int -> [Node] -> [Node]
    forall a. Int -> [a] -> [a]
    drop 1 [Node]
    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 :: Bool -> Splice m
    ifElseCSplice cond :: Bool
    cond = HeistT m IO Node
    forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m Node
    getParamNode HeistT m IO Node -> (Node -> Splice m) -> Splice m
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= ([Node] -> Splice m
    forall (n :: * -> *). Monad n => [Node] -> Splice n
    rewrite ([Node] -> Splice m) -> (Node -> [Node]) -> Node -> Splice m
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Node -> [Node]
    X.childNodes)
      where rewrite :: [Node] -> Splice n
    rewrite nodes :: [Node]
    nodes =
              let (ns :: [Node]
    ns, ns' :: [Node]
    ns') = (Node -> Bool) -> [Node] -> ([Node], [Node])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break (\n :: 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 "else") [Node]
    nodes
              in [Node] -> Splice n
    forall (n :: * -> *). Monad n => [Node] -> Splice n
    C.runNodeList ([Node] -> Splice n) -> [Node] -> Splice n
    forall a b. (a -> b) -> a -> b
    $ if Bool
    cond then [Node]
    ns else (Int -> [Node] -> [Node]
    forall a. Int -> [a] -> [a]
    drop 1 [Node]
    ns')