-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | An Haskell template system supporting both HTML5 and XML.
--   
--   Heist is a powerful template system that supports both HTML5 and XML.
--   Some of Heist's features are:
--   
--   <ul>
--   <li>Designer-friendly HTML5 (or XML) syntax</li>
--   <li>Templates can be reloaded to make changes visible without
--   recompiling your Haskell code</li>
--   <li>Enforces near-perfect separation of business logic and view</li>
--   <li>Powerful abstraction primitives allowing you to eliminate
--   repetition</li>
--   <li>Easy creation of domain-specific markup languages</li>
--   <li>Built-in support for including JSON and Markdown content in
--   templates</li>
--   <li>Simple mechanism for designer-specified template caching</li>
--   <li>Optional merging of multiple &lt;head&gt; tags defined anywhere in
--   the document</li>
--   </ul>
@package heist
@version 0.13.1.2


-- | An API implementing a convenient syntax for defining and manipulating
--   splices. This module was born from the observation that a list of
--   tuples is semantically ambiguous about how duplicate keys should be
--   handled. Additionally, the syntax is inherently rather cumbersome and
--   difficult to work with. This API takes advantage of do notation to
--   provide a very light syntax for defining splices while at the same
--   time eliminating the semantic ambiguity of alists.
--   
--   Here's how you can define splices:
--   
--   <pre>
--   mySplices :: Splices Text
--   mySplices = do
--     "firstName" ## "John"
--     "lastName"  ## "Smith"
--   </pre>
module Heist.SpliceAPI

-- | A monad providing convenient syntax for defining splices.
newtype SplicesM s a
SplicesM :: State (Map Text s) a -> SplicesM s a
unSplices :: SplicesM s a -> State (Map Text s) a

-- | Convenient type alias that will probably be used most of the time.
type Splices s = SplicesM s ()

-- | Forces a splice to be added. If the key already exists, its value is
--   overwritten.
(##) :: Text -> s -> Splices s

-- | Tries to add a splice, but if the key already exists, then it throws
--   an error message. This may be useful if name collisions are bad and
--   you want to crash when they occur.
(#!) :: Text -> s -> Splices s

-- | Inserts into the map only if the key does not already exist.
(#?) :: Text -> s -> Splices s

-- | A <a>Splices</a> with nothing in it.
noSplices :: Splices s

-- | Runs the SplicesM monad, generating a map of splices.
runSplices :: SplicesM s a -> Map Text s

-- | Constructs an alist representation.
splicesToList :: SplicesM s a -> [(Text, s)]

-- | Internal helper function for adding a map.
add :: Map Text s -> Splices s

-- | Maps a function over all the splices.
mapS :: (a -> b) -> Splices a -> Splices b

-- | Applies an argument to a splice function.
applyS :: a -> Splices (a -> b) -> Splices b

-- | Inserts a splice into the <a>Splices</a>.
insertS :: Text -> s -> Splices s -> Splices s

-- | Inserts a splice with a function combining new value and old value.
insertWithS :: (s -> s -> s) -> Text -> s -> SplicesM s a2 -> SplicesM s ()

-- | Union of <a>Splices</a> with a combining function.
unionWithS :: (s -> s -> s) -> SplicesM s a1 -> SplicesM s a2 -> SplicesM s ()

-- | Infix operator for <tt>flip applyS</tt>
($$) :: Splices (a -> b) -> a -> Splices b

-- | Maps a function over all the splice names.
mapNames :: (Text -> Text) -> Splices a -> Splices a

-- | Adds a prefix to the tag names for a list of splices. If the existing
--   tag name is empty, then the new tag name is just the prefix. Otherwise
--   the new tag name is the prefix followed by the separator followed by
--   the existing name.
prefixSplices :: Text -> Text -> Splices a -> Splices a

-- | <a>prefixSplices</a> specialized to use a colon as separator in the
--   style of XML namespaces.
namespaceSplices :: Text -> Splices a -> Splices a
instance Functor (SplicesM s)
instance Applicative (SplicesM s)
instance Monad (SplicesM s)
instance MonadState (Map Text s) (SplicesM s)
instance Monoid (Splices s)


-- | Compiled splices are similar to the original Heist (interpreted)
--   splices, but without the high performance costs of traversing a DOM at
--   runtime. Compiled splices do all of their DOM processing at load time.
--   They are compiled to produce a runtime computation that generates a
--   ByteString Builder. This preserves the ability to write splices that
--   access runtime information from the HTTP request, database, etc.
--   
--   If you import both this module and <a>Heist.Interpreted</a> in the
--   same file, then you will need to import them qualified.
module Heist.Compiled

-- | A compiled Splice is a HeistT computation that returns a <tt>DList
--   (Chunk m)</tt>.
--   
--   The more interesting part of the type signature is what comes before
--   the return value. The first type parameter in <tt><a>HeistT</a> n
--   IO</tt> is the runtime monad. This reveals that the Chunks know about
--   the runtime monad. The second type parameter in <tt>HeistT n IO</tt>
--   is <tt>IO</tt>. This tells is that the compiled splices themselves are
--   run in the IO monad, which will usually mean at load time. Compiled
--   splices run at load time, and they return computations that run at
--   runtime.
type Splice n = HeistT n IO (DList (Chunk n))

-- | Looks up a compiled template and returns a runtime monad computation
--   that constructs a builder.
renderTemplate :: Monad n => HeistState n -> ByteString -> Maybe (n Builder, MIMEType)

-- | Given a list of output chunks, consolidate turns consecutive runs of
--   <tt>Pure Html</tt> values into maximally-efficient pre-rendered strict
--   <a>ByteString</a> chunks.
codeGen :: Monad n => DList (Chunk n) -> RuntimeSplice n Builder

-- | Runs the parameter node's children and returns the resulting compiled
--   chunks. By itself this function is a simple passthrough splice that
--   makes the spliced node disappear. In combination with locally bound
--   splices, this function makes it easier to pass the desired view into
--   your splices.
runChildren :: Monad n => Splice n

-- | Converts a pure text splice function to a pure Builder splice
--   function.
textSplice :: (a -> Text) -> a -> Builder

-- | Converts a pure Node splice function to a pure Builder splice
--   function.
nodeSplice :: (a -> [Node]) -> a -> Builder

-- | Converts a pure Builder splice function into a monadic splice function
--   of a RuntimeSplice.
pureSplice :: Monad n => (a -> Builder) -> RuntimeSplice n a -> Splice n

-- | Similar to <a>mapSplices</a> in interpreted mode. Gets a runtime list
--   of items and applies a compiled runtime splice function to each
--   element of the list.
deferMany :: Monad n => (RuntimeSplice n a -> Splice n) -> RuntimeSplice n [a] -> Splice n

-- | Saves the results of a runtme computation in a <a>Promise</a> so they
--   don't get recalculated if used more than once.
deferMap :: Monad n => (a -> RuntimeSplice n b) -> (RuntimeSplice n b -> Splice n) -> RuntimeSplice n a -> Splice n

-- | Like deferMap, but only runs the result if a Maybe function of the
--   runtime value returns Just. If it returns Nothing, then no output is
--   generated.
--   
--   This is a good example of how to do more complex flow control with
--   promises. The generalization of this abstraction is too complex to be
--   distilled to elegant high-level combinators. If you need to implement
--   your own special flow control, then you should use functions from the
--   <a>LowLevel</a> module similarly to how it is done in the
--   implementation of this function.
mayDeferMap :: Monad n => (a -> RuntimeSplice n (Maybe b)) -> (RuntimeSplice n b -> Splice n) -> RuntimeSplice n a -> Splice n

-- | Converts an RuntimeSplice into a Splice, given a helper function that
--   generates a Builder.
bindLater :: Monad n => (a -> RuntimeSplice n Builder) -> RuntimeSplice n a -> Splice n

-- | Runs a splice, but first binds splices given by splice functions that
--   need some runtime data.
withSplices :: Monad n => Splice n -> Splices (RuntimeSplice n a -> Splice n) -> RuntimeSplice n a -> Splice n

-- | Like withSplices, but evaluates the splice repeatedly for each element
--   in a list generated at runtime.
manyWithSplices :: Monad n => Splice n -> Splices (RuntimeSplice n a -> Splice n) -> RuntimeSplice n [a] -> Splice n

-- | Adds a list of compiled splices to the splice map. This function is
--   useful because it allows compiled splices to bind other compiled
--   splices during load-time splice processing.
withLocalSplices :: Splices (Splice n) -> Splices (AttrSplice n) -> HeistT n IO a -> HeistT n IO a

-- | Yields a pure Builder known at load time. You should use this and
--   <a>yieldPureText</a> as much as possible to maximize the parts of your
--   page that can be compiled to static ByteStrings.
yieldPure :: Builder -> DList (Chunk n)

-- | Yields a runtime action that returns a builder.
yieldRuntime :: RuntimeSplice n Builder -> DList (Chunk n)

-- | Yields a runtime action that returns no value and is only needed for
--   its side effect.
yieldRuntimeEffect :: Monad n => RuntimeSplice n () -> DList (Chunk n)

-- | A convenience wrapper around yieldPure for working with Text. Roughly
--   equivalent to <a>textSplice</a> from Heist.Interpreted.
yieldPureText :: Text -> DList (Chunk n)

-- | Convenience wrapper around yieldRuntime allowing you to work with
--   Text.
yieldRuntimeText :: Monad n => RuntimeSplice n Text -> DList (Chunk n)

-- | Returns a computation that performs load-time splice processing on the
--   supplied list of nodes.
runNodeList :: Monad n => [Node] -> Splice n

-- | Runs a single node. If there is no splice referenced anywhere in the
--   subtree, then it is rendered as a pure chunk, otherwise it calls
--   compileNode to generate the appropriate runtime computation.
runNode :: Monad n => Node -> Splice n

-- | Performs splice processing on a list of attributes. This is useful in
--   situations where you need to stop recursion, but still run splice
--   processing on the node's attributes.
runAttributes :: Monad n => [(Text, Text)] -> HeistT n IO [DList (Chunk n)]

-- | Performs splice processing on a list of attributes. This is useful in
--   situations where you need to stop recursion, but still run splice
--   processing on the node's attributes.
runAttributesRaw :: Monad n => [(Text, Text)] -> HeistT n IO (RuntimeSplice n [(Text, Text)])

-- | Looks up a compiled template and returns a compiled splice.
callTemplate :: Monad n => ByteString -> HeistT n IO (DList (Chunk n))

module Heist.Compiled.LowLevel

-- | Promises are used for referencing the results of future runtime
--   computations during load time splice processing.
data Promise a

-- | Creates an empty promise.
newEmptyPromise :: HeistT n IO (Promise a)

-- | Gets the result of a promised runtime computation.
getPromise :: Monad n => Promise a -> RuntimeSplice n a

-- | Adds a promise to the runtime splice context.
putPromise :: Monad n => Promise a -> a -> RuntimeSplice n ()

-- | Modifies a promise.
adjustPromise :: Monad n => Promise a -> (a -> a) -> RuntimeSplice n ()


-- | This module defines the API for writing and working with interpreted
--   splices. It exports some of the same symbols as <a>Heist.Compiled</a>,
--   so you will probably want to import it qualified.
--   
--   Interpreted splices can be thought of as a function <tt>Node -&gt; m
--   [Node]</tt>. Heist then substitutes the resulting list of nodes into
--   your template in place of the input node. <a>Splice</a> is implemented
--   as a type synonym <tt>type Splice m = HeistT m [Node]</tt>, and
--   <tt>HeistT</tt> has a function <tt>getParamNode</tt> that lets you get
--   the input node.
--   
--   Suppose you have a place on your page where you want to display a link
--   with the text "Logout username" if the user is currently logged in or
--   a link to the login page if no user is logged in. Assume you have a
--   function <tt>getUser :: MyAppMonad (Maybe Text)</tt> that gets the
--   current user. You can implement this functionality with a
--   <a>Splice</a> as follows:
--   
--   <pre>
--   import           Blaze.ByteString.Builder
--   import           Data.ByteString.Char8 (ByteString)
--   import qualified Data.ByteString.Char8 as B
--   import           Data.Text (Text)
--   import qualified Data.Text as T
--   import qualified Text.XmlHtml as X
--   
--   import qualified Heist.Interpreted as I
--   
--   link :: Text -&gt; Text -&gt; X.Node
--   link target text = X.Element "a" [("href", target)] [X.TextNode text]
--   
--   loginLink :: X.Node
--   loginLink = link "/login" "Login"
--   
--   logoutLink :: Text -&gt; X.Node
--   logoutLink user = link "/logout" (T.append "Logout " user)
--   
--   loginLogoutSplice :: I.Splice MyAppMonad
--   loginLogoutSplice = do
--       user &lt;- lift getUser
--       return [maybe loginLink logoutLink user]
--   </pre>
module Heist.Interpreted
type Splice n = HeistT n n Template

-- | Adds an HTML format template to the heist state.
addTemplate :: ByteString -> Template -> Maybe FilePath -> HeistState n -> HeistState n

-- | Adds an XML format template to the heist state.
addXMLTemplate :: ByteString -> Template -> Maybe FilePath -> HeistState n -> HeistState n

-- | Convenience function for looking up a splice.
lookupSplice :: Text -> HeistState n -> Maybe (Splice n)

-- | Binds a new splice declaration to a tag name within a
--   <a>HeistState</a>.
bindSplice :: Text -> Splice n -> HeistState n -> HeistState n

-- | Binds a set of new splice declarations within a <a>HeistState</a>.
bindSplices :: Splices (Splice n) -> HeistState n -> HeistState n

-- | Binds a set of new splice declarations within a <a>HeistState</a>.
bindAttributeSplices :: Splices (AttrSplice n) -> HeistState n -> HeistState n

-- | Converts <a>Text</a> to a splice returning a single <tt>TextNode</tt>.
textSplice :: Monad m => Text -> HeistT n m Template

-- | Runs the parameter node's children and returns the resulting node
--   list. By itself this function is a simple passthrough splice that
--   makes the spliced node disappear. In combination with locally bound
--   splices, this function makes it easier to pass the desired view into
--   your splices.
runChildren :: Monad n => Splice n

-- | Binds a list of splices before using the children of the spliced node
--   as a view.
runChildrenWith :: Monad n => Splices (Splice n) -> Splice n

-- | Wrapper around runChildrenWith that applies a transformation function
--   to the second item in each of the tuples before calling
--   runChildrenWith.
runChildrenWithTrans :: Monad n => (b -> Splice n) -> Splices b -> Splice n

-- | Like runChildrenWith but using constant templates rather than dynamic
--   splices.
runChildrenWithTemplates :: Monad n => Splices Template -> Splice n

-- | Like runChildrenWith but using literal text rather than dynamic
--   splices.
runChildrenWithText :: Monad n => Splices Text -> Splice n

-- | Maps a splice generating function over a list and concatenates the
--   results. This function now has a more general type signature so it
--   works with both compiled and interpreted splices. The old type
--   signature was this:
--   
--   <pre>
--   mapSplices :: (Monad n)
--           =&gt; (a -&gt; Splice n n)
--           -&gt; [a]
--           -&gt; Splice n n
--   </pre>
mapSplices :: (Monad m, Monoid b) => (a -> m b) -> [a] -> m b

-- | Stops the recursive processing of splices. Consider the following
--   example:
--   
--   <pre>
--   &lt;foo&gt;
--     &lt;bar&gt;
--       ...
--     &lt;/bar&gt;
--   &lt;/foo&gt;
--   </pre>
--   
--   Assume that <tt>"foo"</tt> is bound to a splice procedure. Running the
--   <tt>foo</tt> splice will result in a list of nodes <tt>L</tt>.
--   Normally <tt>foo</tt> will recursively scan <tt>L</tt> for splices and
--   run them. If <tt>foo</tt> calls <tt>stopRecursion</tt>, <tt>L</tt>
--   will be included in the output verbatim without running any splices.
stopRecursion :: Monad m => HeistT n m ()

-- | Performs splice processing on a single node.
runNode :: Monad n => Node -> Splice n

-- | Performs splice processing on a list of attributes. This is useful in
--   situations where you need to stop recursion, but still run splice
--   processing on the node's attributes.
runAttributes :: Monad n => [(Text, Text)] -> HeistT n n [(Text, Text)]

-- | Performs splice processing on a list of nodes.
runNodeList :: Monad n => [Node] -> Splice n

-- | Looks up a template name evaluates it by calling runNodeList.
evalTemplate :: Monad n => ByteString -> HeistT n n (Maybe Template)

-- | Binds a list of constant string splices.
bindStrings :: Monad n => Splices Text -> HeistState n -> HeistState n

-- | Binds a single constant string splice.
bindString :: Monad n => Text -> Text -> HeistState n -> HeistState n

-- | Renders a template with the specified parameters. This is the function
--   to use when you want to <a>call</a> a template and pass in parameters
--   from inside a splice. If the template does not exist, this version
--   simply returns an empty list.
callTemplate :: Monad n => ByteString -> Splices (Splice n) -> HeistT n n Template

-- | Like callTemplate except the splices being bound are constant text
--   splices.
callTemplateWithText :: Monad n => ByteString -> Splices Text -> HeistT n n Template

-- | Renders a template from the specified HeistState to a <a>Builder</a>.
--   The MIME type returned is based on the detected character encoding,
--   and whether the root template was an HTML or XML format template. It
--   will always be <tt>text<i>html@ or @text</i>xml</tt>. If a more
--   specific MIME type is needed for a particular XML application, it must
--   be provided by the application.
renderTemplate :: Monad n => HeistState n -> ByteString -> n (Maybe (Builder, MIMEType))

-- | Renders a template with the specified arguments passed to it. This is
--   a convenience function for the common pattern of calling
--   renderTemplate after using bindString, bindStrings, or bindSplice to
--   set up the arguments to the template.
renderWithArgs :: Monad n => Splices Text -> HeistState n -> ByteString -> n (Maybe (Builder, MIMEType))

module Heist.Splices.Apply

-- | Default name for the apply splice.
applyTag :: Text

-- | Default attribute name for the apply tag.
applyAttr :: Text
rawApply :: Monad n => Text -> [Node] -> Maybe FilePath -> TPath -> [Node] -> Splice n

-- | Applies a template as if the supplied nodes were the children of the
--   <a>apply</a> tag.
applyNodes :: MonadIO n => Template -> Text -> Splice n

-- | Implementation of the apply splice.
applyImpl :: MonadIO n => Splice n

-- | This splice crashes with an error message. Its purpose is to provide a
--   load-time warning to anyone still using the old content tag in their
--   templates. In Heist 0.10, tho content tag was replaced by two separate
--   apply-content and bind-content tags used by the apply and bind splices
--   respectively.
deprecatedContentCheck :: Monad m => Splice m

module Heist.Splices.Bind

-- | Default name for the bind splice.
bindTag :: Text

-- | Default attribute name for the bind tag.
bindAttr :: Text

-- | Implementation of the bind splice.
bindImpl :: MonadIO n => Splice n


-- | The "cache" splice ensures that its contents are cached and only
--   evaluated periodically. The cached contents are returned every time
--   the splice is referenced.
--   
--   Use the ttl attribute to set the amount of time between reloads. The
--   ttl value should be a positive integer followed by a single character
--   specifying the units. Valid units are a single letter abbreviation for
--   one of seconds, minutes, hours, days, and weeks. If the ttl string is
--   invalid or the ttl attribute is not specified, the cache is never
--   refreshed unless explicitly cleared with clearCacheTagState. The
--   compiled splice version of the cache tag does not require a cache tag
--   state, so clearCacheTagState will not work for compiled cache tags.
module Heist.Splices.Cache

-- | State for storing cache tag information
data CacheTagState

-- | This is the splice that actually does the work. You should bind it to
--   the same tag name as you bound the splice returned by mkCacheTag
--   otherwise it won't work and you'll get runtime errors.
cacheImpl :: MonadIO n => CacheTagState -> Splice n

-- | This is the compiled splice version of cacheImpl.
cacheImplCompiled :: MonadIO n => CacheTagState -> Splice n

-- | Returns items necessary to set up a "cache" tag. The cache tag cannot
--   be bound automatically with the other default Heist tags. This is
--   because this function also returns CacheTagState, so the user will be
--   able to clear it with the <a>clearCacheTagState</a> function.
--   
--   This function returns a splice and a CacheTagState. The splice is of
--   type <tt>Splice IO</tt> because it has to be bound as a load time
--   preprocessing splice. Haskell's type system won't allow you to screw
--   up and pass this splice as the wrong argument to initHeist.
mkCacheTag :: IO (Splice IO, CacheTagState)

-- | Clears the cache tag state.
clearCacheTagState :: CacheTagState -> IO ()

module Heist.Splices.Html

-- | Name for the html splice.
htmlTag :: Text

-- | The html splice runs all children and then traverses the returned node
--   forest removing all head nodes. Then it merges them all and prepends
--   it to the html tag's child list.
htmlImpl :: Monad n => Splice n

-- | Extracts all heads from a node tree.
extractHeads :: Node -> ([Node], Maybe Node)

module Heist.Splices.Ignore

-- | Default name for the ignore splice.
ignoreTag :: Text

-- | The ignore tag and everything it surrounds disappears in the rendered
--   output.
ignoreImpl :: Monad m => Splice m


-- | The "markdown" splice formats markdown content as HTML and inserts it
--   into the document.
--   
--   If the file attribute is present the contents of the tag is ignored
--   and the file specified is converted to HTML.
--   
--   Otherwise the non-markup children of the tag are processed as markdown
--   and converted to HTML.
--   
--   This splice requires that the "pandoc" executable is in your path.
module Heist.Splices.Markdown
data PandocMissingException
PandocMissingException :: PandocMissingException
data MarkdownException
MarkdownException :: ByteString -> MarkdownException
data NoMarkdownFileException
NoMarkdownFileException :: NoMarkdownFileException

-- | Default name for the markdown splice.
markdownTag :: Text

-- | Implementation of the markdown splice.
markdownSplice :: MonadIO m => Splice m
pandoc :: FilePath -> FilePath -> FilePath -> IO ByteString
pandocBS :: FilePath -> ByteString -> IO ByteString
readProcessWithExitCode' :: FilePath -> [String] -> ByteString -> IO (ExitCode, ByteString, ByteString)
instance Typeable PandocMissingException
instance Typeable MarkdownException
instance Typeable NoMarkdownFileException
instance Exception NoMarkdownFileException
instance Show NoMarkdownFileException
instance Exception MarkdownException
instance Show MarkdownException
instance Exception PandocMissingException
instance Show PandocMissingException

module Heist.Splices

-- | Run the splice contents if given condition is True, make splice
--   disappear if not.
ifISplice :: Monad m => Bool -> Splice m

-- | Function for constructing if splices that use a runtime predicate
--   function to determine whether the node's children should be rendered.
ifCSplice :: Monad m => (t -> Bool) -> RuntimeSplice m t -> Splice m

module Heist.Splices.BindStrict

-- | Default name for the bind splice.
bindStrictTag :: Text

-- | Implementation of the bind splice.
bindStrictImpl :: MonadIO n => Splice n

module Heist.Splices.Json

-- | This splice binds convenience tags for the given JSON (or
--   JSON-convertible) value and runs the tag's child nodes using the new
--   bindings.
--   
--   <i>Tags bound when you pass in an object</i>
--   
--   Tags bound for an object looking like this:
--   
--   <pre>
--   { "k_1": v_1, ..., "k_N": v_N }
--   </pre>
--   
--   <tt>&lt;value:{k_i}&gt;</tt> -- treats v_i as text
--   <tt>&lt;snippet:{k_i}&gt;</tt> -- treats v_i as HTML
--   <tt>&lt;with:{k_i}&gt;</tt> -- explodes v_i and runs its children
--   
--   <tt>&lt;value var="foo.bar.baz"/&gt;</tt> -- walks the JSON tree to
--   find "foo.bar.baz", and interprets it as a string <tt>&lt;snippet
--   var="foo.bar.baz"/&gt;</tt> <tt>&lt;with
--   var="foo.bar.baz"&gt;...&lt;with&gt;</tt>
--   
--   <i>Tags bound when you pass in anything else</i>
--   
--   <tt>&lt;value/&gt;</tt> -- the given JSON value, as a string
--   <tt>&lt;snippet/&gt;</tt> -- the given JSON value, parsed and spliced
--   in as HTML
bindJson :: (ToJSON a, Monad n) => a -> Splice n


-- | This module defines the core data types used by Heist. In practice you
--   will also want to import one or both of <a>Heist.Compiled</a> or
--   <a>Heist.Interpreted</a> to get functions needed for writing splices.
--   
--   The Heist template system allows you to build custom HTML and XML
--   based markup languages. With Heist you can define your own
--   domain-specific tags implemented with Haskell and use them in your
--   templates.
module Heist

-- | Loads templates from disk. This function returns just a template map
--   so you can load multiple directories and combine the maps before
--   initializing your HeistState.
loadTemplates :: FilePath -> EitherT [String] IO TemplateRepo

-- | Reloads all the templates an an existing TemplateRepo.
reloadTemplates :: TemplateRepo -> EitherT [String] IO TemplateRepo

-- | Adds a path prefix to a templates in a map returned by loadTemplates.
--   If you want to add multiple levels of directories, separate them with
--   slashes as in <a>foo/bar</a>. Using an empty string as a path prefix
--   will leave the map unchanged.
addTemplatePathPrefix :: ByteString -> TemplateRepo -> TemplateRepo

-- | This is the main Heist initialization function. You pass in a map of
--   all templates and all of your splices and it constructs and returns a
--   HeistState.
--   
--   We don't provide functions to add either type of loadtime splices to
--   your HeistState after initHeist because it doesn't make any sense
--   unless you re-initialize all templates with the new splices. If you
--   add any old-style runtime heist splices after calling this function,
--   they will still work fine if you use Heist.Interpreted.renderTemplate.
--   If you add any templates later, then those templates will be available
--   for interpreted rendering, but not for compiled rendering.
--   
--   In the past you could add templates to your HeistState after
--   initialization using its Monoid instance. Due to implementation
--   details, this is no longer possible. All of your templates must be
--   known when you call this function.
initHeist :: Monad n => HeistConfig n -> EitherT [String] IO (HeistState n)

-- | Wrapper around initHeist that also sets up a cache tag. It sets up
--   both compiled and interpreted versions of the cache tag splices. If
--   you need to configure the cache tag differently than how this function
--   does it, you will still probably want to pattern your approach after
--   this function's implementation.
initHeistWithCacheTag :: MonadIO n => HeistConfig n -> EitherT [String] IO (HeistState n, CacheTagState)

-- | The built-in set of static splices. All the splices that used to be
--   enabled by default are included here. To get the normal Heist behavior
--   you should include these in the hcLoadTimeSplices list in your
--   HeistConfig. If you are using interpreted splice mode, then you might
--   also want to bind the <a>deprecatedContentCheck</a> splice to the
--   content tag as a load time splice.
defaultInterpretedSplices :: MonadIO m => Splices (Splice m)

-- | The built-in set of splices that you should use in compiled splice
--   mode. This list includes everything from
--   <a>defaultInterpretedSplices</a> plus a splice for the content tag
--   that errors out when it sees any instance of the old content tag,
--   which has now been moved to two separate tags called apply-content and
--   bind-content.
defaultLoadTimeSplices :: MonadIO m => Splices (Splice m)
data HeistConfig m
HeistConfig :: Splices (Splice m) -> Splices (Splice IO) -> Splices (Splice m) -> Splices (AttrSplice m) -> [TemplateLocation] -> HeistConfig m

-- | Interpreted splices are the splices that Heist has always had. They
--   return a list of nodes and are processed at runtime.
hcInterpretedSplices :: HeistConfig m -> Splices (Splice m)

-- | Load time splices are like interpreted splices because they return a
--   list of nodes. But they are like compiled splices because they are
--   processed once at load time. All of Heist's built-in splices should be
--   used as load time splices.
hcLoadTimeSplices :: HeistConfig m -> Splices (Splice IO)

-- | Compiled splices return a DList of Chunks and are processed at load
--   time to generate a runtime monad action that will be used to render
--   the template.
hcCompiledSplices :: HeistConfig m -> Splices (Splice m)

-- | Attribute splices are bound to attribute names and return a list of
--   attributes.
hcAttributeSplices :: HeistConfig m -> Splices (AttrSplice m)

-- | A list of all the locations that Heist should get its templates from.
hcTemplateLocations :: HeistConfig m -> [TemplateLocation]
type TemplateRepo = HashMap TPath DocumentFile

-- | An IO action for getting a template repo from this location. By not
--   just using a directory path here, we support templates loaded from a
--   database, retrieved from the network, or anything else you can think
--   of.
type TemplateLocation = EitherT [String] IO TemplateRepo

-- | A <a>Template</a> is a forest of XML nodes. Here we deviate from the
--   "single root node" constraint of well-formed XML because we want to
--   allow templates to contain document fragments that may not have a
--   single root.
type Template = [Node]

-- | Reversed list of directories. This holds the path to the template
--   currently being processed.
type TPath = [ByteString]

-- | MIME Type. The type alias is here to make the API clearer.
type MIMEType = ByteString

-- | Holds data about templates read from disk.
data DocumentFile
DocumentFile :: Document -> Maybe FilePath -> DocumentFile
dfDoc :: DocumentFile -> Document
dfFile :: DocumentFile -> Maybe FilePath

-- | Type alias for attribute splices. The function parameter is the value
--   of the bound attribute splice. The return value is a list of attribute
--   key/value pairs that get substituted in the place of the bound
--   attribute.
type AttrSplice m = Text -> RuntimeSplice m [(Text, Text)]

-- | Monad used for runtime splice execution.
data RuntimeSplice m a

-- | Opaque type representing pieces of output from compiled splices.
data Chunk m

-- | Holds all the state information needed for template processing. You
--   will build a <tt>HeistState</tt> using <tt>initHeist</tt> and any of
--   Heist's <tt>HeistState -&gt; HeistState</tt> "filter" functions. Then
--   you use the resulting <tt>HeistState</tt> in calls to
--   <tt>renderTemplate</tt>.
--   
--   m is the runtime monad
data HeistState m

-- | Gets the names of all the templates defined in a HeistState.
templateNames :: HeistState m -> [TPath]

-- | Gets the names of all the templates defined in a HeistState.
compiledTemplateNames :: HeistState m -> [TPath]

-- | Returns <a>True</a> if the given template can be found in the heist
--   state.
hasTemplate :: ByteString -> HeistState n -> Bool

-- | Gets the names of all the interpreted splices defined in a HeistState.
spliceNames :: HeistState m -> [Text]

-- | Gets the names of all the compiled splices defined in a HeistState.
compiledSpliceNames :: HeistState m -> [Text]

-- | HeistT is the monad transformer used for splice processing. HeistT
--   intentionally does not expose any of its functionality via MonadState
--   or MonadReader functions. We define passthrough instances for the most
--   common types of monads. These instances allow the user to use HeistT
--   in a monad stack without needing calls to <a>lift</a>.
--   
--   <tt>n</tt> is the runtime monad (the parameter to HeistState).
--   
--   <tt>m</tt> is the monad being run now. In this case, "now" is a
--   variable concept. The type <tt>HeistT n n</tt> means that "now" is
--   runtime. The type <tt>HeistT n IO</tt> means that "now" is
--   <tt>IO</tt>, and more importantly it is NOT runtime. In Heist, the
--   rule of thumb is that <tt>IO</tt> means load time and <tt>n</tt> means
--   runtime.
data HeistT n m a

-- | Evaluates a template monad as a computation in the underlying monad.
evalHeistT :: Monad m => HeistT n m a -> Node -> HeistState n -> m a

-- | Gets the node currently being processed.
--   
--   <pre>
--   &lt;speech author="Shakespeare"&gt;
--     To sleep, perchance to dream.
--   &lt;/speech&gt;
--   </pre>
--   
--   When you call <tt>getParamNode</tt> inside the code for the
--   <tt>speech</tt> splice, it returns the Node for the <tt>speech</tt>
--   tag and its children. <tt>getParamNode &gt;&gt;= childNodes</tt>
--   returns a list containing one <tt>TextNode</tt> containing part of
--   Hamlet's speech. <tt>liftM (getAttribute "author") getParamNode</tt>
--   would return <tt>Just <a>Shakespeare</a></tt>.
getParamNode :: Monad m => HeistT n m Node

-- | Gets the current context
getContext :: Monad m => HeistT n m TPath

-- | Gets the full path to the file holding the template currently being
--   processed. Returns Nothing if the template is not associated with a
--   file on disk or if there is no template being processed.
getTemplateFilePath :: Monad m => HeistT n m (Maybe FilePath)

-- | HeistT's <a>local</a>.
localParamNode :: Monad m => (Node -> Node) -> HeistT n m a -> HeistT n m a

-- | HeistT's <a>gets</a>.
getsHS :: Monad m => (HeistState n -> r) -> HeistT n m r

-- | HeistT's <a>get</a>.
getHS :: Monad m => HeistT n m (HeistState n)

-- | HeistT's <a>put</a>.
putHS :: Monad m => HeistState n -> HeistT n m ()

-- | HeistT's <a>modify</a>.
modifyHS :: Monad m => (HeistState n -> HeistState n) -> HeistT n m ()

-- | Restores the HeistState. This function is almost like putHS except it
--   preserves the current doctypes. You should use this function instead
--   of <tt>putHS</tt> to restore an old state. This was needed because
--   doctypes needs to be in a <a>global scope</a> as opposed to the
--   template call <a>local scope</a> of state items such as
--   recursionDepth, curContext, and spliceMap.
restoreHS :: Monad m => HeistState n -> HeistT n m ()

-- | Abstracts the common pattern of running a HeistT computation with a
--   modified heist state.
localHS :: Monad m => (HeistState n -> HeistState n) -> HeistT n m a -> HeistT n m a

-- | Reads an HTML template from disk.
getDoc :: String -> IO (Either String DocumentFile)

-- | Reads an XML template from disk.
getXMLDoc :: String -> IO (Either String DocumentFile)

-- | If Heist is running in fail fast mode, then this function will throw
--   an exception with the second argument as the error message. Otherwise,
--   the first argument will be executed to represent silent failure.
--   
--   This behavior allows us to fail quickly if an error crops up during
--   load-time splice processing or degrade more gracefully if the error
--   occurs while a user request is being processed.
orError :: Monad m => HeistT n m b -> String -> HeistT n m b
instance Monoid (HeistConfig m)


-- | This module defines a TemplateDirectory data structure for convenient
--   interaction with templates within web apps.
module Heist.TemplateDirectory

-- | Structure representing a template directory.
data TemplateDirectory n

-- | Creates and returns a new <a>TemplateDirectory</a> wrapped in an
--   Either for error handling.
newTemplateDirectory :: MonadIO n => FilePath -> HeistConfig n -> EitherT [String] IO (TemplateDirectory n)

-- | Creates and returns a new <a>TemplateDirectory</a>, using the monad's
--   fail function on error.
newTemplateDirectory' :: MonadIO n => FilePath -> HeistConfig n -> IO (TemplateDirectory n)

-- | Gets the <a>HeistState</a> from a TemplateDirectory.
getDirectoryHS :: MonadIO n => TemplateDirectory n -> IO (HeistState n)

-- | Clears the TemplateDirectory's cache tag state.
getDirectoryCTS :: TemplateDirectory n -> IO CacheTagState

-- | Clears cached content and reloads templates from disk.
reloadTemplateDirectory :: MonadIO n => TemplateDirectory n -> IO (Either String ())
