-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | An implementation of the Jinja2 template language in Haskell
--
-- Ginger is Jinja, minus the most blatant pythonisms. Wants to be
-- feature complete, but isn't quite there yet.
@package ginger
@version 0.2.6.0
module Text.PrintfA
data PrintfArgT
P :: a -> PrintfArgT
data PrintfTypeT
T :: (forall r. PrintfType r => r) -> PrintfTypeT
[unT] :: PrintfTypeT -> forall r. PrintfType r => r
printfa :: PrintfType t => String -> [PrintfArgT] -> t
-- | A HTML type, useful for implementing type-safe conversion between
-- plain text and HTML. The HTML representation used here assumed Unicode
-- throughout, and UTF-8 should be used as the encoding when sending
-- Html objects as responses to a HTTP client.
module Text.Ginger.Html
-- | A chunk of HTML source.
data Html
-- | Convert a chunk of HTML source code into an Html value as-is.
-- Note that this bypasses any and all HTML encoding; the caller is
-- responsible for taking appropriate measures against XSS and other
-- potential vulnerabilities. In other words, the input to this function
-- is considered pre-sanitized.
unsafeRawHtml :: Text -> Html
-- | Safely convert plain text to HTML.
html :: Text -> Html
-- | Extract HTML source code from an Html value.
htmlSource :: Html -> Text
-- | Types that support conversion to HTML.
class ToHtml s
toHtml :: ToHtml s => s -> Html
instance GHC.Classes.Ord Text.Ginger.Html.Html
instance GHC.Classes.Eq Text.Ginger.Html.Html
instance GHC.Show.Show Text.Ginger.Html.Html
instance GHC.Base.Monoid Text.Ginger.Html.Html
instance Text.Ginger.Html.ToHtml Data.Text.Internal.Text
instance Text.Ginger.Html.ToHtml [GHC.Types.Char]
instance Text.Ginger.Html.ToHtml Text.Ginger.Html.Html
-- | GVal is a generic unitype value, representing the kind of values that
-- Ginger can understand.
--
-- Most of the types in this module are parametrized over an m
-- type, which is the host monad for template execution, as passed to
-- runGingerT. For most kinds of values, m is
-- transparent, and in many cases a ToGVal instance can be written
-- that works for all possible m; the reason we need to
-- parametrize the values themselves over the carrier monad is because we
-- want to support impure functions, which requires access to the
-- underlying carrier monad (e.g. IO).
module Text.Ginger.GVal
-- | A variant type designed as the unitype for the template language. Any
-- value referenced in a template, returned from within a template, or
-- used in a template context, will be a GVal. m, in most
-- cases, should be a Monad.
--
-- Some laws apply here, most notably:
--
--
data GVal m
GVal :: Maybe [GVal m] -> Maybe [(Text, GVal m)] -> Maybe (Text -> Maybe (GVal m)) -> Html -> Text -> Bool -> Maybe Scientific -> Maybe (Function m) -> Maybe Int -> Bool -> Maybe Value -> GVal m
-- | Convert value to list, if possible
[asList] :: GVal m -> Maybe [GVal m]
-- | Convert value to association list ("dictionary"), if possible
[asDictItems] :: GVal m -> Maybe [(Text, GVal m)]
-- | Convert value to a lookup function
[asLookup] :: GVal m -> Maybe (Text -> Maybe (GVal m))
-- | Render value as HTML
[asHtml] :: GVal m -> Html
-- | Render value as plain-text
[asText] :: GVal m -> Text
-- | Get value's truthiness
[asBoolean] :: GVal m -> Bool
-- | Convert value to a number, if possible
[asNumber] :: GVal m -> Maybe Scientific
-- | Access value as a callable function, if it is one
[asFunction] :: GVal m -> Maybe (Function m)
-- | Get length of value, if it is a collection (list/dict)
[length] :: GVal m -> Maybe Int
-- | Check if the value is null
[isNull] :: GVal m -> Bool
-- | Provide a custom JSON representation of the value
[asJSON] :: GVal m -> Maybe Value
-- | Convenience wrapper around asDictItems to represent a
-- GVal as a HashMap.
asHashMap :: GVal m -> Maybe (HashMap Text (GVal m))
-- | The default GVal is equivalent to NULL.
-- | Conversion to JSON values attempts the following conversions, in
-- order:
--
--
--
-- Note that the default conversions will never return booleans unless
-- asJSON explicitly does this, because asText will always
-- return *something*.
-- | For convenience, Show is implemented in a way that looks
-- similar to JavaScript / JSON
-- | Converting to HTML hooks into the ToHtml instance for Text for
-- most tags. Tags that have no obvious textual representation render as
-- empty HTML.
-- | A function that can be called from within a template execution
-- context.
type Function m = [(Maybe Text, GVal m)] -> m (GVal m)
-- | Match arguments passed to a function at runtime against a list of
-- declared argument names. matchFuncArgs argNames argsPassed
-- returns (matchedArgs, positionalArgs, namedArgs), where
-- matchedArgs is a list of arguments matched against declared
-- names (by name or by position), positionalArgs are the unused
-- positional (unnamed) arguments, and namedArgs are the unused
-- named arguments.
matchFuncArgs :: [Text] -> [(Maybe Text, GVal m)] -> (HashMap Text (GVal m), [GVal m], HashMap Text (GVal m))
-- | Types that implement conversion to GVal.
class ToGVal m a
toGVal :: ToGVal m a => a -> GVal m
-- | Trivial instance for GVal itself.
-- | Nothing becomes NULL, Just unwraps.
-- | Haskell lists become list-like GVals
-- | HashMap of Text becomes a dictionary-like GVal
-- | A key/value pair, used for constructing dictionary GVals using a
-- compact syntax.
type Pair m = (Text, GVal m)
-- | Construct a dictionary GVal from a list of pairs. Internally, this
-- uses a hashmap, so element order will not be preserved.
dict :: [Pair m] -> GVal m
-- | Construct an ordered dictionary GVal from a list of pairs. Internally,
-- this conversion uses both a hashmap (for O(1) lookup) and the original
-- list, so element order is preserved, but there is a bit of a memory
-- overhead.
orderedDict :: [Pair m] -> GVal m
-- | Construct a pair from a key and a value.
(~>) :: ToGVal m a => Text -> a -> Pair m
infixr 8 ~>
-- | Silly helper function, needed to bypass the default Show
-- instance of Scientific in order to make integral
-- Scientifics look like integers.
scientificToText :: Scientific -> Text
-- | Booleans render as 1 or empty string, and otherwise behave as
-- expected.
-- | String -> GVal conversion uses the IsString
-- class; because String is an alias for '[Char]', there is also
-- a ToGVal instance for String, but it marshals strings
-- as lists of characters, i.e., calling toGVal on a string
-- produces a list of characters on the GVal side.
-- | Single characters are treated as length-1 Texts.
-- | This instance is slightly wrong; the asBoolean,
-- asNumber, and asText methods all treat the HTML source
-- as plain text. We do this to avoid parsing the HTML back into a
-- Text (and dealing with possible parser errors); the reason this
-- instance exists at all is that we still want to be able to pass
-- pre-rendered HTML around sometimes, and as long as we don't call any
-- numeric or string functions on it, everything is fine. When such HTML
-- values accidentally do get used as strings, the HTML source will bleed
-- into the visible text, but at least this will not introduce an XSS
-- vulnerability.
--
-- It is therefore recommended to avoid passing Html values into
-- templates, and also to avoid calling any string functions on
-- Html values inside templates (e.g. capturing macro output and
-- then passing it through a textual filter).
-- | Convert Aeson Values to GVals over an arbitrary host
-- monad. Because JSON cannot represent functions, this conversion will
-- never produce a Function. Further, the ToJSON instance
-- for such a GVal will always produce the exact Value
-- that was use to construct the it.
rawJSONToGVal :: Value -> GVal m
-- | Turn a Function into a GVal
fromFunction :: Function m -> GVal m
-- | Check if the given GVal is a list-like object
isList :: GVal m -> Bool
-- | Check if the given GVal is a dictionary-like object
isDict :: GVal m -> Bool
-- | Treat a GVal as a flat list and look up a value by integer
-- index. If the value is not a List, or if the index exceeds the list
-- length, return Nothing.
lookupIndex :: Int -> GVal m -> Maybe (GVal m)
-- | Helper function; look up a value by an integer index when the index
-- may or may not be available. If no index is given, return
-- Nothing.
lookupIndexMay :: Maybe Int -> GVal m -> Maybe (GVal m)
-- | Strictly-typed lookup: treat value as a dictionary-like object and
-- look up the value at a given key.
lookupKey :: Text -> GVal m -> Maybe (GVal m)
-- | Loosely-typed lookup: try dictionary-style lookup first (treat index
-- as a string, and container as a dictionary), if that doesn't yield
-- anything (either because the index is not string-ish, or because the
-- container doesn't provide dictionary-style access), try index-based
-- lookup.
lookupLoose :: GVal m -> GVal m -> Maybe (GVal m)
-- | Treat a GVal as a dictionary and list all the keys, with no
-- particular ordering.
keys :: GVal m -> Maybe [Text]
-- | Convert a GVal to a number.
toNumber :: GVal m -> Maybe Scientific
-- | Convert a GVal to an Int. The conversion will fail when
-- the value is not numeric, and also if it is too large to fit in an
-- Int.
toInt :: GVal m -> Maybe Int
-- | Loose cast to boolean.
--
-- Numeric zero, empty strings, empty lists, empty objects,
-- Null, and boolean False are considered falsy, anything
-- else (including functions) is considered true-ish.
toBoolean :: GVal m -> Bool
-- | Dynamically cast to a function. This yields Just a
-- Function if the value is a function, Nothing if it's
-- not.
toFunction :: GVal m -> Maybe (Function m)
instance Data.Default.Class.Default (Text.Ginger.GVal.GVal m)
instance Data.Aeson.Types.ToJSON.ToJSON (Text.Ginger.GVal.GVal m)
instance GHC.Show.Show (Text.Ginger.GVal.GVal m)
instance Text.Ginger.Html.ToHtml (Text.Ginger.GVal.GVal m)
instance Text.Printf.PrintfArg (Text.Ginger.GVal.GVal m)
instance Text.Ginger.GVal.ToGVal m (Text.Ginger.GVal.GVal m)
instance Text.Ginger.GVal.ToGVal m v => Text.Ginger.GVal.ToGVal m (GHC.Base.Maybe v)
instance Text.Ginger.GVal.ToGVal m v => Text.Ginger.GVal.ToGVal m [v]
instance Text.Ginger.GVal.ToGVal m v => Text.Ginger.GVal.ToGVal m (Data.HashMap.Base.HashMap Data.Text.Internal.Text v)
instance Text.Ginger.GVal.ToGVal m GHC.Types.Int
instance Text.Ginger.GVal.ToGVal m GHC.Integer.Type.Integer
instance Text.Ginger.GVal.ToGVal m Data.Scientific.Scientific
instance (Text.Ginger.GVal.ToGVal m a, Text.Ginger.GVal.ToGVal m b) => Text.Ginger.GVal.ToGVal m (a, b)
instance (Text.Ginger.GVal.ToGVal m a, Text.Ginger.GVal.ToGVal m b, Text.Ginger.GVal.ToGVal m c) => Text.Ginger.GVal.ToGVal m (a, b, c)
instance (Text.Ginger.GVal.ToGVal m a, Text.Ginger.GVal.ToGVal m b, Text.Ginger.GVal.ToGVal m c, Text.Ginger.GVal.ToGVal m d) => Text.Ginger.GVal.ToGVal m (a, b, c, d)
instance Text.Ginger.GVal.ToGVal m GHC.Types.Bool
instance Data.String.IsString (Text.Ginger.GVal.GVal m)
instance Text.Ginger.GVal.ToGVal m GHC.Types.Char
instance Text.Ginger.GVal.ToGVal m Data.Text.Internal.Text
instance Text.Ginger.GVal.ToGVal m Data.Text.Internal.Lazy.Text
instance Text.Ginger.GVal.ToGVal m Text.Ginger.Html.Html
instance Text.Ginger.GVal.ToGVal m Data.Aeson.Types.Internal.Value
-- | Implements Ginger's Abstract Syntax Tree.
module Text.Ginger.AST
-- | A context variable name.
type VarName = Text
-- | Top-level data structure, representing a fully parsed template.
data Template
Template :: Statement -> HashMap VarName Block -> Maybe Template -> Template
[templateBody] :: Template -> Statement
[templateBlocks] :: Template -> HashMap VarName Block
[templateParent] :: Template -> Maybe Template
-- | A macro definition ( {% macro %} )
data Macro
Macro :: [VarName] -> Statement -> Macro
[macroArgs] :: Macro -> [VarName]
[macroBody] :: Macro -> Statement
-- | A block definition ( {% block %} )
data Block
Block :: Statement -> Block
[blockBody] :: Block -> Statement
-- | Ginger statements.
data Statement
-- | A sequence of multiple statements
MultiS :: [Statement] -> Statement
-- | Run wrapped statement in a local scope
ScopedS :: Statement -> Statement
-- | Literal output (anything outside of any tag)
LiteralS :: Html -> Statement
-- | {{ expression }}
InterpolationS :: Expression -> Statement
-- | {% if expression %}statement{% else %}statement{% endif %}
IfS :: Expression -> Statement -> Statement -> Statement
-- | {% for index, varname in expression %}statement{% endfor %}
ForS :: (Maybe VarName) -> VarName -> Expression -> Statement -> Statement
-- | {% set varname = expr %}
SetVarS :: VarName -> Expression -> Statement
-- | {% macro varname %}statements{% endmacro %}
DefMacroS :: VarName -> Macro -> Statement
BlockRefS :: VarName -> Statement
-- | {% include "template" %}
PreprocessedIncludeS :: Template -> Statement
-- | The do-nothing statement (NOP)
NullS :: Statement
-- | Expressions, building blocks for the expression minilanguage.
data Expression
-- | String literal expression: "foobar"
StringLiteralE :: Text -> Expression
-- | Numeric literal expression: 123.4
NumberLiteralE :: Scientific -> Expression
-- | Boolean literal expression: true
BoolLiteralE :: Bool -> Expression
-- | Literal null
NullLiteralE :: Expression
-- | Variable reference: foobar
VarE :: VarName -> Expression
-- | List construct: [ expr, expr, expr ]
ListE :: [Expression] -> Expression
-- | Object construct: { expr: expr, expr: expr, ... }
ObjectE :: [(Expression, Expression)] -> Expression
-- | foo[bar] (also dot access)
MemberLookupE :: Expression -> Expression -> Expression
-- | foo(bar=baz, quux)
CallE :: Expression -> [(Maybe Text, Expression)] -> Expression
-- | (foo, bar) -> expr
LambdaE :: [Text] -> Expression -> Expression
-- | expr ? expr : expr
TernaryE :: Expression -> Expression -> Expression -> Expression
instance GHC.Show.Show Text.Ginger.AST.Block
instance GHC.Show.Show Text.Ginger.AST.Template
instance GHC.Show.Show Text.Ginger.AST.Macro
instance GHC.Show.Show Text.Ginger.AST.Statement
instance GHC.Show.Show Text.Ginger.AST.Expression
-- | A syntax tree optimizer
module Text.Ginger.Optimizer
class Optimizable a
optimize :: Optimizable a => a -> a
instance Text.Ginger.Optimizer.Optimizable Text.Ginger.AST.Template
instance Text.Ginger.Optimizer.Optimizable Text.Ginger.AST.Statement
instance Text.Ginger.Optimizer.Optimizable Text.Ginger.AST.Block
instance Text.Ginger.Optimizer.Optimizable Text.Ginger.AST.Macro
-- | Ginger parser.
module Text.Ginger.Parse
-- | Parse Ginger source from memory.
parseGinger :: Monad m => IncludeResolver m -> Maybe SourceName -> Source -> m (Either ParserError Template)
-- | Parse Ginger source from a file.
parseGingerFile :: Monad m => IncludeResolver m -> SourceName -> m (Either ParserError Template)
-- | Error information for Ginger parser errors.
data ParserError
ParserError :: String -> Maybe SourceName -> Maybe Int -> Maybe Int -> ParserError
-- | Human-readable error message
[peErrorMessage] :: ParserError -> String
-- | Source name, if any
[peSourceName] :: ParserError -> Maybe SourceName
-- | Line number, if available
[peSourceLine] :: ParserError -> Maybe Int
-- | Column number, if available
[peSourceColumn] :: ParserError -> Maybe Int
-- | Used to resolve includes. Ginger will call this function whenever it
-- encounters an {% include %}, {% import %}, or {% extends %} directive.
-- If the required source code is not available, the resolver should
-- return Nothing, else Just the source.
type IncludeResolver m = SourceName -> m (Maybe Source)
-- | Input type for the parser (source code).
type Source = String
-- | A source identifier (typically a filename).
type SourceName = String
instance GHC.Show.Show Text.Ginger.Parse.ParserError
-- | 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 = makeContext contextLookup
-- in htmlSource $ runGinger context template
--
module Text.Ginger.Run
-- | Monadically run a Ginger template. The m parameter is the
-- carrier monad.
runGingerT :: (ToGVal (Run m h) h, Monoid h, Monad m, Functor m) => GingerContext m h -> Template -> m ()
-- | 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 (Writer h) h) h, Monoid h) => GingerContext (Writer h) h -> Template -> h
-- | Execution context. Determines how to look up variables from the
-- environment, and how to write out template output.
data GingerContext m h
-- | Deprecated: Compatibility alias for makeContextHtml
makeContext :: (VarName -> GVal (Run (Writer Html) Html)) -> GingerContext (Writer Html) Html
-- | Deprecated: Compatibility alias for makeContextHtmlM
makeContextM :: (Monad m, Functor m) => (VarName -> Run m Html (GVal (Run m Html))) -> (Html -> m ()) -> GingerContext m Html
-- | Create an execution context for runGinger. The argument is a lookup
-- function that maps top-level context keys to ginger values.
-- makeContext is a specialized version of makeContextM,
-- targeting the Writer Html monad (which is what is used
-- for the non-monadic template interpreter runGinger).
--
-- The type of the lookup function may look intimidating, but in most
-- cases, marshalling values from Haskell to Ginger is a matter of
-- calling toGVal on them, so the 'GVal (Run (Writer Html))' part
-- can usually be ignored. See the GVal module for details.
makeContext' :: Monoid h => (VarName -> GVal (Run (Writer h) h)) -> (GVal (Run (Writer h) h) -> h) -> GingerContext (Writer h) h
-- | Create an execution context for runGingerT. Takes a lookup function,
-- which returns ginger values into the carrier monad based on a lookup
-- key, and a writer function (outputting HTML by whatever means the
-- carrier monad provides, e.g. putStr for IO, or
-- tell for Writers).
makeContextM' :: (Monad m, Functor m) => (VarName -> Run m h (GVal (Run m h))) -> (h -> m ()) -> (GVal (Run m h) -> h) -> GingerContext m h
makeContextHtml :: (VarName -> GVal (Run (Writer Html) Html)) -> GingerContext (Writer Html) Html
makeContextHtmlM :: (Monad m, Functor m) => (VarName -> Run m Html (GVal (Run m Html))) -> (Html -> m ()) -> GingerContext m Html
makeContextText :: (VarName -> GVal (Run (Writer Text) Text)) -> GingerContext (Writer Text) Text
makeContextTextM :: (Monad m, Functor m) => (VarName -> Run m Text (GVal (Run m Text))) -> (Text -> m ()) -> GingerContext m Text
-- | Internal type alias for our template-runner monad stack.
type Run m h = StateT (RunState m h) (ReaderT (GingerContext m h) m)
-- | Lift a value from the host monad m into the Run monad.
liftRun :: Monad m => m a -> Run m h a
-- | Lift a function from the host monad m into the Run
-- monad.
liftRun2 :: Monad m => (a -> m b) -> a -> Run m h b
-- | Match args according to a given arg spec, Python style. The return
-- value is a triple of (matched, args, kwargs, unmatchedNames),
-- where matches is a hash map of named captured arguments, args
-- is a list of remaining unmatched positional arguments, kwargs is a
-- list of remaining unmatched named arguments, and
-- unmatchedNames contains the argument names that haven't been
-- matched.
extractArgs :: [Text] -> [(Maybe Text, a)] -> (HashMap Text a, [a], HashMap Text a, [Text])
-- | Parse argument list into type-safe argument structure.
extractArgsT :: ([Maybe a] -> b) -> [Text] -> [(Maybe Text, a)] -> Either ([a], HashMap Text a, [Text]) b
-- | Parse argument list into flat list of matched arguments.
extractArgsL :: [Text] -> [(Maybe Text, a)] -> Either ([a], HashMap Text a, [Text]) [Maybe a]
extractArgsDefL :: [(Text, a)] -> [(Maybe Text, a)] -> Either ([a], HashMap Text a, [Text]) [a]
-- | A Haskell implementation of the Jinja2 template language.
--
-- Ginger aims to be as close to the original Jinja language as possible,
-- but avoiding blatant pythonisms and features that make little sense
-- outside of an impure dynamic host language context, especially when
-- this would require sacrificing runtime performance.
module Text.Ginger