aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Krewinkel <[email protected]>2022-10-12 11:03:42 +0200
committerJohn MacFarlane <[email protected]>2022-10-12 10:16:01 -0700
commit14c7b5db20e8864f745cc95fb71c08befe49da0c (patch)
tree388ab3ef48d0aace93117379dd8571cb7ca3e478
parent253d2e768a43c8ab3ad8e1c46b2bc4a02acec946 (diff)
Lua: add function `pandoc.template.meta_to_context`.
The functions converts Meta values to template contexts; the intended use is in combination with `pandoc.template.apply`.
-rw-r--r--doc/lua-filters.md23
-rw-r--r--pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Context.hs15
-rw-r--r--pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Template.hs32
3 files changed, 65 insertions, 5 deletions
diff --git a/doc/lua-filters.md b/doc/lua-filters.md
index 362756404..0c88433ae 100644
--- a/doc/lua-filters.md
+++ b/doc/lua-filters.md
@@ -5238,6 +5238,29 @@ Returns:
- raw template (string)
+### meta_to_context {#pandoc.template.meta_to_context}
+
+`meta_to_context (meta, blocks_writer, inlines_writer)`
+
+Creates template context from the document's [Meta]{#type-meta}
+data, using the given functions to convert [Blocks] and [Inlines]
+to [Doc] values.
+
+Parameters:
+
+`meta`
+: document metadata ([Meta])
+
+`blocks_writer`
+: converter from [Blocks] to [Doc] values (function)
+
+`inlines_writer`
+: converter from [Inlines] to [Doc] values (function)
+
+Returns:
+
+- template context (table)
+
# Module pandoc.types
Constructors for types which are not part of the pandoc AST.
diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Context.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Context.hs
index dfaa1ff87..26dffec21 100644
--- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Context.hs
+++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Context.hs
@@ -18,7 +18,7 @@ module Text.Pandoc.Lua.Marshal.Context
, pushContext
) where
-import Control.Monad ((<$!>))
+import Control.Monad (when, (<$!>))
import Data.Text (Text)
import HsLua as Lua
import HsLua.Module.DocLayout (peekDoc, pushDoc)
@@ -36,7 +36,18 @@ peekContext idx = Context <$!> peekMap peekText peekVal idx
-- | Pushes a template context to the Lua stack.
pushContext :: LuaError e => Pusher e (Context Text)
-pushContext = pushMap pushText pushVal . unContext
+pushContext ctx = do
+ pushMap pushText pushVal $ unContext ctx
+ created <- Lua.newmetatable "pandoc Context"
+ when created $ do
+ pushName "__concat"
+ pushHaskellFunction $ do
+ c1 <- forcePeek $ peekContext (nthBottom 1)
+ c2 <- forcePeek $ peekContext (nthBottom 2)
+ pushContext (c1 <> c2)
+ return 1
+ rawset (nth 3)
+ setmetatable (nth 2)
pushVal :: LuaError e => Pusher e (Val Text)
pushVal = \case
diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Template.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Template.hs
index be769e988..d84f0c6d7 100644
--- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Template.hs
+++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Template.hs
@@ -12,11 +12,13 @@ module Text.Pandoc.Lua.Module.Template
) where
import HsLua
-import HsLua.Module.DocLayout (pushDoc)
+import HsLua.Module.DocLayout (peekDoc, pushDoc)
import Text.Pandoc.Error (PandocError)
-import Text.Pandoc.Lua.Marshal.Context (peekContext)
+import Text.Pandoc.Lua.Marshal.AST (peekMeta, pushBlocks, pushInlines)
+import Text.Pandoc.Lua.Marshal.Context (peekContext, pushContext)
import Text.Pandoc.Lua.Marshal.Template (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 )
@@ -40,7 +42,7 @@ functions :: [DocumentedFunction PandocError]
functions =
[ defun "apply"
### liftPure2 renderTemplate
- <#> parameter peekTemplate "pandoc Template" "template" "template to apply"
+ <#> parameter peekTemplate "Template" "template" "template to apply"
<#> parameter peekContext "table" "context" "variable values"
=#> functionResult pushDoc "Doc" "rendered template"
#? T.unlines
@@ -74,4 +76,28 @@ functions =
=#> functionResult pushText "string"
"string representation of the writer's default template"
+ , 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."
+ ]
]