git.iko.soy/typeable/pandoc
on master help sign in
LaTeX reader: improved parsing of `\def`, `\let`.

We now correctly parse: ``` \def\bar{hello} \let\fooi\bar \def\fooii{\bar} \fooi +\fooii \def\bar{goodbye} \fooi +\fooii ```

commite6ee032a6de22f5a2dd18030d0956e67d1fc26ba authorJohn MacFarlane <jgm@berkeley.edu> dateMon 15 Oct 2018, 11:27 (8 years ago) parent68ec838
2 files changed+41−27
src/Text/Pandoc/Readers/LaTeX.hs+18−11 src/Text/Pandoc/Readers/LaTeX/Parsing.hs+23−16
src/Text/Pandoc/Readers/LaTeX.hs+18−11
@@ -1506,21 +1506,28 @@ macroDef =
15061506letmacro :: PandocMonad m => LP m (Text, Macro)
15071507letmacro = do
15081508 controlSeq "let"
1509− Tok _ (CtrlSeq name) _ <- anyControlSeq
1510− optional $ symbol '='
1511− spaces
1512− contents <- bracedOrToken
1513− return (name, Macro ExpandWhenDefined [] Nothing contents)
1509+ (name, contents) <- withVerbatimMode $ do
1510+ Tok _ (CtrlSeq name) _ <- withVerbatimMode anyControlSeq
1511+ optional $ symbol '='
1512+ spaces
1513+ -- we first parse in verbatim mode, and then expand macros,
1514+ -- because we don't want \let\foo\bar to turn into
1515+ -- \let\foo hello if we have previously \def\bar{hello}
1516+ contents <- bracedOrToken
1517+ return (name, contents)
1518+ contents' <- fromMaybe contents <$> doMacros' 0 contents
1519+ return (name, Macro ExpandWhenDefined [] Nothing contents')
15141520
15151521defmacro :: PandocMonad m => LP m (Text, Macro)
1516−defmacro = try $ do
1517− controlSeq "def"
1518− Tok _ (CtrlSeq name) _ <- anyControlSeq
1519− argspecs <- many (argspecArg <|> argspecPattern)
1522+defmacro = try $
15201523 -- we use withVerbatimMode, because macros are to be expanded
15211524 -- at point of use, not point of definition
1522− contents <- withVerbatimMode bracedOrToken
1523− return (name, Macro ExpandWhenUsed argspecs Nothing contents)
1525+ withVerbatimMode $ do
1526+ controlSeq "def"
1527+ Tok _ (CtrlSeq name) _ <- anyControlSeq
1528+ argspecs <- many (argspecArg <|> argspecPattern)
1529+ contents <- bracedOrToken
1530+ return (name, Macro ExpandWhenUsed argspecs Nothing contents)
15241531
15251532argspecArg :: PandocMonad m => LP m ArgSpec
15261533argspecArg = do
src/Text/Pandoc/Readers/LaTeX/Parsing.hs+23−16
@@ -49,6 +49,7 @@ module Text.Pandoc.Readers.LaTeX.Parsing
4949 , toksToString
5050 , satisfyTok
5151 , doMacros
52+ , doMacros'
5253 , setpos
5354 , anyControlSeq
5455 , anySymbol
@@ -451,22 +452,28 @@ doMacros' n inp = do
451452 case M.lookup name macros of
452453 Nothing -> return Nothing
453454 Just (Macro expansionPoint argspecs optarg newtoks) -> do
454− setInput ts
455− args <- case optarg of
456− Nothing -> getargs M.empty argspecs
457− Just o -> do
458− x <- option o bracketedToks
459− getargs (M.singleton 1 x) argspecs
460− -- first boolean param is true if we're tokenizing
461− -- an argument (in which case we don't want to
462− -- expand #1 etc.)
463− ts' <- getInput
464− let result = foldr (addTok False args spos) ts' newtoks
465− case expansionPoint of
466− ExpandWhenUsed ->
467− doMacros' (n' + 1) result >>=
468− maybe (return (Just result)) (return . Just)
469− ExpandWhenDefined -> return $ Just result
455+ let getargs' = do
456+ args <- case optarg of
457+ Nothing -> getargs M.empty argspecs
458+ Just o -> do
459+ x <- option o bracketedToks
460+ getargs (M.singleton 1 x) argspecs
461+ rest <- getInput
462+ return (args, rest)
463+ lstate <- getState
464+ res <- lift $ runParserT getargs' lstate "args" ts
465+ case res of
466+ Left _ -> fail $ "Could not parse arguments for " ++
467+ T.unpack name
468+ Right (args, rest) -> do
469+ -- first boolean param is true if we're tokenizing
470+ -- an argument (in which case we don't want to
471+ -- expand #1 etc.)
472+ let result = foldr (addTok False args spos) rest newtoks
473+ case expansionPoint of
474+ ExpandWhenUsed ->
475+ maybe (Just result) Just <$> doMacros' (n' + 1) result
476+ ExpandWhenDefined -> return $ Just result
470477
471478setpos :: SourcePos -> Tok -> Tok
472479setpos spos (Tok _ tt txt) = Tok spos tt txt