{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Hakyll.Web.Template.Internal.Element
( TemplateKey (..)
, TemplateExpr (..)
, TemplateElement (..)
, templateElems
, parseTemplateElemsFile
) where
import Control.Applicative ((<|>), (<*))
import Control.Monad (void)
import Control.Arrow (left)
import Data.Binary (Binary, get, getWord8, put, putWord8)
import Data.List (intercalate)
import Data.Maybe (isJust)
import Data.Typeable (Typeable)
import GHC.Exts (IsString (..))
import qualified Text.Parsec as P
import qualified Text.Parsec.String as P
import Hakyll.Core.Util.Parser
newtype TemplateKey = TemplateKey String
deriving (Get TemplateKey
[TemplateKey] -> Put
TemplateKey -> Put
(TemplateKey -> Put)
-> Get TemplateKey -> ([TemplateKey] -> Put) -> Binary TemplateKey
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [TemplateKey] -> Put
$cputList :: [TemplateKey] -> Put
get :: Get TemplateKey
$cget :: Get TemplateKey
put :: TemplateKey -> Put
$cput :: TemplateKey -> Put
Binary, Int -> TemplateKey -> ShowS
[TemplateKey] -> ShowS
TemplateKey -> String
(Int -> TemplateKey -> ShowS)
-> (TemplateKey -> String)
-> ([TemplateKey] -> ShowS)
-> Show TemplateKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TemplateKey] -> ShowS
$cshowList :: [TemplateKey] -> ShowS
show :: TemplateKey -> String
$cshow :: TemplateKey -> String
showsPrec :: Int -> TemplateKey -> ShowS
$cshowsPrec :: Int -> TemplateKey -> ShowS
Show, TemplateKey -> TemplateKey -> Bool
(TemplateKey -> TemplateKey -> Bool)
-> (TemplateKey -> TemplateKey -> Bool) -> Eq TemplateKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemplateKey -> TemplateKey -> Bool
$c/= :: TemplateKey -> TemplateKey -> Bool
== :: TemplateKey -> TemplateKey -> Bool
$c== :: TemplateKey -> TemplateKey -> Bool
Eq, Typeable)
instance IsString TemplateKey where
fromString :: String -> TemplateKey
fromString = String -> TemplateKey
TemplateKey
data TemplateElement
= Chunk String
| Expr TemplateExpr
| Escaped
| If TemplateExpr [TemplateElement] (Maybe [TemplateElement])
| For TemplateExpr [TemplateElement] (Maybe [TemplateElement])
| Partial TemplateExpr
| TrimL
| TrimR
deriving (Int -> TemplateElement -> ShowS
[TemplateElement] -> ShowS
TemplateElement -> String
(Int -> TemplateElement -> ShowS)
-> (TemplateElement -> String)
-> ([TemplateElement] -> ShowS)
-> Show TemplateElement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TemplateElement] -> ShowS
$cshowList :: [TemplateElement] -> ShowS
show :: TemplateElement -> String
$cshow :: TemplateElement -> String
showsPrec :: Int -> TemplateElement -> ShowS
$cshowsPrec :: Int -> TemplateElement -> ShowS
Show, TemplateElement -> TemplateElement -> Bool
(TemplateElement -> TemplateElement -> Bool)
-> (TemplateElement -> TemplateElement -> Bool)
-> Eq TemplateElement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemplateElement -> TemplateElement -> Bool
$c/= :: TemplateElement -> TemplateElement -> Bool
== :: TemplateElement -> TemplateElement -> Bool
$c== :: TemplateElement -> TemplateElement -> Bool
Eq, Typeable)
instance Binary TemplateElement where
put :: TemplateElement -> Put
put (Chunk String
string) = Word8 -> Put
putWord8 Word8
0 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> Put
forall t. Binary t => t -> Put
put String
string
put (Expr TemplateExpr
e) = Word8 -> Put
putWord8 Word8
1 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TemplateExpr -> Put
forall t. Binary t => t -> Put
put TemplateExpr
e
put TemplateElement
Escaped = Word8 -> Put
putWord8 Word8
2
put (If TemplateExpr
e [TemplateElement]
t Maybe [TemplateElement]
f) = Word8 -> Put
putWord8 Word8
3 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TemplateExpr -> Put
forall t. Binary t => t -> Put
put TemplateExpr
e Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [TemplateElement] -> Put
forall t. Binary t => t -> Put
put [TemplateElement]
t Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe [TemplateElement] -> Put
forall t. Binary t => t -> Put
put Maybe [TemplateElement]
f
put (For TemplateExpr
e [TemplateElement]
b Maybe [TemplateElement]
s) = Word8 -> Put
putWord8 Word8
4 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TemplateExpr -> Put
forall t. Binary t => t -> Put
put TemplateExpr
e Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [TemplateElement] -> Put
forall t. Binary t => t -> Put
put [TemplateElement]
b Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe [TemplateElement] -> Put
forall t. Binary t => t -> Put
put Maybe [TemplateElement]
s
put (Partial TemplateExpr
e) = Word8 -> Put
putWord8 Word8
5 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TemplateExpr -> Put
forall t. Binary t => t -> Put
put TemplateExpr
e
put TemplateElement
TrimL = Word8 -> Put
putWord8 Word8
6
put TemplateElement
TrimR = Word8 -> Put
putWord8 Word8
7
get :: Get TemplateElement
get = Get Word8
getWord8 Get Word8 -> (Word8 -> Get TemplateElement) -> Get TemplateElement
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
tag -> case Word8
tag of
Word8
0 -> String -> TemplateElement
Chunk (String -> TemplateElement) -> Get String -> Get TemplateElement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get String
forall t. Binary t => Get t
get
Word8
1 -> TemplateExpr -> TemplateElement
Expr (TemplateExpr -> TemplateElement)
-> Get TemplateExpr -> Get TemplateElement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get TemplateExpr
forall t. Binary t => Get t
get
Word8
2 -> TemplateElement -> Get TemplateElement
forall (f :: * -> *) a. Applicative f => a -> f a
pure TemplateElement
Escaped
Word8
3 -> TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement
If (TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement)
-> Get TemplateExpr
-> Get
([TemplateElement] -> Maybe [TemplateElement] -> TemplateElement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get TemplateExpr
forall t. Binary t => Get t
get Get
([TemplateElement] -> Maybe [TemplateElement] -> TemplateElement)
-> Get [TemplateElement]
-> Get (Maybe [TemplateElement] -> TemplateElement)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get [TemplateElement]
forall t. Binary t => Get t
get Get (Maybe [TemplateElement] -> TemplateElement)
-> Get (Maybe [TemplateElement]) -> Get TemplateElement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get (Maybe [TemplateElement])
forall t. Binary t => Get t
get
Word8
4 -> TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement
For (TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement)
-> Get TemplateExpr
-> Get
([TemplateElement] -> Maybe [TemplateElement] -> TemplateElement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get TemplateExpr
forall t. Binary t => Get t
get Get
([TemplateElement] -> Maybe [TemplateElement] -> TemplateElement)
-> Get [TemplateElement]
-> Get (Maybe [TemplateElement] -> TemplateElement)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get [TemplateElement]
forall t. Binary t => Get t
get Get (Maybe [TemplateElement] -> TemplateElement)
-> Get (Maybe [TemplateElement]) -> Get TemplateElement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get (Maybe [TemplateElement])
forall t. Binary t => Get t
get
Word8
5 -> TemplateExpr -> TemplateElement
Partial (TemplateExpr -> TemplateElement)
-> Get TemplateExpr -> Get TemplateElement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get TemplateExpr
forall t. Binary t => Get t
get
Word8
6 -> TemplateElement -> Get TemplateElement
forall (f :: * -> *) a. Applicative f => a -> f a
pure TemplateElement
TrimL
Word8
7 -> TemplateElement -> Get TemplateElement
forall (f :: * -> *) a. Applicative f => a -> f a
pure TemplateElement
TrimR
Word8
_ -> String -> Get TemplateElement
forall a. HasCallStack => String -> a
error String
"Hakyll.Web.Template.Internal: Error reading cached template"
data TemplateExpr
= Ident TemplateKey
| Call TemplateKey [TemplateExpr]
| StringLiteral String
deriving (TemplateExpr -> TemplateExpr -> Bool
(TemplateExpr -> TemplateExpr -> Bool)
-> (TemplateExpr -> TemplateExpr -> Bool) -> Eq TemplateExpr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemplateExpr -> TemplateExpr -> Bool
$c/= :: TemplateExpr -> TemplateExpr -> Bool
== :: TemplateExpr -> TemplateExpr -> Bool
$c== :: TemplateExpr -> TemplateExpr -> Bool
Eq, Typeable)
instance Show TemplateExpr where
show :: TemplateExpr -> String
show (Ident (TemplateKey String
k)) = String
k
show (Call (TemplateKey String
k) [TemplateExpr]
as) =
String
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((TemplateExpr -> String) -> [TemplateExpr] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map TemplateExpr -> String
forall a. Show a => a -> String
show [TemplateExpr]
as) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (StringLiteral String
s) = ShowS
forall a. Show a => a -> String
show String
s
instance Binary TemplateExpr where
put :: TemplateExpr -> Put
put (Ident TemplateKey
k) = Word8 -> Put
putWord8 Word8
0 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TemplateKey -> Put
forall t. Binary t => t -> Put
put TemplateKey
k
put (Call TemplateKey
k [TemplateExpr]
as) = Word8 -> Put
putWord8 Word8
1 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TemplateKey -> Put
forall t. Binary t => t -> Put
put TemplateKey
k Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [TemplateExpr] -> Put
forall t. Binary t => t -> Put
put [TemplateExpr]
as
put (StringLiteral String
s) = Word8 -> Put
putWord8 Word8
2 Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> Put
forall t. Binary t => t -> Put
put String
s
get :: Get TemplateExpr
get = Get Word8
getWord8 Get Word8 -> (Word8 -> Get TemplateExpr) -> Get TemplateExpr
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
tag -> case Word8
tag of
Word8
0 -> TemplateKey -> TemplateExpr
Ident (TemplateKey -> TemplateExpr)
-> Get TemplateKey -> Get TemplateExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get TemplateKey
forall t. Binary t => Get t
get
Word8
1 -> TemplateKey -> [TemplateExpr] -> TemplateExpr
Call (TemplateKey -> [TemplateExpr] -> TemplateExpr)
-> Get TemplateKey -> Get ([TemplateExpr] -> TemplateExpr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get TemplateKey
forall t. Binary t => Get t
get Get ([TemplateExpr] -> TemplateExpr)
-> Get [TemplateExpr] -> Get TemplateExpr
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get [TemplateExpr]
forall t. Binary t => Get t
get
Word8
2 -> String -> TemplateExpr
StringLiteral (String -> TemplateExpr) -> Get String -> Get TemplateExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get String
forall t. Binary t => Get t
get
Word8
_ -> String -> Get TemplateExpr
forall a. HasCallStack => String -> a
error String
"Hakyll.Web.Template.Internal: Error reading cached template"
parseTemplateElemsFile :: FilePath -> String -> Either String [TemplateElement]
parseTemplateElemsFile :: String -> String -> Either String [TemplateElement]
parseTemplateElemsFile String
file = (ParseError -> String)
-> Either ParseError [TemplateElement]
-> Either String [TemplateElement]
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left (\ParseError
e -> String
"Cannot parse template " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ParseError -> String
forall a. Show a => a -> String
show ParseError
e)
(Either ParseError [TemplateElement]
-> Either String [TemplateElement])
-> (String -> Either ParseError [TemplateElement])
-> String
-> Either String [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parsec String () [TemplateElement]
-> String -> String -> Either ParseError [TemplateElement]
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
P.parse (Parsec String () [TemplateElement]
templateElems Parsec String () [TemplateElement]
-> ParsecT String () Identity ()
-> Parsec String () [TemplateElement]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
P.eof) String
file
templateElems :: P.Parser [TemplateElement]
templateElems :: Parsec String () [TemplateElement]
templateElems = [[TemplateElement]] -> [TemplateElement]
forall a. Monoid a => [a] -> a
mconcat ([[TemplateElement]] -> [TemplateElement])
-> ParsecT String () Identity [[TemplateElement]]
-> Parsec String () [TemplateElement]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec String () [TemplateElement]
-> ParsecT String () Identity [[TemplateElement]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ([Parsec String () [TemplateElement]]
-> Parsec String () [TemplateElement]
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
P.choice [ ParsecT String () Identity TemplateElement
-> Parsec String () [TemplateElement]
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
lift ParsecT String () Identity TemplateElement
chunk
, ParsecT String () Identity TemplateElement
-> Parsec String () [TemplateElement]
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
lift ParsecT String () Identity TemplateElement
escaped
, Parsec String () [TemplateElement]
conditional
, Parsec String () [TemplateElement]
for
, Parsec String () [TemplateElement]
partial
, Parsec String () [TemplateElement]
expr
])
where lift :: ParsecT String () Identity a -> ParsecT String () Identity [a]
lift = (a -> [a])
-> ParsecT String () Identity a -> ParsecT String () Identity [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[])
chunk :: P.Parser TemplateElement
chunk :: ParsecT String () Identity TemplateElement
chunk = String -> TemplateElement
Chunk (String -> TemplateElement)
-> ParsecT String () Identity String
-> ParsecT String () Identity TemplateElement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 (String -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"$")
expr :: P.Parser [TemplateElement]
expr :: Parsec String () [TemplateElement]
expr = Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement])
-> Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ do
Bool
trimLExpr <- Parser Bool
trimOpen
TemplateExpr
e <- Parser TemplateExpr
expr'
Bool
trimRExpr <- Parser Bool
trimClose
[TemplateElement] -> Parsec String () [TemplateElement]
forall (m :: * -> *) a. Monad m => a -> m a
return ([TemplateElement] -> Parsec String () [TemplateElement])
-> [TemplateElement] -> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement
TrimL | Bool
trimLExpr] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateExpr -> TemplateElement
Expr TemplateExpr
e] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimR | Bool
trimRExpr]
expr' :: P.Parser TemplateExpr
expr' :: Parser TemplateExpr
expr' = Parser TemplateExpr
stringLiteral Parser TemplateExpr -> Parser TemplateExpr -> Parser TemplateExpr
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser TemplateExpr
call Parser TemplateExpr -> Parser TemplateExpr -> Parser TemplateExpr
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser TemplateExpr
ident
escaped :: P.Parser TemplateElement
escaped :: ParsecT String () Identity TemplateElement
escaped = TemplateElement
Escaped TemplateElement
-> ParsecT String () Identity String
-> ParsecT String () Identity TemplateElement
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"$$")
trimOpen :: P.Parser Bool
trimOpen :: Parser Bool
trimOpen = do
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'$'
Maybe Char
trimLIf <- ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char))
-> ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall a b. (a -> b) -> a -> b
$ ParsecT String () Identity Char -> ParsecT String () Identity Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'-')
Bool -> Parser Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Parser Bool) -> Bool -> Parser Bool
forall a b. (a -> b) -> a -> b
$ Maybe Char -> Bool
forall a. Maybe a -> Bool
isJust Maybe Char
trimLIf
trimClose :: P.Parser Bool
trimClose :: Parser Bool
trimClose = do
Maybe Char
trimIfR <- ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char))
-> ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall a b. (a -> b) -> a -> b
$ (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'-')
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'$'
Bool -> Parser Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Parser Bool) -> Bool -> Parser Bool
forall a b. (a -> b) -> a -> b
$ Maybe Char -> Bool
forall a. Maybe a -> Bool
isJust Maybe Char
trimIfR
conditional :: P.Parser [TemplateElement]
conditional :: Parsec String () [TemplateElement]
conditional = Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement])
-> Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ do
Bool
trimLIf <- Parser Bool
trimOpen
ParsecT String () Identity String -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity String
-> ParsecT String () Identity ())
-> ParsecT String () Identity String
-> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"if("
TemplateExpr
e <- Parser TemplateExpr
expr'
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
')'
Bool
trimRIf <- Parser Bool
trimClose
[TemplateElement]
thenBranch <- Parsec String () [TemplateElement]
templateElems
Maybe (Bool, [TemplateElement], Bool)
elseParse <- String -> Parser (Maybe (Bool, [TemplateElement], Bool))
opt String
"else"
Bool
trimLEnd <- Parser Bool
trimOpen
ParsecT String () Identity String -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity String
-> ParsecT String () Identity ())
-> ParsecT String () Identity String
-> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"endif"
Bool
trimREnd <- Parser Bool
trimClose
let ([TemplateElement]
thenBody, Maybe [TemplateElement]
elseBody) = ([TemplateElement], Maybe [TemplateElement])
-> ((Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement]))
-> Maybe (Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([TemplateElement]
thenNoElse, Maybe [TemplateElement]
forall a. Maybe a
Nothing) (Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement])
thenElse Maybe (Bool, [TemplateElement], Bool)
elseParse
where thenNoElse :: [TemplateElement]
thenNoElse =
[TemplateElement
TrimR | Bool
trimRIf] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement]
thenBranch [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimL | Bool
trimLEnd]
thenElse :: (Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement])
thenElse (Bool
trimLElse, [TemplateElement]
elseBranch, Bool
trimRElse) = ([TemplateElement]
thenB, Maybe [TemplateElement]
elseB)
where thenB :: [TemplateElement]
thenB = [TemplateElement
TrimR | Bool
trimRIf]
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement]
thenBranch
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimL | Bool
trimLElse]
elseB :: Maybe [TemplateElement]
elseB = [TemplateElement] -> Maybe [TemplateElement]
forall a. a -> Maybe a
Just ([TemplateElement] -> Maybe [TemplateElement])
-> [TemplateElement] -> Maybe [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement
TrimR | Bool
trimRElse]
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement]
elseBranch
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimL | Bool
trimLEnd]
[TemplateElement] -> Parsec String () [TemplateElement]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TemplateElement] -> Parsec String () [TemplateElement])
-> [TemplateElement] -> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement
TrimL | Bool
trimLIf] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement
If TemplateExpr
e [TemplateElement]
thenBody Maybe [TemplateElement]
elseBody] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimR | Bool
trimREnd]
for :: P.Parser [TemplateElement]
for :: Parsec String () [TemplateElement]
for = Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement])
-> Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ do
Bool
trimLFor <- Parser Bool
trimOpen
ParsecT String () Identity String -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity String
-> ParsecT String () Identity ())
-> ParsecT String () Identity String
-> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"for("
TemplateExpr
e <- Parser TemplateExpr
expr'
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
')'
Bool
trimRFor <- Parser Bool
trimClose
[TemplateElement]
bodyBranch <- Parsec String () [TemplateElement]
templateElems
Maybe (Bool, [TemplateElement], Bool)
sepParse <- String -> Parser (Maybe (Bool, [TemplateElement], Bool))
opt String
"sep"
Bool
trimLEnd <- Parser Bool
trimOpen
ParsecT String () Identity String -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity String
-> ParsecT String () Identity ())
-> ParsecT String () Identity String
-> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"endfor"
Bool
trimREnd <- Parser Bool
trimClose
let ([TemplateElement]
forBody, Maybe [TemplateElement]
sepBody) = ([TemplateElement], Maybe [TemplateElement])
-> ((Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement]))
-> Maybe (Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([TemplateElement]
forNoSep, Maybe [TemplateElement]
forall a. Maybe a
Nothing) (Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement])
forSep Maybe (Bool, [TemplateElement], Bool)
sepParse
where forNoSep :: [TemplateElement]
forNoSep =
[TemplateElement
TrimR | Bool
trimRFor] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement]
bodyBranch [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimL | Bool
trimLEnd]
forSep :: (Bool, [TemplateElement], Bool)
-> ([TemplateElement], Maybe [TemplateElement])
forSep (Bool
trimLSep, [TemplateElement]
sepBranch, Bool
trimRSep) = ([TemplateElement]
forB, Maybe [TemplateElement]
sepB)
where forB :: [TemplateElement]
forB = [TemplateElement
TrimR | Bool
trimRFor]
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement]
bodyBranch
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimL | Bool
trimLSep]
sepB :: Maybe [TemplateElement]
sepB = [TemplateElement] -> Maybe [TemplateElement]
forall a. a -> Maybe a
Just ([TemplateElement] -> Maybe [TemplateElement])
-> [TemplateElement] -> Maybe [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement
TrimR | Bool
trimRSep]
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement]
sepBranch
[TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimL | Bool
trimLEnd]
[TemplateElement] -> Parsec String () [TemplateElement]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TemplateElement] -> Parsec String () [TemplateElement])
-> [TemplateElement] -> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement
TrimL | Bool
trimLFor] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement
For TemplateExpr
e [TemplateElement]
forBody Maybe [TemplateElement]
sepBody] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimR | Bool
trimREnd]
partial :: P.Parser [TemplateElement]
partial :: Parsec String () [TemplateElement]
partial = Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement])
-> Parsec String () [TemplateElement]
-> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ do
Bool
trimLPart <- Parser Bool
trimOpen
ParsecT String () Identity String -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity String
-> ParsecT String () Identity ())
-> ParsecT String () Identity String
-> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"partial("
TemplateExpr
e <- Parser TemplateExpr
expr'
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
')'
Bool
trimRPart <- Parser Bool
trimClose
[TemplateElement] -> Parsec String () [TemplateElement]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TemplateElement] -> Parsec String () [TemplateElement])
-> [TemplateElement] -> Parsec String () [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement
TrimL | Bool
trimLPart] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateExpr -> TemplateElement
Partial TemplateExpr
e] [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall a. [a] -> [a] -> [a]
++ [TemplateElement
TrimR | Bool
trimRPart]
ident :: P.Parser TemplateExpr
ident :: Parser TemplateExpr
ident = Parser TemplateExpr -> Parser TemplateExpr
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parser TemplateExpr -> Parser TemplateExpr)
-> Parser TemplateExpr -> Parser TemplateExpr
forall a b. (a -> b) -> a -> b
$ TemplateKey -> TemplateExpr
Ident (TemplateKey -> TemplateExpr)
-> ParsecT String () Identity TemplateKey -> Parser TemplateExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity TemplateKey
key
call :: P.Parser TemplateExpr
call :: Parser TemplateExpr
call = Parser TemplateExpr -> Parser TemplateExpr
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parser TemplateExpr -> Parser TemplateExpr)
-> Parser TemplateExpr -> Parser TemplateExpr
forall a b. (a -> b) -> a -> b
$ do
TemplateKey
f <- ParsecT String () Identity TemplateKey
key
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'('
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
P.spaces
[TemplateExpr]
as <- Parser TemplateExpr
-> ParsecT String () Identity ()
-> ParsecT String () Identity [TemplateExpr]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
P.sepBy Parser TemplateExpr
expr' (ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
P.spaces ParsecT String () Identity ()
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
',' ParsecT String () Identity Char
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
P.spaces)
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
P.spaces
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
')'
TemplateExpr -> Parser TemplateExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (TemplateExpr -> Parser TemplateExpr)
-> TemplateExpr -> Parser TemplateExpr
forall a b. (a -> b) -> a -> b
$ TemplateKey -> [TemplateExpr] -> TemplateExpr
Call TemplateKey
f [TemplateExpr]
as
stringLiteral :: P.Parser TemplateExpr
stringLiteral :: Parser TemplateExpr
stringLiteral = do
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'\"'
String
str <- ParsecT String () Identity Char
-> ParsecT String () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String () Identity Char
-> ParsecT String () Identity String)
-> ParsecT String () Identity Char
-> ParsecT String () Identity String
forall a b. (a -> b) -> a -> b
$ do
Char
x <- String -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"\""
if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\\' then ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.anyChar else Char -> ParsecT String () Identity Char
forall (m :: * -> *) a. Monad m => a -> m a
return Char
x
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'\"'
TemplateExpr -> Parser TemplateExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (TemplateExpr -> Parser TemplateExpr)
-> TemplateExpr -> Parser TemplateExpr
forall a b. (a -> b) -> a -> b
$ String -> TemplateExpr
StringLiteral String
str
key :: P.Parser TemplateKey
key :: ParsecT String () Identity TemplateKey
key = String -> TemplateKey
TemplateKey (String -> TemplateKey)
-> ParsecT String () Identity String
-> ParsecT String () Identity TemplateKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity String
metadataKey
opt :: String -> P.Parser (Maybe (Bool, [TemplateElement], Bool))
opt :: String -> Parser (Maybe (Bool, [TemplateElement], Bool))
opt String
clause = ParsecT String () Identity (Bool, [TemplateElement], Bool)
-> Parser (Maybe (Bool, [TemplateElement], Bool))
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (ParsecT String () Identity (Bool, [TemplateElement], Bool)
-> Parser (Maybe (Bool, [TemplateElement], Bool)))
-> ParsecT String () Identity (Bool, [TemplateElement], Bool)
-> Parser (Maybe (Bool, [TemplateElement], Bool))
forall a b. (a -> b) -> a -> b
$ ParsecT String () Identity (Bool, [TemplateElement], Bool)
-> ParsecT String () Identity (Bool, [TemplateElement], Bool)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT String () Identity (Bool, [TemplateElement], Bool)
-> ParsecT String () Identity (Bool, [TemplateElement], Bool))
-> ParsecT String () Identity (Bool, [TemplateElement], Bool)
-> ParsecT String () Identity (Bool, [TemplateElement], Bool)
forall a b. (a -> b) -> a -> b
$ do
Bool
trimL <- Parser Bool
trimOpen
ParsecT String () Identity String -> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity String
-> ParsecT String () Identity ())
-> ParsecT String () Identity String
-> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
clause
Bool
trimR <- Parser Bool
trimClose
[TemplateElement]
branch <- Parsec String () [TemplateElement]
templateElems
(Bool, [TemplateElement], Bool)
-> ParsecT String () Identity (Bool, [TemplateElement], Bool)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool
trimL, [TemplateElement]
branch, Bool
trimR)