diff options
| author | Albert Krewinkel <[email protected]> | 2022-01-02 15:28:59 +0100 |
|---|---|---|
| committer | John MacFarlane <[email protected]> | 2022-01-02 11:55:02 -0800 |
| commit | efdba79ad18fcbe33992878b02be25f8e9616b0c (patch) | |
| tree | 2c6f82d499bd12105f34de14d4fcf957c93ce27d /src/Text | |
| parent | 60fc05e2ce2dc4b0191ee98daccf301a065e2dae (diff) | |
Lua writer: allow variables to be set via second return value of `Doc`
New templates variables can be added by giving variable-value pairs as a
second return value of the global function `Doc`.
Example:
function Doc (body, meta, vars)
vars.date = vars.date or os.date '%B %e, %Y'
return body, vars
end
Closes: #6731
Diffstat (limited to 'src/Text')
| -rw-r--r-- | src/Text/Pandoc/Writers/Custom.hs | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/src/Text/Pandoc/Writers/Custom.hs b/src/Text/Pandoc/Writers/Custom.hs index d13fbfb24..95e7355ae 100644 --- a/src/Text/Pandoc/Writers/Custom.hs +++ b/src/Text/Pandoc/Writers/Custom.hs @@ -16,20 +16,23 @@ Conversion of 'Pandoc' documents to custom markup using a Lua writer. -} module Text.Pandoc.Writers.Custom ( writeCustom ) where +import Control.Applicative (optional) import Control.Arrow ((***)) import Control.Exception import Control.Monad (when) import Data.List (intersperse) import qualified Data.Map as M +import Data.Maybe (fromMaybe) import qualified Data.Text as T import Data.Text (Text, pack) import HsLua as Lua hiding (Operation (Div), render) import HsLua.Class.Peekable (PeekError) import Text.DocLayout (render, literal) +import Text.DocTemplates (Context) import Control.Monad.IO.Class (MonadIO) import Text.Pandoc.Definition import Text.Pandoc.Lua (Global (..), runLua, setGlobals) -import Text.Pandoc.Lua.Util (addField, dofileWithTraceback) +import Text.Pandoc.Lua.Util (addField, dofileWithTraceback, peekViaJSON) import Text.Pandoc.Options import Text.Pandoc.Class (PandocMonad) import Text.Pandoc.Templates (renderTemplate) @@ -98,12 +101,12 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do -- to handle this more gracefully): when (stat /= Lua.OK) Lua.throwErrorAsException - rendered <- docToCustom opts doc - context <- metaToContext opts - (fmap (literal . pack) . blockListToCustom) - (fmap (literal . pack) . inlineListToCustom) - meta - return (pack rendered, context) + (rendered, context) <- docToCustom opts doc + metaContext <- metaToContext opts + (fmap (literal . pack) . blockListToCustom) + (fmap (literal . pack) . inlineListToCustom) + meta + return (pack rendered, context <> metaContext) case res of Left msg -> throw msg Right (body, context) -> return $ @@ -113,10 +116,19 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do renderTemplate tpl $ setField "body" body context docToCustom :: forall e. PeekError e - => WriterOptions -> Pandoc -> LuaE e String + => WriterOptions -> Pandoc -> LuaE e (String, Context Text) docToCustom opts (Pandoc (Meta metamap) blocks) = do body <- blockListToCustom blocks - invoke @e "Doc" body (fmap (Stringify @e) metamap) (writerVariables opts) + -- invoke doesn't work with multiple return values, so we have to call + -- `Doc` manually. + Lua.getglobal "Doc" -- function + push body -- argument 1 + push (fmap (Stringify @e) metamap) -- argument 2 + push (writerVariables opts) -- argument 3 + call 3 2 + rendered <- peek (nth 2) -- first return value + context <- forcePeek . optional $ peekViaJSON top -- snd return value + return (rendered, fromMaybe mempty context) -- | Convert Pandoc block element to Custom. blockToCustom :: forall e. PeekError e |
