{-#LANGUAGE FlexibleContexts #-}
{-#LANGUAGE FlexibleInstances #-}
{-#LANGUAGE OverloadedStrings #-}
{-#LANGUAGE TupleSections #-}
{-#LANGUAGE TypeSynonymInstances #-}
{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE ScopedTypeVariables #-}
{-#LANGUAGE LambdaCase #-}
-- | Execute Ginger templates in an arbitrary monad.
--
-- Usage example:
--
-- > render :: Template -> Text -> Text -> Text
-- > render template username imageURL = do
-- >    let contextLookup varName =
-- >            case varName of
-- >                "username" -> toGVal username
-- >                "imageURL" -> toGVal imageURL
-- >                _ -> def -- def for GVal is equivalent to a NULL value
-- >        context = makeContextHtml contextLookup
-- >    in htmlSource $ runGinger context template
module Text.Ginger.Run
(
-- * The \"easy\" interface
-- | Provides a straightforward way of rendering templates monadically
-- as well as purely.
  easyRenderM
, easyRender
, easyContext
-- * The \"direct\" interface
-- | This interface gives more control than the easy interface, at the
-- expense of requiring more yak shaving.
, runGingerT
, runGinger
, makeContext
, makeContextM
, makeContext'
, makeContextM'
, makeContextExM'
, makeContextHtml
, makeContextHtmlM
, makeContextHtmlExM
, makeContextText
, makeContextTextM
, makeContextTextExM
-- * The context type
, GingerContext
-- * The Run monad
, Run, liftRun, liftRun2
-- * Helper functions for interpreting argument lists
, extractArgs, extractArgsT, extractArgsL, extractArgsDefL
-- * Hoisting
, hoistContext
, hoistRun
, hoistNewlines
, hoistRunState
-- * Errors
, RuntimeError (..)
, runtimeErrorWhat
, runtimeErrorWhere
, runtimeErrorMessage
)
where

import Prelude ( (.), ($), (==), (/=)
               , (>), (<), (>=), (<=)
               , (+), (-), (*), (/), div, (**), (^)
               , (||), (&&)
               , (++)
               , Show, show
               , undefined, otherwise
               , Maybe (..)
               , Bool (..)
               , Int, Integer, String
               , fromIntegral, floor, round
               , not
               , show
               , uncurry
               , seq
               , fst, snd
               , maybe
               , Either (..)
               , id
               )
import qualified Prelude
import Data.Maybe (fromMaybe, isJust, isNothing)
import qualified Data.List as List
import Text.Ginger.AST
import Text.Ginger.Html
import Text.Ginger.GVal
import Text.Ginger.Run.Type
import Text.Ginger.Run.Builtins
import Text.Ginger.Run.FuncUtils
import Text.Ginger.Run.VM
import Text.Printf
import Text.PrintfA
import Text.Ginger.Parse (parseGinger, ParserError)
import Control.Monad.Trans.Except (runExceptT, catchE)

import Data.Text (Text)
import Data.String (fromString)
import qualified Data.Text as Text
import qualified Data.ByteString.UTF8 as UTF8
import Control.Monad
import Control.Monad.Identity
import Control.Monad.Writer
import Control.Monad.Reader
import Control.Monad.State
import Control.Applicative
import qualified Data.HashMap.Strict as HashMap
import Data.HashMap.Strict (HashMap)
import qualified Data.Map.Strict as Map
import Data.Map.Strict (Map)
import Data.Scientific (Scientific, formatScientific)
import qualified Data.Scientific as Scientific
import Data.Default (def)
import Safe (readMay, lastDef, headMay)
import Network.HTTP.Types (urlEncode)
import Debug.Trace (trace)
import Data.List (lookup, zipWith, unzip)
import Data.Monoid (Monoid (..), (<>))
import Data.Aeson as JSON

defaultScope :: forall m h p
              . ( Monoid h
                , Monad m
                , ToGVal (Run p m h) h
                , ToGVal (Run p m h) p
                )
             => [(Text, GVal (Run p m h))]
defaultScope :: forall (m :: * -> *) h p.
(Monoid h, Monad m, ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
[(Text, GVal (Run p m h))]
defaultScope =
    [ (Text
"raw", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnRawHtml)
    , (Text
"abs", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> (Scientific -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
unaryNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
Prelude.abs)
    , (Text
"any", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnAny)
    , (Text
"all", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnAll)
    , (Text
"apply", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnApply)
    -- TODO: batch
    , (Text
"capitalize", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
([Text] -> Text)
-> [(Maybe Text, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
variadicStringFunc forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
Prelude.map Text -> Text
capitalize)
    , (Text
"ceil", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> (Scientific -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
unaryNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
Prelude.ceiling)
    , (Text
"center", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnCenter)
    , (Text
"compose", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnCompose)
    , (Text
"concat", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnConcat)
    , (Text
"contains", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnContains)
    , (Text
"d", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnDefault)
    , (Text
"date", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnDateFormat)
    , (Text
"dateformat", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnDateFormat)
    , (Text
"default", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnDefault)
    , (Text
"dictsort", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnDictsort)
    , (Text
"difference", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> ([Scientific] -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
variadicNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall a. Num a => [a] -> a
difference)
    , (Text
"divisibleby", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnDivisibleBy)
    , (Text
"e", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnEscape)
    , (Text
"eq", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnEquals)
    , (Text
"equals", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnEquals)
    , (Text
"equalto", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnEquals)
    , (Text
"escape", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnEscape)
    , (Text
"eval", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) h p.
(Monad m, Monoid h, ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
Function (Run p m h)
gfnEval)
    , (Text
"even", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnEven)
    , (Text
"filesizeformat", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnFileSizeFormat)
    , (Text
"filter", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnFilter)
    , (Text
"floor", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> (Scientific -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
unaryNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
Prelude.floor)
    , (Text
"format", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnPrintf)
    , (Text
"ge", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnGreaterEquals)
    , (Text
"gt", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnGreater)
    , (Text
"greater", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnGreater)
    , (Text
"greaterthan", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnGreater)
    , (Text
"greaterEquals", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnGreaterEquals)
    , (Text
"int", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) h p.
Monad m =>
(GVal (Run p m h) -> GVal (Run p m h)) -> Function (Run p m h)
unaryFunc forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. (RealFrac a, Integral b) => a -> b
Prelude.truncate :: Scientific -> Int) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). GVal m -> Maybe Scientific
asNumber)
    , (Text
"int_ratio", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> ([Scientific] -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
variadicNumericFunc Scientific
1 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Integral a, Num a) => [a] -> a
intRatio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
Prelude.map forall a b. (RealFrac a, Integral b) => a -> b
Prelude.floor)
    , (Text
"is_lt", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnLess)
    , (Text
"iterable", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) h p.
Monad m =>
(GVal (Run p m h) -> GVal (Run p m h)) -> Function (Run p m h)
unaryFunc forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\GVal (Run p m h)
x -> forall (m :: * -> *). GVal m -> Bool
isList GVal (Run p m h)
x Bool -> Bool -> Bool
|| forall (m :: * -> *). GVal m -> Bool
isDict GVal (Run p m h)
x))
    , (Text
"json", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnJSON)
    , (Text
"length", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnLength)
    , (Text
"le", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnLessEquals)
    , (Text
"less", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnLess)
    , (Text
"lessthan", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnLess)
    , (Text
"lessEquals", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnLessEquals)
    , (Text
"lt", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnLess)
    , (Text
"map", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) a.
(Monad m, MonadError (RuntimeError a) m) =>
Function m
gfnMap)
    , (Text
"modulo", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> ([Scientific] -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
variadicNumericFunc Scientific
1 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Integral a, Num a) => [a] -> a
modulo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
Prelude.map forall a b. (RealFrac a, Integral b) => a -> b
Prelude.floor)
    , (Text
"ne", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnNEquals)
    , (Text
"nequals", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnNEquals)
    , (Text
"num", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) h p.
Monad m =>
(GVal (Run p m h) -> GVal (Run p m h)) -> Function (Run p m h)
unaryFunc forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). GVal m -> Maybe Scientific
asNumber)
    , (Text
"odd", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnOdd)
    , (Text
"partial", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnPartial)
    , (Text
"printf", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnPrintf)
    , (Text
"product", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> ([Scientific] -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
variadicNumericFunc Scientific
1 forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Prelude.product)
    , (Text
"ratio", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> ([Scientific] -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
variadicNumericFunc Scientific
1 forall a b. (a -> b) -> a -> b
$ forall a. RealFloat a => a -> Scientific
Scientific.fromFloatDigits forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Show a, Fractional a, Num a) => [a] -> a
ratio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
Prelude.map forall a. RealFloat a => Scientific -> a
Scientific.toRealFloat)
    , (Text
"replace", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnReplace)
    , (Text
"round", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> (Scientific -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
unaryNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
Prelude.round)
    , (Text
"show", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) h p.
Monad m =>
(GVal (Run p m h) -> GVal (Run p m h)) -> Function (Run p m h)
unaryFunc forall a b. (a -> b) -> a -> b
$ forall a. IsString a => String -> a
fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show)
    , (Text
"slice", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnSlice)
    , (Text
"sort", forall (m :: * -> *). Function m -> GVal m
fromFunction forall p (m :: * -> *) h. Monad m => Function (Run p m h)
gfnSort)
    , (Text
"split", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnSplit)
    , (Text
"str", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) h p.
Monad m =>
(GVal (Run p m h) -> GVal (Run p m h)) -> Function (Run p m h)
unaryFunc forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). GVal m -> Text
asText)
    , (Text
"sum", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> ([Scientific] -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
variadicNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Prelude.sum)
    , (Text
"truncate", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
Scientific
-> (Scientific -> Scientific)
-> [(Maybe Text, GVal (Run p m h))]
-> Run p m h (GVal (Run p m h))
unaryNumericFunc Scientific
0 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
Prelude.truncate)
    , (Text
"urlencode", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnUrlEncode)
    , (Text
"upper", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
([Text] -> Text)
-> [(Maybe Text, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
variadicStringFunc forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
Prelude.map Text -> Text
Text.toUpper)
    , (Text
"lower", forall (m :: * -> *). Function m -> GVal m
fromFunction forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) p h.
Monad m =>
([Text] -> Text)
-> [(Maybe Text, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
variadicStringFunc forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
Prelude.map Text -> Text
Text.toLower)
    , (Text
"throw", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) h p.
(Monad m, Monoid h, ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
Function (Run p m h)
gfnThrow)
    , (Text
"zip", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnZip)
    , (Text
"zipwith", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *) p h. Monad m => Function (Run p m h)
gfnZipWith)

    -- Tests/predicates

    , (Text
"in", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnIn)
    , (Text
"escaped", forall (m :: * -> *). Function m -> GVal m
fromFunction forall (m :: * -> *). Monad m => Function m
gfnEscaped)

    , (Text
"regex", forall (m :: * -> *) p h. Monad m => GVal (Run p m h)
gfoRegex)

    -- TODO: sameas (predicate)
    -- NOTE that this test doesn't make sense in a host language where pointers
    -- are transparent - in Haskell, we simply don't care whether two values
    -- share a memory location or not, and whether they do or not might even
    -- depend on build flags.

    -- TODO: mapping (predicate)
    -- TODO: none (predicate)
    -- TODO: number (predicate)
    -- TODO: sequence (predicate)
    -- TODO: string (predicate)
    -- TODO: callable

    -- TODO: defined (predicate)
    -- TODO: undefined (predicate)
    -- NOTE that @defined@ cannot actually be written as a function. See
    -- issue #33.

    -- TODO: lower (predicate)
    -- TODO: upper (predicate)
    ]

-- | Simplified interface to render a ginger template \"into\" a monad.
--
-- @easyRenderM emit context template@ renders the @template@ with the
-- given @context@ object (which should represent some sort of
-- dictionary-like object) by feeding any output to the @emit@ function.
easyRenderM :: ( Monad m
               , ContextEncodable h
               , Monoid h
               , ToGVal (Run p m h) v
               , ToGVal (Run p m h) h
               , ToGVal (Run p m h) p
               )
            => (h -> m ())
            -> v
            -> Template p
            -> m (Either (RuntimeError p) (GVal (Run p m h)))
easyRenderM :: forall (m :: * -> *) h p v.
(Monad m, ContextEncodable h, Monoid h, ToGVal (Run p m h) v,
 ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
(h -> m ())
-> v
-> Template p
-> m (Either (RuntimeError p) (GVal (Run p m h)))
easyRenderM h -> m ()
emit v
context Template p
template =
    forall p (m :: * -> *) h.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
GingerContext p m h
-> Template p -> m (Either (RuntimeError p) (GVal (Run p m h)))
runGingerT (forall (m :: * -> *) h p v.
(Monad m, ContextEncodable h, ToGVal (Run p m h) v) =>
(h -> m ()) -> v -> GingerContext p m h
easyContext h -> m ()
emit v
context) Template p
template

-- | Simplified interface to render a ginger template in a pure fashion.
--
-- @easyRender context template@ renders the @template@ with the
-- given @context@ object (which should represent some sort of
-- dictionary-like object) by returning the concatenated output.
easyRender :: ( ContextEncodable h
              , Monoid h
              , ToGVal (Run p (Writer h) h) v
              , ToGVal (Run p (Writer h) h) h
              , ToGVal (Run p (Writer h) h) p
              )
           => v
           -> Template p
           -> h
easyRender :: forall h p v.
(ContextEncodable h, Monoid h, ToGVal (Run p (Writer h) h) v,
 ToGVal (Run p (Writer h) h) h, ToGVal (Run p (Writer h) h) p) =>
v -> Template p -> h
easyRender v
context Template p
template =
    forall w a. Writer w a -> w
execWriter forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) h p v.
(Monad m, ContextEncodable h, Monoid h, ToGVal (Run p m h) v,
 ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
(h -> m ())
-> v
-> Template p
-> m (Either (RuntimeError p) (GVal (Run p m h)))
easyRenderM forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell v
context Template p
template

-- | Purely expand a Ginger template. The underlying carrier monad is 'Writer'
-- 'h', which is used to collect the output and render it into a 'h'
-- value.
runGinger :: ( ToGVal (Run p (Writer h) h) h
             , ToGVal (Run p (Writer h) h) p
             , Monoid h
             )
          => GingerContext p (Writer h) h
          -> Template p
          -> h
runGinger :: forall p h.
(ToGVal (Run p (Writer h) h) h, ToGVal (Run p (Writer h) h) p,
 Monoid h) =>
GingerContext p (Writer h) h -> Template p -> h
runGinger GingerContext p (Writer h) h
context Template p
template =
    forall w a. Writer w a -> w
execWriter forall a b. (a -> b) -> a -> b
$ forall p (m :: * -> *) h.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
GingerContext p m h
-> Template p -> m (Either (RuntimeError p) (GVal (Run p m h)))
runGingerT GingerContext p (Writer h) h
context Template p
template

-- | Monadically run a Ginger template. The @m@ parameter is the carrier monad.
runGingerT :: ( ToGVal (Run p m h) h
              , ToGVal (Run p m h) p
              , Monoid h
              , Monad m
              )
           => GingerContext p m h
           -> Template p
           -> m (Either (RuntimeError p) (GVal (Run p m h)))
runGingerT :: forall p (m :: * -> *) h.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
GingerContext p m h
-> Template p -> m (Either (RuntimeError p) (GVal (Run p m h)))
runGingerT GingerContext p m h
context Template p
tpl =
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (forall p (m :: * -> *) h.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Template p -> Run p m h (GVal (Run p m h))
runTemplate Template p
tpl)) (forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Template p -> RunState p m h
defRunState Template p
tpl)) GingerContext p m h
context

-- | Find the effective base template of an inheritance chain
baseTemplate :: Template p -> Template p
baseTemplate :: forall p. Template p -> Template p
baseTemplate Template p
t =
    case forall a. Template a -> Maybe (Template a)
templateParent Template p
t of
        Maybe (Template p)
Nothing -> Template p
t
        Just Template p
p -> forall p. Template p -> Template p
baseTemplate Template p
p

-- | Run a template.
runTemplate :: ( ToGVal (Run p m h) h
               , ToGVal (Run p m h) p
               , Monoid h
               , Monad m
               )
            => Template p
            -> Run p m h (GVal (Run p m h))
runTemplate :: forall p (m :: * -> *) h.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Template p -> Run p m h (GVal (Run p m h))
runTemplate =
    forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Template a -> Statement a
templateBody forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p. Template p -> Template p
baseTemplate

-- | Run an action within a different template context.
withTemplate :: Monad m
             => Template p
             -> Run p m h a
             -> Run p m h a
withTemplate :: forall (m :: * -> *) p h a.
Monad m =>
Template p -> Run p m h a -> Run p m h a
withTemplate Template p
tpl Run p m h a
a = do
    Template p
oldTpl <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> Template p
rsCurrentTemplate
    Maybe Text
oldBlockName <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> Maybe Text
rsCurrentBlockName
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\RunState p m h
s -> RunState p m h
s { rsCurrentTemplate :: Template p
rsCurrentTemplate = Template p
tpl, rsCurrentBlockName :: Maybe Text
rsCurrentBlockName = forall a. Maybe a
Nothing })
    a
result <- forall (m :: * -> *) p h a.
Monad m =>
p -> Run p m h a -> Run p m h a
withSourcePos (forall (f :: * -> *) p. Annotated f => f p -> p
annotation Template p
tpl) Run p m h a
a
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\RunState p m h
s -> RunState p m h
s { rsCurrentTemplate :: Template p
rsCurrentTemplate = Template p
oldTpl, rsCurrentBlockName :: Maybe Text
rsCurrentBlockName = Maybe Text
oldBlockName })
    forall (m :: * -> *) a. Monad m => a -> m a
return a
result

-- | Run an action within a block context
withBlockName :: Monad m
              => VarName
              -> Run p m h a
              -> Run p m h a
withBlockName :: forall (m :: * -> *) p h a.
Monad m =>
Text -> Run p m h a -> Run p m h a
withBlockName Text
blockName Run p m h a
a = do
    Maybe Text
oldBlockName <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> Maybe Text
rsCurrentBlockName
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\RunState p m h
s -> RunState p m h
s { rsCurrentBlockName :: Maybe Text
rsCurrentBlockName = forall a. a -> Maybe a
Just Text
blockName })
    a
result <- Run p m h a
a
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\RunState p m h
s -> RunState p m h
s { rsCurrentBlockName :: Maybe Text
rsCurrentBlockName = Maybe Text
oldBlockName })
    forall (m :: * -> *) a. Monad m => a -> m a
return a
result

lookupBlock :: Monad m => VarName -> Run p m h (Block p)
lookupBlock :: forall (m :: * -> *) p h. Monad m => Text -> Run p m h (Block p)
lookupBlock Text
blockName = do
    Template p
tpl <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> Template p
rsCurrentTemplate
    let blockMay :: Maybe (Block p)
blockMay = forall p. Text -> Template p -> Maybe (Block p)
resolveBlock Text
blockName Template p
tpl
    case Maybe (Block p)
blockMay of
        Maybe (Block p)
Nothing -> forall (m :: * -> *) p h a.
Monad m =>
RuntimeError p -> Run p m h a
throwHere forall a b. (a -> b) -> a -> b
$ forall p. Text -> RuntimeError p
UndefinedBlockError Text
blockName
        Just Block p
block -> forall (m :: * -> *) a. Monad m => a -> m a
return Block p
block
    where
        resolveBlock :: VarName -> Template p -> Maybe (Block p)
        resolveBlock :: forall p. Text -> Template p -> Maybe (Block p)
resolveBlock Text
name Template p
tpl =
            case forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
name (forall a. Template a -> HashMap Text (Block a)
templateBlocks Template p
tpl) of
                Just Block p
block ->
                    forall (m :: * -> *) a. Monad m => a -> m a
return Block p
block -- Found it!
                Maybe (Block p)
Nothing ->
                    forall a. Template a -> Maybe (Template a)
templateParent Template p
tpl forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall p. Text -> Template p -> Maybe (Block p)
resolveBlock Text
name

-- | Run one statement.
runStatement :: forall m h p
              . ( ToGVal (Run p m h) h
                , ToGVal (Run p m h) p
                , Monoid h
                , Monad m
                )
             => Statement p
             -> Run p m h (GVal (Run p m h))
runStatement :: forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
stmt =
    forall (m :: * -> *) p h a.
Monad m =>
p -> Run p m h a -> Run p m h a
withSourcePos
        (forall (f :: * -> *) p. Annotated f => f p -> p
annotation Statement p
stmt)
        (forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement' Statement p
stmt)

runStatement' :: forall m h p
              . ( ToGVal (Run p m h) h
                , ToGVal (Run p m h) p
                , Monoid h
                , Monad m
                )
             => Statement p
             -> Run p m h (GVal (Run p m h))
runStatement' :: forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement' (NullS p
_) =
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
runStatement' (MultiS p
_ [Statement p]
xs) =
    forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Statement p]
xs forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        [] -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
        [GVal (Run p m h)]
rvals -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
List.last [GVal (Run p m h)]
rvals
runStatement' (LiteralS p
_ Html
html) =
    forall (m :: * -> *) h p.
(Monad m, Monoid h) =>
GVal (Run p m h) -> Run p m h ()
echo (forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal Html
html) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
runStatement' (InterpolationS p
_ Expression p
expr) =
    forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
expr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) h p.
(Monad m, Monoid h) =>
GVal (Run p m h) -> Run p m h ()
echo forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
runStatement' (ExpressionS p
_ Expression p
expr) =
    forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
expr
runStatement' (IfS p
_ Expression p
condExpr Statement p
true Statement p
false) = do
    GVal (Run p m h)
cond <- forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
condExpr
    forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement forall a b. (a -> b) -> a -> b
$ if forall (m :: * -> *). GVal m -> Bool
toBoolean GVal (Run p m h)
cond then Statement p
true else Statement p
false

runStatement' (IndentS p
_ Expression p
expr Statement p
body) = do
    GVal (Run p m h)
i <- forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
expr
    GVal (Run p m h) -> h
encode <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall p (m :: * -> *) h.
GingerContext p m h -> GVal (Run p m h) -> h
contextEncode
    let istr :: h
istr = GVal (Run p m h) -> h
encode GVal (Run p m h)
i
    forall (m :: * -> *) h p a.
(Monad m, Monoid h) =>
h -> Run p m h a -> Run p m h a
indented h
istr forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
body

runStatement' (SwitchS p
_ Expression p
pivotExpr [(Expression p, Statement p)]
cases Statement p
defBranch) = do
    GVal (Run p m h)
pivot <- forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
pivotExpr
    let branches :: [ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
branches =
            [ \ExceptT
  (RuntimeError p)
  (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
  (GVal (Run p m h))
cont -> do
                GVal (Run p m h)
cond <- forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
condExpr
                if GVal (Run p m h)
pivot forall (m :: * -> *). GVal m -> GVal m -> Bool
`looseEquals` GVal (Run p m h)
cond
                    then forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
body
                    else ExceptT
  (RuntimeError p)
  (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
  (GVal (Run p m h))
cont
            | (Expression p
condExpr, Statement p
body)
            <- [(Expression p, Statement p)]
cases
            ] forall a. [a] -> [a] -> [a]
++
            [ forall a b. a -> b -> a
Prelude.const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
defBranch ]
    [ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
go [ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
branches
    where
        go :: [ Run p m h (GVal (Run p m h)) -> Run p m h (GVal (Run p m h)) ]
           -> Run p m h (GVal (Run p m h))
        go :: [ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
go [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
        go (ExceptT
  (RuntimeError p)
  (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
  (GVal (Run p m h))
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
x:[ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
xs) = ExceptT
  (RuntimeError p)
  (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
  (GVal (Run p m h))
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
x ([ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
go [ExceptT
   (RuntimeError p)
   (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
   (GVal (Run p m h))
 -> ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
      (GVal (Run p m h))]
xs)

runStatement' (SetVarS p
_ Text
name Expression p
valExpr) = do
    GVal (Run p m h)
val <- forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
valExpr
    forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
name GVal (Run p m h)
val
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def

runStatement' (DefMacroS p
_ Text
name Macro p
macro) = do
    let val :: GVal (Run p m h)
val = forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Macro p -> GVal (Run p m h)
macroToGVal Macro p
macro
    forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
name GVal (Run p m h)
val
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def

runStatement' (BlockRefS p
_ Text
blockName) = do
    Block p
block <- forall (m :: * -> *) p h. Monad m => Text -> Run p m h (Block p)
lookupBlock Text
blockName
    forall (m :: * -> *) p h a.
Monad m =>
Text -> Run p m h a -> Run p m h a
withBlockName Text
blockName forall a b. (a -> b) -> a -> b
$
        forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement (forall a. Block a -> Statement a
blockBody Block p
block)

runStatement' (ScopedS p
_ Statement p
body) = forall (m :: * -> *) p h a. Monad m => Run p m h a -> Run p m h a
withLocalScope Monad m =>
ExceptT
  (RuntimeError p)
  (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
  (GVal (Run p m h))
runInner
    where
        runInner :: Monad m => Run p m h (GVal (Run p m h))
        runInner :: Monad m =>
ExceptT
  (RuntimeError p)
  (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
  (GVal (Run p m h))
runInner = forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
body

runStatement' (ForS p
_ Maybe Text
varNameIndex Text
varNameValue Expression p
itereeExpr Statement p
body) = do
    let go :: Int -> GVal (Run p m h) -> Run p m h (GVal (Run p m h))
        go :: Int
-> GVal (Run p m h)
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
go Int
recursionDepth GVal (Run p m h)
iteree = do
            [(GVal (Run p m h), GVal (Run p m h))]
iterPairs <- if forall a. Maybe a -> Bool
isJust (forall (m :: * -> *). GVal m -> Maybe [(Text, GVal m)]
asDictItems GVal (Run p m h)
iteree)
                then forall (m :: * -> *) a. Monad m => a -> m a
return [ (forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal Text
k, GVal (Run p m h)
v) | (Text
k, GVal (Run p m h)
v) <- forall a. a -> Maybe a -> a
fromMaybe [] (forall (m :: * -> *). GVal m -> Maybe [(Text, GVal m)]
asDictItems GVal (Run p m h)
iteree) ]
                else case forall (m :: * -> *). GVal m -> Maybe [GVal m]
asList GVal (Run p m h)
iteree of
                  Just [GVal (Run p m h)]
items -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
Prelude.zip (forall a b. (a -> b) -> [a] -> [b]
Prelude.map forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal ([Int
0..] :: [Int])) [GVal (Run p m h)]
items
                  Maybe [GVal (Run p m h)]
Nothing -> do
                    forall (m :: * -> *) p h. Monad m => RuntimeError p -> Run p m h ()
warn forall a b. (a -> b) -> a -> b
$ forall p. [Text] -> Maybe Text -> RuntimeError p
TypeError [Text
"list", Text
"dictionary"] (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
tshow GVal (Run p m h)
iteree)
                    forall (m :: * -> *) a. Monad m => a -> m a
return []
            let numItems :: Int
                numItems :: Int
numItems = forall (t :: * -> *) a. Foldable t => t a -> Int
Prelude.length [(GVal (Run p m h), GVal (Run p m h))]
iterPairs
                cycle :: Int -> [(Maybe Text, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
                cycle :: Int
-> [(Maybe Text, GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
cycle Int
index [(Maybe Text, GVal (Run p m h))]
args = forall (m :: * -> *) a. Monad m => a -> m a
return
                                 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a -> a
fromMaybe forall a. Default a => a
def
                                 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe a
headMay
                                 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
Prelude.drop (Int
index forall a. Integral a => a -> a -> a
`Prelude.mod` forall (t :: * -> *) a. Foldable t => t a -> Int
Prelude.length [(Maybe Text, GVal (Run p m h))]
args)
                                 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd
                                 forall a b. (a -> b) -> a -> b
$ [(Maybe Text, GVal (Run p m h))]
args
                loop :: [(Maybe Text, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
                loop :: [(Maybe Text, GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
loop [] = forall (m :: * -> *) p h a.
Monad m =>
RuntimeError p -> Run p m h a
throwHere forall a b. (a -> b) -> a -> b
$ forall p. Maybe Text -> Text -> RuntimeError p
ArgumentsError (forall a. a -> Maybe a
Just Text
"loop") Text
"at least one argument is required"
                loop ((Maybe Text
_, GVal (Run p m h)
loopee):[(Maybe Text, GVal (Run p m h))]
_) = Int
-> GVal (Run p m h)
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
go (forall a. Enum a => a -> a
Prelude.succ Int
recursionDepth) GVal (Run p m h)
loopee
                iteration :: (Int, (GVal (Run p m h), GVal (Run p m h)))
                          -> Run p m h (GVal (Run p m h))
                iteration :: (Int, (GVal (Run p m h), GVal (Run p m h)))
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
iteration (Int
index, (GVal (Run p m h)
key, GVal (Run p m h)
value)) = do
                    forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
varNameValue GVal (Run p m h)
value
                    forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
"loop" forall a b. (a -> b) -> a -> b
$
                        (forall (m :: * -> *). [Pair m] -> GVal m
dict [ Text
"index" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> forall a. Enum a => a -> a
Prelude.succ Int
index
                             , Text
"index0" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> Int
index
                             , Text
"revindex" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> (Int
numItems forall a. Num a => a -> a -> a
- Int
index)
                             , Text
"revindex0" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> (Int
numItems forall a. Num a => a -> a -> a
- Int
index forall a. Num a => a -> a -> a
- Int
1)
                             , Text
"depth" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> forall a. Enum a => a -> a
Prelude.succ Int
recursionDepth
                             , Text
"depth0" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> Int
recursionDepth
                             , Text
"first" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> (Int
index forall a. Eq a => a -> a -> Bool
== Int
0)
                             , Text
"last" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> (forall a. Enum a => a -> a
Prelude.succ Int
index forall a. Eq a => a -> a -> Bool
== Int
numItems)
                             , Text
"length" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> Int
numItems
                             , Text
"cycle" forall (m :: * -> *) a. ToGVal m a => Text -> a -> Pair m
~> forall (m :: * -> *). Function m -> GVal m
fromFunction (Int
-> [(Maybe Text, GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
cycle Int
index)
                             ])
                             { asFunction :: Maybe
  ([(Maybe Text, GVal (Run p m h))]
   -> ExceptT
        (RuntimeError p)
        (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
        (GVal (Run p m h)))
asFunction = forall a. a -> Maybe a
Just [(Maybe Text, GVal (Run p m h))]
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
loop }
                    case Maybe Text
varNameIndex of
                        Maybe Text
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
                        Just Text
n -> forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
n GVal (Run p m h)
key
                    forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
body
            (forall (m :: * -> *) p h a. Monad m => Run p m h a -> Run p m h a
withLocalScope forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (forall a b. [a] -> [b] -> [(a, b)]
Prelude.zip [Int
0..] [(GVal (Run p m h), GVal (Run p m h))]
iterPairs) (Int, (GVal (Run p m h), GVal (Run p m h)))
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
iteration) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                [] -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
                [GVal (Run p m h)]
rvals -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
List.last [GVal (Run p m h)]
rvals
    forall {m :: * -> *} {p} {h}.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
itereeExpr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int
-> GVal (Run p m h)
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal (Run p m h))
go Int
0

runStatement' (PreprocessedIncludeS p
_ Template p
tpl) =
    forall (m :: * -> *) p h a.
Monad m =>
Template p -> Run p m h a -> Run p m h a
withTemplate Template p
tpl forall a b. (a -> b) -> a -> b
$ forall p (m :: * -> *) h.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Template p -> Run p m h (GVal (Run p m h))
runTemplate Template p
tpl

runStatement' (TryCatchS p
_ Statement p
tryS [CatchBlock p]
catchesS Statement p
finallyS) = do
    GVal (Run p m h)
result <- (forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
tryS) forall (m :: * -> *) e a e'.
Monad m =>
ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a
`catchE` forall {m :: * -> *} {p} {h} {p}.
(Monad m,
 ToGVal
   (ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
   p,
 ToGVal
   (ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
   h,
 ToGVal
   (ExceptT
      (RuntimeError p)
      (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
   p,
 Monoid h) =>
[CatchBlock p]
-> RuntimeError p
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal
        (ExceptT
           (RuntimeError p)
           (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))))
handle [CatchBlock p]
catchesS
    forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
finallyS
    forall (m :: * -> *) a. Monad m => a -> m a
return GVal (Run p m h)
result
    where
        handle :: [CatchBlock p]
-> RuntimeError p
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal
        (ExceptT
           (RuntimeError p)
           (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))))
handle [] RuntimeError p
e = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
        handle ((Catch Maybe Text
whatMay Maybe Text
varNameMay Statement p
catchS):[CatchBlock p]
catches) RuntimeError p
e = do
            let what :: Text
what = forall p. RuntimeError p -> Text
runtimeErrorWhat RuntimeError p
e
            if Maybe Text
whatMay forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just Text
what Bool -> Bool -> Bool
|| Maybe Text
whatMay forall a. Eq a => a -> a -> Bool
== forall a. Maybe a
Nothing
                then
                    forall (m :: * -> *) p h a. Monad m => Run p m h a -> Run p m h a
withLocalScope forall a b. (a -> b) -> a -> b
$ do
                        case Maybe Text
varNameMay of
                            Maybe Text
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                            Just Text
varName -> forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
varName (forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal RuntimeError p
e)
                        forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
catchS
                else
                    [CatchBlock p]
-> RuntimeError p
-> ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))
     (GVal
        (ExceptT
           (RuntimeError p)
           (StateT (RunState p m h) (ReaderT (GingerContext p m h) m))))
handle [CatchBlock p]
catches RuntimeError p
e

-- | Deeply magical function that converts a 'Macro' into a Function.
macroToGVal :: forall m h p
             . ( ToGVal (Run p m h) h
               , ToGVal (Run p m h) p
               , Monoid h
               , Monad m
               ) => Macro p -> GVal (Run p m h)
macroToGVal :: forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Macro p -> GVal (Run p m h)
macroToGVal (Macro [Text]
argNames Statement p
body) =
    forall (m :: * -> *). Function m -> GVal m
fromFunction Function (Run p m h)
f
    where
        f :: Function (Run p m h)
        -- Establish a local state to not contaminate the parent scope
        -- with function arguments and local variables, and;
        -- Establish a local context, where we override the HTML writer,
        -- rewiring it to append any output to the state's capture.
        f :: Function (Run p m h)
f [(Maybe Text, GVal (Run p m h))]
args =
            forall (m :: * -> *) s a. (Monad m, MonadState s m) => m a -> m a
withLocalState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\GingerContext p m h
c -> GingerContext p m h
c { contextWrite :: h -> Run p m h ()
contextWrite = forall h (m :: * -> *) p. (Monoid h, Monad m) => h -> Run p m h ()
appendCapture }) forall a b. (a -> b) -> a -> b
$ do
                forall h (m :: * -> *) p. (Monoid h, Monad m) => Run p m h ()
clearCapture
                forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap Text (GVal (Run p m h))
matchedArgs) (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar)
                forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
"varargs" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall a b. (a -> b) -> a -> b
$ [GVal (Run p m h)]
positionalArgs
                forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar Text
"kwargs" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall a b. (a -> b) -> a -> b
$ HashMap Text (GVal (Run p m h))
namedArgs
                forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
body
                -- At this point, we're still inside the local state, so the
                -- capture contains the macro's output; we now simply return
                -- the capture as the function's return value.
                forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) p h. Monad m => Run p m h h
fetchCapture
                where
                    matchArgs' :: [(Maybe Text, GVal (Run p m h))] -> (HashMap Text (GVal (Run p m h)), [GVal (Run p m h)], HashMap Text (GVal (Run p m h)))
                    matchArgs' :: [(Maybe Text, GVal (Run p m h))]
-> (HashMap Text (GVal (Run p m h)), [GVal (Run p m h)],
    HashMap Text (GVal (Run p m h)))
matchArgs' = forall (m :: * -> *).
[Text]
-> [(Maybe Text, GVal m)]
-> (HashMap Text (GVal m), [GVal m], HashMap Text (GVal m))
matchFuncArgs [Text]
argNames
                    (HashMap Text (GVal (Run p m h))
matchedArgs, [GVal (Run p m h)]
positionalArgs, HashMap Text (GVal (Run p m h))
namedArgs) = [(Maybe Text, GVal (Run p m h))]
-> (HashMap Text (GVal (Run p m h)), [GVal (Run p m h)],
    HashMap Text (GVal (Run p m h)))
matchArgs' [(Maybe Text, GVal (Run p m h))]
args

-- | Run p (evaluate) an expression and return its value into the Run p monad
runExpression :: Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
expr =
    forall (m :: * -> *) p h a.
Monad m =>
p -> Run p m h a -> Run p m h a
withSourcePos
        (forall (f :: * -> *) p. Annotated f => f p -> p
annotation Expression p
expr)
        (Expression p -> Run p m h (GVal (Run p m h))
runExpression' Expression p
expr)

runExpression' :: Expression p -> Run p m h (GVal (Run p m h))
runExpression' (StringLiteralE p
_ Text
str) = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall a b. (a -> b) -> a -> b
$ Text
str
runExpression' (NumberLiteralE p
_ Scientific
n) = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall a b. (a -> b) -> a -> b
$ Scientific
n
runExpression' (BoolLiteralE p
_ Bool
b) = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall a b. (a -> b) -> a -> b
$ Bool
b
runExpression' (NullLiteralE p
_) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
runExpression' (VarE p
_ Text
key) = forall (m :: * -> *) p h.
Monad m =>
Text -> Run p m h (GVal (Run p m h))
getVar Text
key
runExpression' (ListE p
_ [Expression p]
xs) = forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Expression p]
xs Expression p -> Run p m h (GVal (Run p m h))
runExpression
runExpression' (ObjectE p
_ [(Expression p, Expression p)]
xs) = do
    [(Text, GVal (Run p m h))]
items <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Expression p, Expression p)]
xs forall a b. (a -> b) -> a -> b
$ \(Expression p
a, Expression p
b) -> do
        Text
l <- forall (m :: * -> *). GVal m -> Text
asText forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
a
        GVal (Run p m h)
r <- Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
b
        forall (m :: * -> *) a. Monad m => a -> m a
return (Text
l, GVal (Run p m h)
r)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ [(Text, GVal (Run p m h))]
items
runExpression' (MemberLookupE p
_ Expression p
baseExpr Expression p
indexExpr) = do
    GVal (Run p m h)
base <- Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
baseExpr
    GVal (Run p m h)
index <- Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
indexExpr
    forall (m :: * -> *) p a h.
Monad m =>
RuntimeError p -> a -> Maybe a -> Run p m h a
warnFromMaybe (forall p. Text -> RuntimeError p
IndexError forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
tshow (forall (m :: * -> *). GVal m -> Text
asText GVal (Run p m h)
index)) forall a. Default a => a
def forall a b. (a -> b) -> a -> b
$
        forall (m :: * -> *). GVal m -> GVal m -> Maybe (GVal m)
lookupLoose GVal (Run p m h)
index GVal (Run p m h)
base
runExpression' (CallE p
_ Expression p
funcE [(Maybe Text, Expression p)]
argsEs) = do
    [(Maybe Text, GVal (Run p m h))]
args <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Maybe Text, Expression p)]
argsEs forall a b. (a -> b) -> a -> b
$
        \(Maybe Text
argName, Expression p
argE) -> (Maybe Text
argName,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
argE
    GVal (Run p m h)
e <- Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
funcE
    let func :: Maybe (Function (Run p m h))
func = forall (m :: * -> *). GVal m -> Maybe (Function m)
toFunction GVal (Run p m h)
e
    case Maybe (Function (Run p m h))
func of
        Maybe (Function (Run p m h))
Nothing -> do
            forall (m :: * -> *) p h. Monad m => RuntimeError p -> Run p m h ()
warn forall p. RuntimeError p
NotAFunctionError
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Default a => a
def
        Just Function (Run p m h)
f -> Function (Run p m h)
f [(Maybe Text, GVal (Run p m h))]
args
runExpression' (LambdaE p
_ [Text]
argNames Expression p
body) = do
    let fn :: [(a, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
fn [(a, GVal (Run p m h))]
args = forall (m :: * -> *) p h a. Monad m => Run p m h a -> Run p m h a
withLocalScope forall a b. (a -> b) -> a -> b
$ do
            forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a b. [a] -> [b] -> [(a, b)]
Prelude.zip [Text]
argNames (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(a, GVal (Run p m h))]
args)) forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (m :: * -> *) p h.
Monad m =>
Text -> GVal (Run p m h) -> Run p m h ()
setVar
            Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
body
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Function m -> GVal m
fromFunction forall {a}. [(a, GVal (Run p m h))] -> Run p m h (GVal (Run p m h))
fn
runExpression' (TernaryE p
_ Expression p
condition Expression p
yes Expression p
no) = do
    GVal (Run p m h)
condVal <- Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
condition
    let expr :: Expression p
expr = if forall (m :: * -> *). GVal m -> Bool
asBoolean GVal (Run p m h)
condVal then Expression p
yes else Expression p
no
    Expression p -> Run p m h (GVal (Run p m h))
runExpression Expression p
expr
runExpression' (DoE p
_ Statement p
stmt) =
    forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement Statement p
stmt

-- | Helper function to output a HTML value using whatever print function the
-- context provides.
echo :: (Monad m, Monoid h)
     => GVal (Run p m h) -> Run p m h ()
echo :: forall (m :: * -> *) h p.
(Monad m, Monoid h) =>
GVal (Run p m h) -> Run p m h ()
echo GVal
  (ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
src = do
    GVal
  (ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
-> h
e <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall p (m :: * -> *) h.
GingerContext p m h -> GVal (Run p m h) -> h
contextEncode
    h -> Run p m h ()
p <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall p (m :: * -> *) h. GingerContext p m h -> h -> Run p m h ()
contextWrite
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall p (m :: * -> *) h. GingerContext p m h -> Maybe (Newlines h)
contextNewlines forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Newlines h)
Nothing ->
            h -> Run p m h ()
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. GVal
  (ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
-> h
e forall a b. (a -> b) -> a -> b
$ GVal
  (ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
src
        Just Newlines h
newlines -> do
            [h]
indentation <- forall a. a -> Maybe a -> a
fromMaybe [] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> Maybe [h]
rsIndentation
            let ls :: [h]
ls = forall h. Newlines h -> h -> [h]
splitLines Newlines h
newlines forall a b. (a -> b) -> a -> b
$ GVal
  (ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
-> h
e GVal
  (ExceptT
     (RuntimeError p)
     (StateT (RunState p m h) (ReaderT (GingerContext p m h) m)))
src
                indent :: h
indent = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
List.reverse forall a b. (a -> b) -> a -> b
$ [h]
indentation
            forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [h]
ls forall a b. (a -> b) -> a -> b
$ \h
l -> do
                Bool
atLineStart <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> Bool
rsAtLineStart
                if Bool
atLineStart
                    then h -> Run p m h ()
p forall a b. (a -> b) -> a -> b
$ h
indent forall a. Semigroup a => a -> a -> a
<> h
l
                    else h -> Run p m h ()
p h
l
                forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \RunState p m h
state -> RunState p m h
state {
                    rsAtLineStart :: Bool
rsAtLineStart = forall h. Newlines h -> h -> Bool
endsWithNewline Newlines h
newlines h
l
                }

indented :: (Monad m, Monoid h)
         => h
         -> Run p m h a
         -> Run p m h a
indented :: forall (m :: * -> *) h p a.
(Monad m, Monoid h) =>
h -> Run p m h a -> Run p m h a
indented h
i Run p m h a
action = do
    forall (m :: * -> *) h p. (Monad m, Monoid h) => h -> Run p m h ()
pushIndent h
i forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Run p m h a
action forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (m :: * -> *) h p. (Monad m, Monoid h) => Run p m h ()
popIndent

pushIndent :: (Monad m, Monoid h)
           => h
           -> Run p m h ()
pushIndent :: forall (m :: * -> *) h p. (Monad m, Monoid h) => h -> Run p m h ()
pushIndent h
i =
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \RunState p m h
state ->
        RunState p m h
state { rsIndentation :: Maybe [h]
rsIndentation = forall a. a -> Maybe [a] -> Maybe [a]
increaseIndent h
i (forall p (m :: * -> *) h. RunState p m h -> Maybe [h]
rsIndentation RunState p m h
state) }
popIndent :: (Monad m, Monoid h)
           => Run p m h ()
popIndent :: forall (m :: * -> *) h p. (Monad m, Monoid h) => Run p m h ()
popIndent =
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \RunState p m h
state ->
        RunState p m h
state { rsIndentation :: Maybe [h]
rsIndentation = forall a. Maybe [a] -> Maybe [a]
decreaseIndent (forall p (m :: * -> *) h. RunState p m h -> Maybe [h]
rsIndentation RunState p m h
state) }

increaseIndent :: a -> Maybe [a] -> Maybe [a]
increaseIndent :: forall a. a -> Maybe [a] -> Maybe [a]
increaseIndent a
_ Maybe [a]
Nothing = forall a. a -> Maybe a
Just []
increaseIndent a
x (Just [a]
xs) = forall a. a -> Maybe a
Just (a
xforall a. a -> [a] -> [a]
:[a]
xs)

decreaseIndent :: Maybe [a] -> Maybe [a]
decreaseIndent :: forall a. Maybe [a] -> Maybe [a]
decreaseIndent Maybe [a]
Nothing = forall a. Maybe a
Nothing
decreaseIndent (Just []) = forall a. Maybe a
Nothing
decreaseIndent (Just (a
x:[a]
xs)) = forall a. a -> Maybe a
Just [a]
xs

defRunState :: forall m h p
             . ( ToGVal (Run p m h) h
               , ToGVal (Run p m h) p
               , Monoid h
               , Monad m
               )
            => Template p
            -> RunState p m h
defRunState :: forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Template p -> RunState p m h
defRunState Template p
tpl =
    RunState
        { rsScope :: HashMap Text (GVal (Run p m h))
rsScope = forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList forall (m :: * -> *) h p.
(Monoid h, Monad m, ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
[(Text, GVal (Run p m h))]
defaultScope
        , rsCapture :: h
rsCapture = forall a. Monoid a => a
mempty
        , rsCurrentTemplate :: Template p
rsCurrentTemplate = Template p
tpl
        , rsCurrentBlockName :: Maybe Text
rsCurrentBlockName = forall a. Maybe a
Nothing
        , rsIndentation :: Maybe [h]
rsIndentation = forall a. Maybe a
Nothing
        , rsAtLineStart :: Bool
rsAtLineStart = Bool
True
        , rsCurrentSourcePos :: p
rsCurrentSourcePos = forall (f :: * -> *) p. Annotated f => f p -> p
annotation Template p
tpl
        }

gfnThrow :: ( Monad m
            , Monoid h
            , ToGVal (Run p m h) h
            , ToGVal (Run p m h) p
            )
         => Function (Run p m h)
gfnThrow :: forall (m :: * -> *) h p.
(Monad m, Monoid h, ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
Function (Run p m h)
gfnThrow [(Maybe Text, GVal (Run p m h))]
args =
    forall (m :: * -> *) p h a.
Monad m =>
RuntimeError p -> Run p m h a
throwHere (forall p. Text -> RuntimeError p
RuntimeError forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (m :: * -> *). GVal m -> Text
asText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ [(Maybe Text, GVal (Run p m h))]
args)

gfnEval :: ( Monad m
           , Monoid h
           , ToGVal (Run p m h) h
           , ToGVal (Run p m h) p
           )
        => Function (Run p m h)
gfnEval :: forall (m :: * -> *) h p.
(Monad m, Monoid h, ToGVal (Run p m h) h, ToGVal (Run p m h) p) =>
Function (Run p m h)
gfnEval [(Maybe Text, GVal (Run p m h))]
args =
    let extracted :: Either
  ([GVal (Run p m h)], HashMap Text (GVal (Run p m h)), [Text])
  [GVal (Run p m h)]
extracted =
            forall a.
[(Text, a)]
-> [(Maybe Text, a)] -> Either ([a], HashMap Text a, [Text]) [a]
extractArgsDefL
                [ (Text
"src", forall a. Default a => a
def)
                , (Text
"context", forall a. Default a => a
def)
                ]
                [(Maybe Text, GVal (Run p m h))]
args
    in case Either
  ([GVal (Run p m h)], HashMap Text (GVal (Run p m h)), [Text])
  [GVal (Run p m h)]
extracted of
        Left ([GVal (Run p m h)], HashMap Text (GVal (Run p m h)), [Text])
_ -> forall (m :: * -> *) p h a.
Monad m =>
RuntimeError p -> Run p m h a
throwHere forall a b. (a -> b) -> a -> b
$ forall p. Maybe Text -> Text -> RuntimeError p
ArgumentsError (forall a. a -> Maybe a
Just Text
"eval") Text
"expected: (src, context)"
        Right [GVal (Run p m h)
gSrc, GVal (Run p m h)
gContext] -> do
            Either ParserError (Template SourcePos)
result' <- forall (m :: * -> *).
Monad m =>
IncludeResolver m
-> Maybe String
-> String
-> m (Either ParserError (Template SourcePos))
parseGinger
                (forall a b. a -> b -> a
Prelude.const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Maybe a
Nothing) -- include resolver
                forall a. Maybe a
Nothing -- source name
                (Text -> String
Text.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). GVal m -> Text
asText forall a b. (a -> b) -> a -> b
$ GVal (Run p m h)
gSrc) -- source code
            p
pos <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall p (m :: * -> *) h. RunState p m h -> p
rsCurrentSourcePos
            let result :: Either ParserError (Template p)
result = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. a -> b -> a
Prelude.const p
pos) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either ParserError (Template SourcePos)
result'
            Template p
tpl <- case Either ParserError (Template p)
result of
                Left ParserError
err -> forall (m :: * -> *) p h a.
Monad m =>
RuntimeError p -> Run p m h a
throwHere forall a b. (a -> b) -> a -> b
$ forall p. ParserError -> RuntimeError p
EvalParseError ParserError
err
                Right Template p
t -> forall (m :: * -> *) a. Monad m => a -> m a
return Template p
t
            let localLookup :: a -> m (GVal (Run p m h))
localLookup a
varName = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
                    forall (m :: * -> *). GVal m -> GVal m -> GVal m -> GVal m
lookupLooseDef forall a. Default a => a
def (forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal a
varName) GVal (Run p m h)
gContext
                localContext :: GingerContext p m h -> GingerContext p m h
localContext GingerContext p m h
c = GingerContext p m h
c
                    { contextWrite :: h -> Run p m h ()
contextWrite = forall h (m :: * -> *) p. (Monoid h, Monad m) => h -> Run p m h ()
appendCapture
                    , contextLookup :: Text -> Run p m h (GVal (Run p m h))
contextLookup = forall {m :: * -> *} {a}.
(Monad m, ToGVal (Run p m h) a) =>
a -> m (GVal (Run p m h))
localLookup
                    }
            forall (m :: * -> *) s a. (Monad m, MonadState s m) => m a -> m a
withLocalState forall a b. (a -> b) -> a -> b
$ do
                forall s (m :: * -> *). MonadState s m => s -> m ()
put forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Template p -> RunState p m h
defRunState Template p
tpl
                forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local GingerContext p m h -> GingerContext p m h
localContext forall a b. (a -> b) -> a -> b
$ do
                    forall h (m :: * -> *) p. (Monoid h, Monad m) => Run p m h ()
clearCapture
                    forall (m :: * -> *) h p.
(ToGVal (Run p m h) h, ToGVal (Run p m h) p, Monoid h, Monad m) =>
Statement p -> Run p m h (GVal (Run p m h))
runStatement forall a b. (a -> b) -> a -> b
$ forall a. Template a -> Statement a
templateBody Template p
tpl
                    -- At this point, we're still inside the local state, so the
                    -- capture contains the macro's output; we now simply return
                    -- the capture as the function's return value.
                    forall (m :: * -> *) a. ToGVal m a => a -> GVal m
toGVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) p h. Monad m => Run p m h h
fetchCapture