{-# 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 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 { moduleName = "pandoc.template" , moduleDescription = T.unlines [ "Handle pandoc templates." ] , moduleFields = [] , moduleOperations = [] , moduleFunctions = functions , moduleTypeInitializers = [initType typeTemplate] } -- | Template module functions. functions :: [DocumentedFunction PandocError] functions = [ defun "apply" ### liftPure2 renderTemplate <#> parameter peekTemplate "Template" "template" "template to apply" <#> parameter peekContext "table" "context" "variable values" =#> functionResult pushDoc "Doc" "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." ] `since` makeVersion [3,0] , defun "compile" ### (\template mfilepath -> unPandocLua $ case mfilepath of Just fp -> runWithPartials (compileTemplate fp template) Nothing -> runWithDefaultPartials (compileTemplate "templates/default" template)) <#> parameter peekText "string" "template" "template string" <#> opt (stringParam "templates_path" ("parameter to determine a default path and extension for " <> "partials; uses the data files templates path by default.")) =#> functionResult (either failLua pushTemplate) "Template" "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." ] `since` makeVersion [2,17] , defun "default" ### (\mformat -> unPandocLua $ do let getFORMAT = liftPandocLua $ do getglobal "FORMAT" forcePeek $ peekText top `lastly` pop 1 format <- maybe getFORMAT pure mformat getDefaultTemplate format) <#> opt (textParam "writer" ("name of the writer for which the template should be " <> "retrieved; defaults to the global `FORMAT`.")) =#> functionResult pushText "string" "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." ] `since` makeVersion [2,17] , defun "get" ### (unPandocLua . getTemplate) <#> stringParam "filename" "name of the template" =#> textResult "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." ] `since` makeVersion [3,2,1] , defun "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) <#> parameter peekMeta "Meta" "meta" "document metadata" <#> parameter pure "function" "blocks_writer" "converter from [[Blocks]] to [[Doc]] values" <#> parameter pure "function" "inlines_writer" "converter from [[Inlines]] to [[Doc]] values" =#> functionResult pushContext "table" "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." ] `since` makeVersion [3,0] ]