pandoc-2.18: src/Text/Pandoc/Writers/Custom.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Text.Pandoc.Writers.Custom
Copyright : 2012-2022 John MacFarlane,
License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
Conversion of 'Pandoc' documents to custom markup using
a Lua writer.
-}
module Text.Pandoc.Writers.Custom ( writeCustom ) where
import Control.Exception
import Control.Monad ((<=<))
import Data.Text (Text)
import HsLua
import Control.Monad.IO.Class (MonadIO)
import Text.Pandoc.Class (PandocMonad)
import Text.Pandoc.Definition (Pandoc (..))
import Text.Pandoc.Lua (Global (..), runLua, setGlobals)
import Text.Pandoc.Options (WriterOptions)
import qualified Text.Pandoc.Lua.Writer.Classic as Classic
-- | Convert Pandoc to custom markup.
writeCustom :: (PandocMonad m, MonadIO m)
=> FilePath -> WriterOptions -> Pandoc -> m Text
writeCustom luaFile opts doc = either throw pure <=< runLua $ do
setGlobals [ PANDOC_DOCUMENT doc
, PANDOC_SCRIPT_FILE luaFile
, PANDOC_WRITER_OPTIONS opts
]
dofileTrace luaFile >>= \case
OK -> pure ()
_ -> throwErrorAsException
-- Most classic writers contain code that throws an error if a global
-- is not present. This would break our check for the existence of a
-- "Writer" function. We resort to raw access for that reason, but
-- could also catch the error instead.
let rawgetglobal x = do
pushglobaltable
pushName x
rawget (nth 2) <* remove (nth 2) -- remove global table
rawgetglobal "Writer" >>= \case
TypeNil -> do
pop 1 -- remove nil
Classic.runCustom opts doc
_ -> do
-- Writer on top of the stack. Call it with document and writer
-- options as arguments.
push doc
push opts
callTrace 2 1
forcePeek $ peekText top