@@ -110,6 +110,8 @@ import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
110110import Text.Pandoc.Shared
111111import Text.Parsec.Pos
112112
113+-- import Debug.Trace (traceShowId)
114+
113115newtype DottedNum = DottedNum [Int]
114116 deriving (Show)
115117
@@ -231,7 +233,7 @@ rawLaTeXParser retokenize parser valParser = do
231233 Right toks' -> do
232234 res <- lift $ runParserT (do when retokenize $ do
233235 -- retokenize, applying macros
234− doMacros 0
236+ doMacros
235237 ts <- many (satisfyTok (const True))
236238 setInput ts
237239 rawparser)
@@ -246,7 +248,7 @@ rawLaTeXParser retokenize parser valParser = do
246248applyMacros :: (PandocMonad m, HasMacros s, HasReaderOptions s)
247249 => String -> ParserT String s m String
248250applyMacros s = (guardDisabled Ext_latex_macros >> return s) <|>
249− do let retokenize = doMacros 0 *>
251+ do let retokenize = doMacros *>
250252 (toksToString <$> many (satisfyTok (const True)))
251253 pstate <- getState
252254 let lstate = def{ sOptions = extractReaderOptions pstate
@@ -371,7 +373,7 @@ satisfyTok :: PandocMonad m => (Tok -> Bool) -> LP m Tok
371373satisfyTok f =
372374 try $ do
373375 res <- tokenPrim (T.unpack . untoken) updatePos matcher
374− doMacros 0 -- apply macros on remaining input stream
376+ doMacros -- apply macros on remaining input stream
375377 return res
376378 where matcher t | f t = Just t
377379 | otherwise = Nothing
@@ -379,25 +381,29 @@ satisfyTok f =
379381 updatePos _spos _ (Tok pos _ _ : _) = pos
380382 updatePos spos _ [] = incSourceColumn spos 1
381383
382−doMacros :: PandocMonad m => Int -> LP m ()
383−doMacros n = do
384+doMacros :: PandocMonad m => LP m ()
385+doMacros = do
384386 verbatimMode <- sVerbatimMode <$> getState
385387 unless verbatimMode $ do
386− inp <- getInput
387− case inp of
388− Tok spos (CtrlSeq "begin") _ : Tok _ Symbol "{" :
389− Tok _ Word name : Tok _ Symbol "}" : ts
390− -> handleMacros spos name ts
391− Tok spos (CtrlSeq "end") _ : Tok _ Symbol "{" :
392− Tok _ Word name : Tok _ Symbol "}" : ts
393− -> handleMacros spos ("end" <> name) ts
394− Tok _ (CtrlSeq "expandafter") _ : t : ts
395− -> do setInput ts
396− doMacros n
397− getInput >>= setInput . combineTok t
398− Tok spos (CtrlSeq name) _ : ts
399− -> handleMacros spos name ts
400− _ -> return ()
388+ mbNewInp <- getInput >>= doMacros' 1
389+ case mbNewInp of
390+ Nothing -> return ()
391+ Just inp -> setInput inp
392+
393+doMacros' :: PandocMonad m => Int -> [Tok] -> LP m (Maybe [Tok])
394+doMacros' n inp = do
395+ case inp of
396+ Tok spos (CtrlSeq "begin") _ : Tok _ Symbol "{" :
397+ Tok _ Word name : Tok _ Symbol "}" : ts
398+ -> handleMacros n spos name ts
399+ Tok spos (CtrlSeq "end") _ : Tok _ Symbol "{" :
400+ Tok _ Word name : Tok _ Symbol "}" : ts
401+ -> handleMacros n spos ("end" <> name) ts
402+ Tok _ (CtrlSeq "expandafter") _ : t : ts
403+ -> (fmap (combineTok t)) <$> doMacros' n ts
404+ Tok spos (CtrlSeq name) _ : ts
405+ -> handleMacros n spos name ts
406+ _ -> return Nothing
401407
402408 where
403409 combineTok (Tok spos (CtrlSeq name) x) (Tok _ Word w : ts)
@@ -419,9 +425,7 @@ doMacros n = do
419425 getargs argmap rest
420426 getargs argmap (ArgNum i : Pattern toks : rest) =
421427 try $ do
422− x <- mconcat <$> manyTill
423− (braced <|> ((:[]) <$> anyTok))
424− (matchPattern toks)
428+ x <- mconcat <$> manyTill bracedOrToken (matchPattern toks)
425429 getargs (M.insert i x argmap) rest
426430 getargs argmap (ArgNum i : rest) = do
427431 x <- try $ spaces >> bracedOrToken
@@ -439,10 +443,12 @@ doMacros n = do
439443 Tok spos (CtrlSeq x) (txt <> " ") : acc
440444 addTok _ _ spos t acc = setpos spos t : acc
441445
442− handleMacros spos name ts = do
446+ handleMacros n' spos name ts = do
447+ when (n' > 20) -- detect macro expansion loops
448+ $ throwError $ PandocMacroLoop (T.unpack name)
443449 macros <- sMacros <$> getState
444450 case M.lookup name macros of
445− Nothing -> return ()
451+ Nothing -> return Nothing
446452 Just (Macro expansionPoint argspecs optarg newtoks) -> do
447453 setInput ts
448454 args <- case optarg of
@@ -454,15 +460,12 @@ doMacros n = do
454460 -- an argument (in which case we don't want to
455461 -- expand #1 etc.)
456462 ts' <- getInput
457− setInput $ foldr (addTok False args spos) ts' newtoks
458−
463+ let result = foldr (addTok False args spos) ts' newtoks
459464 case expansionPoint of
460− ExpandWhenUsed ->
461− if n > 20 -- detect macro expansion loops
462− then throwError $ PandocMacroLoop (T.unpack name)
463− else doMacros (n + 1)
464− ExpandWhenDefined -> return ()
465−
465+ ExpandWhenUsed ->
466+ doMacros' (n' + 1) result >>=
467+ maybe (return (Just result)) (return . Just)
468+ ExpandWhenDefined -> return $ Just result
466469
467470setpos :: SourcePos -> Tok -> Tok
468471setpos spos (Tok _ tt txt) = Tok spos tt txt