    {-# LANGUAGE OverloadedStrings #-}
    {- |
       Module      : Text.Pandoc.Lua.Module.Template
       Copyright   : Copyright © 2022-2024 Albert Krewinkel, John MacFarlane
       License     : GNU GPL, version 2 or above
       Maintainer  : Albert Krewinkel <albert+pandoc@tarleb.com>

    Lua module to handle pandoc templates.
    -}
    module Text.Pandoc.Lua.Module.Template
      ( documentedModule
      ) where

    import Data.Version (makeVersion)
    import HsLua
    import HsLua.Module.DocLayout (peekDoc, pushDoc)
    import Text.Pandoc.Error (PandocError)
    import Text.Pandoc.Lua.Marshal.AST (peekMeta, pushBlocks, pushInlines)
    import Text.Pandoc.Lua.Marshal.Context (peekContext, pushContext)
    import Text.Pandoc.Lua.Marshal.Template (typeTemplate, peekTemplate, pushTemplate)
    import Text.Pandoc.Lua.PandocLua (PandocLua (unPandocLua), liftPandocLua)
    import Text.Pandoc.Writers.Shared (metaToContext')
    import Text.Pandoc.Templates
      ( compileTemplate, getDefaultTemplate, getTemplate, renderTemplate
      , runWithPartials, runWithDefaultPartials )

    import qualified Data.Text as T

    -- | The "pandoc.template" module.
    documentedModule :: Module PandocError
    documentedModule :: Module PandocError
    documentedModule = Module
      { moduleName :: Name
    moduleName = Name
    "pandoc.template"
      , moduleDescription :: Text
    moduleDescription = [Text] -> Text
    T.unlines
        [ Text
    "Handle pandoc templates."
        ]
      , moduleFields :: [Field PandocError]
    moduleFields = []
      , moduleOperations :: [(Operation, DocumentedFunction PandocError)]
    moduleOperations = []
      , moduleFunctions :: [DocumentedFunction PandocError]
    moduleFunctions = [DocumentedFunction PandocError]
    functions
      , moduleTypeInitializers :: [LuaE PandocError Name]
    moduleTypeInitializers = [DocumentedTypeWithList PandocError (Template Text) Void
    -> LuaE PandocError Name
    forall e a itemtype.
    LuaError e =>
    DocumentedTypeWithList e a itemtype -> LuaE e Name
    initType DocumentedTypeWithList PandocError (Template Text) Void
    forall e. LuaError e => DocumentedType e (Template Text)
    typeTemplate]
      }

    -- | Template module functions.
    functions :: [DocumentedFunction PandocError]
    functions :: [DocumentedFunction PandocError]
    functions =
      [ Name
    -> (Template Text -> Context Text -> LuaE PandocError (Doc Text))
    -> HsFnPrecursor
         PandocError
         (Template Text -> Context Text -> LuaE PandocError (Doc Text))
    forall a e. Name -> a -> HsFnPrecursor e a
    defun Name
    "apply"
         ### liftPure2 renderTemplate
         HsFnPrecursor
      PandocError
      (Template Text -> Context Text -> LuaE PandocError (Doc Text))
    -> Parameter PandocError (Template Text)
    -> HsFnPrecursor
         PandocError (Context Text -> LuaE PandocError (Doc Text))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Peeker PandocError (Template Text)
    -> TypeSpec
    -> Text
    -> Text
    -> Parameter PandocError (Template Text)
    forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
    parameter Peeker PandocError (Template Text)
    peekTemplate TypeSpec
    "Template" Text
    "template" Text
    "template to apply"
         HsFnPrecursor
      PandocError (Context Text -> LuaE PandocError (Doc Text))
    -> Parameter PandocError (Context Text)
    -> HsFnPrecursor PandocError (LuaE PandocError (Doc Text))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Peeker PandocError (Context Text)
    -> TypeSpec -> Text -> Text -> Parameter PandocError (Context Text)
    forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
    parameter Peeker PandocError (Context Text)
    forall e. LuaError e => Peeker e (Context Text)
    peekContext TypeSpec
    "table" Text
    "context" Text
    "variable values"
         HsFnPrecursor PandocError (LuaE PandocError (Doc Text))
    -> FunctionResults PandocError (Doc Text)
    -> DocumentedFunction PandocError
    forall e a.
    HsFnPrecursor e (LuaE e a)
    -> FunctionResults e a -> DocumentedFunction e
    =#> Pusher PandocError (Doc Text)
    -> TypeSpec -> Text -> FunctionResults PandocError (Doc Text)
    forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
    functionResult Pusher PandocError (Doc Text)
    forall e. LuaError e => Pusher e (Doc Text)
    pushDoc TypeSpec
    "Doc" Text
    "rendered template"
         #? T.unlines
         [ "Applies a context with variable assignments to a template,"
         , "returning the rendered template. The `context` parameter must be a"
         , "table with variable names as keys and [[Doc]], string, boolean, or"
         , "table as values, where the table can be either be a list of the"
         , "aforementioned types, or a nested context."
         ]
        DocumentedFunction PandocError
    -> Version -> DocumentedFunction PandocError
    forall e. DocumentedFunction e -> Version -> DocumentedFunction e
    `since` [Int] -> Version
    makeVersion [Int
    3,Int
    0]

      , Name
    -> (Text
        -> Maybe String
        -> LuaE PandocError (Either String (Template Text)))
    -> HsFnPrecursor
         PandocError
         (Text
          -> Maybe String
          -> LuaE PandocError (Either String (Template Text)))
    forall a e. Name -> a -> HsFnPrecursor e a
    defun Name
    "compile"
         ### (\template mfilepath -> unPandocLua $
               case mfilepath of
                 Just fp -> runWithPartials (compileTemplate fp template)
                 Nothing -> runWithDefaultPartials
                            (compileTemplate "templates/default" template))
         HsFnPrecursor
      PandocError
      (Text
       -> Maybe String
       -> LuaE PandocError (Either String (Template Text)))
    -> Parameter PandocError Text
    -> HsFnPrecursor
         PandocError
         (Maybe String -> LuaE PandocError (Either String (Template Text)))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Peeker PandocError Text
    -> TypeSpec -> Text -> Text -> Parameter PandocError Text
    forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
    parameter Peeker PandocError Text
    forall e. Peeker e Text
    peekText TypeSpec
    "string" Text
    "template" Text
    "template string"
         HsFnPrecursor
      PandocError
      (Maybe String -> LuaE PandocError (Either String (Template Text)))
    -> Parameter PandocError (Maybe String)
    -> HsFnPrecursor
         PandocError (LuaE PandocError (Either String (Template Text)))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Parameter PandocError String
    -> Parameter PandocError (Maybe String)
    forall e a. Parameter e a -> Parameter e (Maybe a)
    opt (Text -> Text -> Parameter PandocError String
    forall e. Text -> Text -> Parameter e String
    stringParam Text
    "templates_path"
                  (Text
    "parameter to determine a default path and extension for " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                   Text
    "partials; uses the data files templates path by default."))
         HsFnPrecursor
      PandocError (LuaE PandocError (Either String (Template Text)))
    -> FunctionResults PandocError (Either String (Template Text))
    -> DocumentedFunction PandocError
    forall e a.
    HsFnPrecursor e (LuaE e a)
    -> FunctionResults e a -> DocumentedFunction e
    =#> Pusher PandocError (Either String (Template Text))
    -> TypeSpec
    -> Text
    -> FunctionResults PandocError (Either String (Template Text))
    forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
    functionResult ((String -> LuaE PandocError ())
    -> (Template Text -> LuaE PandocError ())
    -> Pusher PandocError (Either String (Template Text))
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either String -> LuaE PandocError ()
    forall e a. LuaError e => String -> LuaE e a
    failLua Template Text -> LuaE PandocError ()
    forall e. LuaError e => Pusher e (Template Text)
    pushTemplate) TypeSpec
    "Template"
               Text
    "compiled template"
         #? T.unlines
         [ "Compiles a template string into a [[Template]] object usable by"
         , "pandoc."
         , ""
         , "If the `templates_path` parameter is specified, then it should be the"
         , "file path associated with the template. It is used when checking"
         , "for partials. Partials will be taken only from the default data"
         , "files if this parameter is omitted."
         , ""
         , "An error is raised if compilation fails."
         ]
        DocumentedFunction PandocError
    -> Version -> DocumentedFunction PandocError
    forall e. DocumentedFunction e -> Version -> DocumentedFunction e
    `since` [Int] -> Version
    makeVersion [Int
    2,Int
    17]

      , Name
    -> (Maybe Text -> LuaE PandocError Text)
    -> HsFnPrecursor PandocError (Maybe Text -> LuaE PandocError Text)
    forall a e. Name -> a -> HsFnPrecursor e a
    defun Name
    "default"
         ### (\mformat -> unPandocLua $ do
               let getFORMAT = liftPandocLua $ do
                     getglobal "FORMAT"
                     forcePeek $ peekText top `lastly` pop 1
               format <- maybe getFORMAT pure mformat
               getDefaultTemplate format)
         HsFnPrecursor PandocError (Maybe Text -> LuaE PandocError Text)
    -> Parameter PandocError (Maybe Text)
    -> HsFnPrecursor PandocError (LuaE PandocError Text)
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Parameter PandocError Text -> Parameter PandocError (Maybe Text)
    forall e a. Parameter e a -> Parameter e (Maybe a)
    opt (Text -> Text -> Parameter PandocError Text
    forall e. Text -> Text -> Parameter e Text
    textParam Text
    "writer"
                  (Text
    "name of the writer for which the template should be " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                   Text
    "retrieved; defaults to the global `FORMAT`."))
         HsFnPrecursor PandocError (LuaE PandocError Text)
    -> FunctionResults PandocError Text
    -> DocumentedFunction PandocError
    forall e a.
    HsFnPrecursor e (LuaE e a)
    -> FunctionResults e a -> DocumentedFunction e
    =#> Pusher PandocError Text
    -> TypeSpec -> Text -> FunctionResults PandocError Text
    forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
    functionResult Pusher PandocError Text
    forall e. Pusher e Text
    pushText TypeSpec
    "string" Text
    "raw template"
        #? T.unlines
        [ "Returns the default template for a given writer as a string. An"
        , "error is thrown if no such template can be found."
        ]
        DocumentedFunction PandocError
    -> Version -> DocumentedFunction PandocError
    forall e. DocumentedFunction e -> Version -> DocumentedFunction e
    `since` [Int] -> Version
    makeVersion [Int
    2,Int
    17]

      , Name
    -> (String -> LuaE PandocError Text)
    -> HsFnPrecursor PandocError (String -> LuaE PandocError Text)
    forall a e. Name -> a -> HsFnPrecursor e a
    defun Name
    "get"
         ### (unPandocLua . getTemplate)
         HsFnPrecursor PandocError (String -> LuaE PandocError Text)
    -> Parameter PandocError String
    -> HsFnPrecursor PandocError (LuaE PandocError Text)
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Text -> Text -> Parameter PandocError String
    forall e. Text -> Text -> Parameter e String
    stringParam Text
    "filename" Text
    "name of the template"
         HsFnPrecursor PandocError (LuaE PandocError Text)
    -> FunctionResults PandocError Text
    -> DocumentedFunction PandocError
    forall e a.
    HsFnPrecursor e (LuaE e a)
    -> FunctionResults e a -> DocumentedFunction e
    =#> Text -> FunctionResults PandocError Text
    forall e. Text -> FunctionResults e Text
    textResult Text
    "content of template file"
         #? T.unlines
         [ "Retrieve text for a template."
         , ""
         , "This function first checks the resource paths for a file of this"
         , "name; if none is found, the `templates` directory in the user data"
         , "directory is checked.  Returns the content of the file, or throws"
         , "an error if no file is found."
         ]
        DocumentedFunction PandocError
    -> Version -> DocumentedFunction PandocError
    forall e. DocumentedFunction e -> Version -> DocumentedFunction e
    `since` [Int] -> Version
    makeVersion [Int
    3,Int
    2,Int
    1]

      , Name
    -> (Meta
        -> StackIndex -> StackIndex -> LuaE PandocError (Context Text))
    -> HsFnPrecursor
         PandocError
         (Meta
          -> StackIndex -> StackIndex -> LuaE PandocError (Context Text))
    forall a e. Name -> a -> HsFnPrecursor e a
    defun Name
    "meta_to_context"
         ### (\meta blockWriterIdx inlineWriterIdx -> unPandocLua $ do
                 let blockWriter blks = liftPandocLua $ do
                       pushvalue blockWriterIdx
                       pushBlocks blks
                       callTrace 1 1
                       forcePeek $ peekDoc top
                 let inlineWriter blks = liftPandocLua $ do
                       pushvalue inlineWriterIdx
                       pushInlines blks
                       callTrace 1 1
                       forcePeek $ peekDoc top
                 metaToContext' blockWriter inlineWriter meta)
         HsFnPrecursor
      PandocError
      (Meta
       -> StackIndex -> StackIndex -> LuaE PandocError (Context Text))
    -> Parameter PandocError Meta
    -> HsFnPrecursor
         PandocError
         (StackIndex -> StackIndex -> LuaE PandocError (Context Text))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Peeker PandocError Meta
    -> TypeSpec -> Text -> Text -> Parameter PandocError Meta
    forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
    parameter Peeker PandocError Meta
    forall e. LuaError e => Peeker e Meta
    peekMeta TypeSpec
    "Meta" Text
    "meta" Text
    "document metadata"
         HsFnPrecursor
      PandocError
      (StackIndex -> StackIndex -> LuaE PandocError (Context Text))
    -> Parameter PandocError StackIndex
    -> HsFnPrecursor
         PandocError (StackIndex -> LuaE PandocError (Context Text))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Peeker PandocError StackIndex
    -> TypeSpec -> Text -> Text -> Parameter PandocError StackIndex
    forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
    parameter Peeker PandocError StackIndex
    forall a. a -> Peek PandocError a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure TypeSpec
    "function" Text
    "blocks_writer"
               Text
    "converter from [[Blocks]] to [[Doc]] values"
         HsFnPrecursor
      PandocError (StackIndex -> LuaE PandocError (Context Text))
    -> Parameter PandocError StackIndex
    -> HsFnPrecursor PandocError (LuaE PandocError (Context Text))
    forall e a b.
    HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
    <#> Peeker PandocError StackIndex
    -> TypeSpec -> Text -> Text -> Parameter PandocError StackIndex
    forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
    parameter Peeker PandocError StackIndex
    forall a. a -> Peek PandocError a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure TypeSpec
    "function" Text
    "inlines_writer"
               Text
    "converter from [[Inlines]] to [[Doc]] values"
         HsFnPrecursor PandocError (LuaE PandocError (Context Text))
    -> FunctionResults PandocError (Context Text)
    -> DocumentedFunction PandocError
    forall e a.
    HsFnPrecursor e (LuaE e a)
    -> FunctionResults e a -> DocumentedFunction e
    =#> Pusher PandocError (Context Text)
    -> TypeSpec -> Text -> FunctionResults PandocError (Context Text)
    forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
    functionResult Pusher PandocError (Context Text)
    forall e. LuaError e => Pusher e (Context Text)
    pushContext TypeSpec
    "table" Text
    "template context"
         #? T.unlines
         [ "Creates template context from the document's [[Meta]] data, using the"
         , "given functions to convert [[Blocks]] and [[Inlines]] to [[Doc]]"
         , "values."
         ]
        DocumentedFunction PandocError
    -> Version -> DocumentedFunction PandocError
    forall e. DocumentedFunction e -> Version -> DocumentedFunction e
    `since` [Int] -> Version
    makeVersion [Int
    3,Int
    0]
      ]