{-# LANGUAGE RelaxedPolyRec, DeriveDataTypeable #-}
{-# OPTIONS_HADDOCK not-home #-}

module Text.StringTemplate.Base
    (StringTemplate(..), StringTemplateShows(..), ToSElem(..), STGroup,
     Stringable(..), stShowsToSE, inSGen,
     toString, toPPDoc, render, newSTMP, newAngleSTMP,
     getStringTemplate, getStringTemplate',
     setAttribute, setManyAttrib,
     setNativeAttribute, setManyNativeAttrib,
     withContext, optInsertTmpl, setEncoder,
     paddedTrans, SEnv(..), parseSTMP, dumpAttribs,
     checkTemplate, checkTemplateDeep,
     parseSTMPNames
    ) where
import Control.Arrow
import Control.Applicative hiding ((<|>),many,optional)
import Control.Monad
import Control.DeepSeq
import qualified Control.Exception as C
import Data.List
import Data.Maybe
import Data.Monoid
import Data.Typeable
import System.IO.Unsafe

import Text.ParserCombinators.Parsec
import qualified Data.Map as M
import qualified Text.PrettyPrint.HughesPJ as PP

import Text.StringTemplate.Classes
import Text.StringTemplate.Instances()

{--------------------------------------------------------------------
  Generic Utilities
--------------------------------------------------------------------}

type TmplParser = GenParser Char ((Char, Char),[String],[String],[String])

(<$$>) :: (Functor f1, Functor f) => (a -> b) -> f (f1 a) -> f (f1 b)
<$$> :: (a -> b) -> f (f1 a) -> f (f1 b)
(<$$>) = (f1 a -> f1 b) -> f (f1 a) -> f (f1 b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
(<$>) ((f1 a -> f1 b) -> f (f1 a) -> f (f1 b))
-> ((a -> b) -> f1 a -> f1 b) -> (a -> b) -> f (f1 a) -> f (f1 b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> f1 a -> f1 b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
(<$>)
infixr 8 <$$>

(|.) :: (t1 -> t2) -> (t -> t1) -> t -> t2
|. :: (t1 -> t2) -> (t -> t1) -> t -> t2
(|.) t1 -> t2
f t -> t1
g = t1 -> t2
f (t1 -> t2) -> (t -> t1) -> t -> t2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> t1
g
infixr 3 |.

(.>>) :: (Monad m) => m a -> m b -> m b
.>> :: m a -> m b -> m b
(.>>) m a
f m b
g = m a
f m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m b
g
infixr 5 .>>

fromMany :: b -> ([a] -> b) -> [a] -> b
fromMany :: b -> ([a] -> b) -> [a] -> b
fromMany b
e [a] -> b
_ [] = b
e
fromMany b
_ [a] -> b
f [a]
xs  = [a] -> b
f [a]
xs

swing :: (((a -> c1) -> c1) -> b -> c) -> b -> a -> c
swing :: (((a -> c1) -> c1) -> b -> c) -> b -> a -> c
swing = (a -> b -> c) -> b -> a -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((a -> b -> c) -> b -> a -> c)
-> ((((a -> c1) -> c1) -> b -> c) -> a -> b -> c)
-> (((a -> c1) -> c1) -> b -> c)
-> b
-> a
-> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((((a -> c1) -> c1) -> b -> c)
-> (a -> (a -> c1) -> c1) -> a -> b -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> c1) -> a -> c1) -> a -> (a -> c1) -> c1
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> c1) -> a -> c1
forall a. a -> a
id)

paddedTrans :: a -> [[a]] -> [[a]]
paddedTrans :: a -> [[a]] -> [[a]]
paddedTrans a
_ [] = []
paddedTrans a
n [[a]]
as = Int -> [[a]] -> [[a]]
forall a. Int -> [a] -> [a]
take ([Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> ([[a]] -> [Int]) -> [[a]] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> Int) -> [[a]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[a]] -> Int) -> [[a]] -> Int
forall a b. (a -> b) -> a -> b
$ [[a]]
as) ([[a]] -> [[a]]) -> ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[a]] -> [[a]]
trans ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> a -> b
$ [[a]]
as
    where trans :: [[a]] -> [[a]]
trans ([] : [[a]]
xss)  = (a
n a -> [a] -> [a]
forall a. a -> [a] -> [a]
: ([a] -> a) -> [[a]] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> a
h [[a]]
xss) [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
:  [[a]] -> [[a]]
trans ([a
n] [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: ([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> [a]
t [[a]]
xss)
          trans ((a
x : [a]
xs) : [[a]]
xss) = (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: ([a] -> a) -> [[a]] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> a
h [[a]]
xss) [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: [[a]] -> [[a]]
trans ([a] -> [a]
m [a]
xs [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: ([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> [a]
t [[a]]
xss)
          trans [[a]]
_ = [];
          h :: [a] -> a
h (a
x:[a]
_) = a
x; h [a]
_ = a
n; t :: [a] -> [a]
t (a
_:a
y:[a]
xs) = a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs; t [a]
_ = [a
n];
          m :: [a] -> [a]
m (a
x:[a]
xs) = a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs; m [a]
_ = [a
n];

{--------------------------------------------------------------------
  StringTemplate and the API
--------------------------------------------------------------------}

-- | A function that generates StringTemplates.
-- This is conceptually a query function into a \"group\" of StringTemplates.
type STGroup a = String -> (StFirst (StringTemplate a))

-- | A String with \"holes\" in it. StringTemplates may be composed of any
-- 'Stringable' type, which at the moment includes 'String's, 'ByteString's,
-- PrettyPrinter 'Doc's, and 'Endo' 'String's, which are actually of type
-- 'ShowS'. When a StringTemplate is composed of a type, its internals are
-- as well, so it is, so to speak \"turtles all the way down.\"
data StringTemplate a = STMP {StringTemplate a -> SEnv a
senv :: SEnv a,  StringTemplate a -> Either String (SEnv a -> a)
runSTMP :: Either String (SEnv a -> a), StringTemplate a
-> SEnv a -> (Maybe String, Maybe [String], Maybe [String])
chkSTMP :: SEnv a -> (Maybe String, Maybe [String], Maybe [String])}

-- | Renders a StringTemplate to a String.
toString :: StringTemplate String -> String
toString :: StringTemplate String -> String
toString = StringTemplate String -> String
forall a. Stringable a => StringTemplate a -> a
render

-- | Renders a StringTemplate to a 'Text.PrettyPrint.HughesPJ.Doc'.
toPPDoc :: StringTemplate PP.Doc -> PP.Doc
toPPDoc :: StringTemplate Doc -> Doc
toPPDoc = StringTemplate Doc -> Doc
forall a. Stringable a => StringTemplate a -> a
render

-- | Generic render function for a StringTemplate of any type.
render :: Stringable a => StringTemplate a -> a
render :: StringTemplate a -> a
render = (String -> SEnv a -> a)
-> ((SEnv a -> a) -> SEnv a -> a)
-> Either String (SEnv a -> a)
-> SEnv a
-> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr) (SEnv a -> a) -> SEnv a -> a
forall a. a -> a
id (Either String (SEnv a -> a) -> SEnv a -> a)
-> (StringTemplate a -> Either String (SEnv a -> a))
-> StringTemplate a
-> SEnv a
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StringTemplate a -> Either String (SEnv a -> a)
forall a. StringTemplate a -> Either String (SEnv a -> a)
runSTMP (StringTemplate a -> SEnv a -> a)
-> (StringTemplate a -> SEnv a) -> StringTemplate a -> a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv

nullEnv :: SEnv a
nullEnv :: SEnv a
nullEnv = SMap a
-> [(String, SEnv a -> SElem a)] -> STGroup a -> (a -> a) -> SEnv a
forall a.
SMap a
-> [(String, SEnv a -> SElem a)] -> STGroup a -> (a -> a) -> SEnv a
SEnv SMap a
forall k a. Map k a
M.empty [] STGroup a
forall a. Monoid a => a
mempty a -> a
forall a. a -> a
id

-- | Returns a tuple of three Maybes. The first is set if there is a parse error in the template.
-- The next is set to a list of attributes that have not been set, or Nothing if all attributes are set.
-- The last is set to a list of invoked templates that cannot be looked up, or Nothing if all invoked templates can be found.
-- Note that this check is shallow -- i.e. missing attributes and templates are only caught in the top level template, not any invoked subtemplate.
checkTemplate :: Stringable a => StringTemplate a -> (Maybe String, Maybe [String], Maybe [String])
checkTemplate :: StringTemplate a -> (Maybe String, Maybe [String], Maybe [String])
checkTemplate StringTemplate a
t = StringTemplate a
-> SEnv a -> (Maybe String, Maybe [String], Maybe [String])
forall a.
StringTemplate a
-> SEnv a -> (Maybe String, Maybe [String], Maybe [String])
chkSTMP StringTemplate a
t (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
t)

-- | Parses a String to produce a StringTemplate, with \'$\'s as delimiters.
-- It is constructed with a stub group that cannot look up other templates.
newSTMP :: Stringable a => String -> StringTemplate a
newSTMP :: String -> StringTemplate a
newSTMP String
s = SEnv a
-> Either String (SEnv a -> a)
-> (SEnv a -> (Maybe String, Maybe [String], Maybe [String]))
-> StringTemplate a
forall a.
SEnv a
-> Either String (SEnv a -> a)
-> (SEnv a -> (Maybe String, Maybe [String], Maybe [String]))
-> StringTemplate a
STMP SEnv a
forall a. SEnv a
nullEnv ((Char, Char) -> String -> Either String (SEnv a -> a)
forall a.
Stringable a =>
(Char, Char) -> String -> Either String (SEnv a -> a)
parseSTMP (Char
'$',Char
'$') String
s) ((Char, Char)
-> String
-> SEnv a
-> (Maybe String, Maybe [String], Maybe [String])
forall a.
Stringable a =>
(Char, Char)
-> String
-> SEnv a
-> (Maybe String, Maybe [String], Maybe [String])
chkStmp (Char
'$',Char
'$') String
s)

-- | Parses a String to produce a StringTemplate, delimited by angle brackets.
-- It is constructed with a stub group that cannot look up other templates.
newAngleSTMP :: Stringable a => String -> StringTemplate a
newAngleSTMP :: String -> StringTemplate a
newAngleSTMP String
s = SEnv a
-> Either String (SEnv a -> a)
-> (SEnv a -> (Maybe String, Maybe [String], Maybe [String]))
-> StringTemplate a
forall a.
SEnv a
-> Either String (SEnv a -> a)
-> (SEnv a -> (Maybe String, Maybe [String], Maybe [String]))
-> StringTemplate a
STMP SEnv a
forall a. SEnv a
nullEnv ((Char, Char) -> String -> Either String (SEnv a -> a)
forall a.
Stringable a =>
(Char, Char) -> String -> Either String (SEnv a -> a)
parseSTMP (Char
'<',Char
'>') String
s) ((Char, Char)
-> String
-> SEnv a
-> (Maybe String, Maybe [String], Maybe [String])
forall a.
Stringable a =>
(Char, Char)
-> String
-> SEnv a
-> (Maybe String, Maybe [String], Maybe [String])
chkStmp (Char
'<',Char
'>') String
s)

-- | Yields a StringTemplate with the appropriate attribute set.
-- If the attribute already exists, it is appended to a list.
setAttribute :: (ToSElem a, Stringable b) => String -> a -> StringTemplate b -> StringTemplate b
setAttribute :: String -> a -> StringTemplate b -> StringTemplate b
setAttribute String
s a
x StringTemplate b
st = StringTemplate b
st {senv :: SEnv b
senv = String -> SElem b -> SEnv b -> SEnv b
forall a. Stringable a => String -> SElem a -> SEnv a -> SEnv a
envInsApp String
s (a -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem a
x) (StringTemplate b -> SEnv b
forall a. StringTemplate a -> SEnv a
senv StringTemplate b
st)}

-- | Yields a StringTemplate with the appropriate attributes set.
-- If any attribute already exists, it is appended to a list.
setManyAttrib :: (ToSElem a, Stringable b) => [(String, a)] -> StringTemplate b -> StringTemplate b
setManyAttrib :: [(String, a)] -> StringTemplate b -> StringTemplate b
setManyAttrib = (StringTemplate b -> [(String, a)] -> StringTemplate b)
-> [(String, a)] -> StringTemplate b -> StringTemplate b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((StringTemplate b -> [(String, a)] -> StringTemplate b)
 -> [(String, a)] -> StringTemplate b -> StringTemplate b)
-> (((String, a) -> StringTemplate b -> StringTemplate b)
    -> StringTemplate b -> [(String, a)] -> StringTemplate b)
-> ((String, a) -> StringTemplate b -> StringTemplate b)
-> [(String, a)]
-> StringTemplate b
-> StringTemplate b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StringTemplate b -> (String, a) -> StringTemplate b)
-> StringTemplate b -> [(String, a)] -> StringTemplate b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((StringTemplate b -> (String, a) -> StringTemplate b)
 -> StringTemplate b -> [(String, a)] -> StringTemplate b)
-> (((String, a) -> StringTemplate b -> StringTemplate b)
    -> StringTemplate b -> (String, a) -> StringTemplate b)
-> ((String, a) -> StringTemplate b -> StringTemplate b)
-> StringTemplate b
-> [(String, a)]
-> StringTemplate b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, a) -> StringTemplate b -> StringTemplate b)
-> StringTemplate b -> (String, a) -> StringTemplate b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((String, a) -> StringTemplate b -> StringTemplate b)
 -> [(String, a)] -> StringTemplate b -> StringTemplate b)
-> ((String, a) -> StringTemplate b -> StringTemplate b)
-> [(String, a)]
-> StringTemplate b
-> StringTemplate b
forall a b. (a -> b) -> a -> b
$ (String -> a -> StringTemplate b -> StringTemplate b)
-> (String, a) -> StringTemplate b -> StringTemplate b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry String -> a -> StringTemplate b -> StringTemplate b
forall a b.
(ToSElem a, Stringable b) =>
String -> a -> StringTemplate b -> StringTemplate b
setAttribute

-- | Yields a StringTemplate with the appropriate attribute set.
-- If the attribute already exists, it is appended to a list.
-- This will not translate the attribute through any intermediate
-- representation, so is more efficient when, e.g. setting
-- attributes that are large bytestrings in a bytestring template.
setNativeAttribute :: Stringable b => String -> b -> StringTemplate b -> StringTemplate b
setNativeAttribute :: String -> b -> StringTemplate b -> StringTemplate b
setNativeAttribute String
s b
x StringTemplate b
st = StringTemplate b
st {senv :: SEnv b
senv = String -> SElem b -> SEnv b -> SEnv b
forall a. Stringable a => String -> SElem a -> SEnv a -> SEnv a
envInsApp String
s (b -> SElem b
forall a. a -> SElem a
SNAT b
x) (StringTemplate b -> SEnv b
forall a. StringTemplate a -> SEnv a
senv StringTemplate b
st)}

-- | Yields a StringTemplate with the appropriate attributes set.
-- If any attribute already exists, it is appended to a list.
-- Attributes are added natively, which may provide
-- efficiency gains.
setManyNativeAttrib :: (Stringable b) => [(String, b)] -> StringTemplate b -> StringTemplate b
setManyNativeAttrib :: [(String, b)] -> StringTemplate b -> StringTemplate b
setManyNativeAttrib = (StringTemplate b -> [(String, b)] -> StringTemplate b)
-> [(String, b)] -> StringTemplate b -> StringTemplate b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((StringTemplate b -> [(String, b)] -> StringTemplate b)
 -> [(String, b)] -> StringTemplate b -> StringTemplate b)
-> (((String, b) -> StringTemplate b -> StringTemplate b)
    -> StringTemplate b -> [(String, b)] -> StringTemplate b)
-> ((String, b) -> StringTemplate b -> StringTemplate b)
-> [(String, b)]
-> StringTemplate b
-> StringTemplate b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StringTemplate b -> (String, b) -> StringTemplate b)
-> StringTemplate b -> [(String, b)] -> StringTemplate b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((StringTemplate b -> (String, b) -> StringTemplate b)
 -> StringTemplate b -> [(String, b)] -> StringTemplate b)
-> (((String, b) -> StringTemplate b -> StringTemplate b)
    -> StringTemplate b -> (String, b) -> StringTemplate b)
-> ((String, b) -> StringTemplate b -> StringTemplate b)
-> StringTemplate b
-> [(String, b)]
-> StringTemplate b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, b) -> StringTemplate b -> StringTemplate b)
-> StringTemplate b -> (String, b) -> StringTemplate b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((String, b) -> StringTemplate b -> StringTemplate b)
 -> [(String, b)] -> StringTemplate b -> StringTemplate b)
-> ((String, b) -> StringTemplate b -> StringTemplate b)
-> [(String, b)]
-> StringTemplate b
-> StringTemplate b
forall a b. (a -> b) -> a -> b
$ (String -> b -> StringTemplate b -> StringTemplate b)
-> (String, b) -> StringTemplate b -> StringTemplate b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry String -> b -> StringTemplate b -> StringTemplate b
forall b.
Stringable b =>
String -> b -> StringTemplate b -> StringTemplate b
setNativeAttribute

-- | Replaces the attributes of a StringTemplate with those
-- described in the second argument. If the argument does not yield
-- a set of named attributes but only a single one, that attribute
-- is named, as a default, \"it\".
withContext :: (ToSElem a, Stringable b) => StringTemplate b -> a -> StringTemplate b
withContext :: StringTemplate b -> a -> StringTemplate b
withContext StringTemplate b
st a
x = case a -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem a
x of
                     SM SMap b
a -> StringTemplate b
st {senv :: SEnv b
senv = (StringTemplate b -> SEnv b
forall a. StringTemplate a -> SEnv a
senv StringTemplate b
st) {smp :: SMap b
smp = SMap b
a}}
                     SElem b
b -> StringTemplate b
st {senv :: SEnv b
senv = (StringTemplate b -> SEnv b
forall a. StringTemplate a -> SEnv a
senv StringTemplate b
st) {smp :: SMap b
smp = String -> SElem b -> SMap b
forall k a. k -> a -> Map k a
M.singleton String
"it" SElem b
b}}

-- | Queries an String Template Group and returns Just the appropriate
-- StringTemplate if it exists, otherwise, Nothing.
getStringTemplate :: (Stringable a) => String -> STGroup a -> Maybe (StringTemplate a)
getStringTemplate :: String -> STGroup a -> Maybe (StringTemplate a)
getStringTemplate String
s STGroup a
sg = StFirst (StringTemplate a) -> Maybe (StringTemplate a)
forall a. StFirst a -> Maybe a
stGetFirst (STGroup a
sg String
s)

-- | As with 'getStringTemplate' but never inlined, so appropriate for use
-- with volatile template groups.
{-# NOINLINE getStringTemplate' #-}
getStringTemplate' :: (Stringable a) => String -> STGroup a -> Maybe (StringTemplate a)
getStringTemplate' :: String -> STGroup a -> Maybe (StringTemplate a)
getStringTemplate' String
s STGroup a
sg = StFirst (StringTemplate a) -> Maybe (StringTemplate a)
forall a. StFirst a -> Maybe a
stGetFirst (STGroup a
sg String
s)

-- | Adds a set of global options to a single template
optInsertTmpl :: [(String, String)] -> StringTemplate a -> StringTemplate a
optInsertTmpl :: [(String, String)] -> StringTemplate a -> StringTemplate a
optInsertTmpl [(String, String)]
x StringTemplate a
st = StringTemplate a
st {senv :: SEnv a
senv = [(String, SEnv a -> SElem a)] -> SEnv a -> SEnv a
forall a. [(String, SEnv a -> SElem a)] -> SEnv a -> SEnv a
optInsert (((String, String) -> (String, SEnv a -> SElem a))
-> [(String, String)] -> [(String, SEnv a -> SElem a)]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> SEnv a -> SElem a)
-> (String, String) -> (String, SEnv a -> SElem a)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second String -> SEnv a -> SElem a
forall b a. String -> b -> SElem a
justSTR) [(String, String)]
x) (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
st)}

-- | Sets an encoding function of a template that all values are
-- rendered with. For example one useful encoder would be 'Text.Html.stringToHtmlString'. All attributes will be encoded once and only once.
setEncoder :: (Stringable a) => (a -> a) -> StringTemplate a -> StringTemplate a
setEncoder :: (a -> a) -> StringTemplate a -> StringTemplate a
setEncoder a -> a
x StringTemplate a
st = StringTemplate a
st {senv :: SEnv a
senv = (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
st) {senc :: a -> a
senc = a -> a
x} }

-- | A special template that simply dumps the values of all the attributes set in it.
-- This may be made available to any template as a function by adding it to its group.
-- I.e. @ myNewGroup = addSuperGroup myGroup $ groupStringTemplates [("dumpAttribs", dumpAttribs)] @
dumpAttribs :: Stringable a => StringTemplate a
dumpAttribs :: StringTemplate a
dumpAttribs = SEnv a
-> Either String (SEnv a -> a)
-> (SEnv a -> (Maybe String, Maybe [String], Maybe [String]))
-> StringTemplate a
forall a.
SEnv a
-> Either String (SEnv a -> a)
-> (SEnv a -> (Maybe String, Maybe [String], Maybe [String]))
-> StringTemplate a
STMP SEnv a
forall a. SEnv a
nullEnv ((SEnv a -> a) -> Either String (SEnv a -> a)
forall a b. b -> Either a b
Right ((SEnv a -> a) -> Either String (SEnv a -> a))
-> (SEnv a -> a) -> Either String (SEnv a -> a)
forall a b. (a -> b) -> a -> b
$ \SEnv a
env -> SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal SEnv a
env (SMap a -> SElem a
forall a. SMap a -> SElem a
SM (SMap a -> SElem a) -> SMap a -> SElem a
forall a b. (a -> b) -> a -> b
$ SEnv a -> SMap a
forall a. SEnv a -> SMap a
smp SEnv a
env)) ((Maybe String, Maybe [String], Maybe [String])
-> SEnv a -> (Maybe String, Maybe [String], Maybe [String])
forall a b. a -> b -> a
const (Maybe String
forall a. Maybe a
Nothing, Maybe [String]
forall a. Maybe a
Nothing, Maybe [String]
forall a. Maybe a
Nothing))

{--------------------------------------------------------------------
  Internal API
--------------------------------------------------------------------}
--IMPLEMENT groups having stLookup return a Maybe for regions

data SEnv a = SEnv {SEnv a -> SMap a
smp :: SMap a, SEnv a -> [(String, SEnv a -> SElem a)]
sopts :: [(String, (SEnv a -> SElem a))], SEnv a -> STGroup a
sgen :: STGroup a, SEnv a -> a -> a
senc :: a -> a}

inSGen :: (STGroup a -> STGroup a) -> StringTemplate a -> StringTemplate a
inSGen :: (STGroup a -> STGroup a) -> StringTemplate a -> StringTemplate a
inSGen STGroup a -> STGroup a
f st :: StringTemplate a
st@STMP{senv :: forall a. StringTemplate a -> SEnv a
senv = SEnv a
env} = StringTemplate a
st {senv :: SEnv a
senv = SEnv a
env {sgen :: STGroup a
sgen = STGroup a -> STGroup a
f (SEnv a -> STGroup a
forall a. SEnv a -> STGroup a
sgen SEnv a
env)} }

{-
envLookup :: String -> SEnv a -> Maybe (SElem a)
envLookup x = M.lookup x . smp
-}

envLookupEx :: String -> SEnv a -> SElem a
envLookupEx :: String -> SEnv a -> SElem a
envLookupEx String
x SEnv a
snv = case String -> Map String (SElem a) -> Maybe (SElem a)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
x (SEnv a -> Map String (SElem a)
forall a. SEnv a -> SMap a
smp SEnv a
snv) of
                      Just SElem a
a -> SElem a
a
                      Maybe (SElem a)
Nothing -> case String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"throwException" SEnv a
snv of
                                   Just SEnv a -> SElem a
_ -> TmplException -> SElem a
forall a e. Exception e => e -> a
C.throw (TmplException -> SElem a) -> TmplException -> SElem a
forall a b. (a -> b) -> a -> b
$ String -> TmplException
NoAttrib String
x
                                   Maybe (SEnv a -> SElem a)
Nothing -> SElem a
forall a. SElem a
SNull

envInsert :: (String, SElem a) -> SEnv a -> SEnv a
envInsert :: (String, SElem a) -> SEnv a -> SEnv a
envInsert (String
s, SElem a
x) SEnv a
y = SEnv a
y {smp :: SMap a
smp = String -> SElem a -> SMap a -> SMap a
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert String
s SElem a
x (SEnv a -> SMap a
forall a. SEnv a -> SMap a
smp SEnv a
y)}
envInsApp :: Stringable a => String -> SElem a -> SEnv a -> SEnv a
envInsApp :: String -> SElem a -> SEnv a -> SEnv a
envInsApp  String
s  SElem a
x  SEnv a
y = SEnv a
y {smp :: SMap a
smp = (SElem a -> SElem a -> SElem a)
-> String -> SElem a -> SMap a -> SMap a
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith SElem a -> SElem a -> SElem a
forall a. SElem a -> SElem a -> SElem a
go String
s SElem a
x (SEnv a -> SMap a
forall a. SEnv a -> SMap a
smp SEnv a
y)}
    where go :: SElem a -> SElem a -> SElem a
go SElem a
a (LI [SElem a]
bs) = [SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI (SElem a
aSElem a -> [SElem a] -> [SElem a]
forall a. a -> [a] -> [a]
:[SElem a]
bs)
          go SElem a
a SElem a
b = [SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI [SElem a
a,SElem a
b]

optLookup :: String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup :: String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
x = String
-> [(String, SEnv a -> SElem a)] -> Maybe (SEnv a -> SElem a)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
x ([(String, SEnv a -> SElem a)] -> Maybe (SEnv a -> SElem a))
-> (SEnv a -> [(String, SEnv a -> SElem a)])
-> SEnv a
-> Maybe (SEnv a -> SElem a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SEnv a -> [(String, SEnv a -> SElem a)]
forall a. SEnv a -> [(String, SEnv a -> SElem a)]
sopts
optInsert :: [(String, SEnv a -> SElem a)] -> SEnv a -> SEnv a
optInsert :: [(String, SEnv a -> SElem a)] -> SEnv a -> SEnv a
optInsert [(String, SEnv a -> SElem a)]
x SEnv a
env = SEnv a
env {sopts :: [(String, SEnv a -> SElem a)]
sopts = [(String, SEnv a -> SElem a)]
x [(String, SEnv a -> SElem a)]
-> [(String, SEnv a -> SElem a)] -> [(String, SEnv a -> SElem a)]
forall a. [a] -> [a] -> [a]
++ SEnv a -> [(String, SEnv a -> SElem a)]
forall a. SEnv a -> [(String, SEnv a -> SElem a)]
sopts SEnv a
env}
nullOpt :: SEnv a -> SElem a
nullOpt :: SEnv a -> SElem a
nullOpt = (SEnv a -> SElem a)
-> Maybe (SEnv a -> SElem a) -> SEnv a -> SElem a
forall a. a -> Maybe a -> a
fromMaybe (String -> SEnv a -> SElem a
forall b a. String -> b -> SElem a
justSTR String
"") (Maybe (SEnv a -> SElem a) -> SEnv a -> SElem a)
-> (SEnv a -> Maybe (SEnv a -> SElem a)) -> SEnv a -> SElem a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"null"

stLookup :: (Stringable a) => String -> SEnv a -> StringTemplate a
stLookup :: String -> SEnv a -> StringTemplate a
stLookup String
x SEnv a
env = StringTemplate a
-> (StringTemplate a -> StringTemplate a)
-> Maybe (StringTemplate a)
-> StringTemplate a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> StringTemplate a
forall a. Stringable a => String -> StringTemplate a
newSTMP (String
"No Template Found for: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x))
                 (\StringTemplate a
st-> StringTemplate a
st {senv :: SEnv a
senv = SEnv a -> SEnv a -> SEnv a
forall a. SEnv a -> SEnv a -> SEnv a
mergeSEnvs SEnv a
env (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
st)}) (Maybe (StringTemplate a) -> StringTemplate a)
-> Maybe (StringTemplate a) -> StringTemplate a
forall a b. (a -> b) -> a -> b
$ StFirst (StringTemplate a) -> Maybe (StringTemplate a)
forall a. StFirst a -> Maybe a
stGetFirst (SEnv a -> STGroup a
forall a. SEnv a -> STGroup a
sgen SEnv a
env String
x)

--merges values of former into latter, preserving encoder
--of latter, as well as non-overriden options. group of latter is overridden.
mergeSEnvs :: SEnv a -> SEnv a -> SEnv a
mergeSEnvs :: SEnv a -> SEnv a -> SEnv a
mergeSEnvs SEnv a
x SEnv a
y = SEnv :: forall a.
SMap a
-> [(String, SEnv a -> SElem a)] -> STGroup a -> (a -> a) -> SEnv a
SEnv {smp :: SMap a
smp = SMap a -> SMap a -> SMap a
forall k a. Ord k => Map k a -> Map k a -> Map k a
M.union (SEnv a -> SMap a
forall a. SEnv a -> SMap a
smp SEnv a
x) (SEnv a -> SMap a
forall a. SEnv a -> SMap a
smp SEnv a
y), sopts :: [(String, SEnv a -> SElem a)]
sopts = (SEnv a -> [(String, SEnv a -> SElem a)]
forall a. SEnv a -> [(String, SEnv a -> SElem a)]
sopts SEnv a
y [(String, SEnv a -> SElem a)]
-> [(String, SEnv a -> SElem a)] -> [(String, SEnv a -> SElem a)]
forall a. [a] -> [a] -> [a]
++ SEnv a -> [(String, SEnv a -> SElem a)]
forall a. SEnv a -> [(String, SEnv a -> SElem a)]
sopts SEnv a
x), sgen :: STGroup a
sgen = SEnv a -> STGroup a
forall a. SEnv a -> STGroup a
sgen SEnv a
x, senc :: a -> a
senc = SEnv a -> a -> a
forall a. SEnv a -> a -> a
senc SEnv a
y}

parseSTMP :: (Stringable a) => (Char, Char) -> String -> Either String (SEnv a -> a)
parseSTMP :: (Char, Char) -> String -> Either String (SEnv a -> a)
parseSTMP (Char, Char)
x = (ParseError -> Either String (SEnv a -> a))
-> ((SEnv a -> a) -> Either String (SEnv a -> a))
-> Either ParseError (SEnv a -> a)
-> Either String (SEnv a -> a)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Either String (SEnv a -> a)
forall a b. a -> Either a b
Left (String -> Either String (SEnv a -> a))
-> (ParseError -> String)
-> ParseError
-> Either String (SEnv a -> a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseError -> String
forall a. Show a => a -> String
show) (SEnv a -> a) -> Either String (SEnv a -> a)
forall a b. b -> Either a b
Right (Either ParseError (SEnv a -> a) -> Either String (SEnv a -> a))
-> (String -> Either ParseError (SEnv a -> a))
-> String
-> Either String (SEnv a -> a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenParser
  Char ((Char, Char), [String], [String], [String]) (SEnv a -> a)
-> ((Char, Char), [String], [String], [String])
-> String
-> String
-> Either ParseError (SEnv a -> a)
forall tok st a.
GenParser tok st a -> st -> String -> [tok] -> Either ParseError a
runParser (Bool
-> GenParser
     Char ((Char, Char), [String], [String], [String]) (SEnv a -> a)
forall a. Stringable a => Bool -> TmplParser (SEnv a -> a)
stmpl Bool
False) ((Char, Char)
x,[],[],[]) String
"" (String -> Either ParseError (SEnv a -> a))
-> (String -> String) -> String -> Either ParseError (SEnv a -> a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
dropTrailingBr

dropTrailingBr :: String -> String
dropTrailingBr :: String -> String
dropTrailingBr (Char
'\r':Char
'\n':[]) = []
dropTrailingBr (Char
'\n':[]) = []
dropTrailingBr [] = []
dropTrailingBr (Char
x:String
xs) = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
dropTrailingBr String
xs

getSeps :: TmplParser (Char, Char)
getSeps :: TmplParser (Char, Char)
getSeps = (\((Char, Char)
x,[String]
_,[String]
_,[String]
_) -> (Char, Char)
x) (((Char, Char), [String], [String], [String]) -> (Char, Char))
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     ((Char, Char), [String], [String], [String])
-> TmplParser (Char, Char)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState

tellName :: String -> TmplParser ()
tellName :: String -> TmplParser ()
tellName String
x = ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
-> (((Char, Char), [String], [String], [String]) -> TmplParser ())
-> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \((Char, Char)
s,[String]
q,[String]
n,[String]
t) -> ((Char, Char), [String], [String], [String]) -> TmplParser ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState ((Char, Char)
s,[String]
q,String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
n,[String]
t)

tellQQ :: String -> TmplParser ()
tellQQ :: String -> TmplParser ()
tellQQ String
x = ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
-> (((Char, Char), [String], [String], [String]) -> TmplParser ())
-> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \((Char, Char)
s,[String]
q,[String]
n,[String]
t) -> ((Char, Char), [String], [String], [String]) -> TmplParser ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState ((Char, Char)
s,String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
q,[String]
n,[String]
t)

tellTmpl :: String -> TmplParser ()
tellTmpl :: String -> TmplParser ()
tellTmpl String
x = ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
-> (((Char, Char), [String], [String], [String]) -> TmplParser ())
-> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \((Char, Char)
s,[String]
q,[String]
n,[String]
t) -> ((Char, Char), [String], [String], [String]) -> TmplParser ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState ((Char, Char)
s,[String]
q,[String]
n,String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
t)

-- | Gets all quasiquoted names, normal names & templates used in a given template.
-- Must be passed a pair of chars denoting the delimeters to be used.
parseSTMPNames :: (Char, Char) -> String -> Either ParseError ([String],[String],[String])
parseSTMPNames :: (Char, Char)
-> String -> Either ParseError ([String], [String], [String])
parseSTMPNames (Char, Char)
cs String
s = GenParser
  Char
  ((Char, Char), [String], [String], [String])
  ([String], [String], [String])
-> ((Char, Char), [String], [String], [String])
-> String
-> String
-> Either ParseError ([String], [String], [String])
forall tok st a.
GenParser tok st a -> st -> String -> [tok] -> Either ParseError a
runParser GenParser
  Char
  ((Char, Char), [String], [String], [String])
  ([String], [String], [String])
getRefs ((Char, Char)
cs,[],[],[]) String
"" String
s
    where getRefs :: GenParser
  Char
  ((Char, Char), [String], [String], [String])
  ([String], [String], [String])
getRefs = do
            SEnv String -> String
_ <- Bool -> TmplParser (SEnv String -> String)
forall a. Stringable a => Bool -> TmplParser (SEnv a -> a)
stmpl Bool
False :: TmplParser (SEnv String -> String)
            ((Char, Char)
_,[String]
qqnames,[String]
regnames,[String]
tmpls) <- ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ((Char, Char), [String], [String], [String])
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
            ([String], [String], [String])
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     ([String], [String], [String])
forall (m :: * -> *) a. Monad m => a -> m a
return ([String]
qqnames, [String]
regnames, [String]
tmpls)

chkStmp :: Stringable a => (Char, Char) -> String -> SEnv a -> (Maybe String, Maybe [String], Maybe [String])
chkStmp :: (Char, Char)
-> String
-> SEnv a
-> (Maybe String, Maybe [String], Maybe [String])
chkStmp (Char, Char)
cs String
s SEnv a
snv = case (Char, Char)
-> String -> Either ParseError ([String], [String], [String])
parseSTMPNames (Char, Char)
cs String
s of
                     Left ParseError
err -> (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String
"Parse error: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ParseError -> String
forall a. Show a => a -> String
show ParseError
err, Maybe [String]
forall a. Maybe a
Nothing, Maybe [String]
forall a. Maybe a
Nothing)
                     Right ([String]
_, [String]
regnames, [String]
tmpls) ->
                         let nonms :: [String]
nonms   = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (\String
x -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem String
x (Map String (SElem a) -> [String]
forall k a. Map k a -> [k]
M.keys (Map String (SElem a) -> [String])
-> Map String (SElem a) -> [String]
forall a b. (a -> b) -> a -> b
$ SEnv a -> Map String (SElem a)
forall a. SEnv a -> SMap a
smp SEnv a
snv)) [String]
regnames
                             notmpls :: [String]
notmpls = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (\String
x -> Maybe (StringTemplate a) -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe (StringTemplate a) -> Bool)
-> Maybe (StringTemplate a) -> Bool
forall a b. (a -> b) -> a -> b
$ StFirst (StringTemplate a) -> Maybe (StringTemplate a)
forall a. StFirst a -> Maybe a
stGetFirst (SEnv a -> STGroup a
forall a. SEnv a -> STGroup a
sgen SEnv a
snv String
x)) [String]
tmpls
                         in (Maybe String
forall a. Maybe a
Nothing, if [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
nonms then Maybe [String]
forall a. Maybe a
Nothing else [String] -> Maybe [String]
forall a. a -> Maybe a
Just [String]
nonms,
                                      if [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
notmpls then Maybe [String]
forall a. Maybe a
Nothing else [String] -> Maybe [String]
forall a. a -> Maybe a
Just [String]
notmpls)

data TmplException = NoAttrib String | NoTmpl String | ParseError String String deriving (Int -> TmplException -> String -> String
[TmplException] -> String -> String
TmplException -> String
(Int -> TmplException -> String -> String)
-> (TmplException -> String)
-> ([TmplException] -> String -> String)
-> Show TmplException
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [TmplException] -> String -> String
$cshowList :: [TmplException] -> String -> String
show :: TmplException -> String
$cshow :: TmplException -> String
showsPrec :: Int -> TmplException -> String -> String
$cshowsPrec :: Int -> TmplException -> String -> String
Show, Typeable)
instance C.Exception TmplException

-- | Generic render function for a StringTemplate of any type.
renderErr :: Stringable a => String -> StringTemplate a -> a
renderErr :: String -> StringTemplate a -> a
renderErr String
n StringTemplate a
t = case StringTemplate a -> Either String (SEnv a -> a)
forall a. StringTemplate a -> Either String (SEnv a -> a)
runSTMP StringTemplate a
t of
                Right SEnv a -> a
rt -> SEnv a -> a
rt (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
t)
                Left String
err -> case String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"throwException" (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
t) of
                              Just SEnv a -> SElem a
_ -> TmplException -> a
forall a e. Exception e => e -> a
C.throw (TmplException -> a) -> TmplException -> a
forall a b. (a -> b) -> a -> b
$ String -> String -> TmplException
ParseError String
n String
err
                              Maybe (SEnv a -> SElem a)
Nothing -> String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr String
err (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
t)

-- | Returns a tuple of three lists. The first is of templates with parse errors, and their errors. The next is of missing attributes, and the last is of missing templates. If there are no errors, then all lists will be empty. This check is performed recursively.
checkTemplateDeep :: (Stringable a, NFData a) => StringTemplate a -> ([(String,String)], [String], [String])
checkTemplateDeep :: StringTemplate a -> ([(String, String)], [String], [String])
checkTemplateDeep StringTemplate a
t = case StringTemplate a -> Either String (SEnv a -> a)
forall a. StringTemplate a -> Either String (SEnv a -> a)
runSTMP StringTemplate a
t of
                        Left String
err -> ([(String
"Top Level Template", String
err)], [],[])
                        Right SEnv a -> a
_ -> IO ([(String, String)], [String], [String])
-> ([(String, String)], [String], [String])
forall a. IO a -> a
unsafePerformIO (IO ([(String, String)], [String], [String])
 -> ([(String, String)], [String], [String]))
-> IO ([(String, String)], [String], [String])
-> ([(String, String)], [String], [String])
forall a b. (a -> b) -> a -> b
$ ([(String, String)], [String], [String])
-> StringTemplate a -> IO ([(String, String)], [String], [String])
forall a.
(NFData a, Stringable a) =>
([(String, String)], [String], [String])
-> StringTemplate a -> IO ([(String, String)], [String], [String])
go ([],[],[]) (StringTemplate a -> IO ([(String, String)], [String], [String]))
-> StringTemplate a -> IO ([(String, String)], [String], [String])
forall a b. (a -> b) -> a -> b
$ (STGroup a -> STGroup a) -> StringTemplate a -> StringTemplate a
forall a.
(STGroup a -> STGroup a) -> StringTemplate a -> StringTemplate a
inSGen (STGroup a -> STGroup a -> STGroup a
forall a. Monoid a => a -> a -> a
`mappend` STGroup a
forall a. String -> StFirst a
nullGroup) (StringTemplate a -> StringTemplate a)
-> StringTemplate a -> StringTemplate a
forall a b. (a -> b) -> a -> b
$ [(String, String)] -> StringTemplate a -> StringTemplate a
forall a.
[(String, String)] -> StringTemplate a -> StringTemplate a
optInsertTmpl [(String
"throwException",String
"true")] StringTemplate a
t
    where go :: ([(String, String)], [String], [String])
-> StringTemplate a -> IO ([(String, String)], [String], [String])
go ([(String, String)]
e1,[String]
e2,[String]
e3) StringTemplate a
tmpl = (() -> IO ()
forall a. a -> IO a
C.evaluate (a -> ()
forall a. NFData a => a -> ()
rnf (a -> ()) -> a -> ()
forall a b. (a -> b) -> a -> b
$ StringTemplate a -> a
forall a. Stringable a => StringTemplate a -> a
render StringTemplate a
tmpl) IO ()
-> IO ([(String, String)], [String], [String])
-> IO ([(String, String)], [String], [String])
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ([(String, String)], [String], [String])
-> IO ([(String, String)], [String], [String])
forall (m :: * -> *) a. Monad m => a -> m a
return ([(String, String)]
e1,[String]
e2,[String]
e3)) IO ([(String, String)], [String], [String])
-> (TmplException -> IO ([(String, String)], [String], [String]))
-> IO ([(String, String)], [String], [String])
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`C.catch`
                                  \TmplException
e -> case TmplException
e of NoTmpl String
x -> ([(String, String)], [String], [String])
-> StringTemplate a -> IO ([(String, String)], [String], [String])
go ([(String, String)]
e1,[String]
e2,String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
e3) (StringTemplate a -> IO ([(String, String)], [String], [String]))
-> StringTemplate a -> IO ([(String, String)], [String], [String])
forall a b. (a -> b) -> a -> b
$ String -> StringTemplate a -> StringTemplate a
forall a.
Stringable a =>
String -> StringTemplate a -> StringTemplate a
addSub String
x StringTemplate a
tmpl
                                                  NoAttrib String
x -> ([(String, String)], [String], [String])
-> StringTemplate a -> IO ([(String, String)], [String], [String])
go ([(String, String)]
e1,String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
e2, [String]
e3) (StringTemplate a -> IO ([(String, String)], [String], [String]))
-> StringTemplate a -> IO ([(String, String)], [String], [String])
forall a b. (a -> b) -> a -> b
$ String -> String -> StringTemplate a -> StringTemplate a
forall a b.
(ToSElem a, Stringable b) =>
String -> a -> StringTemplate b -> StringTemplate b
setAttribute String
x String
"" StringTemplate a
tmpl
                                                  ParseError String
n String
x -> ([(String, String)], [String], [String])
-> StringTemplate a -> IO ([(String, String)], [String], [String])
go ((String
n,String
x)(String, String) -> [(String, String)] -> [(String, String)]
forall a. a -> [a] -> [a]
:[(String, String)]
e1,[String]
e2,[String]
e3) (StringTemplate a -> IO ([(String, String)], [String], [String]))
-> StringTemplate a -> IO ([(String, String)], [String], [String])
forall a b. (a -> b) -> a -> b
$ String -> StringTemplate a -> StringTemplate a
forall a.
Stringable a =>
String -> StringTemplate a -> StringTemplate a
addSub String
n StringTemplate a
tmpl
          addSub :: String -> StringTemplate a -> StringTemplate a
addSub String
x StringTemplate a
tmpl = (STGroup a -> STGroup a) -> StringTemplate a -> StringTemplate a
forall a.
(STGroup a -> STGroup a) -> StringTemplate a -> StringTemplate a
inSGen (STGroup a -> STGroup a -> STGroup a
forall a. Monoid a => a -> a -> a
mappend (STGroup a -> STGroup a -> STGroup a)
-> STGroup a -> STGroup a -> STGroup a
forall a b. (a -> b) -> a -> b
$ String -> STGroup a
forall a a.
(Eq a, Stringable a) =>
a -> a -> StFirst (StringTemplate a)
blankGroup String
x) StringTemplate a
tmpl
          blankGroup :: a -> a -> StFirst (StringTemplate a)
blankGroup a
x a
s = Maybe (StringTemplate a) -> StFirst (StringTemplate a)
forall a. Maybe a -> StFirst a
StFirst (Maybe (StringTemplate a) -> StFirst (StringTemplate a))
-> Maybe (StringTemplate a) -> StFirst (StringTemplate a)
forall a b. (a -> b) -> a -> b
$ if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
s then StringTemplate a -> Maybe (StringTemplate a)
forall a. a -> Maybe a
Just (String -> StringTemplate a
forall a. Stringable a => String -> StringTemplate a
newSTMP String
"") else Maybe (StringTemplate a)
forall a. Maybe a
Nothing
          nullGroup :: String -> StFirst a
nullGroup String
x = Maybe a -> StFirst a
forall a. Maybe a -> StFirst a
StFirst (Maybe a -> StFirst a) -> Maybe a -> StFirst a
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
Just (TmplException -> a
forall a e. Exception e => e -> a
C.throw (TmplException -> a) -> TmplException -> a
forall a b. (a -> b) -> a -> b
$ String -> TmplException
NoTmpl String
x)

{--------------------------------------------------------------------
  Internal API for polymorphic display of elements
--------------------------------------------------------------------}

mconcatMap' :: Stringable a => SEnv a -> [b] -> (b -> a) -> a
mconcatMap' :: SEnv a -> [b] -> (b -> a) -> a
mconcatMap' SEnv a
snv [b]
xs b -> a
f = a -> [a] -> a
forall a. Stringable a => a -> [a] -> a
mintercalate a
sep ([a] -> a) -> ([b] -> [a]) -> [b] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> a) -> [b] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map b -> a
f ([b] -> a) -> [b] -> a
forall a b. (a -> b) -> a -> b
$ [b]
xs
    where sep :: a
sep = SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal SEnv a
snv (SElem a -> a) -> SElem a -> a
forall a b. (a -> b) -> a -> b
$ (SEnv a -> SElem a)
-> Maybe (SEnv a -> SElem a) -> SEnv a -> SElem a
forall a. a -> Maybe a -> a
fromMaybe (String -> SEnv a -> SElem a
forall b a. String -> b -> SElem a
justSTR String
"") (Maybe (SEnv a -> SElem a) -> SEnv a -> SElem a)
-> (SEnv a -> Maybe (SEnv a -> SElem a)) -> SEnv a -> SElem a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"separator" (SEnv a -> SElem a) -> SEnv a -> SElem a
forall a b. (a -> b) -> a -> b
$ SEnv a
snv

showVal :: Stringable a => SEnv a -> SElem a -> a
showVal :: SEnv a -> SElem a -> a
showVal SEnv a
snv SElem a
se = case SElem a
se of
                   STR String
x  -> String -> a
stEncode String
x
                   BS  ByteString
x  -> ByteString -> a
stEncodeBS ByteString
x
                   TXT Text
x  -> Text -> a
stEncodeText Text
x
                   LI [SElem a]
xs  -> (SEnv a -> SElem a -> a) -> [SElem a] -> a
forall b. (SEnv a -> b -> a) -> [b] -> a
joinUpWith SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal [SElem a]
xs
                   SM SMap a
sm  -> (SEnv a -> (String, SElem a) -> a) -> [(String, SElem a)] -> a
forall b. (SEnv a -> b -> a) -> [b] -> a
joinUpWith SEnv a -> (String, SElem a) -> a
showAssoc ([(String, SElem a)] -> a) -> [(String, SElem a)] -> a
forall a b. (a -> b) -> a -> b
$ SMap a -> [(String, SElem a)]
forall k a. Map k a -> [(k, a)]
M.assocs SMap a
sm
                   STSH STShow
x -> String -> a
stEncode (STShow -> String
format STShow
x)
                   SNAT a
x -> SEnv a -> a -> a
forall a. SEnv a -> a -> a
senc SEnv a
snv a
x
                   SBLE a
x -> a
x
                   SElem a
SNull  -> SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal (SEnv a -> SElem a -> a) -> (SEnv a -> SElem a) -> SEnv a -> a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SEnv a -> SElem a
forall a. SEnv a -> SElem a
nullOpt (SEnv a -> a) -> SEnv a -> a
forall a b. (a -> b) -> a -> b
$ SEnv a
snv
    where format :: STShow -> String
format = (STShow -> String)
-> ((SEnv a -> SElem a) -> STShow -> String)
-> Maybe (SEnv a -> SElem a)
-> STShow
-> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe STShow -> String
stshow (((SEnv a -> SElem a) -> STShow -> String)
 -> Maybe (SEnv a -> SElem a) -> STShow -> String)
-> (SEnv a -> (SEnv a -> SElem a) -> STShow -> String)
-> SEnv a
-> Maybe (SEnv a -> SElem a)
-> STShow
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SEnv a -> (SEnv a -> SElem a) -> STShow -> String
forall a.
Stringable a =>
SEnv a -> (SEnv a -> SElem a) -> STShow -> String
stfshow (SEnv a -> Maybe (SEnv a -> SElem a) -> STShow -> String)
-> (SEnv a -> Maybe (SEnv a -> SElem a))
-> SEnv a
-> STShow
-> String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"format" (SEnv a -> STShow -> String) -> SEnv a -> STShow -> String
forall a b. (a -> b) -> a -> b
$ SEnv a
snv
          joinUpWith :: (SEnv a -> b -> a) -> [b] -> a
joinUpWith SEnv a -> b -> a
f [b]
xs = SEnv a -> [b] -> (b -> a) -> a
forall a b. Stringable a => SEnv a -> [b] -> (b -> a) -> a
mconcatMap' SEnv a
snv [b]
xs (SEnv a -> b -> a
f SEnv a
snv)
          showAssoc :: SEnv a -> (String, SElem a) -> a
showAssoc SEnv a
e (String
k,SElem a
v) = String -> a
stEncode (String
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": ") a -> a -> a
forall a. Stringable a => a -> a -> a
`mlabel` SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal SEnv a
e SElem a
v
          stEncode :: String -> a
stEncode     = SEnv a -> a -> a
forall a. SEnv a -> a -> a
senc SEnv a
snv (a -> a) -> (String -> a) -> String -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a
forall a. Stringable a => String -> a
stFromString
          stEncodeBS :: ByteString -> a
stEncodeBS   = SEnv a -> a -> a
forall a. SEnv a -> a -> a
senc SEnv a
snv (a -> a) -> (ByteString -> a) -> ByteString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> a
forall a. Stringable a => ByteString -> a
stFromByteString
          stEncodeText :: Text -> a
stEncodeText = SEnv a -> a -> a
forall a. SEnv a -> a -> a
senc SEnv a
snv (a -> a) -> (Text -> a) -> Text -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> a
forall a. Stringable a => Text -> a
stFromText

showStr :: Stringable a => String -> SEnv a -> a
showStr :: String -> SEnv a -> a
showStr = a -> SEnv a -> a
forall a b. a -> b -> a
const (a -> SEnv a -> a) -> (String -> a) -> String -> SEnv a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a
forall a. Stringable a => String -> a
stFromString

{--------------------------------------------------------------------
  Utility Combinators
--------------------------------------------------------------------}

justSTR :: String -> b -> SElem a
justSTR :: String -> b -> SElem a
justSTR = SElem a -> b -> SElem a
forall a b. a -> b -> a
const (SElem a -> b -> SElem a)
-> (String -> SElem a) -> String -> b -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> SElem a
forall a. String -> SElem a
STR
stshow :: STShow -> String
stshow :: STShow -> String
stshow (STShow a
a) = a -> String
forall a. StringTemplateShows a => a -> String
stringTemplateShow a
a
stfshow :: Stringable a => SEnv a -> (SEnv a -> SElem a) -> STShow -> String
stfshow :: SEnv a -> (SEnv a -> SElem a) -> STShow -> String
stfshow SEnv a
snv SEnv a -> SElem a
fs (STShow a
a) = String -> a -> String
forall a. StringTemplateShows a => String -> a -> String
stringTemplateFormattedShow
                            (a -> String
forall a. Stringable a => a -> String
stToString (a -> String)
-> (SEnv a -> SElem a -> a) -> SEnv a -> SElem a -> String
forall (f1 :: * -> *) (f :: * -> *) a b.
(Functor f1, Functor f) =>
(a -> b) -> f (f1 a) -> f (f1 b)
<$$> SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal (SEnv a -> SElem a -> String)
-> (SEnv a -> SElem a) -> SEnv a -> String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SEnv a -> SElem a
fs (SEnv a -> String) -> SEnv a -> String
forall a b. (a -> b) -> a -> b
$ SEnv a
snv) a
a

around :: Char -> GenParser Char st t -> Char -> GenParser Char st t
around :: Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
x GenParser Char st t
p Char
y = do {Char
_ <- Char -> ParsecT String st Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
x; t
v<-GenParser Char st t
p; Char
_ <- Char -> ParsecT String st Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
y; t -> GenParser Char st t
forall (m :: * -> *) a. Monad m => a -> m a
return t
v}
spaced :: GenParser Char st t -> GenParser Char st t
spaced :: GenParser Char st t -> GenParser Char st t
spaced GenParser Char st t
p = do {ParsecT String st Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces; t
v<-GenParser Char st t
p; ParsecT String st Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces; t -> GenParser Char st t
forall (m :: * -> *) a. Monad m => a -> m a
return t
v}

identifierChar :: GenParser Char st Char
identifierChar :: GenParser Char st Char
identifierChar = GenParser Char st Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum GenParser Char st Char
-> GenParser Char st Char -> GenParser Char st Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> GenParser Char st Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'_'

word :: GenParser Char st String
word :: GenParser Char st String
word = ParsecT String st Identity Char -> GenParser Char st String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String st Identity Char
forall st. GenParser Char st Char
identifierChar

comlist :: GenParser Char st a -> GenParser Char st [a]
comlist :: GenParser Char st a -> GenParser Char st [a]
comlist GenParser Char st a
p = GenParser Char st [a] -> GenParser Char st [a]
forall st t. GenParser Char st t -> GenParser Char st t
spaced (GenParser Char st a
p GenParser Char st a
-> ParsecT String st Identity Char -> GenParser Char st [a]
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]
`sepBy1` ParsecT String st Identity Char -> ParsecT String st Identity Char
forall st t. GenParser Char st t -> GenParser Char st t
spaced (Char -> ParsecT String st Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','))

props :: Stringable a => TmplParser [SEnv a -> SElem a]
props :: TmplParser [SEnv a -> SElem a]
props = ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
-> TmplParser [SEnv a -> SElem a]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT
   String
   ((Char, Char), [String], [String], [String])
   Identity
   (SEnv a -> SElem a)
 -> TmplParser [SEnv a -> SElem a])
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> TmplParser [SEnv a -> SElem a]
forall a b. (a -> b) -> a -> b
$ Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'.' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'(' ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn Char
')' ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> SEnv a -> SElem a
forall b a. String -> b -> SElem a
justSTR (String -> SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
forall st. GenParser Char st String
word)

escapedChar, escapedStr :: String -> GenParser Char st String
escapedChar :: String -> GenParser Char st String
escapedChar String
chs =
    String -> ParsecT String st Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
chs ParsecT String st Identity Char
-> (Char -> GenParser Char st String) -> GenParser Char st String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Char
x -> if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\\' then ParsecT String st Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar ParsecT String st Identity Char
-> (Char -> GenParser Char st String) -> GenParser Char st String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Char
y -> String -> GenParser Char st String
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
y] else String -> GenParser Char st String
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x]
escapedStr :: String -> GenParser Char st String
escapedStr String
chs = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> ParsecT String st Identity [String] -> GenParser Char st String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenParser Char st String -> ParsecT String st Identity [String]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> GenParser Char st String
forall st. String -> GenParser Char st String
escapedChar String
chs)

{-
escapedStr' chs = dropTrailingBr <$> escapedStr chs
-}

{--------------------------------------------------------------------
  The Grammar
--------------------------------------------------------------------}
myConcat :: Stringable a => [SEnv a -> a] -> (SEnv a -> a)
myConcat :: [SEnv a -> a] -> SEnv a -> a
myConcat [SEnv a -> a]
xs SEnv a
a = [SEnv a -> a] -> ((SEnv a -> a) -> a) -> a
forall a b. Stringable a => [b] -> (b -> a) -> a
mconcatMap [SEnv a -> a]
xs ((SEnv a -> a) -> SEnv a -> a
forall a b. (a -> b) -> a -> b
$ SEnv a
a)


-- | if p is true, stmpl can fail gracefully, false it dies hard.
-- Set to false at the top level, and true within if expressions.
stmpl :: Stringable a => Bool -> TmplParser (SEnv a -> a)
stmpl :: Bool -> TmplParser (SEnv a -> a)
stmpl Bool
p = do
  (Char
ca, Char
cb) <- TmplParser (Char, Char)
getSeps
  [SEnv a -> a] -> SEnv a -> a
forall a. Stringable a => [SEnv a -> a] -> SEnv a -> a
myConcat ([SEnv a -> a] -> SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> a]
-> TmplParser (SEnv a -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TmplParser (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> a]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr (String -> SEnv a -> a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> TmplParser (SEnv a -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall st. String -> GenParser Char st String
escapedStr [Char
ca] TmplParser (SEnv a -> a)
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try (Char
-> TmplParser (SEnv a -> a) -> Char -> TmplParser (SEnv a -> a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
ca TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
optExpr Char
cb)
                    TmplParser (SEnv a -> a)
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
comment TmplParser (SEnv a -> a)
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> a)
bl TmplParser (SEnv a -> a) -> String -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"template")
      where bl :: TmplParser (SEnv a -> a)
bl | Bool
p = TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
blank | Bool
otherwise = TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
blank

subStmp :: Stringable a => TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
subStmp :: TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
subStmp = do
  (Char
ca, Char
cb) <- TmplParser (Char, Char)
getSeps
  ([SElem a], [SElem a]) -> SEnv a -> SEnv a
udEnv <- (([SElem a], [SElem a]) -> SEnv a -> SEnv a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (([SElem a], [SElem a]) -> SEnv a -> SEnv a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (([SElem a], [SElem a]) -> SEnv a -> SEnv a)
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option ([String] -> ([SElem a], [SElem a]) -> SEnv a -> SEnv a
forall a. [String] -> ([SElem a], [SElem a]) -> SEnv a -> SEnv a
transform [String
"it"]) ([String] -> ([SElem a], [SElem a]) -> SEnv a -> SEnv a
forall a. [String] -> ([SElem a], [SElem a]) -> SEnv a -> SEnv a
transform ([String] -> ([SElem a], [SElem a]) -> SEnv a -> SEnv a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [String]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (([SElem a], [SElem a]) -> SEnv a -> SEnv a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [String]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [String]
forall tok st a. GenParser tok st a -> GenParser tok st a
try ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [String]
forall u. ParsecT String u Identity [String]
attribNames)
  SEnv a -> a
st <- [SEnv a -> a] -> SEnv a -> a
forall a. Stringable a => [SEnv a -> a] -> SEnv a -> a
myConcat ([SEnv a -> a] -> SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> a]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> a]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr (String -> SEnv a -> a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall st. String -> GenParser Char st String
escapedStr (Char
caChar -> String -> String
forall a. a -> [a] -> [a]
:String
"}|")
                         ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try (Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
-> Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
ca ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
optExpr Char
cb)
                         ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
comment ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
blank  ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> a)
-> String
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"subtemplate")
  (([SElem a], [SElem a]) -> SEnv a -> a)
-> TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SEnv a -> a
st (SEnv a -> a)
-> (([SElem a], [SElem a]) -> SEnv a -> SEnv a)
-> ([SElem a], [SElem a])
-> SEnv a
-> a
forall (f1 :: * -> *) (f :: * -> *) a b.
(Functor f1, Functor f) =>
(a -> b) -> f (f1 a) -> f (f1 b)
<$$> ([SElem a], [SElem a]) -> SEnv a -> SEnv a
udEnv)
      where transform :: [String] -> ([SElem a], [SElem a]) -> SEnv a -> SEnv a
transform [String]
an ([SElem a]
att,[SElem a]
is) =
                (SEnv a -> [(String, SElem a)] -> SEnv a)
-> [(String, SElem a)] -> SEnv a -> SEnv a
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((String, SElem a) -> SEnv a -> SEnv a)
-> SEnv a -> [(String, SElem a)] -> SEnv a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (String, SElem a) -> SEnv a -> SEnv a
forall a. (String, SElem a) -> SEnv a -> SEnv a
envInsert) ([(String, SElem a)] -> SEnv a -> SEnv a)
-> [(String, SElem a)] -> SEnv a -> SEnv a
forall a b. (a -> b) -> a -> b
$ [String] -> [SElem a] -> [(String, SElem a)]
forall a b. [a] -> [b] -> [(a, b)]
zip (String
"i"String -> [String] -> [String]
forall a. a -> [a] -> [a]
:String
"i0"String -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
an) ([SElem a]
is[SElem a] -> [SElem a] -> [SElem a]
forall a. [a] -> [a] -> [a]
++[SElem a]
att)
            attribNames :: ParsecT String u Identity [String]
attribNames = (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|' ParsecT String u Identity Char
-> ParsecT String u Identity [String]
-> ParsecT String u Identity [String]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>) (ParsecT String u Identity [String]
 -> ParsecT String u Identity [String])
-> ([String] -> ParsecT String u Identity [String])
-> [String]
-> ParsecT String u Identity [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> ParsecT String u Identity [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> ParsecT String u Identity [String])
-> ParsecT String u Identity [String]
-> ParsecT String u Identity [String]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< GenParser Char u String -> ParsecT String u Identity [String]
forall st a. GenParser Char st a -> GenParser Char st [a]
comlist (GenParser Char u String -> GenParser Char u String
forall st t. GenParser Char st t -> GenParser Char st t
spaced GenParser Char u String
forall st. GenParser Char st String
word)

comment :: Stringable a => TmplParser (SEnv a -> a)
comment :: TmplParser (SEnv a -> a)
comment = do
  (Char
ca, Char
cb) <- TmplParser (Char, Char)
getSeps
  String
_ <- String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string [Char
ca,Char
'!'] ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
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]
manyTill ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar (ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall tok st a. GenParser tok st a -> GenParser tok st a
try (ParsecT
   String ((Char, Char), [String], [String], [String]) Identity String
 -> ParsecT
      String
      ((Char, Char), [String], [String], [String])
      Identity
      String)
-> (String
    -> ParsecT
         String
         ((Char, Char), [String], [String], [String])
         Identity
         String)
-> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (String
 -> ParsecT
      String
      ((Char, Char), [String], [String], [String])
      Identity
      String)
-> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall a b. (a -> b) -> a -> b
$ [Char
'!',Char
cb])
  (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr String
"")

blank :: Stringable a => TmplParser (SEnv a -> a)
blank :: TmplParser (SEnv a -> a)
blank = do
  (Char
ca, Char
cb) <- TmplParser (Char, Char)
getSeps
  Char
_ <- Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
ca
  TmplParser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
  Char
_ <- Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
cb
  (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr String
"")

optExpr :: Stringable a => TmplParser (SEnv a -> a)
optExpr :: TmplParser (SEnv a -> a)
optExpr = do
  (Char
_, Char
cb) <- TmplParser (Char, Char)
getSeps
  (ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall tok st a. GenParser tok st a -> GenParser tok st a
try (String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (String
"else"String -> String -> String
forall a. [a] -> [a] -> [a]
++[Char
cb])) ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall tok st a. GenParser tok st a -> GenParser tok st a
try (String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"elseif(") ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
    ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall tok st a. GenParser tok st a -> GenParser tok st a
try (String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"endif")) ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> TmplParser () -> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
.>> String -> TmplParser ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Malformed If Statement." TmplParser () -> TmplParser () -> TmplParser ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> () -> TmplParser ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  SEnv a -> a
expr <- TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
ifstat TmplParser (SEnv a -> a)
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall st t. GenParser Char st t -> GenParser Char st t
spaced TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
exprn
  [(String, SEnv a -> SElem a)]
opts <- (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [(String, SEnv a -> SElem a)]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [(String, SEnv a -> SElem a)]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [(String, SEnv a -> SElem a)]
optList) ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [(String, SEnv a -> SElem a)]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [(String, SEnv a -> SElem a)]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [(String, SEnv a -> SElem a)]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> [(String, SEnv a -> SElem a)]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [(String, SEnv a -> SElem a)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
  (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return ((SEnv a -> a) -> TmplParser (SEnv a -> a))
-> (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall a b. (a -> b) -> a -> b
$ SEnv a -> a
expr (SEnv a -> a) -> (SEnv a -> SEnv a) -> SEnv a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(String, SEnv a -> SElem a)] -> SEnv a -> SEnv a
forall a. [(String, SEnv a -> SElem a)] -> SEnv a -> SEnv a
optInsert [(String, SEnv a -> SElem a)]
opts
      where -- opt = around ';' (spaced word) '=' >>= (<$> spaced subexprn) . (,)
            optList :: ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [(String, SEnv a -> SElem a)]
optList = ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (String, SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [(String, SEnv a -> SElem a)]
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]
sepBy ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (String, SEnv a -> SElem a)
oneOpt (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
',' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';')
            oneOpt :: ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (String, SEnv a -> SElem a)
oneOpt = do
              String
o <- ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall st t. GenParser Char st t -> GenParser Char st t
spaced ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
forall st. GenParser Char st String
word
              Char
_ <- Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'='
              SEnv a -> SElem a
v <- GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv a -> SElem a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (SEnv a -> SElem a)
forall st t. GenParser Char st t -> GenParser Char st t
spaced GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn
              (String, SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (String, SEnv a -> SElem a)
forall (m :: * -> *) a. Monad m => a -> m a
return (String
o,SEnv a -> SElem a
v)

{--------------------------------------------------------------------
  Statements
--------------------------------------------------------------------}

optLine :: TmplParser ()
optLine :: TmplParser ()
optLine = ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> TmplParser ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\r') TmplParser () -> TmplParser () -> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> TmplParser ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n')

--if env then do stuff
getProp :: Stringable a => [SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
getProp :: [SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
getProp (SEnv a -> SElem a
p:[SEnv a -> SElem a]
ps) (SM SMap a
mp) SEnv a
env =
  case String -> SMap a -> Maybe (SElem a)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (a -> String
forall a. Stringable a => a -> String
stToString (a -> String) -> (SElem a -> a) -> SElem a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal SEnv a
env (SElem a -> String) -> SElem a -> String
forall a b. (a -> b) -> a -> b
$ SEnv a -> SElem a
p SEnv a
env) SMap a
mp of
    Just SElem a
prop -> [SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
forall a.
Stringable a =>
[SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
getProp [SEnv a -> SElem a]
ps SElem a
prop SEnv a
env
    Maybe (SElem a)
Nothing -> case String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"throwException" SEnv a
env of
                 Just SEnv a -> SElem a
_ -> TmplException -> SElem a
forall a e. Exception e => e -> a
C.throw (TmplException -> SElem a)
-> (String -> TmplException) -> String -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TmplException
NoAttrib (String -> SElem a) -> String -> SElem a
forall a b. (a -> b) -> a -> b
$ String
"yeek" --intercalate "." . map showIt $ (p:ps)
                 Maybe (SEnv a -> SElem a)
Nothing -> SElem a
forall a. SElem a
SNull
  --where showIt x = stToString . showVal env $ x env
getProp (SEnv a -> SElem a
_:[SEnv a -> SElem a]
_) SElem a
_ SEnv a
_ = SElem a
forall a. SElem a
SNull
getProp [SEnv a -> SElem a]
_ SElem a
se SEnv a
_ = SElem a
se

ifIsSet :: t -> t -> Bool -> SElem a -> t
ifIsSet :: t -> t -> Bool -> SElem a -> t
ifIsSet t
t t
e Bool
n SElem a
SNull = if Bool
n then t
e else t
t
ifIsSet t
t t
e Bool
n SElem a
_ = if Bool
n then t
t else t
e

ifstat ::Stringable a => TmplParser (SEnv a -> a)
ifstat :: TmplParser (SEnv a -> a)
ifstat = do
  (Char
_, Char
cb) <- TmplParser (Char, Char)
getSeps
  String
_ <- String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"if("
  Bool
n <- Bool
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Bool
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Bool
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
True (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Bool
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False)
  SEnv a -> SElem a
e <- TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn
  [SEnv a -> SElem a]
p <- TmplParser [SEnv a -> SElem a]
forall a. Stringable a => TmplParser [SEnv a -> SElem a]
props
  Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
cb ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> TmplParser () -> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TmplParser ()
optLine
  SEnv a -> a
act <- Bool -> TmplParser (SEnv a -> a)
forall a. Stringable a => Bool -> TmplParser (SEnv a -> a)
stmpl Bool
True
  SEnv a -> a
cont <- (TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
elseifstat TmplParser (SEnv a -> a)
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
elsestat TmplParser (SEnv a -> a)
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
endifstat)
  (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return ((SEnv a -> a) -> (SEnv a -> a) -> Bool -> SElem a -> SEnv a -> a
forall t a. t -> t -> Bool -> SElem a -> t
ifIsSet SEnv a -> a
act SEnv a -> a
cont Bool
n (SElem a -> SEnv a -> a) -> (SEnv a -> SElem a) -> SEnv a -> a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
forall a.
Stringable a =>
[SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
getProp [SEnv a -> SElem a]
p (SElem a -> SEnv a -> SElem a)
-> (SEnv a -> SElem a) -> SEnv a -> SElem a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SEnv a -> SElem a
e)

elseifstat ::Stringable a => TmplParser (SEnv a -> a)
elseifstat :: TmplParser (SEnv a -> a)
elseifstat = TmplParser (Char, Char)
getSeps TmplParser (Char, Char)
-> ((Char, Char)
    -> ParsecT
         String ((Char, Char), [String], [String], [String]) Identity Char)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char (Char
 -> ParsecT
      String ((Char, Char), [String], [String], [String]) Identity Char)
-> ((Char, Char) -> Char)
-> (Char, Char)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char, Char) -> Char
forall a b. (a, b) -> a
fst ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"else" ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
ifstat

elsestat ::Stringable a => TmplParser (SEnv a -> a)
elsestat :: TmplParser (SEnv a -> a)
elsestat = do
  (Char
ca, Char
cb) <- TmplParser (Char, Char)
getSeps
  String
_ <- Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
ca (String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"else") Char
cb
  TmplParser ()
optLine
  SEnv a -> a
act <- Bool -> TmplParser (SEnv a -> a)
forall a. Stringable a => Bool -> TmplParser (SEnv a -> a)
stmpl Bool
True
  String
_ <- Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
ca ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"endif"
  (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return SEnv a -> a
act

endifstat ::Stringable a => TmplParser (SEnv a -> a)
endifstat :: TmplParser (SEnv a -> a)
endifstat = TmplParser (Char, Char)
getSeps TmplParser (Char, Char)
-> ((Char, Char)
    -> ParsecT
         String ((Char, Char), [String], [String], [String]) Identity Char)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char (Char
 -> ParsecT
      String ((Char, Char), [String], [String], [String]) Identity Char)
-> ((Char, Char) -> Char)
-> (Char, Char)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char, Char) -> Char
forall a b. (a, b) -> a
fst ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"endif" ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> TmplParser (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> SEnv a -> a
forall a. Stringable a => String -> SEnv a -> a
showStr String
"")

{--------------------------------------------------------------------
  Expressions
--------------------------------------------------------------------}

exprn :: Stringable a => TmplParser (SEnv a -> a)
exprn :: TmplParser (SEnv a -> a)
exprn = do
  [SEnv a -> SElem a]
exprs <- GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv a -> SElem a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [SEnv a -> SElem a]
forall st a. GenParser Char st a -> GenParser Char st [a]
comlist ( (a -> SElem a
forall a. a -> SElem a
SBLE (a -> SElem a)
-> TmplParser (SEnv a -> a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (SEnv a -> SElem a)
forall (f1 :: * -> *) (f :: * -> *) a b.
(Functor f1, Functor f) =>
(a -> b) -> f (f1 a) -> f (f1 b)
<$$> Char
-> TmplParser (SEnv a -> a) -> Char -> TmplParser (SEnv a -> a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'(' TmplParser (SEnv a -> a)
forall a. Stringable a => TmplParser (SEnv a -> a)
exprn Char
')')
                     GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv a -> SElem a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (SEnv a -> SElem a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn)
             GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [SEnv a -> SElem a]
-> String
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [SEnv a -> SElem a]
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"expression"
  [[SElem a] -> SEnv a -> [a]]
templ <- ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [[SElem a] -> SEnv a -> [a]]
tmplChain
  (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return ((SEnv a -> a) -> TmplParser (SEnv a -> a))
-> (SEnv a -> a) -> TmplParser (SEnv a -> a)
forall a b. (a -> b) -> a -> b
$ (SEnv a -> a)
-> ([[SElem a] -> SEnv a -> [a]] -> SEnv a -> a)
-> [[SElem a] -> SEnv a -> [a]]
-> SEnv a
-> a
forall b a. b -> ([a] -> b) -> [a] -> b
fromMany (SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal (SEnv a -> SElem a -> a) -> (SEnv a -> SElem a) -> SEnv a -> a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [SEnv a -> SElem a] -> SEnv a -> SElem a
forall a. [a] -> a
head [SEnv a -> SElem a]
exprs)
             (([SEnv a -> SElem a] -> SEnv a -> [SElem a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [SEnv a -> SElem a]
exprs (SEnv a -> [SElem a]) -> ([SElem a] -> SEnv a -> a) -> SEnv a -> a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) (([SElem a] -> SEnv a -> a) -> SEnv a -> a)
-> ([[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> a)
-> [[SElem a] -> SEnv a -> [a]]
-> SEnv a
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> a
forall a.
Stringable a =>
[[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> a
seqTmpls') [[SElem a] -> SEnv a -> [a]]
templ
      where tmplChain :: ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [[SElem a] -> SEnv a -> [a]]
tmplChain = ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  ([SElem a] -> SEnv a -> [a])
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [[SElem a] -> SEnv a -> [a]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
':' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     ([SElem a] -> SEnv a -> [a])
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     ([SElem a] -> SEnv a -> [a])
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [([SElem a], [SElem a]) -> SEnv a -> a]
-> [SElem a] -> SEnv a -> [a]
forall a.
Stringable a =>
[([SElem a], [SElem a]) -> SEnv a -> a]
-> [SElem a] -> SEnv a -> [a]
iterApp ([([SElem a], [SElem a]) -> SEnv a -> a]
 -> [SElem a] -> SEnv a -> [a])
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [([SElem a], [SElem a]) -> SEnv a -> a]
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     ([SElem a] -> SEnv a -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (([SElem a], [SElem a]) -> SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [([SElem a], [SElem a]) -> SEnv a -> a]
forall st a. GenParser Char st a -> GenParser Char st [a]
comlist (GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (([SElem a], [SElem a]) -> SEnv a -> a)
forall a.
Stringable a =>
TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
anonTmpl GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (([SElem a], [SElem a]) -> SEnv a -> a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (([SElem a], [SElem a]) -> SEnv a -> a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (([SElem a], [SElem a]) -> SEnv a -> a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (([SElem a], [SElem a]) -> SEnv a -> a)
forall a.
Stringable a =>
TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
regTemplate)) ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  [[SElem a] -> SEnv a -> [a]]
-> String
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [[SElem a] -> SEnv a -> [a]]
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"template call"

seqTmpls' :: Stringable a => [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> a
seqTmpls' :: [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> a
seqTmpls' [[SElem a] -> SEnv a -> [a]]
tmpls [SElem a]
elems SEnv a
snv = a -> [a] -> a
forall a. Stringable a => a -> [a] -> a
mintercalate a
sep ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> [a]
forall a.
Stringable a =>
[[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> [a]
seqTmpls [[SElem a] -> SEnv a -> [a]]
tmpls [SElem a]
elems SEnv a
snv
    where sep :: a
sep = SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal SEnv a
snv (SElem a -> a) -> SElem a -> a
forall a b. (a -> b) -> a -> b
$ (SEnv a -> SElem a)
-> Maybe (SEnv a -> SElem a) -> SEnv a -> SElem a
forall a. a -> Maybe a -> a
fromMaybe (String -> SEnv a -> SElem a
forall b a. String -> b -> SElem a
justSTR String
"") (Maybe (SEnv a -> SElem a) -> SEnv a -> SElem a)
-> (SEnv a -> Maybe (SEnv a -> SElem a)) -> SEnv a -> SElem a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> SEnv a -> Maybe (SEnv a -> SElem a)
forall a. String -> SEnv a -> Maybe (SEnv a -> SElem a)
optLookup String
"separator" (SEnv a -> SElem a) -> SEnv a -> SElem a
forall a b. (a -> b) -> a -> b
$ SEnv a
snv

seqTmpls :: Stringable a => [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> [a]
seqTmpls :: [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> [a]
seqTmpls [[SElem a] -> SEnv a -> [a]
f]    [SElem a]
y SEnv a
snv = [SElem a] -> SEnv a -> [a]
f [SElem a]
y SEnv a
snv
seqTmpls ([SElem a] -> SEnv a -> [a]
f:[[SElem a] -> SEnv a -> [a]]
fs) [SElem a]
y SEnv a
snv = ([SElem a] -> [a]) -> [[SElem a]] -> [a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\[SElem a]
x -> [[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> [a]
forall a.
Stringable a =>
[[SElem a] -> SEnv a -> [a]] -> [SElem a] -> SEnv a -> [a]
seqTmpls [[SElem a] -> SEnv a -> [a]]
fs [SElem a]
x SEnv a
snv) ((a -> [SElem a]) -> [a] -> [[SElem a]]
forall a b. (a -> b) -> [a] -> [b]
map ((SElem a -> [SElem a] -> [SElem a]
forall a. a -> [a] -> [a]
:[]) (SElem a -> [SElem a]) -> (a -> SElem a) -> a -> [SElem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SElem a
forall a. a -> SElem a
SBLE) ([a] -> [[SElem a]]) -> [a] -> [[SElem a]]
forall a b. (a -> b) -> a -> b
$ [SElem a] -> SEnv a -> [a]
f [SElem a]
y SEnv a
snv)
seqTmpls  [[SElem a] -> SEnv a -> [a]]
_ [SElem a]
_ SEnv a
_   = [String -> a
forall a. Stringable a => String -> a
stFromString String
""]

subexprn :: Stringable a => TmplParser (SEnv a -> SElem a)
subexprn :: TmplParser (SEnv a -> SElem a)
subexprn = [SEnv a -> SElem a] -> SEnv a -> SElem a
forall a. Stringable a => [SEnv a -> SElem a] -> SEnv a -> SElem a
cct ([SEnv a -> SElem a] -> SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> SElem a]
-> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall st t. GenParser Char st t -> GenParser Char st t
spaced
            (TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
braceConcat
             TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> a -> SElem a
forall a. a -> SElem a
SBLE (a -> SElem a)
-> ((([SElem a], [SElem a]) -> SEnv a -> a) -> SEnv a -> a)
-> (([SElem a], [SElem a]) -> SEnv a -> a)
-> SEnv a
-> SElem a
forall (f1 :: * -> *) (f :: * -> *) a b.
(Functor f1, Functor f) =>
(a -> b) -> f (f1 a) -> f (f1 b)
<$$> ((([SElem a], [SElem a]) -> SEnv a -> a)
-> ([SElem a], [SElem a]) -> SEnv a -> a
forall a b. (a -> b) -> a -> b
$ ([SElem a
forall a. SElem a
SNull],[SElem a]
forall a. [SElem a]
ix0)) ((([SElem a], [SElem a]) -> SEnv a -> a) -> SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (([SElem a], [SElem a]) -> SEnv a -> a)
-> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (([SElem a], [SElem a]) -> SEnv a -> a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (([SElem a], [SElem a]) -> SEnv a -> a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (([SElem a], [SElem a]) -> SEnv a -> a)
forall a.
Stringable a =>
TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
regTemplate
             TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
attrib
             TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> a -> SElem a
forall a. a -> SElem a
SBLE (a -> SElem a)
-> ((([SElem a], [SElem a]) -> SEnv a -> a) -> SEnv a -> a)
-> (([SElem a], [SElem a]) -> SEnv a -> a)
-> SEnv a
-> SElem a
forall (f1 :: * -> *) (f :: * -> *) a b.
(Functor f1, Functor f) =>
(a -> b) -> f (f1 a) -> f (f1 b)
<$$> ((([SElem a], [SElem a]) -> SEnv a -> a)
-> ([SElem a], [SElem a]) -> SEnv a -> a
forall a b. (a -> b) -> a -> b
$ ([SElem a
forall a. SElem a
SNull],[SElem a]
forall a. [SElem a]
ix0)) ((([SElem a], [SElem a]) -> SEnv a -> a) -> SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (([SElem a], [SElem a]) -> SEnv a -> a)
-> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (([SElem a], [SElem a]) -> SEnv a -> a)
forall a.
Stringable a =>
TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
anonTmpl
             TmplParser (SEnv a -> SElem a)
-> String -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"expression")
           TmplParser (SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> SElem a]
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]
`sepBy1` ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall st t. GenParser Char st t -> GenParser Char st t
spaced (Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'+')
    where cct :: [SEnv a -> SElem a] -> SEnv a -> SElem a
cct xs :: [SEnv a -> SElem a]
xs@(SEnv a -> SElem a
_:SEnv a -> SElem a
_:[SEnv a -> SElem a]
_) = a -> SElem a
forall a. a -> SElem a
SBLE (a -> SElem a) -> (SEnv a -> a) -> SEnv a -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
|.
                           ([SElem a] -> (SElem a -> a) -> a)
-> (SElem a -> a) -> [SElem a] -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip [SElem a] -> (SElem a -> a) -> a
forall a b. Stringable a => [b] -> (b -> a) -> a
mconcatMap ((SElem a -> a) -> [SElem a] -> a)
-> (SEnv a -> SElem a -> a) -> SEnv a -> [SElem a] -> a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SEnv a -> SElem a -> a
forall a. Stringable a => SEnv a -> SElem a -> a
showVal (SEnv a -> [SElem a] -> a) -> (SEnv a -> [SElem a]) -> SEnv a -> a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [SEnv a -> SElem a] -> SEnv a -> [SElem a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [SEnv a -> SElem a]
xs
          cct [SEnv a -> SElem a
x] = SEnv a -> SElem a
x
          cct  [SEnv a -> SElem a]
_  = SElem a -> SEnv a -> SElem a
forall a b. a -> b -> a
const SElem a
forall a. SElem a
SNull

braceConcat :: Stringable a => TmplParser (SEnv a -> SElem a)
braceConcat :: TmplParser (SEnv a -> SElem a)
braceConcat = [SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI ([SElem a] -> SElem a)
-> ([SElem a] -> [SElem a]) -> [SElem a] -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SElem a -> [SElem a] -> [SElem a])
-> [SElem a] -> [SElem a] -> [SElem a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr SElem a -> [SElem a] -> [SElem a]
forall a. SElem a -> [SElem a] -> [SElem a]
go [] ([SElem a] -> SElem a)
-> ([SEnv a -> SElem a] -> SEnv a -> [SElem a])
-> [SEnv a -> SElem a]
-> SEnv a
-> SElem a
forall (f1 :: * -> *) (f :: * -> *) a b.
(Functor f1, Functor f) =>
(a -> b) -> f (f1 a) -> f (f1 b)
<$$> [SEnv a -> SElem a] -> SEnv a -> [SElem a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([SEnv a -> SElem a] -> SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> SElem a]
-> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> SElem a]
-> Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> SElem a]
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'['(TmplParser (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     [SEnv a -> SElem a]
forall st a. GenParser Char st a -> GenParser Char st [a]
comlist TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn)Char
']'
    where go :: SElem a -> [SElem a] -> [SElem a]
go (LI [SElem a]
x) [SElem a]
lst = [SElem a]
x[SElem a] -> [SElem a] -> [SElem a]
forall a. [a] -> [a] -> [a]
++[SElem a]
lst; go SElem a
x [SElem a]
lst = SElem a
xSElem a -> [SElem a] -> [SElem a]
forall a. a -> [a] -> [a]
:[SElem a]
lst

literal :: GenParser Char st (b -> SElem a)
literal :: GenParser Char st (b -> SElem a)
literal = String -> b -> SElem a
forall b a. String -> b -> SElem a
justSTR (String -> b -> SElem a)
-> ParsecT String st Identity String
-> GenParser Char st (b -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char
-> ParsecT String st Identity String
-> Char
-> ParsecT String st Identity String
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'"' ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> ParsecT String st Identity [String]
-> ParsecT String st Identity String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String st Identity String
-> ParsecT String st Identity [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT String st Identity String
forall st. String -> GenParser Char st String
escapedChar String
"\"")) Char
'"'
                   ParsecT String st Identity String
-> ParsecT String st Identity String
-> ParsecT String st Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char
-> ParsecT String st Identity String
-> Char
-> ParsecT String st Identity String
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'\'' ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> ParsecT String st Identity [String]
-> ParsecT String st Identity String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String st Identity String
-> ParsecT String st Identity [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT String st Identity String
forall st. String -> GenParser Char st String
escapedChar String
"'")) Char
'\'')

attrib :: Stringable a => TmplParser (SEnv a -> SElem a)
attrib :: TmplParser (SEnv a -> SElem a)
attrib = do
  SEnv a -> SElem a
a <-     TmplParser (SEnv a -> SElem a)
forall st b a. GenParser Char st (b -> SElem a)
literal
       TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall tok st a. GenParser tok st a -> GenParser tok st a
try TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
functn
       TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> SEnv a -> SElem a
forall a. String -> SEnv a -> SElem a
envLookupEx (String -> SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
regWord
       TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> SEnv a -> SElem a
forall a. String -> SEnv a -> SElem a
envLookupEx (String -> SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
qqWord
       TmplParser (SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char
-> TmplParser (SEnv a -> SElem a)
-> Char
-> TmplParser (SEnv a -> SElem a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'(' TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn Char
')'
          TmplParser (SEnv a -> SElem a)
-> String -> TmplParser (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"attribute"
  [SEnv a -> SElem a]
proprs <- TmplParser [SEnv a -> SElem a]
forall a. Stringable a => TmplParser [SEnv a -> SElem a]
props
  (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall (m :: * -> *) a. Monad m => a -> m a
return ((SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a))
-> (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall a b. (a -> b) -> a -> b
$ (SEnv a -> SElem a)
-> ([SEnv a -> SElem a] -> SEnv a -> SElem a)
-> [SEnv a -> SElem a]
-> SEnv a
-> SElem a
forall b a. b -> ([a] -> b) -> [a] -> b
fromMany SEnv a -> SElem a
a ((SEnv a -> SElem a
a (SEnv a -> SElem a)
-> (SElem a -> SEnv a -> SElem a) -> SEnv a -> SElem a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((SElem a -> SEnv a -> SElem a) -> SEnv a -> SElem a)
-> ([SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a)
-> [SEnv a -> SElem a]
-> SEnv a
-> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
forall a.
Stringable a =>
[SEnv a -> SElem a] -> SElem a -> SEnv a -> SElem a
getProp) [SEnv a -> SElem a]
proprs
      where qqWord :: ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
qqWord = do
              String
w <- Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'`' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
forall st. GenParser Char st String
word Char
'`'
              String -> TmplParser ()
tellQQ String
w
              String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return (String
 -> ParsecT
      String
      ((Char, Char), [String], [String], [String])
      Identity
      String)
-> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall a b. (a -> b) -> a -> b
$ Char
'`' Char -> String -> String
forall a. a -> [a] -> [a]
: String
w String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"`"
            regWord :: ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
regWord = do
              String
w <- ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
forall st. GenParser Char st String
word
              String -> TmplParser ()
tellName String
w
              String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return String
w

--add null func
functn :: Stringable a => TmplParser (SEnv a -> SElem a)
functn :: TmplParser (SEnv a -> SElem a)
functn = do
  String
f <- String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"first" ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall tok st a. GenParser tok st a -> GenParser tok st a
try (String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"rest") ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"reverse"
       ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"strip"
       ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall tok st a. GenParser tok st a -> GenParser tok st a
try (String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"length") ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"last" ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"function"
  (String -> SElem a -> SElem a
forall a. String -> SElem a -> SElem a
fApply String
f (SElem a -> SElem a) -> (SEnv a -> SElem a) -> SEnv a -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((SEnv a -> SElem a) -> SEnv a -> SElem a)
-> TmplParser (SEnv a -> SElem a) -> TmplParser (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char
-> TmplParser (SEnv a -> SElem a)
-> Char
-> TmplParser (SEnv a -> SElem a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'(' TmplParser (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn Char
')'
      where fApply :: String -> SElem a -> SElem a
fApply String
str (LI [SElem a]
xs)
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"first"  = if [SElem a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SElem a]
xs then SElem a
forall a. SElem a
SNull else [SElem a] -> SElem a
forall a. [a] -> a
head [SElem a]
xs
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"last"   = if [SElem a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SElem a]
xs then SElem a
forall a. SElem a
SNull else [SElem a] -> SElem a
forall a. [a] -> a
last [SElem a]
xs
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"rest"   = if [SElem a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SElem a]
xs then SElem a
forall a. SElem a
SNull else ([SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI ([SElem a] -> SElem a)
-> ([SElem a] -> [SElem a]) -> [SElem a] -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SElem a] -> [SElem a]
forall a. [a] -> [a]
tail) [SElem a]
xs
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"reverse" = [SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI ([SElem a] -> SElem a)
-> ([SElem a] -> [SElem a]) -> [SElem a] -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SElem a] -> [SElem a]
forall a. [a] -> [a]
reverse ([SElem a] -> SElem a) -> [SElem a] -> SElem a
forall a b. (a -> b) -> a -> b
$ [SElem a]
xs
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"strip"  = [SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI ([SElem a] -> SElem a)
-> ([SElem a] -> [SElem a]) -> [SElem a] -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SElem a -> Bool) -> [SElem a] -> [SElem a]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (SElem a -> Bool) -> SElem a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SElem a -> Bool
forall a. SElem a -> Bool
liNil) ([SElem a] -> SElem a) -> [SElem a] -> SElem a
forall a b. (a -> b) -> a -> b
$ [SElem a]
xs
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"length" = String -> SElem a
forall a. String -> SElem a
STR (String -> SElem a)
-> ([SElem a] -> String) -> [SElem a] -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show (Int -> String) -> ([SElem a] -> Int) -> [SElem a] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SElem a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([SElem a] -> SElem a) -> [SElem a] -> SElem a
forall a b. (a -> b) -> a -> b
$ [SElem a]
xs
            fApply String
str SElem a
x
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"rest"   = [SElem a] -> SElem a
forall a. [SElem a] -> SElem a
LI []
                | String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"length" = String -> SElem a
forall a. String -> SElem a
STR String
"1"
                | Bool
otherwise       = SElem a
x
            liNil :: SElem a -> Bool
liNil (LI [SElem a]
x) = [SElem a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SElem a]
x
            liNil SElem a
_      = Bool
False

{--------------------------------------------------------------------
  Templates
--------------------------------------------------------------------}
--change makeTmpl to do notation for clarity?



mkIndex :: (Num b, Show b) => [b] -> [[SElem a]]
mkIndex :: [b] -> [[SElem a]]
mkIndex = (b -> [SElem a]) -> [b] -> [[SElem a]]
forall a b. (a -> b) -> [a] -> [b]
map ((:) (SElem a -> [SElem a] -> [SElem a])
-> (b -> SElem a) -> b -> [SElem a] -> [SElem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> SElem a
forall a. String -> SElem a
STR (String -> SElem a) -> (b -> String) -> b -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> String
forall a. Show a => a -> String
show (b -> String) -> (b -> b) -> b -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b
1b -> b -> b
forall a. Num a => a -> a -> a
+) (b -> [SElem a] -> [SElem a]) -> (b -> [SElem a]) -> b -> [SElem a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (SElem a -> [SElem a] -> [SElem a]
forall a. a -> [a] -> [a]
:[]) (SElem a -> [SElem a]) -> (b -> SElem a) -> b -> [SElem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> SElem a
forall a. String -> SElem a
STR (String -> SElem a) -> (b -> String) -> b -> SElem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> String
forall a. Show a => a -> String
show)
ix0 :: [SElem a]
ix0 :: [SElem a]
ix0 = [String -> SElem a
forall a. String -> SElem a
STR String
"1",String -> SElem a
forall a. String -> SElem a
STR String
"0"]

cycleApp :: (Stringable a) => [([SElem a], [SElem a]) -> SEnv a -> a] -> [([SElem a], [SElem a])]  -> SEnv a -> [a]
cycleApp :: [([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
cycleApp [([SElem a], [SElem a]) -> SEnv a -> a]
x [([SElem a], [SElem a])]
y SEnv a
snv = ((SEnv a -> a) -> a) -> [SEnv a -> a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map ((SEnv a -> a) -> SEnv a -> a
forall a b. (a -> b) -> a -> b
$ SEnv a
snv) (((([SElem a], [SElem a]) -> SEnv a -> a)
 -> ([SElem a], [SElem a]) -> SEnv a -> a)
-> [([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])]
-> [SEnv a -> a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (([SElem a], [SElem a]) -> SEnv a -> a)
-> ([SElem a], [SElem a]) -> SEnv a -> a
forall a b. (a -> b) -> a -> b
($) ([([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a]) -> SEnv a -> a]
forall a. [a] -> [a]
cycle [([SElem a], [SElem a]) -> SEnv a -> a]
x) [([SElem a], [SElem a])]
y)

pluslen :: [a] -> [([a], [SElem b])]
pluslen :: [a] -> [([a], [SElem b])]
pluslen [a]
xs = [[a]] -> [[SElem b]] -> [([a], [SElem b])]
forall a b. [a] -> [b] -> [(a, b)]
zip ((a -> [a]) -> [a] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[]) [a]
xs) ([[SElem b]] -> [([a], [SElem b])])
-> [[SElem b]] -> [([a], [SElem b])]
forall a b. (a -> b) -> a -> b
$ [Int] -> [[SElem b]]
forall b a. (Num b, Show b) => [b] -> [[SElem a]]
mkIndex [Int
0..([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)]

liTrans :: [SElem a] -> [([SElem a], [SElem a])]
liTrans :: [SElem a] -> [([SElem a], [SElem a])]
liTrans = [[SElem a]] -> [([SElem a], [SElem a])]
forall a a. [a] -> [(a, [SElem a])]
pluslen' ([[SElem a]] -> [([SElem a], [SElem a])])
-> ([SElem a] -> [[SElem a]])
-> [SElem a]
-> [([SElem a], [SElem a])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SElem a -> [[SElem a]] -> [[SElem a]]
forall a. a -> [[a]] -> [[a]]
paddedTrans SElem a
forall a. SElem a
SNull ([[SElem a]] -> [[SElem a]])
-> ([SElem a] -> [[SElem a]]) -> [SElem a] -> [[SElem a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SElem a -> [SElem a]) -> [SElem a] -> [[SElem a]]
forall a b. (a -> b) -> [a] -> [b]
map SElem a -> [SElem a]
forall a. SElem a -> [SElem a]
u
    where u :: SElem a -> [SElem a]
u (LI [SElem a]
x) = [SElem a]
x; u SElem a
x = [SElem a
x]
          pluslen' :: [a] -> [(a, [SElem a])]
pluslen' [a]
xs = [a] -> [[SElem a]] -> [(a, [SElem a])]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs ([[SElem a]] -> [(a, [SElem a])])
-> [[SElem a]] -> [(a, [SElem a])]
forall a b. (a -> b) -> a -> b
$ [Int] -> [[SElem a]]
forall b a. (Num b, Show b) => [b] -> [[SElem a]]
mkIndex [Int
0..([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)]

--map repeatedly, then finally concat
iterApp :: Stringable a => [([SElem a], [SElem a]) -> SEnv a -> a] -> [SElem a] -> SEnv a -> [a]
iterApp :: [([SElem a], [SElem a]) -> SEnv a -> a]
-> [SElem a] -> SEnv a -> [a]
iterApp [([SElem a], [SElem a]) -> SEnv a -> a
f] (LI [SElem a]
xs:[])    SEnv a
snv = (([SElem a], [SElem a]) -> a) -> [([SElem a], [SElem a])] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map ((([SElem a], [SElem a]) -> SEnv a -> a)
-> SEnv a -> ([SElem a], [SElem a]) -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([SElem a], [SElem a]) -> SEnv a -> a
f SEnv a
snv) ([SElem a] -> [([SElem a], [SElem a])]
forall a b. [a] -> [([a], [SElem b])]
pluslen [SElem a]
xs)
iterApp [([SElem a], [SElem a]) -> SEnv a -> a
f] vars :: [SElem a]
vars@(LI [SElem a]
_:[SElem a]
_) SEnv a
snv = (([SElem a], [SElem a]) -> a) -> [([SElem a], [SElem a])] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map ((([SElem a], [SElem a]) -> SEnv a -> a)
-> SEnv a -> ([SElem a], [SElem a]) -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([SElem a], [SElem a]) -> SEnv a -> a
f SEnv a
snv) ([SElem a] -> [([SElem a], [SElem a])]
forall a. [SElem a] -> [([SElem a], [SElem a])]
liTrans [SElem a]
vars)
iterApp [([SElem a], [SElem a]) -> SEnv a -> a
f] [SElem a]
v             SEnv a
snv = [([SElem a], [SElem a]) -> SEnv a -> a
f ([SElem a]
v,[SElem a]
forall a. [SElem a]
ix0) SEnv a
snv]
iterApp [([SElem a], [SElem a]) -> SEnv a -> a]
fs (LI [SElem a]
xs:[])     SEnv a
snv = [([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
forall a.
Stringable a =>
[([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
cycleApp [([SElem a], [SElem a]) -> SEnv a -> a]
fs ([SElem a] -> [([SElem a], [SElem a])]
forall a b. [a] -> [([a], [SElem b])]
pluslen [SElem a]
xs) SEnv a
snv
iterApp [([SElem a], [SElem a]) -> SEnv a -> a]
fs vars :: [SElem a]
vars@(LI [SElem a]
_:[SElem a]
_)  SEnv a
snv = [([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
forall a.
Stringable a =>
[([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
cycleApp [([SElem a], [SElem a]) -> SEnv a -> a]
fs ([SElem a] -> [([SElem a], [SElem a])]
forall a. [SElem a] -> [([SElem a], [SElem a])]
liTrans [SElem a]
vars) SEnv a
snv
iterApp [([SElem a], [SElem a]) -> SEnv a -> a]
fs [SElem a]
xs             SEnv a
snv = [([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
forall a.
Stringable a =>
[([SElem a], [SElem a]) -> SEnv a -> a]
-> [([SElem a], [SElem a])] -> SEnv a -> [a]
cycleApp [([SElem a], [SElem a]) -> SEnv a -> a]
fs ([SElem a] -> [([SElem a], [SElem a])]
forall a b. [a] -> [([a], [SElem b])]
pluslen [SElem a]
xs) SEnv a
snv

anonTmpl :: Stringable a => TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
anonTmpl :: TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
anonTmpl = Char
-> TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
-> Char
-> TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'{' TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
forall a.
Stringable a =>
TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
subStmp Char
'}'

regTemplate :: Stringable a => TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
regTemplate :: TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
regTemplate = do
  GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv String -> SElem String)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     (SEnv String -> SElem String)
forall tok st a. GenParser tok st a -> GenParser tok st a
try (GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv String -> SElem String)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
functn::TmplParser (SEnv String -> SElem String)) GenParser
  Char
  ((Char, Char), [String], [String], [String])
  (SEnv String -> SElem String)
-> TmplParser () -> TmplParser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
.>> String -> TmplParser ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"" TmplParser () -> TmplParser () -> TmplParser ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> () -> TmplParser ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  SEnv a -> SElem a
name <- String -> SEnv a -> SElem a
forall b a. String -> b -> SElem a
justSTR (String -> SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
forall st. GenParser Char st Char
identifierChar ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/')
          ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'(' ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn Char
')'
  SElem a -> TmplParser ()
forall a. SElem a -> TmplParser ()
tryTellTmpl (SEnv a -> SElem a
name SEnv a
forall a. SEnv a
nullEnv)
  [(String, SEnv a -> SElem a)]
vals <- Char
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
-> Char
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall st t.
Char -> GenParser Char st t -> Char -> GenParser Char st t
around Char
'(' (GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall st t. GenParser Char st t -> GenParser Char st t
spaced (GenParser
   Char
   ((Char, Char), [String], [String], [String])
   [(String, SEnv a -> SElem a)]
 -> GenParser
      Char
      ((Char, Char), [String], [String], [String])
      [(String, SEnv a -> SElem a)])
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall a b. (a -> b) -> a -> b
$ GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall tok st a. GenParser tok st a -> GenParser tok st a
try GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
assgn GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
anonassgn GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> [(String, SEnv a -> SElem a)]
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall (m :: * -> *) a. Monad m => a -> m a
return []) Char
')'
  (([SElem a], [SElem a]) -> SEnv a -> a)
-> TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return ((([SElem a], [SElem a]) -> SEnv a -> a)
 -> TmplParser (([SElem a], [SElem a]) -> SEnv a -> a))
-> (([SElem a], [SElem a]) -> SEnv a -> a)
-> TmplParser (([SElem a], [SElem a]) -> SEnv a -> a)
forall a b. (a -> b) -> a -> b
$ (SEnv a -> SEnv a -> a) -> SEnv a -> a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join ((SEnv a -> SEnv a -> a) -> SEnv a -> a)
-> (([SElem a], [SElem a]) -> SEnv a -> SEnv a -> a)
-> ([SElem a], [SElem a])
-> SEnv a
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((SElem a -> SEnv a -> a)
-> (SEnv a -> SElem a) -> SEnv a -> SEnv a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SEnv a -> SElem a
name) ((SElem a -> SEnv a -> a) -> SEnv a -> SEnv a -> a)
-> (([SElem a], [SElem a]) -> SElem a -> SEnv a -> a)
-> ([SElem a], [SElem a])
-> SEnv a
-> SEnv a
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(String, SEnv a -> SElem a)]
-> ([SElem a], [SElem a]) -> SElem a -> SEnv a -> a
forall t2 a.
Stringable t2 =>
[(String, SEnv t2 -> SElem t2)]
-> ([SElem t2], [SElem t2]) -> SElem a -> SEnv t2 -> t2
makeTmpl [(String, SEnv a -> SElem a)]
vals
      where makeTmpl :: [(String, SEnv t2 -> SElem t2)]
-> ([SElem t2], [SElem t2]) -> SElem a -> SEnv t2 -> t2
makeTmpl [(String, SEnv t2 -> SElem t2)]
v ((SElem t2
se:[SElem t2]
_),[SElem t2]
is) (STR String
x)  =
                String -> StringTemplate t2 -> t2
forall a. Stringable a => String -> StringTemplate a -> a
renderErr String
x (StringTemplate t2 -> t2)
-> (SEnv t2 -> StringTemplate t2) -> SEnv t2 -> t2
forall b c a. (b -> c) -> (a -> b) -> a -> c
|. [(String, SElem t2)] -> StringTemplate t2 -> StringTemplate t2
forall (t :: * -> *) a.
Foldable t =>
t (String, SElem a) -> StringTemplate a -> StringTemplate a
stBind ([(String, SElem t2)] -> StringTemplate t2 -> StringTemplate t2)
-> (SEnv t2 -> [(String, SElem t2)])
-> SEnv t2
-> StringTemplate t2
-> StringTemplate t2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [SElem t2] -> [(String, SElem t2)]
forall a b. [a] -> [b] -> [(a, b)]
zip [String
"it",String
"i",String
"i0"] (SElem t2
seSElem t2 -> [SElem t2] -> [SElem t2]
forall a. a -> [a] -> [a]
:[SElem t2]
is) [(String, SElem t2)]
-> [(String, SElem t2)] -> [(String, SElem t2)]
forall a. [a] -> [a] -> [a]
++)
                             ([(String, SElem t2)] -> [(String, SElem t2)])
-> (SEnv t2 -> [(String, SElem t2)])
-> SEnv t2
-> [(String, SElem t2)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((SEnv t2 -> SElem t2) -> SElem t2)
 -> [(String, SEnv t2 -> SElem t2)] -> [(String, SElem t2)])
-> [(String, SEnv t2 -> SElem t2)]
-> SEnv t2
-> [(String, SElem t2)]
forall a c1 b c. (((a -> c1) -> c1) -> b -> c) -> b -> a -> c
swing (((String, SEnv t2 -> SElem t2) -> (String, SElem t2))
-> [(String, SEnv t2 -> SElem t2)] -> [(String, SElem t2)]
forall a b. (a -> b) -> [a] -> [b]
map (((String, SEnv t2 -> SElem t2) -> (String, SElem t2))
 -> [(String, SEnv t2 -> SElem t2)] -> [(String, SElem t2)])
-> (((SEnv t2 -> SElem t2) -> SElem t2)
    -> (String, SEnv t2 -> SElem t2) -> (String, SElem t2))
-> ((SEnv t2 -> SElem t2) -> SElem t2)
-> [(String, SEnv t2 -> SElem t2)]
-> [(String, SElem t2)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((SEnv t2 -> SElem t2) -> SElem t2)
-> (String, SEnv t2 -> SElem t2) -> (String, SElem t2)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second) [(String, SEnv t2 -> SElem t2)]
v (SEnv t2 -> StringTemplate t2 -> StringTemplate t2)
-> (SEnv t2 -> StringTemplate t2) -> SEnv t2 -> StringTemplate t2
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SEnv t2 -> StringTemplate t2
forall a. Stringable a => String -> SEnv a -> StringTemplate a
stLookup String
x
            makeTmpl [(String, SEnv t2 -> SElem t2)]
_ ([SElem t2], [SElem t2])
_ SElem a
_ = String -> SEnv t2 -> t2
forall a. Stringable a => String -> SEnv a -> a
showStr String
"Invalid Template Specified"
            stBind :: t (String, SElem a) -> StringTemplate a -> StringTemplate a
stBind t (String, SElem a)
v StringTemplate a
st = StringTemplate a
st {senv :: SEnv a
senv = ((String, SElem a) -> SEnv a -> SEnv a)
-> SEnv a -> t (String, SElem a) -> SEnv a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (String, SElem a) -> SEnv a -> SEnv a
forall a. (String, SElem a) -> SEnv a -> SEnv a
envInsert (StringTemplate a -> SEnv a
forall a. StringTemplate a -> SEnv a
senv StringTemplate a
st) t (String, SElem a)
v}
            anonassgn :: GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
anonassgn = ((String, SEnv a -> SElem a)
-> [(String, SEnv a -> SElem a)] -> [(String, SEnv a -> SElem a)]
forall a. a -> [a] -> [a]
:[]) ((String, SEnv a -> SElem a) -> [(String, SEnv a -> SElem a)])
-> ((SEnv a -> SElem a) -> (String, SEnv a -> SElem a))
-> (SEnv a -> SElem a)
-> [(String, SEnv a -> SElem a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,) String
"it" ((SEnv a -> SElem a) -> [(String, SEnv a -> SElem a)])
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn
            assgn :: GenParser
  Char
  ((Char, Char), [String], [String], [String])
  [(String, SEnv a -> SElem a)]
assgn = (ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity String
forall st t. GenParser Char st t -> GenParser Char st t
spaced ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
forall st. GenParser Char st String
word ParsecT
  String ((Char, Char), [String], [String], [String]) Identity String
-> (String
    -> ParsecT
         String
         ((Char, Char), [String], [String], [String])
         Identity
         (String, SEnv a -> SElem a))
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (String, SEnv a -> SElem a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (((SEnv a -> SElem a) -> (String, SEnv a -> SElem a))
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (String, SEnv a -> SElem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'=' ParsecT
  String ((Char, Char), [String], [String], [String]) Identity Char
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
.>> ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (SEnv a -> SElem a)
forall st t. GenParser Char st t -> GenParser Char st t
spaced ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (SEnv a -> SElem a)
forall a. Stringable a => TmplParser (SEnv a -> SElem a)
subexprn) (((SEnv a -> SElem a) -> (String, SEnv a -> SElem a))
 -> ParsecT
      String
      ((Char, Char), [String], [String], [String])
      Identity
      (String, SEnv a -> SElem a))
-> (String -> (SEnv a -> SElem a) -> (String, SEnv a -> SElem a))
-> String
-> ParsecT
     String
     ((Char, Char), [String], [String], [String])
     Identity
     (String, SEnv a -> SElem a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,))
                    ParsecT
  String
  ((Char, Char), [String], [String], [String])
  Identity
  (String, SEnv a -> SElem a)
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
-> GenParser
     Char
     ((Char, Char), [String], [String], [String])
     [(String, SEnv a -> SElem a)]
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]
`sepEndBy1` Char
-> ParsecT
     String ((Char, Char), [String], [String], [String]) Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';'
            tryTellTmpl :: SElem a -> TmplParser ()
tryTellTmpl (STR String
x) = String -> TmplParser ()
tellTmpl String
x
            tryTellTmpl SElem a
_ = () -> TmplParser ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

--DEBUG

{-pTrace s = pt <|> return ()
    where pt = try $
               do
                 x <- try $ many1 anyChar
                 trace (s++": " ++x) $ try $ char 'z'
                 fail x
-}