{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Heist.Compiled.Internal where
import Blaze.ByteString.Builder
import Blaze.ByteString.Builder.Char.Utf8
import Control.Arrow
import Control.Exception
import Control.Monad
import Control.Monad.RWS.Strict
import Control.Monad.State.Strict
import qualified Data.Attoparsec.Text as AP
import Data.ByteString (ByteString)
import Data.DList (DList)
import qualified Data.DList as DL
import qualified Data.HashMap.Strict as H
import qualified Data.HashSet as S
import qualified Data.HeterogeneousEnvironment as HE
import Data.Map.Syntax
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Vector as V
import Text.Printf
import qualified Text.XmlHtml as X
import qualified Text.XmlHtml.HTML.Meta as X
#if !MIN_VERSION_base(4,8,0)
import Data.Foldable (Foldable)
#endif
import qualified Data.Foldable as Foldable
import Heist.Common
import Heist.Internal.Types.HeistState
type Splice n = HeistT n IO (DList (Chunk n))
runChildren :: Monad n => Splice n
runChildren :: Splice n
runChildren = [Node] -> Splice n
forall (n :: * -> *). Monad n => [Node] -> Splice n
runNodeList ([Node] -> Splice n) -> (Node -> [Node]) -> Node -> Splice n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node -> [Node]
X.childNodes (Node -> Splice n) -> HeistT n IO Node -> Splice n
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< HeistT n IO Node
forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m Node
getParamNode
{-# INLINE runChildren #-}
renderFragment :: Markup -> [X.Node] -> Builder
renderFragment :: Markup -> [Node] -> Builder
renderFragment Markup
markup [Node]
ns =
case Markup
markup of
Markup
Html -> Encoding -> [Node] -> Builder
X.renderHtmlFragment Encoding
X.UTF8 [Node]
ns
Markup
Xml -> Encoding -> [Node] -> Builder
X.renderXmlFragment Encoding
X.UTF8 [Node]
ns
pureTextChunk :: Text -> Chunk n
pureTextChunk :: Text -> Chunk n
pureTextChunk Text
t = ByteString -> Chunk n
forall (m :: * -> *). ByteString -> Chunk m
Pure (ByteString -> Chunk n) -> ByteString -> Chunk n
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 Text
t
{-# INLINE pureTextChunk #-}
yieldPure :: Builder -> DList (Chunk n)
yieldPure :: Builder -> DList (Chunk n)
yieldPure = Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n))
-> (Builder -> Chunk n) -> Builder -> DList (Chunk n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Chunk n
forall (m :: * -> *). ByteString -> Chunk m
Pure (ByteString -> Chunk n)
-> (Builder -> ByteString) -> Builder -> Chunk n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toByteString
{-# INLINE yieldPure #-}
yieldRuntime :: RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime :: RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime = Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n))
-> (RuntimeSplice n Builder -> Chunk n)
-> RuntimeSplice n Builder
-> DList (Chunk n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuntimeSplice n Builder -> Chunk n
forall (m :: * -> *). RuntimeSplice m Builder -> Chunk m
RuntimeHtml
{-# INLINE yieldRuntime #-}
yieldRuntimeEffect :: Monad n => RuntimeSplice n () -> DList (Chunk n)
yieldRuntimeEffect :: RuntimeSplice n () -> DList (Chunk n)
yieldRuntimeEffect = Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n))
-> (RuntimeSplice n () -> Chunk n)
-> RuntimeSplice n ()
-> DList (Chunk n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuntimeSplice n () -> Chunk n
forall (m :: * -> *). RuntimeSplice m () -> Chunk m
RuntimeAction
{-# INLINE yieldRuntimeEffect #-}
yieldPureText :: Text -> DList (Chunk n)
yieldPureText :: Text -> DList (Chunk n)
yieldPureText = Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n))
-> (Text -> Chunk n) -> Text -> DList (Chunk n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk
{-# INLINE yieldPureText #-}
yieldRuntimeText :: Monad n => RuntimeSplice n Text -> DList (Chunk n)
yieldRuntimeText :: RuntimeSplice n Text -> DList (Chunk n)
yieldRuntimeText = RuntimeSplice n Builder -> DList (Chunk n)
forall (n :: * -> *). RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime (RuntimeSplice n Builder -> DList (Chunk n))
-> (RuntimeSplice n Text -> RuntimeSplice n Builder)
-> RuntimeSplice n Text
-> DList (Chunk n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Builder)
-> RuntimeSplice n Text -> RuntimeSplice n Builder
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Text -> Builder
fromText
{-# INLINE yieldRuntimeText #-}
runNodeList :: Monad n => [X.Node] -> Splice n
runNodeList :: [Node] -> Splice n
runNodeList = (Node -> Splice n) -> [Node] -> Splice n
forall (m :: * -> *) b a.
(Monad m, Monoid b) =>
(a -> m b) -> [a] -> m b
mapSplices Node -> Splice n
forall (n :: * -> *). Monad n => Node -> Splice n
runNode
runDocumentFile :: Monad n
=> TPath
-> DocumentFile
-> Splice n
runDocumentFile :: TPath -> DocumentFile -> Splice n
runDocumentFile TPath
tpath DocumentFile
df = do
let markup :: Markup
markup = case DocumentFile -> Document
dfDoc DocumentFile
df of
X.XmlDocument Encoding
_ Maybe DocType
_ [Node]
_ -> Markup
Xml
X.HtmlDocument Encoding
_ Maybe DocType
_ [Node]
_ -> Markup
Html
(HeistState n -> HeistState n) -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m ()
modifyHS (\HeistState n
hs -> HeistState n
hs { _curMarkup :: Markup
_curMarkup = Markup
markup })
let inDoctype :: Maybe DocType
inDoctype = Document -> Maybe DocType
X.docType (Document -> Maybe DocType) -> Document -> Maybe DocType
forall a b. (a -> b) -> a -> b
$ DocumentFile -> Document
dfDoc DocumentFile
df
[DocType] -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
[DocType] -> HeistT n m ()
addDoctype ([DocType] -> HeistT n IO ()) -> [DocType] -> HeistT n IO ()
forall a b. (a -> b) -> a -> b
$ Maybe DocType -> [DocType]
forall a. Maybe a -> [a]
maybeToList Maybe DocType
inDoctype
(HeistState n -> HeistState n) -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m ()
modifyHS (Maybe FilePath -> HeistState n -> HeistState n
forall (n :: * -> *).
Maybe FilePath -> HeistState n -> HeistState n
setCurTemplateFile Maybe FilePath
curPath (HeistState n -> HeistState n)
-> (HeistState n -> HeistState n) -> HeistState n -> HeistState n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TPath -> HeistState n -> HeistState n
forall (n :: * -> *). TPath -> HeistState n -> HeistState n
setCurContext TPath
tpath)
DList (Chunk n)
res <- [Node] -> Splice n
forall (n :: * -> *). Monad n => [Node] -> Splice n
runNodeList [Node]
nodes
Maybe DocType
dt <- (HeistState n -> Maybe DocType) -> HeistT n IO (Maybe DocType)
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS ([DocType] -> Maybe DocType
forall a. [a] -> Maybe a
listToMaybe ([DocType] -> Maybe DocType)
-> (HeistState n -> [DocType]) -> HeistState n -> Maybe DocType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeistState n -> [DocType]
forall (m :: * -> *). HeistState m -> [DocType]
_doctypes)
let enc :: Encoding
enc = Document -> Encoding
X.docEncoding (Document -> Encoding) -> Document -> Encoding
forall a b. (a -> b) -> a -> b
$ DocumentFile -> Document
dfDoc DocumentFile
df
DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> Splice n) -> DList (Chunk n) -> Splice n
forall a b. (a -> b) -> a -> b
$! (Builder -> DList (Chunk n)
forall (n :: * -> *). Builder -> DList (Chunk n)
yieldPure (Encoding -> Maybe DocType -> Builder
X.renderDocType Encoding
enc Maybe DocType
dt) DList (Chunk n) -> DList (Chunk n) -> DList (Chunk n)
forall a. Monoid a => a -> a -> a
`mappend` DList (Chunk n)
res)
where
curPath :: Maybe FilePath
curPath = DocumentFile -> Maybe FilePath
dfFile DocumentFile
df
nodes :: [Node]
nodes = Document -> [Node]
X.docContent (Document -> [Node]) -> Document -> [Node]
forall a b. (a -> b) -> a -> b
$! DocumentFile -> Document
dfDoc DocumentFile
df
compileTemplate
:: Monad n
=> TPath
-> DocumentFile
-> HeistT n IO [Chunk n]
compileTemplate :: TPath -> DocumentFile -> HeistT n IO [Chunk n]
compileTemplate TPath
tpath DocumentFile
df = do
!DList (Chunk n)
chunks <- TPath -> DocumentFile -> Splice n
forall (n :: * -> *). Monad n => TPath -> DocumentFile -> Splice n
runDocumentFile TPath
tpath DocumentFile
df
[Chunk n] -> HeistT n IO [Chunk n]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Chunk n] -> HeistT n IO [Chunk n])
-> [Chunk n] -> HeistT n IO [Chunk n]
forall a b. (a -> b) -> a -> b
$! DList (Chunk n) -> [Chunk n]
forall (n :: * -> *). Monad n => DList (Chunk n) -> [Chunk n]
consolidate DList (Chunk n)
chunks
compileTemplates
:: Monad n
=> (TPath -> Bool)
-> HeistState n
-> IO (Either [String] (HeistState n))
compileTemplates :: (TPath -> Bool)
-> HeistState n -> IO (Either [FilePath] (HeistState n))
compileTemplates TPath -> Bool
f HeistState n
hs = do
(HashMap TPath ([Chunk n], ByteString)
tmap, HeistState n
hs') <- HeistT n IO (HashMap TPath ([Chunk n], ByteString))
-> Node
-> HeistState n
-> IO (HashMap TPath ([Chunk n], ByteString), HeistState n)
forall (n :: * -> *) (m :: * -> *) a.
HeistT n m a -> Node -> HeistState n -> m (a, HeistState n)
runHeistT ((TPath -> Bool)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
forall (n :: * -> *).
Monad n =>
(TPath -> Bool)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
compileTemplates' TPath -> Bool
f) (Text -> Node
X.TextNode Text
"") HeistState n
hs
let pre :: Text
pre = HeistState n -> Text
forall (m :: * -> *). HeistState m -> Text
_splicePrefix HeistState n
hs'
let canError :: Bool
canError = HeistState n -> Bool
forall (m :: * -> *). HeistState m -> Bool
_errorNotBound HeistState n
hs'
let errs :: [SpliceError]
errs = HeistState n -> [SpliceError]
forall (m :: * -> *). HeistState m -> [SpliceError]
_spliceErrors HeistState n
hs'
let nsErr :: Either [FilePath] ()
nsErr = if Bool -> Bool
not (Text -> Bool
T.null Text
pre) Bool -> Bool -> Bool
&& (HeistState n -> Int
forall (m :: * -> *). HeistState m -> Int
_numNamespacedTags HeistState n
hs' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0)
then [FilePath] -> Either [FilePath] ()
forall a b. a -> Either a b
Left [FilePath -> FilePath
noNamespaceSplicesMsg (FilePath -> FilePath) -> FilePath -> FilePath
forall a b. (a -> b) -> a -> b
$ Text -> FilePath
T.unpack Text
pre]
else () -> Either [FilePath] ()
forall a b. b -> Either a b
Right ()
Either [FilePath] (HeistState n)
-> IO (Either [FilePath] (HeistState n))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [FilePath] (HeistState n)
-> IO (Either [FilePath] (HeistState n)))
-> Either [FilePath] (HeistState n)
-> IO (Either [FilePath] (HeistState n))
forall a b. (a -> b) -> a -> b
$ if Bool
canError
then case [SpliceError]
errs of
[] -> Either [FilePath] ()
nsErr Either [FilePath] ()
-> Either [FilePath] (HeistState n)
-> Either [FilePath] (HeistState n)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
(HeistState n -> Either [FilePath] (HeistState n)
forall a b. b -> Either a b
Right (HeistState n -> Either [FilePath] (HeistState n))
-> HeistState n -> Either [FilePath] (HeistState n)
forall a b. (a -> b) -> a -> b
$! HeistState n
hs { _compiledTemplateMap :: HashMap TPath ([Chunk n], ByteString)
_compiledTemplateMap = HashMap TPath ([Chunk n], ByteString)
tmap })
[SpliceError]
es -> [FilePath] -> Either [FilePath] (HeistState n)
forall a b. a -> Either a b
Left ([FilePath] -> Either [FilePath] (HeistState n))
-> [FilePath] -> Either [FilePath] (HeistState n)
forall a b. (a -> b) -> a -> b
$ ([FilePath] -> [FilePath] -> [FilePath])
-> (() -> [FilePath] -> [FilePath])
-> Either [FilePath] ()
-> [FilePath]
-> [FilePath]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
(++) (([FilePath] -> [FilePath]) -> () -> [FilePath] -> [FilePath]
forall a b. a -> b -> a
const [FilePath] -> [FilePath]
forall a. a -> a
id) Either [FilePath] ()
nsErr ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$
(SpliceError -> FilePath) -> [SpliceError] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> FilePath
T.unpack (Text -> FilePath)
-> (SpliceError -> Text) -> SpliceError -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SpliceError -> Text
spliceErrorText) [SpliceError]
es
else Either [FilePath] ()
nsErr Either [FilePath] ()
-> Either [FilePath] (HeistState n)
-> Either [FilePath] (HeistState n)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (HeistState n -> Either [FilePath] (HeistState n)
forall a b. b -> Either a b
Right (HeistState n -> Either [FilePath] (HeistState n))
-> HeistState n -> Either [FilePath] (HeistState n)
forall a b. (a -> b) -> a -> b
$! HeistState n
hs { _compiledTemplateMap :: HashMap TPath ([Chunk n], ByteString)
_compiledTemplateMap = HashMap TPath ([Chunk n], ByteString)
tmap
, _spliceErrors :: [SpliceError]
_spliceErrors = [SpliceError]
errs
})
noNamespaceSplicesMsg :: String -> String
noNamespaceSplicesMsg :: FilePath -> FilePath
noNamespaceSplicesMsg FilePath
pre = [FilePath] -> FilePath
unwords
[ FilePath -> FilePath -> FilePath
forall r. PrintfType r => FilePath -> r
printf FilePath
"You are using a namespace of '%s', but you don't have any" FilePath
ns
, FilePath -> FilePath -> FilePath
forall r. PrintfType r => FilePath -> r
printf FilePath
"tags starting with '%s'. If you have not defined any" FilePath
pre
, FilePath
"splices, then change your namespace to the empty string to get rid"
, FilePath
"of this message."
]
where
ns :: FilePath
ns = FilePath -> FilePath
forall a. [a] -> [a]
reverse (FilePath -> FilePath) -> FilePath -> FilePath
forall a b. (a -> b) -> a -> b
$ Int -> FilePath -> FilePath
forall a. Int -> [a] -> [a]
drop Int
1 (FilePath -> FilePath) -> FilePath -> FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
forall a. [a] -> [a]
reverse FilePath
pre
compileTemplates'
:: Monad n
=> (TPath -> Bool)
-> HeistT n IO (H.HashMap TPath ([Chunk n], MIMEType))
compileTemplates' :: (TPath -> Bool)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
compileTemplates' TPath -> Bool
f = do
HeistState n
hs <- HeistT n IO (HeistState n)
forall (m :: * -> *) (n :: * -> *).
Monad m =>
HeistT n m (HeistState n)
getHS
let tpathDocfiles :: [(TPath, DocumentFile)]
tpathDocfiles :: [(TPath, DocumentFile)]
tpathDocfiles = ((TPath, DocumentFile) -> Bool)
-> [(TPath, DocumentFile)] -> [(TPath, DocumentFile)]
forall a. (a -> Bool) -> [a] -> [a]
filter (TPath -> Bool
f (TPath -> Bool)
-> ((TPath, DocumentFile) -> TPath)
-> (TPath, DocumentFile)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TPath, DocumentFile) -> TPath
forall a b. (a, b) -> a
fst)
(HashMap TPath DocumentFile -> [(TPath, DocumentFile)]
forall k v. HashMap k v -> [(k, v)]
H.toList (HashMap TPath DocumentFile -> [(TPath, DocumentFile)])
-> HashMap TPath DocumentFile -> [(TPath, DocumentFile)]
forall a b. (a -> b) -> a -> b
$ HeistState n -> HashMap TPath DocumentFile
forall (m :: * -> *). HeistState m -> HashMap TPath DocumentFile
_templateMap HeistState n
hs)
(HashMap TPath ([Chunk n], ByteString)
-> (TPath, DocumentFile)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString)))
-> HashMap TPath ([Chunk n], ByteString)
-> [(TPath, DocumentFile)]
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM HashMap TPath ([Chunk n], ByteString)
-> (TPath, DocumentFile)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
forall (n :: * -> *).
Monad n =>
HashMap TPath ([Chunk n], ByteString)
-> (TPath, DocumentFile)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
runOne HashMap TPath ([Chunk n], ByteString)
forall k v. HashMap k v
H.empty [(TPath, DocumentFile)]
tpathDocfiles
where
runOne :: HashMap TPath ([Chunk n], ByteString)
-> (TPath, DocumentFile)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
runOne HashMap TPath ([Chunk n], ByteString)
tmap (TPath
tpath, DocumentFile
df) = do
(HeistState n -> HeistState n) -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m ()
modifyHS (\HeistState n
hs -> HeistState n
hs { _doctypes :: [DocType]
_doctypes = []})
![Chunk n]
mHtml <- TPath -> DocumentFile -> HeistT n IO [Chunk n]
forall (n :: * -> *).
Monad n =>
TPath -> DocumentFile -> HeistT n IO [Chunk n]
compileTemplate TPath
tpath DocumentFile
df
HashMap TPath ([Chunk n], ByteString)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
forall (m :: * -> *) a. Monad m => a -> m a
return (HashMap TPath ([Chunk n], ByteString)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString)))
-> HashMap TPath ([Chunk n], ByteString)
-> HeistT n IO (HashMap TPath ([Chunk n], ByteString))
forall a b. (a -> b) -> a -> b
$! TPath
-> ([Chunk n], ByteString)
-> HashMap TPath ([Chunk n], ByteString)
-> HashMap TPath ([Chunk n], ByteString)
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
H.insert TPath
tpath ([Chunk n]
mHtml, Document -> ByteString
mimeType (Document -> ByteString) -> Document -> ByteString
forall a b. (a -> b) -> a -> b
$! DocumentFile -> Document
dfDoc DocumentFile
df) HashMap TPath ([Chunk n], ByteString)
tmap
consolidate :: (Monad n) => DList (Chunk n) -> [Chunk n]
consolidate :: DList (Chunk n) -> [Chunk n]
consolidate = [Chunk n] -> [Chunk n]
forall (m :: * -> *). Monad m => [Chunk m] -> [Chunk m]
consolidateL ([Chunk n] -> [Chunk n])
-> (DList (Chunk n) -> [Chunk n]) -> DList (Chunk n) -> [Chunk n]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList (Chunk n) -> [Chunk n]
forall a. DList a -> [a]
DL.toList
where
consolidateL :: [Chunk m] -> [Chunk m]
consolidateL [] = []
consolidateL (Chunk m
y:[Chunk m]
ys) = [Chunk m] -> [Chunk m] -> [Chunk m]
forall (m :: * -> *). [Chunk m] -> [Chunk m] -> [Chunk m]
boilDown [] ([Chunk m] -> [Chunk m]) -> [Chunk m] -> [Chunk m]
forall a b. (a -> b) -> a -> b
$! [Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
forall (m :: * -> *).
Monad m =>
[Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [] Chunk m
y [Chunk m]
ys
where
go :: [Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [Chunk m]
soFar Chunk m
x [] = Chunk m
x Chunk m -> [Chunk m] -> [Chunk m]
forall a. a -> [a] -> [a]
: [Chunk m]
soFar
go [Chunk m]
soFar (Pure ByteString
a) ((Pure ByteString
b) : [Chunk m]
xs) =
[Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [Chunk m]
soFar (ByteString -> Chunk m
forall (m :: * -> *). ByteString -> Chunk m
Pure (ByteString -> Chunk m) -> ByteString -> Chunk m
forall a b. (a -> b) -> a -> b
$! ByteString
a ByteString -> ByteString -> ByteString
forall a. Monoid a => a -> a -> a
`mappend` ByteString
b) [Chunk m]
xs
go [Chunk m]
soFar (RuntimeHtml RuntimeSplice m Builder
a) ((RuntimeHtml RuntimeSplice m Builder
b) : [Chunk m]
xs) =
[Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [Chunk m]
soFar (RuntimeSplice m Builder -> Chunk m
forall (m :: * -> *). RuntimeSplice m Builder -> Chunk m
RuntimeHtml (RuntimeSplice m Builder -> Chunk m)
-> RuntimeSplice m Builder -> Chunk m
forall a b. (a -> b) -> a -> b
$! RuntimeSplice m Builder
a RuntimeSplice m Builder
-> RuntimeSplice m Builder -> RuntimeSplice m Builder
forall a. Monoid a => a -> a -> a
`mappend` RuntimeSplice m Builder
b) [Chunk m]
xs
go [Chunk m]
soFar (RuntimeHtml RuntimeSplice m Builder
a) ((RuntimeAction RuntimeSplice m ()
b) : [Chunk m]
xs) =
[Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [Chunk m]
soFar (RuntimeSplice m Builder -> Chunk m
forall (m :: * -> *). RuntimeSplice m Builder -> Chunk m
RuntimeHtml (RuntimeSplice m Builder -> Chunk m)
-> RuntimeSplice m Builder -> Chunk m
forall a b. (a -> b) -> a -> b
$! RuntimeSplice m Builder
a RuntimeSplice m Builder
-> (Builder -> RuntimeSplice m Builder) -> RuntimeSplice m Builder
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Builder
x -> RuntimeSplice m ()
b RuntimeSplice m ()
-> RuntimeSplice m Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a. Monad m => a -> m a
return Builder
x) [Chunk m]
xs
go [Chunk m]
soFar (RuntimeAction RuntimeSplice m ()
a) ((RuntimeHtml RuntimeSplice m Builder
b) : [Chunk m]
xs) =
[Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [Chunk m]
soFar (RuntimeSplice m Builder -> Chunk m
forall (m :: * -> *). RuntimeSplice m Builder -> Chunk m
RuntimeHtml (RuntimeSplice m Builder -> Chunk m)
-> RuntimeSplice m Builder -> Chunk m
forall a b. (a -> b) -> a -> b
$! RuntimeSplice m ()
a RuntimeSplice m ()
-> RuntimeSplice m Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> RuntimeSplice m Builder
b) [Chunk m]
xs
go [Chunk m]
soFar (RuntimeAction RuntimeSplice m ()
a) ((RuntimeAction RuntimeSplice m ()
b) : [Chunk m]
xs) =
[Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go [Chunk m]
soFar (RuntimeSplice m () -> Chunk m
forall (m :: * -> *). RuntimeSplice m () -> Chunk m
RuntimeAction (RuntimeSplice m () -> Chunk m) -> RuntimeSplice m () -> Chunk m
forall a b. (a -> b) -> a -> b
$! RuntimeSplice m ()
a RuntimeSplice m () -> RuntimeSplice m () -> RuntimeSplice m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> RuntimeSplice m ()
b) [Chunk m]
xs
go [Chunk m]
soFar Chunk m
a (Chunk m
b : [Chunk m]
xs) = [Chunk m] -> Chunk m -> [Chunk m] -> [Chunk m]
go (Chunk m
a Chunk m -> [Chunk m] -> [Chunk m]
forall a. a -> [a] -> [a]
: [Chunk m]
soFar) Chunk m
b [Chunk m]
xs
boilDown :: [Chunk m] -> [Chunk m] -> [Chunk m]
boilDown [Chunk m]
soFar [] = [Chunk m]
soFar
boilDown [Chunk m]
soFar ((Pure ByteString
h) : [Chunk m]
xs) = [Chunk m] -> [Chunk m] -> [Chunk m]
boilDown ((ByteString -> Chunk m
forall (m :: * -> *). ByteString -> Chunk m
Pure (ByteString -> Chunk m) -> ByteString -> Chunk m
forall a b. (a -> b) -> a -> b
$! ByteString
h) Chunk m -> [Chunk m] -> [Chunk m]
forall a. a -> [a] -> [a]
: [Chunk m]
soFar) [Chunk m]
xs
boilDown [Chunk m]
soFar (Chunk m
x : [Chunk m]
xs) = [Chunk m] -> [Chunk m] -> [Chunk m]
boilDown (Chunk m
x Chunk m -> [Chunk m] -> [Chunk m]
forall a. a -> [a] -> [a]
: [Chunk m]
soFar) [Chunk m]
xs
codeGen :: Monad n => DList (Chunk n) -> RuntimeSplice n Builder
codeGen :: DList (Chunk n) -> RuntimeSplice n Builder
codeGen DList (Chunk n)
l = (RuntimeSplice n Builder
-> RuntimeSplice n Builder -> RuntimeSplice n Builder)
-> RuntimeSplice n Builder
-> Vector (RuntimeSplice n Builder)
-> RuntimeSplice n Builder
forall a b. (a -> b -> b) -> b -> Vector a -> b
V.foldr RuntimeSplice n Builder
-> RuntimeSplice n Builder -> RuntimeSplice n Builder
forall a. Monoid a => a -> a -> a
mappend RuntimeSplice n Builder
forall a. Monoid a => a
mempty (Vector (RuntimeSplice n Builder) -> RuntimeSplice n Builder)
-> Vector (RuntimeSplice n Builder) -> RuntimeSplice n Builder
forall a b. (a -> b) -> a -> b
$!
(Chunk n -> RuntimeSplice n Builder)
-> Vector (Chunk n) -> Vector (RuntimeSplice n Builder)
forall a b. (a -> b) -> Vector a -> Vector b
V.map Chunk n -> RuntimeSplice n Builder
forall (m :: * -> *). Monad m => Chunk m -> RuntimeSplice m Builder
toAct (Vector (Chunk n) -> Vector (RuntimeSplice n Builder))
-> Vector (Chunk n) -> Vector (RuntimeSplice n Builder)
forall a b. (a -> b) -> a -> b
$! [Chunk n] -> Vector (Chunk n)
forall a. [a] -> Vector a
V.fromList ([Chunk n] -> Vector (Chunk n)) -> [Chunk n] -> Vector (Chunk n)
forall a b. (a -> b) -> a -> b
$! DList (Chunk n) -> [Chunk n]
forall (n :: * -> *). Monad n => DList (Chunk n) -> [Chunk n]
consolidate DList (Chunk n)
l
where
toAct :: Chunk m -> RuntimeSplice m Builder
toAct !(RuntimeHtml !RuntimeSplice m Builder
m) = RuntimeSplice m Builder
m
toAct !(Pure !ByteString
h) = Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a. Monad m => a -> m a
return (Builder -> RuntimeSplice m Builder)
-> Builder -> RuntimeSplice m Builder
forall a b. (a -> b) -> a -> b
$! ByteString -> Builder
fromByteString ByteString
h
toAct !(RuntimeAction !RuntimeSplice m ()
m) = RuntimeSplice m ()
m RuntimeSplice m ()
-> RuntimeSplice m Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a. Monad m => a -> m a
return Builder
forall a. Monoid a => a
mempty
{-# INLINE codeGen #-}
lookupSplice :: Text -> HeistT n IO (Maybe (Splice n))
lookupSplice :: Text -> HeistT n IO (Maybe (Splice n))
lookupSplice Text
nm = do
Text
pre <- (HeistState n -> Text) -> HeistT n IO Text
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS HeistState n -> Text
forall (m :: * -> *). HeistState m -> Text
_splicePrefix
Maybe (Splice n)
res <- (HeistState n -> Maybe (Splice n))
-> HeistT n IO (Maybe (Splice n))
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS (Text -> HashMap Text (Splice n) -> Maybe (Splice n)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
H.lookup Text
nm (HashMap Text (Splice n) -> Maybe (Splice n))
-> (HeistState n -> HashMap Text (Splice n))
-> HeistState n
-> Maybe (Splice n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeistState n -> HashMap Text (Splice n)
forall (m :: * -> *).
HeistState m -> HashMap Text (HeistT m IO (DList (Chunk m)))
_compiledSpliceMap)
if Maybe (Splice n) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (Splice n)
res Bool -> Bool -> Bool
&& Text -> Text -> Bool
T.isPrefixOf Text
pre Text
nm Bool -> Bool -> Bool
&& Bool -> Bool
not (Text -> Bool
T.null Text
pre)
then do
Text -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
Text -> HeistT n m ()
tellSpliceError (Text -> HeistT n IO ()) -> Text -> HeistT n IO ()
forall a b. (a -> b) -> a -> b
$ Text
"No splice bound for " Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` Text
nm
Maybe (Splice n) -> HeistT n IO (Maybe (Splice n))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Splice n)
forall a. Maybe a
Nothing
else Maybe (Splice n) -> HeistT n IO (Maybe (Splice n))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Splice n)
res
runNode :: Monad n => X.Node -> Splice n
runNode :: Node -> Splice n
runNode Node
node = (Node -> Node) -> Splice n -> Splice n
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
(Node -> Node) -> HeistT n m a -> HeistT n m a
localParamNode (Node -> Node -> Node
forall a b. a -> b -> a
const Node
node) (Splice n -> Splice n) -> Splice n -> Splice n
forall a b. (a -> b) -> a -> b
$ do
HeistState n
hs <- HeistT n IO (HeistState n)
forall (m :: * -> *) (n :: * -> *).
Monad m =>
HeistT n m (HeistState n)
getHS
let pre :: Text
pre = HeistState n -> Text
forall (m :: * -> *). HeistState m -> Text
_splicePrefix HeistState n
hs
let hasPrefix :: Bool
hasPrefix = (Text -> Text -> Bool
T.isPrefixOf Text
pre (Text -> Bool) -> Maybe Text -> Maybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Node -> Maybe Text
X.tagName Node
node) Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
Bool -> HeistT n IO () -> HeistT n IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Text -> Bool
T.null Text
pre) Bool -> Bool -> Bool
&& Bool
hasPrefix) HeistT n IO ()
forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m ()
incNamespacedTags
HeistState n
hs' <- HeistT n IO (HeistState n)
forall (m :: * -> *) (n :: * -> *).
Monad m =>
HeistT n m (HeistState n)
getHS
(DList (Chunk n)
res, HeistState n
hs'') <- IO (DList (Chunk n), HeistState n)
-> HeistT n IO (DList (Chunk n), HeistState n)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (DList (Chunk n), HeistState n)
-> HeistT n IO (DList (Chunk n), HeistState n))
-> IO (DList (Chunk n), HeistState n)
-> HeistT n IO (DList (Chunk n), HeistState n)
forall a b. (a -> b) -> a -> b
$ IO (DList (Chunk n), HeistState n)
-> [Handler (DList (Chunk n), HeistState n)]
-> IO (DList (Chunk n), HeistState n)
forall a. IO a -> [Handler a] -> IO a
catches (HeistState n -> IO (DList (Chunk n), HeistState n)
forall (n :: * -> *).
Monad n =>
HeistState n -> IO (DList (Chunk n), HeistState n)
compileIO HeistState n
hs')
[ (CompileException -> IO (DList (Chunk n), HeistState n))
-> Handler (DList (Chunk n), HeistState n)
forall a e. Exception e => (e -> IO a) -> Handler a
Handler (\(CompileException
ex :: CompileException) -> CompileException -> IO (DList (Chunk n), HeistState n)
forall e a. Exception e => e -> IO a
throwIO CompileException
ex)
, (SomeException -> IO (DList (Chunk n), HeistState n))
-> Handler (DList (Chunk n), HeistState n)
forall a e. Exception e => (e -> IO a) -> Handler a
Handler (\(SomeException
ex :: SomeException) -> SomeException -> HeistState n -> IO (DList (Chunk n), HeistState n)
forall e (n :: * -> *) b. Exception e => e -> HeistState n -> IO b
handleError SomeException
ex HeistState n
hs')]
HeistState n -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
HeistState n -> HeistT n m ()
putHS HeistState n
hs''
DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return DList (Chunk n)
res
where
localSplicePath :: HeistT m m a -> HeistT m m a
localSplicePath =
(HeistState m -> HeistState m) -> HeistT m m a -> HeistT m m a
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m a -> HeistT n m a
localHS (\HeistState m
hs -> HeistState m
hs {_splicePath :: [(TPath, Maybe FilePath, Text)]
_splicePath = (HeistState m -> TPath
forall (m :: * -> *). HeistState m -> TPath
_curContext HeistState m
hs,
HeistState m -> Maybe FilePath
forall (m :: * -> *). HeistState m -> Maybe FilePath
_curTemplateFile HeistState m
hs,
Node -> Text
X.elementTag Node
node)(TPath, Maybe FilePath, Text)
-> [(TPath, Maybe FilePath, Text)]
-> [(TPath, Maybe FilePath, Text)]
forall a. a -> [a] -> [a]
:
(HeistState m -> [(TPath, Maybe FilePath, Text)]
forall (m :: * -> *).
HeistState m -> [(TPath, Maybe FilePath, Text)]
_splicePath HeistState m
hs)})
compileIO :: HeistState n -> IO (DList (Chunk n), HeistState n)
compileIO HeistState n
hs = HeistT n IO (DList (Chunk n))
-> Node -> HeistState n -> IO (DList (Chunk n), HeistState n)
forall (n :: * -> *) (m :: * -> *) a.
HeistT n m a -> Node -> HeistState n -> m (a, HeistState n)
runHeistT HeistT n IO (DList (Chunk n))
forall (n :: * -> *). Monad n => HeistT n IO (DList (Chunk n))
compile Node
node HeistState n
hs
compile :: HeistT n IO (DList (Chunk n))
compile = do
Bool
isStatic <- Node -> HeistT n IO Bool
forall (n :: * -> *). Node -> HeistT n IO Bool
subtreeIsStatic Node
node
DList (Chunk n)
dl <- Bool -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *).
Monad n =>
Bool -> HeistT n IO (DList (Chunk n))
compile' Bool
isStatic
IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n)))
-> IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ DList (Chunk n) -> IO (DList (Chunk n))
forall a. a -> IO a
evaluate (DList (Chunk n) -> IO (DList (Chunk n)))
-> DList (Chunk n) -> IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ [Chunk n] -> DList (Chunk n)
forall a. [a] -> DList a
DL.fromList ([Chunk n] -> DList (Chunk n)) -> [Chunk n] -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! DList (Chunk n) -> [Chunk n]
forall (n :: * -> *). Monad n => DList (Chunk n) -> [Chunk n]
consolidate DList (Chunk n)
dl
compile' :: Bool -> HeistT n IO (DList (Chunk n))
compile' Bool
True = do
Markup
markup <- (HeistState n -> Markup) -> HeistT n IO Markup
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS HeistState n -> Markup
forall (m :: * -> *). HeistState m -> Markup
_curMarkup
DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> HeistT n IO (DList (Chunk n)))
-> DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$! Builder -> DList (Chunk n)
forall (n :: * -> *). Builder -> DList (Chunk n)
yieldPure (Builder -> DList (Chunk n)) -> Builder -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Markup -> [Node] -> Builder
renderFragment Markup
markup [Node -> Node
parseAttrs Node
node]
compile' Bool
False = HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) (m :: * -> *) a.
Monad m =>
HeistT m m a -> HeistT m m a
localSplicePath (HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n)))
-> HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ Node -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *). Monad n => Node -> Splice n
compileNode Node
node
handleError :: e -> HeistState n -> IO b
handleError e
ex HeistState n
hs = do
[SpliceError]
errs <- HeistT n IO [SpliceError]
-> Node -> HeistState n -> IO [SpliceError]
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
HeistT n m a -> Node -> HeistState n -> m a
evalHeistT (do HeistT n IO () -> HeistT n IO ()
forall (m :: * -> *) (m :: * -> *) a.
Monad m =>
HeistT m m a -> HeistT m m a
localSplicePath (HeistT n IO () -> HeistT n IO ())
-> HeistT n IO () -> HeistT n IO ()
forall a b. (a -> b) -> a -> b
$ Text -> HeistT n IO ()
forall (m :: * -> *) (n :: * -> *).
Monad m =>
Text -> HeistT n m ()
tellSpliceError (Text -> HeistT n IO ()) -> Text -> HeistT n IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$
FilePath
"Exception in splice compile: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ e -> FilePath
forall a. Show a => a -> FilePath
show e
ex
(HeistState n -> [SpliceError]) -> HeistT n IO [SpliceError]
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS HeistState n -> [SpliceError]
forall (m :: * -> *). HeistState m -> [SpliceError]
_spliceErrors) Node
node HeistState n
hs
CompileException -> IO b
forall e a. Exception e => e -> IO a
throwIO (CompileException -> IO b) -> CompileException -> IO b
forall a b. (a -> b) -> a -> b
$ e -> [SpliceError] -> CompileException
forall e. Exception e => e -> [SpliceError] -> CompileException
CompileException e
ex [SpliceError]
errs
parseAttrs :: X.Node -> X.Node
parseAttrs :: Node -> Node
parseAttrs (X.Element Text
nm [(Text, Text)]
attrs [Node]
ch) = [(Text, Text)]
newAttrs [(Text, Text)] -> Node -> Node
`seq` Text -> [(Text, Text)] -> [Node] -> Node
X.Element Text
nm [(Text, Text)]
newAttrs [Node]
ch
where
newAttrs :: [(Text, Text)]
newAttrs = ((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> (Text, Text)
parseAttr [(Text, Text)]
attrs
parseAttrs !Node
n = Node
n
parseAttr :: (Text, Text) -> (Text, Text)
parseAttr :: (Text, Text) -> (Text, Text)
parseAttr (Text
k,Text
v) = (Text
k, [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$! (AttAST -> Text) -> [AttAST] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map AttAST -> Text
cvt [AttAST]
ast)
where
!ast :: [AttAST]
ast = case IResult Text [AttAST] -> Text -> IResult Text [AttAST]
forall i r. Monoid i => IResult i r -> i -> IResult i r
AP.feed (Parser [AttAST] -> Text -> IResult Text [AttAST]
forall a. Parser a -> Text -> Result a
AP.parse Parser [AttAST]
attParser Text
v) Text
"" of
(AP.Done Text
_ [AttAST]
res) -> [AttAST]
res
(AP.Fail Text
_ [FilePath]
_ FilePath
_) -> []
(AP.Partial Text -> IResult Text [AttAST]
_ ) -> []
cvt :: AttAST -> Text
cvt (Literal Text
x) = Text
x
cvt (Ident Text
i) = [Text] -> Text
T.concat [Text
"${", Text
i, Text
"}"]
subtreeIsStatic :: X.Node -> HeistT n IO Bool
subtreeIsStatic :: Node -> HeistT n IO Bool
subtreeIsStatic (X.Element Text
nm [(Text, Text)]
attrs [Node]
ch) = do
Bool
isNodeDynamic <- (Maybe (Splice n) -> Bool)
-> HeistT n IO (Maybe (Splice n)) -> HeistT n IO Bool
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Maybe (Splice n) -> Bool
forall a. Maybe a -> Bool
isJust (HeistT n IO (Maybe (Splice n)) -> HeistT n IO Bool)
-> HeistT n IO (Maybe (Splice n)) -> HeistT n IO Bool
forall a b. (a -> b) -> a -> b
$ Text -> HeistT n IO (Maybe (Splice n))
forall (n :: * -> *). Text -> HeistT n IO (Maybe (Splice n))
lookupSplice Text
nm
HashMap Text (AttrSplice n)
attrSplices <- (HeistState n -> HashMap Text (AttrSplice n))
-> HeistT n IO (HashMap Text (AttrSplice n))
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS HeistState n -> HashMap Text (AttrSplice n)
forall (m :: * -> *). HeistState m -> HashMap Text (AttrSplice m)
_attrSpliceMap
let hasSubstitutions :: (Text, Text) -> Bool
hasSubstitutions (Text
k,Text
v) = Text -> Bool
hasAttributeSubstitutions Text
v Bool -> Bool -> Bool
||
Text -> HashMap Text (AttrSplice n) -> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
H.member Text
k HashMap Text (AttrSplice n)
attrSplices
if Bool
isNodeDynamic
then Bool -> HeistT n IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else do
let hasDynamicAttrs :: Bool
hasDynamicAttrs = ((Text, Text) -> Bool) -> [(Text, Text)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Text, Text) -> Bool
hasSubstitutions [(Text, Text)]
attrs
if Bool
hasDynamicAttrs
then Bool -> HeistT n IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else do
[Bool]
staticSubtrees <- (Node -> HeistT n IO Bool) -> [Node] -> HeistT n IO [Bool]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Node -> HeistT n IO Bool
forall (n :: * -> *). Node -> HeistT n IO Bool
subtreeIsStatic [Node]
ch
Bool -> HeistT n IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> HeistT n IO Bool) -> Bool -> HeistT n IO Bool
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [Bool]
staticSubtrees
subtreeIsStatic Node
_ = Bool -> HeistT n IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
hasAttributeSubstitutions :: Text -> Bool
hasAttributeSubstitutions :: Text -> Bool
hasAttributeSubstitutions Text
txt = (AttAST -> Bool) -> [AttAST] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any AttAST -> Bool
isIdent [AttAST]
ast
where
ast :: [AttAST]
ast = case IResult Text [AttAST] -> Text -> IResult Text [AttAST]
forall i r. Monoid i => IResult i r -> i -> IResult i r
AP.feed (Parser [AttAST] -> Text -> IResult Text [AttAST]
forall a. Parser a -> Text -> Result a
AP.parse Parser [AttAST]
attParser Text
txt) Text
"" of
(AP.Done Text
_ [AttAST]
res) -> [AttAST]
res
(AP.Fail Text
_ [FilePath]
_ FilePath
_) -> []
(AP.Partial Text -> IResult Text [AttAST]
_ ) -> []
compileNode :: Monad n => X.Node -> Splice n
compileNode :: Node -> Splice n
compileNode (X.Element Text
nm [(Text, Text)]
attrs [Node]
ch) = do
Maybe (Splice n)
msplice <- Text -> HeistT n IO (Maybe (Splice n))
forall (n :: * -> *). Text -> HeistT n IO (Maybe (Splice n))
lookupSplice Text
nm
Splice n -> Maybe (Splice n) -> Splice n
forall a. a -> Maybe a -> a
fromMaybe Splice n
forall (n :: * -> *). Monad n => HeistT n IO (DList (Chunk n))
compileStaticElement Maybe (Splice n)
msplice
where
tag0 :: Text
tag0 = Text -> Text -> Text
T.append Text
"<" Text
nm
end :: Text
end = [Text] -> Text
T.concat [ Text
"</" , Text
nm , Text
">"]
compileStaticElement :: HeistT n IO (DList (Chunk n))
compileStaticElement = do
[DList (Chunk n)]
compiledAttrs <- [(Text, Text)] -> HeistT n IO [DList (Chunk n)]
forall (n :: * -> *).
Monad n =>
[(Text, Text)] -> HeistT n IO [DList (Chunk n)]
runAttributes [(Text, Text)]
attrs
DList (Chunk n)
childHtml <- [Node] -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *). Monad n => [Node] -> Splice n
runNodeList [Node]
ch
DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> HeistT n IO (DList (Chunk n)))
-> DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$! if [Chunk n] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DList (Chunk n) -> [Chunk n]
forall a. DList a -> [a]
DL.toList DList (Chunk n)
childHtml) Bool -> Bool -> Bool
&& Text
nm Text -> HashSet Text -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
`S.member` HashSet Text
X.voidTags
then [DList (Chunk n)] -> DList (Chunk n)
forall a. [DList a] -> DList a
DL.concat [ Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk (Text -> Chunk n) -> Text -> Chunk n
forall a b. (a -> b) -> a -> b
$! Text
tag0
, [DList (Chunk n)] -> DList (Chunk n)
forall a. [DList a] -> DList a
DL.concat [DList (Chunk n)]
compiledAttrs
, Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk Text
" />"
]
else [DList (Chunk n)] -> DList (Chunk n)
forall a. [DList a] -> DList a
DL.concat [ Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk (Text -> Chunk n) -> Text -> Chunk n
forall a b. (a -> b) -> a -> b
$! Text
tag0
, [DList (Chunk n)] -> DList (Chunk n)
forall a. [DList a] -> DList a
DL.concat [DList (Chunk n)]
compiledAttrs
, Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk Text
">"
, DList (Chunk n)
childHtml
, Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk (Text -> Chunk n) -> Text -> Chunk n
forall a b. (a -> b) -> a -> b
$! Text
end
]
compileNode Node
_ = FilePath -> Splice n
forall a. HasCallStack => FilePath -> a
error FilePath
"impossible"
parseAtt :: Monad n => (Text, Text) -> HeistT n IO (DList (Chunk n))
parseAtt :: (Text, Text) -> HeistT n IO (DList (Chunk n))
parseAtt (Text
k,Text
v) = do
Maybe (AttrSplice n)
mas <- (HeistState n -> Maybe (AttrSplice n))
-> HeistT n IO (Maybe (AttrSplice n))
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS (Text -> HashMap Text (AttrSplice n) -> Maybe (AttrSplice n)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
H.lookup Text
k (HashMap Text (AttrSplice n) -> Maybe (AttrSplice n))
-> (HeistState n -> HashMap Text (AttrSplice n))
-> HeistState n
-> Maybe (AttrSplice n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeistState n -> HashMap Text (AttrSplice n)
forall (m :: * -> *). HeistState m -> HashMap Text (AttrSplice m)
_attrSpliceMap)
HeistT n IO (DList (Chunk n))
-> (AttrSplice n -> HeistT n IO (DList (Chunk n)))
-> Maybe (AttrSplice n)
-> HeistT n IO (DList (Chunk n))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe HeistT n IO (DList (Chunk n))
forall (n :: * -> *). HeistT n IO (DList (Chunk n))
doInline (DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> HeistT n IO (DList (Chunk n)))
-> (AttrSplice n -> DList (Chunk n))
-> AttrSplice n
-> HeistT n IO (DList (Chunk n))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AttrSplice n -> DList (Chunk n)
forall (m :: * -> *).
Monad m =>
(Text -> RuntimeSplice m [(Text, Text)]) -> DList (Chunk m)
doAttrSplice) Maybe (AttrSplice n)
mas
where
cvt :: AttAST -> HeistT n IO (DList (Chunk n))
cvt (Literal Text
x) = DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> HeistT n IO (DList (Chunk n)))
-> DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ Text -> DList (Chunk n)
forall (n :: * -> *). Text -> DList (Chunk n)
yieldPureText Text
x
cvt (Ident Text
x) =
(Node -> Node)
-> HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
(Node -> Node) -> HeistT n m a -> HeistT n m a
localParamNode (Node -> Node -> Node
forall a b. a -> b -> a
const (Node -> Node -> Node) -> Node -> Node -> Node
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> [Node] -> Node
X.Element Text
x [] []) (HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n)))
-> HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ Text -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *). Text -> HeistT n IO (DList (Chunk n))
getAttributeSplice Text
x
doInline :: HeistT n IO (DList (Chunk n))
doInline = do
let ast :: [AttAST]
ast = case IResult Text [AttAST] -> Text -> IResult Text [AttAST]
forall i r. Monoid i => IResult i r -> i -> IResult i r
AP.feed (Parser [AttAST] -> Text -> IResult Text [AttAST]
forall a. Parser a -> Text -> Result a
AP.parse Parser [AttAST]
attParser Text
v) Text
"" of
(AP.Done Text
_ [AttAST]
res) -> [AttAST]
res
(AP.Fail Text
_ [FilePath]
_ FilePath
_) -> []
(AP.Partial Text -> IResult Text [AttAST]
_ ) -> []
[DList (Chunk n)]
chunks <- (AttAST -> HeistT n IO (DList (Chunk n)))
-> [AttAST] -> HeistT n IO [DList (Chunk n)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM AttAST -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *). AttAST -> HeistT n IO (DList (Chunk n))
cvt [AttAST]
ast
let value :: DList (Chunk n)
value = [DList (Chunk n)] -> DList (Chunk n)
forall a. [DList a] -> DList a
DL.concat [DList (Chunk n)]
chunks
DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> HeistT n IO (DList (Chunk n)))
-> DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ Text -> DList (Chunk n) -> DList (Chunk n)
forall (n :: * -> *). Text -> DList (Chunk n) -> DList (Chunk n)
attrToChunk Text
k DList (Chunk n)
value
doAttrSplice :: (Text -> RuntimeSplice m [(Text, Text)]) -> DList (Chunk m)
doAttrSplice Text -> RuntimeSplice m [(Text, Text)]
splice = Chunk m -> DList (Chunk m)
forall a. a -> DList a
DL.singleton (Chunk m -> DList (Chunk m)) -> Chunk m -> DList (Chunk m)
forall a b. (a -> b) -> a -> b
$ RuntimeSplice m Builder -> Chunk m
forall (m :: * -> *). RuntimeSplice m Builder -> Chunk m
RuntimeHtml (RuntimeSplice m Builder -> Chunk m)
-> RuntimeSplice m Builder -> Chunk m
forall a b. (a -> b) -> a -> b
$ do
[(Text, Text)]
res <- Text -> RuntimeSplice m [(Text, Text)]
splice Text
v
Builder -> RuntimeSplice m Builder
forall (m :: * -> *) a. Monad m => a -> m a
return (Builder -> RuntimeSplice m Builder)
-> Builder -> RuntimeSplice m Builder
forall a b. (a -> b) -> a -> b
$ [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder) -> [Builder] -> Builder
forall a b. (a -> b) -> a -> b
$ ((Text, Text) -> Builder) -> [(Text, Text)] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> Builder
attrToBuilder [(Text, Text)]
res
parseAtt2 :: Monad n
=> (Text, Text)
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
parseAtt2 :: (Text, Text) -> HeistT n IO (RuntimeSplice n [(Text, Text)])
parseAtt2 (Text
k,Text
v) = do
Maybe (AttrSplice n)
mas <- (HeistState n -> Maybe (AttrSplice n))
-> HeistT n IO (Maybe (AttrSplice n))
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS (Text -> HashMap Text (AttrSplice n) -> Maybe (AttrSplice n)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
H.lookup Text
k (HashMap Text (AttrSplice n) -> Maybe (AttrSplice n))
-> (HeistState n -> HashMap Text (AttrSplice n))
-> HeistState n
-> Maybe (AttrSplice n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeistState n -> HashMap Text (AttrSplice n)
forall (m :: * -> *). HeistState m -> HashMap Text (AttrSplice m)
_attrSpliceMap)
HeistT n IO (RuntimeSplice n [(Text, Text)])
-> (AttrSplice n -> HeistT n IO (RuntimeSplice n [(Text, Text)]))
-> Maybe (AttrSplice n)
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe HeistT n IO (RuntimeSplice n [(Text, Text)])
forall (n :: * -> *).
Monad n =>
HeistT n IO (RuntimeSplice n [(Text, Text)])
doInline (RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall (m :: * -> *) a. Monad m => a -> m a
return (RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)]))
-> (AttrSplice n -> RuntimeSplice n [(Text, Text)])
-> AttrSplice n
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AttrSplice n -> RuntimeSplice n [(Text, Text)]
forall t. (Text -> t) -> t
doAttrSplice) Maybe (AttrSplice n)
mas
where
cvt :: AttAST -> HeistT n IO (RuntimeSplice n Text)
cvt (Literal Text
x) = RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text))
-> RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text)
forall a b. (a -> b) -> a -> b
$ Text -> RuntimeSplice n Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
x
cvt (Ident Text
x) =
(Node -> Node)
-> HeistT n IO (RuntimeSplice n Text)
-> HeistT n IO (RuntimeSplice n Text)
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
(Node -> Node) -> HeistT n m a -> HeistT n m a
localParamNode (Node -> Node -> Node
forall a b. a -> b -> a
const (Node -> Node -> Node) -> Node -> Node -> Node
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> [Node] -> Node
X.Element Text
x [] []) (HeistT n IO (RuntimeSplice n Text)
-> HeistT n IO (RuntimeSplice n Text))
-> HeistT n IO (RuntimeSplice n Text)
-> HeistT n IO (RuntimeSplice n Text)
forall a b. (a -> b) -> a -> b
$ Text -> HeistT n IO (RuntimeSplice n Text)
forall (n :: * -> *).
Monad n =>
Text -> HeistT n IO (RuntimeSplice n Text)
getAttributeSplice2 Text
x
doInline :: HeistT n IO (RuntimeSplice n [(Text, Text)])
doInline = do
let ast :: [AttAST]
ast = case IResult Text [AttAST] -> Text -> IResult Text [AttAST]
forall i r. Monoid i => IResult i r -> i -> IResult i r
AP.feed (Parser [AttAST] -> Text -> IResult Text [AttAST]
forall a. Parser a -> Text -> Result a
AP.parse Parser [AttAST]
attParser Text
v) Text
"" of
(AP.Done Text
_ [AttAST]
res) -> [AttAST]
res
(AP.Fail Text
_ [FilePath]
_ FilePath
_) -> []
(AP.Partial Text -> IResult Text [AttAST]
_ ) -> []
[RuntimeSplice n Text]
chunks <- (AttAST -> HeistT n IO (RuntimeSplice n Text))
-> [AttAST] -> HeistT n IO [RuntimeSplice n Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM AttAST -> HeistT n IO (RuntimeSplice n Text)
forall (n :: * -> *).
Monad n =>
AttAST -> HeistT n IO (RuntimeSplice n Text)
cvt [AttAST]
ast
RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall (m :: * -> *) a. Monad m => a -> m a
return (RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)]))
-> RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall a b. (a -> b) -> a -> b
$ do
[Text]
list <- [RuntimeSplice n Text] -> RuntimeSplice n [Text]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [RuntimeSplice n Text]
chunks
[(Text, Text)] -> RuntimeSplice n [(Text, Text)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(Text
k, [Text] -> Text
T.concat [Text]
list)]
doAttrSplice :: (Text -> t) -> t
doAttrSplice Text -> t
splice = Text -> t
splice Text
v
runAttributes :: Monad n
=> [(Text, Text)]
-> HeistT n IO [DList (Chunk n)]
runAttributes :: [(Text, Text)] -> HeistT n IO [DList (Chunk n)]
runAttributes = ((Text, Text) -> HeistT n IO (DList (Chunk n)))
-> [(Text, Text)] -> HeistT n IO [DList (Chunk n)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Text, Text) -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *).
Monad n =>
(Text, Text) -> HeistT n IO (DList (Chunk n))
parseAtt
runAttributesRaw :: Monad n
=> [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
runAttributesRaw :: [(Text, Text)] -> HeistT n IO (RuntimeSplice n [(Text, Text)])
runAttributesRaw [(Text, Text)]
attrs = do
[RuntimeSplice n [(Text, Text)]]
arrs <- ((Text, Text) -> HeistT n IO (RuntimeSplice n [(Text, Text)]))
-> [(Text, Text)] -> HeistT n IO [RuntimeSplice n [(Text, Text)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Text, Text) -> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall (n :: * -> *).
Monad n =>
(Text, Text) -> HeistT n IO (RuntimeSplice n [(Text, Text)])
parseAtt2 [(Text, Text)]
attrs
RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall (m :: * -> *) a. Monad m => a -> m a
return (RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)]))
-> RuntimeSplice n [(Text, Text)]
-> HeistT n IO (RuntimeSplice n [(Text, Text)])
forall a b. (a -> b) -> a -> b
$ ([[(Text, Text)]] -> [(Text, Text)])
-> RuntimeSplice n [[(Text, Text)]]
-> RuntimeSplice n [(Text, Text)]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM [[(Text, Text)]] -> [(Text, Text)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (RuntimeSplice n [[(Text, Text)]]
-> RuntimeSplice n [(Text, Text)])
-> RuntimeSplice n [[(Text, Text)]]
-> RuntimeSplice n [(Text, Text)]
forall a b. (a -> b) -> a -> b
$ [RuntimeSplice n [(Text, Text)]]
-> RuntimeSplice n [[(Text, Text)]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [RuntimeSplice n [(Text, Text)]]
arrs
attrToChunk :: Text -> DList (Chunk n) -> DList (Chunk n)
attrToChunk :: Text -> DList (Chunk n) -> DList (Chunk n)
attrToChunk !Text
k !DList (Chunk n)
v = do
[DList (Chunk n)] -> DList (Chunk n)
forall a. [DList a] -> DList a
DL.concat
[ Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk (Text -> Chunk n) -> Text -> Chunk n
forall a b. (a -> b) -> a -> b
$! [Text] -> Text
T.concat [Text
" ", Text
k, Text
"=\""]
, DList (Chunk n)
v, Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$! Text -> Chunk n
forall (n :: * -> *). Text -> Chunk n
pureTextChunk Text
"\"" ]
attrToBuilder :: (Text, Text) -> Builder
attrToBuilder :: (Text, Text) -> Builder
attrToBuilder (Text
k,Text
v)
| Text -> Bool
T.null Text
v = [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat
[ Text -> Builder
fromText Text
" "
, Text -> Builder
fromText Text
k
]
| Bool
otherwise = [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat
[ Text -> Builder
fromText Text
" "
, Text -> Builder
fromText Text
k
, Text -> Builder
fromText Text
"=\""
, Text -> Builder
fromText Text
v
, Text -> Builder
fromText Text
"\""
]
getAttributeSplice :: Text -> HeistT n IO (DList (Chunk n))
getAttributeSplice :: Text -> HeistT n IO (DList (Chunk n))
getAttributeSplice Text
name =
Text -> HeistT n IO (Maybe (HeistT n IO (DList (Chunk n))))
forall (n :: * -> *). Text -> HeistT n IO (Maybe (Splice n))
lookupSplice Text
name HeistT n IO (Maybe (HeistT n IO (DList (Chunk n))))
-> (Maybe (HeistT n IO (DList (Chunk n)))
-> HeistT n IO (DList (Chunk n)))
-> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HeistT n IO (DList (Chunk n))
-> Maybe (HeistT n IO (DList (Chunk n)))
-> HeistT n IO (DList (Chunk n))
forall a. a -> Maybe a -> a
fromMaybe
(DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> HeistT n IO (DList (Chunk n)))
-> DList (Chunk n) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ Chunk n -> DList (Chunk n)
forall a. a -> DList a
DL.singleton (Chunk n -> DList (Chunk n)) -> Chunk n -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$ ByteString -> Chunk n
forall (m :: * -> *). ByteString -> Chunk m
Pure (ByteString -> Chunk n) -> ByteString -> Chunk n
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$
[Text] -> Text
T.concat [Text
"${", Text
name, Text
"}"])
{-# INLINE getAttributeSplice #-}
getAttributeSplice2 :: Monad n => Text -> HeistT n IO (RuntimeSplice n Text)
getAttributeSplice2 :: Text -> HeistT n IO (RuntimeSplice n Text)
getAttributeSplice2 Text
name = do
Maybe (Splice n)
mSplice <- Text -> HeistT n IO (Maybe (Splice n))
forall (n :: * -> *). Text -> HeistT n IO (Maybe (Splice n))
lookupSplice Text
name
case Maybe (Splice n)
mSplice of
Maybe (Splice n)
Nothing -> RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text))
-> RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text)
forall a b. (a -> b) -> a -> b
$ Text -> RuntimeSplice n Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> RuntimeSplice n Text) -> Text -> RuntimeSplice n Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat [Text
"${", Text
name, Text
"}"]
Just Splice n
splice -> do
DList (Chunk n)
res <- Splice n
splice
RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text))
-> RuntimeSplice n Text -> HeistT n IO (RuntimeSplice n Text)
forall a b. (a -> b) -> a -> b
$ (Builder -> Text)
-> RuntimeSplice n Builder -> RuntimeSplice n Text
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (ByteString -> Text
T.decodeUtf8 (ByteString -> Text) -> (Builder -> ByteString) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toByteString) (RuntimeSplice n Builder -> RuntimeSplice n Text)
-> RuntimeSplice n Builder -> RuntimeSplice n Text
forall a b. (a -> b) -> a -> b
$ DList (Chunk n) -> RuntimeSplice n Builder
forall (n :: * -> *).
Monad n =>
DList (Chunk n) -> RuntimeSplice n Builder
codeGen DList (Chunk n)
res
{-# INLINE getAttributeSplice2 #-}
newtype Promise a = Promise (HE.Key a)
getPromise :: (Monad n) => Promise a -> RuntimeSplice n a
getPromise :: Promise a -> RuntimeSplice n a
getPromise (Promise Key a
k) = do
Maybe a
mb <- (HeterogeneousEnvironment -> Maybe a) -> RuntimeSplice n (Maybe a)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (Key a -> HeterogeneousEnvironment -> Maybe a
forall a. Key a -> HeterogeneousEnvironment -> Maybe a
HE.lookup Key a
k)
a -> RuntimeSplice n a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> RuntimeSplice n a) -> a -> RuntimeSplice n a
forall a b. (a -> b) -> a -> b
$ a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall a. a
e Maybe a
mb
where
e :: a
e = FilePath -> a
forall a. HasCallStack => FilePath -> a
error (FilePath -> a) -> FilePath -> a
forall a b. (a -> b) -> a -> b
$ FilePath
"getPromise: dereferenced empty key (id "
FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Int -> FilePath
forall a. Show a => a -> FilePath
show (Key a -> Int
forall a. Key a -> Int
HE.getKeyId Key a
k) FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
")"
{-# INLINE getPromise #-}
putPromise :: (Monad n) => Promise a -> a -> RuntimeSplice n ()
putPromise :: Promise a -> a -> RuntimeSplice n ()
putPromise (Promise Key a
k) a
x = (HeterogeneousEnvironment -> HeterogeneousEnvironment)
-> RuntimeSplice n ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Key a -> a -> HeterogeneousEnvironment -> HeterogeneousEnvironment
forall a.
Key a -> a -> HeterogeneousEnvironment -> HeterogeneousEnvironment
HE.insert Key a
k a
x)
{-# INLINE putPromise #-}
adjustPromise :: Monad n => Promise a -> (a -> a) -> RuntimeSplice n ()
adjustPromise :: Promise a -> (a -> a) -> RuntimeSplice n ()
adjustPromise (Promise Key a
k) a -> a
f = (HeterogeneousEnvironment -> HeterogeneousEnvironment)
-> RuntimeSplice n ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((a -> a)
-> Key a -> HeterogeneousEnvironment -> HeterogeneousEnvironment
forall a.
(a -> a)
-> Key a -> HeterogeneousEnvironment -> HeterogeneousEnvironment
HE.adjust a -> a
f Key a
k)
{-# INLINE adjustPromise #-}
newEmptyPromise :: HeistT n IO (Promise a)
newEmptyPromise :: HeistT n IO (Promise a)
newEmptyPromise = do
KeyGen
keygen <- (HeistState n -> KeyGen) -> HeistT n IO KeyGen
forall (m :: * -> *) (n :: * -> *) r.
Monad m =>
(HeistState n -> r) -> HeistT n m r
getsHS HeistState n -> KeyGen
forall (m :: * -> *). HeistState m -> KeyGen
_keygen
Key a
key <- IO (Key a) -> HeistT n IO (Key a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Key a) -> HeistT n IO (Key a))
-> IO (Key a) -> HeistT n IO (Key a)
forall a b. (a -> b) -> a -> b
$ KeyGen -> IO (Key a)
forall a. KeyGen -> IO (Key a)
HE.makeKey KeyGen
keygen
Promise a -> HeistT n IO (Promise a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Promise a -> HeistT n IO (Promise a))
-> Promise a -> HeistT n IO (Promise a)
forall a b. (a -> b) -> a -> b
$! Key a -> Promise a
forall a. Key a -> Promise a
Promise Key a
key
{-# INLINE newEmptyPromise #-}
bindSplice :: Text
-> Splice n
-> HeistState n
-> HeistState n
bindSplice :: Text -> Splice n -> HeistState n -> HeistState n
bindSplice Text
n Splice n
v HeistState n
ts =
HeistState n
ts { _compiledSpliceMap :: HashMap Text (Splice n)
_compiledSpliceMap = Text
-> Splice n -> HashMap Text (Splice n) -> HashMap Text (Splice n)
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
H.insert Text
n' Splice n
v (HeistState n -> HashMap Text (Splice n)
forall (m :: * -> *).
HeistState m -> HashMap Text (HeistT m IO (DList (Chunk m)))
_compiledSpliceMap HeistState n
ts) }
where
n' :: Text
n' = HeistState n -> Text
forall (m :: * -> *). HeistState m -> Text
_splicePrefix HeistState n
ts Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` Text
n
bindSplices :: Splices (Splice n)
-> HeistState n
-> HeistState n
bindSplices :: Splices (Splice n) -> HeistState n -> HeistState n
bindSplices Splices (Splice n)
ss HeistState n
hs =
HeistState n
hs { _compiledSpliceMap :: HashMap Text (Splice n)
_compiledSpliceMap = HeistState n
-> (HeistState n -> HashMap Text (Splice n))
-> Splices (Splice n)
-> HashMap Text (Splice n)
forall (n :: * -> *) v a.
HeistState n
-> (HeistState n -> HashMap Text v)
-> MapSyntaxM Text v a
-> HashMap Text v
applySpliceMap HeistState n
hs HeistState n -> HashMap Text (Splice n)
forall (m :: * -> *).
HeistState m -> HashMap Text (HeistT m IO (DList (Chunk m)))
_compiledSpliceMap Splices (Splice n)
ss }
withLocalSplices :: Splices (Splice n)
-> Splices (AttrSplice n)
-> HeistT n IO a
-> HeistT n IO a
withLocalSplices :: Splices (Splice n)
-> Splices (AttrSplice n) -> HeistT n IO a -> HeistT n IO a
withLocalSplices Splices (Splice n)
ss Splices (AttrSplice n)
as = (HeistState n -> HeistState n) -> HeistT n IO a -> HeistT n IO a
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m a -> HeistT n m a
localHS (Splices (Splice n) -> HeistState n -> HeistState n
forall (n :: * -> *).
Splices (Splice n) -> HeistState n -> HeistState n
bindSplices Splices (Splice n)
ss (HeistState n -> HeistState n)
-> (HeistState n -> HeistState n) -> HeistState n -> HeistState n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Splices (AttrSplice n) -> HeistState n -> HeistState n
forall (n :: * -> *).
Splices (AttrSplice n) -> HeistState n -> HeistState n
bindAttributeSplices Splices (AttrSplice n)
as)
renderTemplate :: Monad n
=> HeistState n
-> ByteString
-> Maybe (n Builder, MIMEType)
renderTemplate :: HeistState n -> ByteString -> Maybe (n Builder, ByteString)
renderTemplate HeistState n
hs ByteString
nm =
((([Chunk n], ByteString), TPath) -> (n Builder, ByteString))
-> Maybe (([Chunk n], ByteString), TPath)
-> Maybe (n Builder, ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Chunk n] -> n Builder)
-> ([Chunk n], ByteString) -> (n Builder, ByteString)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (DList (Chunk n) -> n Builder
forall (n :: * -> *). Monad n => DList (Chunk n) -> n Builder
interpret (DList (Chunk n) -> n Builder)
-> ([Chunk n] -> DList (Chunk n)) -> [Chunk n] -> n Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Chunk n] -> DList (Chunk n)
forall a. [a] -> DList a
DL.fromList) (([Chunk n], ByteString) -> (n Builder, ByteString))
-> ((([Chunk n], ByteString), TPath) -> ([Chunk n], ByteString))
-> (([Chunk n], ByteString), TPath)
-> (n Builder, ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Chunk n], ByteString), TPath) -> ([Chunk n], ByteString)
forall a b. (a, b) -> a
fst) (Maybe (([Chunk n], ByteString), TPath)
-> Maybe (n Builder, ByteString))
-> Maybe (([Chunk n], ByteString), TPath)
-> Maybe (n Builder, ByteString)
forall a b. (a -> b) -> a -> b
$!
ByteString
-> HeistState n
-> (HeistState n -> HashMap TPath ([Chunk n], ByteString))
-> Maybe (([Chunk n], ByteString), TPath)
forall (n :: * -> *) t.
ByteString
-> HeistState n
-> (HeistState n -> HashMap TPath t)
-> Maybe (t, TPath)
lookupTemplate ByteString
nm HeistState n
hs HeistState n -> HashMap TPath ([Chunk n], ByteString)
forall (m :: * -> *).
HeistState m -> HashMap TPath ([Chunk m], ByteString)
_compiledTemplateMap
callTemplate :: Monad n
=> ByteString
-> Splice n
callTemplate :: ByteString -> Splice n
callTemplate ByteString
nm = do
HeistState n
hs <- HeistT n IO (HeistState n)
forall (m :: * -> *) (n :: * -> *).
Monad m =>
HeistT n m (HeistState n)
getHS
Splice n
-> ((DocumentFile, TPath) -> Splice n)
-> Maybe (DocumentFile, TPath)
-> Splice n
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (FilePath -> Splice n
forall a. HasCallStack => FilePath -> a
error FilePath
err) (DocumentFile, TPath) -> Splice n
forall (n :: * -> *) b.
Monad n =>
(DocumentFile, b) -> HeistT n IO (DList (Chunk n))
call (Maybe (DocumentFile, TPath) -> Splice n)
-> Maybe (DocumentFile, TPath) -> Splice n
forall a b. (a -> b) -> a -> b
$ ByteString
-> HeistState n
-> (HeistState n -> HashMap TPath DocumentFile)
-> Maybe (DocumentFile, TPath)
forall (n :: * -> *) t.
ByteString
-> HeistState n
-> (HeistState n -> HashMap TPath t)
-> Maybe (t, TPath)
lookupTemplate ByteString
nm HeistState n
hs HeistState n -> HashMap TPath DocumentFile
forall (m :: * -> *). HeistState m -> HashMap TPath DocumentFile
_templateMap
where
err :: FilePath
err = FilePath
"callTemplate: "FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++(Text -> FilePath
T.unpack (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
T.decodeUtf8 ByteString
nm)FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++(FilePath
" does not exist")
call :: (DocumentFile, b) -> HeistT n IO (DList (Chunk n))
call (DocumentFile
df,b
_) = (HeistState n -> HeistState n)
-> HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall (m :: * -> *) (n :: * -> *) a.
Monad m =>
(HeistState n -> HeistState n) -> HeistT n m a -> HeistT n m a
localHS (\HeistState n
hs' -> HeistState n
hs' {_curTemplateFile :: Maybe FilePath
_curTemplateFile = DocumentFile -> Maybe FilePath
dfFile DocumentFile
df}) (HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n)))
-> HeistT n IO (DList (Chunk n)) -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$
[Node] -> HeistT n IO (DList (Chunk n))
forall (n :: * -> *). Monad n => [Node] -> Splice n
runNodeList ([Node] -> HeistT n IO (DList (Chunk n)))
-> [Node] -> HeistT n IO (DList (Chunk n))
forall a b. (a -> b) -> a -> b
$ Document -> [Node]
X.docContent (Document -> [Node]) -> Document -> [Node]
forall a b. (a -> b) -> a -> b
$ DocumentFile -> Document
dfDoc DocumentFile
df
interpret :: Monad n => DList (Chunk n) -> n Builder
interpret :: DList (Chunk n) -> n Builder
interpret = (StateT HeterogeneousEnvironment n Builder
-> HeterogeneousEnvironment -> n Builder)
-> HeterogeneousEnvironment
-> StateT HeterogeneousEnvironment n Builder
-> n Builder
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT HeterogeneousEnvironment n Builder
-> HeterogeneousEnvironment -> n Builder
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT HeterogeneousEnvironment
HE.empty (StateT HeterogeneousEnvironment n Builder -> n Builder)
-> (DList (Chunk n) -> StateT HeterogeneousEnvironment n Builder)
-> DList (Chunk n)
-> n Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuntimeSplice n Builder
-> StateT HeterogeneousEnvironment n Builder
forall (m :: * -> *) a.
RuntimeSplice m a -> StateT HeterogeneousEnvironment m a
unRT (RuntimeSplice n Builder
-> StateT HeterogeneousEnvironment n Builder)
-> (DList (Chunk n) -> RuntimeSplice n Builder)
-> DList (Chunk n)
-> StateT HeterogeneousEnvironment n Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList (Chunk n) -> RuntimeSplice n Builder
forall (n :: * -> *).
Monad n =>
DList (Chunk n) -> RuntimeSplice n Builder
codeGen
textSplice :: (a -> Text) -> a -> Builder
textSplice :: (a -> Text) -> a -> Builder
textSplice a -> Text
f = Text -> Builder
fromText (Text -> Builder) -> (a -> Text) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
f
nodeSplice :: (a -> [X.Node]) -> a -> Builder
nodeSplice :: (a -> [Node]) -> a -> Builder
nodeSplice a -> [Node]
f = Encoding -> [Node] -> Builder
X.renderHtmlFragment Encoding
X.UTF8 ([Node] -> Builder) -> (a -> [Node]) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Node]
f
{-# DEPRECATED nodeSplice
"Use xmlNodeSplice or htmlNodeSplice, will be removed in Heist 1.1" #-}
xmlNodeSplice :: (a -> [X.Node]) -> a -> Builder
xmlNodeSplice :: (a -> [Node]) -> a -> Builder
xmlNodeSplice a -> [Node]
f = Encoding -> [Node] -> Builder
X.renderXmlFragment Encoding
X.UTF8 ([Node] -> Builder) -> (a -> [Node]) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Node]
f
htmlNodeSplice :: (a -> [X.Node]) -> a -> Builder
htmlNodeSplice :: (a -> [Node]) -> a -> Builder
htmlNodeSplice a -> [Node]
f = Encoding -> [Node] -> Builder
X.renderHtmlFragment Encoding
X.UTF8 ([Node] -> Builder) -> (a -> [Node]) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Node]
f
pureSplice :: Monad n => (a -> Builder) -> RuntimeSplice n a -> Splice n
pureSplice :: (a -> Builder) -> RuntimeSplice n a -> Splice n
pureSplice a -> Builder
f RuntimeSplice n a
n = DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> Splice n) -> DList (Chunk n) -> Splice n
forall a b. (a -> b) -> a -> b
$ RuntimeSplice n Builder -> DList (Chunk n)
forall (n :: * -> *). RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime (Builder -> RuntimeSplice n Builder
forall (m :: * -> *) a. Monad m => a -> m a
return (Builder -> RuntimeSplice n Builder)
-> (a -> Builder) -> a -> RuntimeSplice n Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder
f (a -> RuntimeSplice n Builder)
-> RuntimeSplice n a -> RuntimeSplice n Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< RuntimeSplice n a
n)
withSplices :: Monad n
=> Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n a
-> Splice n
withSplices :: Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n a
-> Splice n
withSplices Splice n
splice Splices (RuntimeSplice n a -> Splice n)
splices RuntimeSplice n a
runtimeAction =
Splices (Splice n)
-> Splices (AttrSplice n) -> Splice n -> Splice n
forall (n :: * -> *) a.
Splices (Splice n)
-> Splices (AttrSplice n) -> HeistT n IO a -> HeistT n IO a
withLocalSplices Splices (Splice n)
splices' Splices (AttrSplice n)
forall a. Monoid a => a
mempty Splice n
splice
where
splices' :: Splices (Splice n)
splices' = ((RuntimeSplice n a -> Splice n) -> Splice n)
-> Splices (RuntimeSplice n a -> Splice n) -> Splices (Splice n)
forall v1 v2 k a. (v1 -> v2) -> MapSyntaxM k v1 a -> MapSyntax k v2
mapV ((RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n
forall a b. (a -> b) -> a -> b
$RuntimeSplice n a
runtimeAction) Splices (RuntimeSplice n a -> Splice n)
splices
{-# INLINE foldMapM #-}
foldMapM :: (Monad f, Monoid m, Foldable list)
=> (a -> f m)
-> list a
-> f m
foldMapM :: (a -> f m) -> list a -> f m
foldMapM a -> f m
f =
(m -> a -> f m) -> m -> list a -> f m
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
Foldable.foldlM (\m
xs a
x -> m
xs m -> f m -> f m
`seq` (m -> m) -> f m -> f m
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (m
xs m -> m -> m
forall a. Semigroup a => a -> a -> a
<>) (a -> f m
f a
x)) m
forall a. Monoid a => a
mempty
manyWithSplices :: (Foldable f, Monad n)
=> Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a)
-> Splice n
manyWithSplices :: Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a)
-> Splice n
manyWithSplices Splice n
splice Splices (RuntimeSplice n a -> Splice n)
splices RuntimeSplice n (f a)
runtimeAction =
Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> Splices (RuntimeSplice n a -> AttrSplice n)
-> RuntimeSplice n (f a)
-> Splice n
forall (f :: * -> *) (n :: * -> *) a.
(Foldable f, Monad n) =>
Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> Splices (RuntimeSplice n a -> AttrSplice n)
-> RuntimeSplice n (f a)
-> Splice n
manyWith Splice n
splice Splices (RuntimeSplice n a -> Splice n)
splices Splices (RuntimeSplice n a -> AttrSplice n)
forall a. Monoid a => a
mempty RuntimeSplice n (f a)
runtimeAction
manyWith :: (Foldable f, Monad n)
=> Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> Splices (RuntimeSplice n a -> AttrSplice n)
-> RuntimeSplice n (f a)
-> Splice n
manyWith :: Splice n
-> Splices (RuntimeSplice n a -> Splice n)
-> Splices (RuntimeSplice n a -> AttrSplice n)
-> RuntimeSplice n (f a)
-> Splice n
manyWith Splice n
splice Splices (RuntimeSplice n a -> Splice n)
splices Splices (RuntimeSplice n a -> AttrSplice n)
attrSplices RuntimeSplice n (f a)
runtimeAction = do
Promise a
p <- HeistT n IO (Promise a)
forall (n :: * -> *) a. HeistT n IO (Promise a)
newEmptyPromise
let splices' :: MapSyntax Text (Splice n)
splices' = ((RuntimeSplice n a -> Splice n) -> Splice n)
-> Splices (RuntimeSplice n a -> Splice n)
-> MapSyntax Text (Splice n)
forall v1 v2 k a. (v1 -> v2) -> MapSyntaxM k v1 a -> MapSyntax k v2
mapV ((RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n
forall a b. (a -> b) -> a -> b
$ Promise a -> RuntimeSplice n a
forall (n :: * -> *) a. Monad n => Promise a -> RuntimeSplice n a
getPromise Promise a
p) Splices (RuntimeSplice n a -> Splice n)
splices
let attrSplices' :: MapSyntax Text (AttrSplice n)
attrSplices' = ((RuntimeSplice n a -> AttrSplice n) -> AttrSplice n)
-> Splices (RuntimeSplice n a -> AttrSplice n)
-> MapSyntax Text (AttrSplice n)
forall v1 v2 k a. (v1 -> v2) -> MapSyntaxM k v1 a -> MapSyntax k v2
mapV ((RuntimeSplice n a -> AttrSplice n)
-> RuntimeSplice n a -> AttrSplice n
forall a b. (a -> b) -> a -> b
$ Promise a -> RuntimeSplice n a
forall (n :: * -> *) a. Monad n => Promise a -> RuntimeSplice n a
getPromise Promise a
p) Splices (RuntimeSplice n a -> AttrSplice n)
attrSplices
DList (Chunk n)
chunks <- MapSyntax Text (Splice n)
-> MapSyntax Text (AttrSplice n) -> Splice n -> Splice n
forall (n :: * -> *) a.
Splices (Splice n)
-> Splices (AttrSplice n) -> HeistT n IO a -> HeistT n IO a
withLocalSplices MapSyntax Text (Splice n)
splices' MapSyntax Text (AttrSplice n)
attrSplices' Splice n
splice
DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> Splice n) -> DList (Chunk n) -> Splice n
forall a b. (a -> b) -> a -> b
$ RuntimeSplice n Builder -> DList (Chunk n)
forall (n :: * -> *). RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime (RuntimeSplice n Builder -> DList (Chunk n))
-> RuntimeSplice n Builder -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$ do
f a
items <- RuntimeSplice n (f a)
runtimeAction
(a -> RuntimeSplice n Builder) -> f a -> RuntimeSplice n Builder
forall (f :: * -> *) m (list :: * -> *) a.
(Monad f, Monoid m, Foldable list) =>
(a -> f m) -> list a -> f m
foldMapM (\a
item -> Promise a -> a -> RuntimeSplice n ()
forall (n :: * -> *) a.
Monad n =>
Promise a -> a -> RuntimeSplice n ()
putPromise Promise a
p a
item RuntimeSplice n ()
-> RuntimeSplice n Builder -> RuntimeSplice n Builder
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> DList (Chunk n) -> RuntimeSplice n Builder
forall (n :: * -> *).
Monad n =>
DList (Chunk n) -> RuntimeSplice n Builder
codeGen DList (Chunk n)
chunks) f a
items
deferMany :: (Foldable f, Monad n)
=> (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a)
-> Splice n
deferMany :: (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a) -> Splice n
deferMany RuntimeSplice n a -> Splice n
f RuntimeSplice n (f a)
getItems = do
Promise a
promise <- HeistT n IO (Promise a)
forall (n :: * -> *) a. HeistT n IO (Promise a)
newEmptyPromise
DList (Chunk n)
chunks <- RuntimeSplice n a -> Splice n
f (RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n
forall a b. (a -> b) -> a -> b
$ Promise a -> RuntimeSplice n a
forall (n :: * -> *) a. Monad n => Promise a -> RuntimeSplice n a
getPromise Promise a
promise
DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> Splice n) -> DList (Chunk n) -> Splice n
forall a b. (a -> b) -> a -> b
$ RuntimeSplice n Builder -> DList (Chunk n)
forall (n :: * -> *). RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime (RuntimeSplice n Builder -> DList (Chunk n))
-> RuntimeSplice n Builder -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$ do
f a
items <- RuntimeSplice n (f a)
getItems
(a -> RuntimeSplice n Builder) -> f a -> RuntimeSplice n Builder
forall (f :: * -> *) m (list :: * -> *) a.
(Monad f, Monoid m, Foldable list) =>
(a -> f m) -> list a -> f m
foldMapM (\a
item -> Promise a -> a -> RuntimeSplice n ()
forall (n :: * -> *) a.
Monad n =>
Promise a -> a -> RuntimeSplice n ()
putPromise Promise a
promise a
item RuntimeSplice n ()
-> RuntimeSplice n Builder -> RuntimeSplice n Builder
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> DList (Chunk n) -> RuntimeSplice n Builder
forall (n :: * -> *).
Monad n =>
DList (Chunk n) -> RuntimeSplice n Builder
codeGen DList (Chunk n)
chunks) f a
items
defer :: Monad n
=> (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n a -> Splice n
defer :: (RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n
defer RuntimeSplice n a -> Splice n
pf RuntimeSplice n a
n = do
Promise a
p2 <- HeistT n IO (Promise a)
forall (n :: * -> *) a. HeistT n IO (Promise a)
newEmptyPromise
let action :: DList (Chunk n)
action = RuntimeSplice n () -> DList (Chunk n)
forall (n :: * -> *).
Monad n =>
RuntimeSplice n () -> DList (Chunk n)
yieldRuntimeEffect (RuntimeSplice n () -> DList (Chunk n))
-> RuntimeSplice n () -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$ Promise a -> a -> RuntimeSplice n ()
forall (n :: * -> *) a.
Monad n =>
Promise a -> a -> RuntimeSplice n ()
putPromise Promise a
p2 (a -> RuntimeSplice n ())
-> RuntimeSplice n a -> RuntimeSplice n ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< RuntimeSplice n a
n
DList (Chunk n)
res <- RuntimeSplice n a -> Splice n
pf (RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n
forall a b. (a -> b) -> a -> b
$ Promise a -> RuntimeSplice n a
forall (n :: * -> *) a. Monad n => Promise a -> RuntimeSplice n a
getPromise Promise a
p2
DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> Splice n) -> DList (Chunk n) -> Splice n
forall a b. (a -> b) -> a -> b
$ DList (Chunk n)
action DList (Chunk n) -> DList (Chunk n) -> DList (Chunk n)
forall a. Monoid a => a -> a -> a
`mappend` DList (Chunk n)
res
deferMap :: Monad n
=> (a -> RuntimeSplice n b)
-> (RuntimeSplice n b -> Splice n)
-> RuntimeSplice n a -> Splice n
deferMap :: (a -> RuntimeSplice n b)
-> (RuntimeSplice n b -> Splice n) -> RuntimeSplice n a -> Splice n
deferMap a -> RuntimeSplice n b
f RuntimeSplice n b -> Splice n
pf RuntimeSplice n a
n = (RuntimeSplice n b -> Splice n) -> RuntimeSplice n b -> Splice n
forall (n :: * -> *) a.
Monad n =>
(RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n
defer RuntimeSplice n b -> Splice n
pf (RuntimeSplice n b -> Splice n) -> RuntimeSplice n b -> Splice n
forall a b. (a -> b) -> a -> b
$ a -> RuntimeSplice n b
f (a -> RuntimeSplice n b) -> RuntimeSplice n a -> RuntimeSplice n b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< RuntimeSplice n a
n
mayDeferMap :: Monad n
=> (a -> RuntimeSplice n (Maybe b))
-> (RuntimeSplice n b -> Splice n)
-> RuntimeSplice n a -> Splice n
mayDeferMap :: (a -> RuntimeSplice n (Maybe b))
-> (RuntimeSplice n b -> Splice n) -> RuntimeSplice n a -> Splice n
mayDeferMap a -> RuntimeSplice n (Maybe b)
f RuntimeSplice n b -> Splice n
pf RuntimeSplice n a
n = (RuntimeSplice n b -> Splice n)
-> RuntimeSplice n (Maybe b) -> Splice n
forall (f :: * -> *) (n :: * -> *) a.
(Foldable f, Monad n) =>
(RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a) -> Splice n
deferMany RuntimeSplice n b -> Splice n
pf (RuntimeSplice n (Maybe b) -> Splice n)
-> RuntimeSplice n (Maybe b) -> Splice n
forall a b. (a -> b) -> a -> b
$ a -> RuntimeSplice n (Maybe b)
f (a -> RuntimeSplice n (Maybe b))
-> RuntimeSplice n a -> RuntimeSplice n (Maybe b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< RuntimeSplice n a
n
bindLater :: (Monad n)
=> (a -> RuntimeSplice n Builder)
-> RuntimeSplice n a
-> Splice n
bindLater :: (a -> RuntimeSplice n Builder) -> RuntimeSplice n a -> Splice n
bindLater a -> RuntimeSplice n Builder
f RuntimeSplice n a
p = DList (Chunk n) -> Splice n
forall (m :: * -> *) a. Monad m => a -> m a
return (DList (Chunk n) -> Splice n) -> DList (Chunk n) -> Splice n
forall a b. (a -> b) -> a -> b
$ RuntimeSplice n Builder -> DList (Chunk n)
forall (n :: * -> *). RuntimeSplice n Builder -> DList (Chunk n)
yieldRuntime (RuntimeSplice n Builder -> DList (Chunk n))
-> RuntimeSplice n Builder -> DList (Chunk n)
forall a b. (a -> b) -> a -> b
$ a -> RuntimeSplice n Builder
f (a -> RuntimeSplice n Builder)
-> RuntimeSplice n a -> RuntimeSplice n Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< RuntimeSplice n a
p