Skip to content

Commit

Permalink
Custom writers: fix handling of common state
Browse files Browse the repository at this point in the history
The CommonState (`PANDOC_STATE` in Lua) may change between the time that
a custom writer script is first loaded and when the writer is run.
However, the writer was always using the initial state, which led to
problems, e.g. when the mediabag was updated in a filter, as those
updates where not visible to the writer.

The state is now updated right before the writer function runs.

Fixes: #9229
  • Loading branch information
tarleb committed Jan 20, 2024
1 parent 40f84c8 commit 1fa28a3
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions pandoc-lua-engine/src/Text/Pandoc/Lua/Custom.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import Text.Pandoc.Lua.Init (runLuaWith)
import Text.Pandoc.Lua.Marshal.Format (peekExtensionsConfig)
import Text.Pandoc.Lua.Marshal.Pandoc (peekPandoc)
import Text.Pandoc.Lua.Marshal.WriterOptions (pushWriterOptions)
import Text.Pandoc.Lua.PandocLua (unPandocLua)
import Text.Pandoc.Readers (Reader (..))
import Text.Pandoc.Sources (ToSources(..))
import Text.Pandoc.Scripting (CustomComponents (..))
import Text.Pandoc.Writers (Writer (..))
import qualified Text.Pandoc.Lua.Writer.Classic as Classic
import qualified Text.Pandoc.Class as PandocMonad

-- | Convert custom markup to Pandoc.
loadCustom :: (PandocMonad m, MonadIO m)
Expand Down Expand Up @@ -80,15 +82,21 @@ loadCustom luaFile = do
pure $
if docType /= TypeFunction
then Nothing
else Just . TextWriter $ \opts doc ->
else Just . TextWriter $ \opts doc -> do
-- See TextWriter below for why the state is updated
st <- PandocMonad.getCommonState
liftIO $ withGCManagedState luaState $
Classic.runCustom @PandocError opts doc
unPandocLua (PandocMonad.putCommonState st) >>
Classic.runCustom @PandocError opts doc
_ -> Just <$!> do
-- Binary writer. Writer function is on top of the stack.
setfield registryindex writerField
pure $ ByteStringWriter $ \opts doc ->
pure $ ByteStringWriter $ \opts doc -> do
-- See TextWriter below for why the state is updated
st <- PandocMonad.getCommonState
-- Call writer with document and writer options as arguments.
liftIO $ withGCManagedState luaState $ do
unPandocLua (PandocMonad.putCommonState st)
getfield registryindex writerField
push doc
pushWriterOptions opts
Expand All @@ -97,8 +105,13 @@ loadCustom luaFile = do
_ -> Just <$!> do
-- New-type text writer. Writer function is on top of the stack.
setfield registryindex writerField
pure $ TextWriter $ \opts doc ->
pure $ TextWriter $ \opts doc -> do
-- The CommonState might have changed since the Lua file was
-- loaded. That's why the state must be updated when the
-- writer is run. (#9229)
st <- PandocMonad.getCommonState
liftIO $ withGCManagedState luaState $ do
unPandocLua (PandocMonad.putCommonState st)
getfield registryindex writerField
push doc
pushWriterOptions opts
Expand Down

0 comments on commit 1fa28a3

Please sign in to comment.