From 4c9baba0ea5552eb7d0def8a4b0733306d28191b Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Wed, 16 Sep 2026 18:01:46 +0000 Subject: [PATCH] Powerpoint writer: cache the parsed slide master in WriterEnv. getMaster re-parsed ppt/slideMasters/slideMaster1.xml on every call, and it is called several times per slide (for layouts, footers, and placeholder dimensions) -- over a hundred parses of the same file for a large presentation, about 2% of total conversion time. The master is already parsed once in presentationToArchive, so store it in a new envMaster field and have getMaster return the cached element. This is safe because envRefArchive and envDistArchive are immutable for the duration of the conversion. Co-Authored-By: Claude --- src/Text/Pandoc/Writers/Powerpoint/Output.hs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Text/Pandoc/Writers/Powerpoint/Output.hs b/src/Text/Pandoc/Writers/Powerpoint/Output.hs index 3496a6c62..c951c014e 100644 --- a/src/Text/Pandoc/Writers/Powerpoint/Output.hs +++ b/src/Text/Pandoc/Writers/Powerpoint/Output.hs @@ -133,6 +133,9 @@ data WriterEnv = WriterEnv { envRefArchive :: Archive , envInSpeakerNotes :: Bool , envSlideLayouts :: Maybe SlideLayouts , envOtherStyleIndents :: Maybe Indents + -- The parsed slide master, cached to avoid + -- re-parsing it for every slide. + , envMaster :: Maybe Element } deriving (Show) @@ -153,6 +156,7 @@ instance Default WriterEnv where , envInSpeakerNotes = False , envSlideLayouts = Nothing , envOtherStyleIndents = Nothing + , envMaster = Nothing } type SlideLayouts = SlideLayoutsOf SlideLayout @@ -687,6 +691,7 @@ presentationToArchive opts meta pres = do , envSpeakerNotesIdMap = makeSpeakerNotesMap pres , envSlideLayouts = Just layouts , envOtherStyleIndents = otherStyleIndents + , envMaster = Just master } let st = def { stMediaGlobalIds = initialGlobalIds refArchive distArchive @@ -997,9 +1002,13 @@ makeMediaEntries = do getMaster :: PandocMonad m => P m Element getMaster = do - refArchive <- asks envRefArchive - distArchive <- asks envDistArchive - getMaster' refArchive distArchive + mbMaster <- asks envMaster + case mbMaster of + Just master -> pure master + Nothing -> do + refArchive <- asks envRefArchive + distArchive <- asks envDistArchive + getMaster' refArchive distArchive getMaster' :: PandocMonad m => Archive -> Archive -> m Element getMaster' refArchive distArchive =