module Heist.Extra where

import Data.Text qualified as T
import Heist qualified as H
import Heist.Internal.Types qualified as HT
import Heist.Interpreted qualified as HI
import Text.XmlHtml qualified as X

-- | Useful for running a splice against an arbitrary node (such as that pulled from pandoc.tpl)
runCustomNode :: X.Node -> H.Splices (HI.Splice Identity) -> HI.Splice Identity
runCustomNode :: Node -> Splices (Splice Identity) -> Splice Identity
runCustomNode Node
node Splices (Splice Identity)
splices =
  forall (m :: Type -> Type) (n :: Type -> Type) a.
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m a -> HeistT n m a
H.localHS (forall (n :: Type -> Type).
Splices (Splice n) -> HeistState n -> HeistState n
HI.bindSplices Splices (Splice Identity)
splices) forall a b. (a -> b) -> a -> b
$ do
    forall (n :: Type -> Type). Monad n => Node -> Splice n
HI.runNode Node
node forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
      [Node
resNode]
        | Node -> Text
X.elementTag Node
resNode forall a. Eq a => a -> a -> Bool
== Node -> Text
X.elementTag Node
node ->
            -- Get rid of the `node` itself.
            Node -> Template
X.elementChildren Node
resNode
      Template
res ->
        Template
res

runCustomTemplate :: HT.Template -> H.Splices (HI.Splice Identity) -> HI.Splice Identity
runCustomTemplate :: Template -> Splices (Splice Identity) -> Splice Identity
runCustomTemplate Template
nodes Splices (Splice Identity)
splices =
  forall (m :: Type -> Type) (n :: Type -> Type) a.
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m a -> HeistT n m a
H.localHS (forall (n :: Type -> Type).
Splices (Splice n) -> HeistState n -> HeistState n
HI.bindSplices Splices (Splice Identity)
splices) forall a b. (a -> b) -> a -> b
$ do
    forall (n :: Type -> Type). Monad n => Template -> Splice n
HI.runNodeList Template
nodes

lookupHtmlTemplate :: Monad n => ByteString -> HT.HeistT m n (Maybe HT.Template)
lookupHtmlTemplate :: forall (n :: Type -> Type) (m :: Type -> Type).
Monad n =>
ByteString -> HeistT m n (Maybe Template)
lookupHtmlTemplate ByteString
name = do
  HeistState m
st <- forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
HeistT n m (HeistState n)
HT.getHS
  forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ do
    X.HtmlDocument Encoding
_ Maybe DocType
_ Template
nodes <- DocumentFile -> Document
H.dfDoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (n :: Type -> Type) t.
ByteString
-> HeistState n
-> (HeistState n -> HashMap TPath t)
-> Maybe (t, TPath)
H.lookupTemplate ByteString
name HeistState m
st forall (m :: Type -> Type).
HeistState m -> HashMap TPath DocumentFile
HT._templateMap
    forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Template
nodes

lookupHtmlTemplateMust :: forall m n. Monad n => ByteString -> HT.HeistT m n HT.Template
lookupHtmlTemplateMust :: forall (m :: Type -> Type) (n :: Type -> Type).
Monad n =>
ByteString -> HeistT m n Template
lookupHtmlTemplateMust ByteString
name =
  forall (n :: Type -> Type) (m :: Type -> Type).
Monad n =>
ByteString -> HeistT m n (Maybe Template)
lookupHtmlTemplate ByteString
name forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Maybe Template
Nothing -> do
      HeistState m
st <- forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
HeistT n m (HeistState n)
HT.getHS
      forall a t. (HasCallStack, IsText t) => t -> a
error forall a b. (a -> b) -> a -> b
$ Text
"heist: " forall a. Semigroup a => a -> a -> a
<> forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 ByteString
name forall a. Semigroup a => a -> a -> a
<> Text
" not found ... among: " forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
", " (forall (n :: Type -> Type). HeistState n -> [Text]
availableTemplates HeistState m
st)
    Just Template
tpl ->
      forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Template
tpl

availableTemplates :: HT.HeistState n -> [Text]
availableTemplates :: forall (n :: Type -> Type). HeistState n -> [Text]
availableTemplates HeistState n
st =
  forall a. Ord a => [a] -> [a]
sort forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type). HeistState m -> [TPath]
H.templateNames HeistState n
st forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> Text -> [Text] -> Text
T.intercalate Text
"/" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 @Text)