{-# LANGUAGE OverloadedStrings #-} {- | Module : Text.Pandoc.Lua.Module.Template Copyright : Copyright © 2022-2023 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, renderTemplate , runWithPartials, runWithDefaultPartials ) import qualified Data.Text as T -- | The "pandoc.template" module. documentedModule :: Module PandocError documentedModule = Module { moduleName = "pandoc.template" , moduleDescription = T.unlines [ "Lua functions for 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 "templ_path" "template path") =#> functionResult (either failLua pushTemplate) "pandoc Template" "compiled template" `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" "writer for which the template should be returned.") =#> functionResult pushText "string" "string representation of the writer's default template" `since` makeVersion [2,17] , 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]{#type-meta}" , "data, using the given functions to convert [Blocks] and [Inlines]" , "to [Doc] values." ] `since` makeVersion [3,0] ]