git.iko.soy/typeable/pandoc
on master help sign in
LaTeX reader: improved parsing of `\def`, `\let`.
e6ee032John MacFarlane
src/Text/Pandoc/Readers/LaTeX.hs+18−11
@@ -1506,21 +1506,28 @@ macroDef =
1506letmacro :: PandocMonad m => LP m (Text, Macro)
1506letmacro :: PandocMonad m => LP m (Text, Macro)
1507letmacro = do
1507letmacro = do
1508 controlSeq "let"
1508 controlSeq "let"
1509+ (name, contents) <- withVerbatimMode $ do
1509− Tok _ (CtrlSeq name) _ <- anyControlSeq
1510+ Tok _ (CtrlSeq name) _ <- withVerbatimMode anyControlSeq
1510− optional $ symbol '='
1511+ optional $ symbol '='
1511− spaces
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}
1512− contents <- bracedOrToken
1516+ contents <- bracedOrToken
1517+ return (name, contents)
1518+ contents' <- fromMaybe contents <$> doMacros' 0 contents
1513− return (name, Macro ExpandWhenDefined [] Nothing contents)
1519+ return (name, Macro ExpandWhenDefined [] Nothing contents')
1514
1520
1515defmacro :: PandocMonad m => LP m (Text, Macro)
1521defmacro :: PandocMonad m => LP m (Text, Macro)
1516−defmacro = try $ do
1522+defmacro = try $
1517− controlSeq "def"
1518− Tok _ (CtrlSeq name) _ <- anyControlSeq
1519− argspecs <- many (argspecArg <|> argspecPattern)
1520 -- we use withVerbatimMode, because macros are to be expanded
1523 -- we use withVerbatimMode, because macros are to be expanded
1521 -- at point of use, not point of definition
1524 -- at point of use, not point of definition
1522− contents <- withVerbatimMode bracedOrToken
1525+ withVerbatimMode $ do
1526+ controlSeq "def"
1527+ Tok _ (CtrlSeq name) _ <- anyControlSeq
1528+ argspecs <- many (argspecArg <|> argspecPattern)
1529+ contents <- bracedOrToken
1523− return (name, Macro ExpandWhenUsed argspecs Nothing contents)
1530+ return (name, Macro ExpandWhenUsed argspecs Nothing contents)
1524
1531
1525argspecArg :: PandocMonad m => LP m ArgSpec
1532argspecArg :: PandocMonad m => LP m ArgSpec
1526argspecArg = do
1533argspecArg = do
src/Text/Pandoc/Readers/LaTeX/Parsing.hs+23−16
@@ -49,6 +49,7 @@ module Text.Pandoc.Readers.LaTeX.Parsing
49 , toksToString
49 , toksToString
50 , satisfyTok
50 , satisfyTok
51 , doMacros
51 , doMacros
52+ , doMacros'
52 , setpos
53 , setpos
53 , anyControlSeq
54 , anyControlSeq
54 , anySymbol
55 , anySymbol
@@ -451,22 +452,28 @@ doMacros' n inp = do
451 case M.lookup name macros of
452 case M.lookup name macros of
452 Nothing -> return Nothing
453 Nothing -> return Nothing
453 Just (Macro expansionPoint argspecs optarg newtoks) -> do
454 Just (Macro expansionPoint argspecs optarg newtoks) -> do
454− setInput ts
455+ let getargs' = do
455− args <- case optarg of
456+ args <- case optarg of
456− Nothing -> getargs M.empty argspecs
457+ Nothing -> getargs M.empty argspecs
457− Just o -> do
458+ Just o -> do
458− x <- option o bracketedToks
459+ x <- option o bracketedToks
459− getargs (M.singleton 1 x) argspecs
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
460− -- first boolean param is true if we're tokenizing
469+ -- first boolean param is true if we're tokenizing
461− -- an argument (in which case we don't want to
470+ -- an argument (in which case we don't want to
462− -- expand #1 etc.)
471+ -- expand #1 etc.)
463− ts' <- getInput
464− let result = foldr (addTok False args spos) ts' newtoks
472+ let result = foldr (addTok False args spos) rest newtoks
465− case expansionPoint of
473+ case expansionPoint of
466− ExpandWhenUsed ->
474+ ExpandWhenUsed ->
467− doMacros' (n' + 1) result >>=
475+ maybe (Just result) Just <$> doMacros' (n' + 1) result
468− maybe (return (Just result)) (return . Just)
469− ExpandWhenDefined -> return $ Just result
476+ ExpandWhenDefined -> return $ Just result
470
477
471setpos :: SourcePos -> Tok -> Tok
478setpos :: SourcePos -> Tok -> Tok
472setpos spos (Tok _ tt txt) = Tok spos tt txt
479setpos spos (Tok _ tt txt) = Tok spos tt txt