diff options
author | John MacFarlane <jgm@berkeley.edu> | 2018-10-15 11:27:04 -0700 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2018-10-15 11:27:04 -0700 |
commit | e6ee032a6de22f5a2dd18030d0956e67d1fc26ba (patch) | |
tree | 151059b0e7a2cd5ff3e1046ecae373f29b164b93 | |
parent | 68ec8380149a314f261e25ca60c6f65b0436b9e4 (diff) | |
download | pandoc-e6ee032a6de22f5a2dd18030d0956e67d1fc26ba.tar.gz |
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
```
-rw-r--r-- | src/Text/Pandoc/Readers/LaTeX.hs | 29 | ||||
-rw-r--r-- | src/Text/Pandoc/Readers/LaTeX/Parsing.hs | 39 |
2 files changed, 41 insertions, 27 deletions
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs index 6c708c6ed..3751921ce 100644 --- a/src/Text/Pandoc/Readers/LaTeX.hs +++ b/src/Text/Pandoc/Readers/LaTeX.hs @@ -1506,21 +1506,28 @@ macroDef = letmacro :: PandocMonad m => LP m (Text, Macro) letmacro = do controlSeq "let" - Tok _ (CtrlSeq name) _ <- anyControlSeq - optional $ symbol '=' - spaces - contents <- bracedOrToken - return (name, Macro ExpandWhenDefined [] Nothing contents) + (name, contents) <- withVerbatimMode $ do + Tok _ (CtrlSeq name) _ <- withVerbatimMode anyControlSeq + optional $ symbol '=' + spaces + -- we first parse in verbatim mode, and then expand macros, + -- because we don't want \let\foo\bar to turn into + -- \let\foo hello if we have previously \def\bar{hello} + contents <- bracedOrToken + return (name, contents) + contents' <- fromMaybe contents <$> doMacros' 0 contents + return (name, Macro ExpandWhenDefined [] Nothing contents') defmacro :: PandocMonad m => LP m (Text, Macro) -defmacro = try $ do - controlSeq "def" - Tok _ (CtrlSeq name) _ <- anyControlSeq - argspecs <- many (argspecArg <|> argspecPattern) +defmacro = try $ -- we use withVerbatimMode, because macros are to be expanded -- at point of use, not point of definition - contents <- withVerbatimMode bracedOrToken - return (name, Macro ExpandWhenUsed argspecs Nothing contents) + withVerbatimMode $ do + controlSeq "def" + Tok _ (CtrlSeq name) _ <- anyControlSeq + argspecs <- many (argspecArg <|> argspecPattern) + contents <- bracedOrToken + return (name, Macro ExpandWhenUsed argspecs Nothing contents) argspecArg :: PandocMonad m => LP m ArgSpec argspecArg = do diff --git a/src/Text/Pandoc/Readers/LaTeX/Parsing.hs b/src/Text/Pandoc/Readers/LaTeX/Parsing.hs index 74305b824..c348ba572 100644 --- a/src/Text/Pandoc/Readers/LaTeX/Parsing.hs +++ b/src/Text/Pandoc/Readers/LaTeX/Parsing.hs @@ -49,6 +49,7 @@ module Text.Pandoc.Readers.LaTeX.Parsing , toksToString , satisfyTok , doMacros + , doMacros' , setpos , anyControlSeq , anySymbol @@ -451,22 +452,28 @@ doMacros' n inp = do case M.lookup name macros of Nothing -> return Nothing Just (Macro expansionPoint argspecs optarg newtoks) -> do - setInput ts - args <- case optarg of - Nothing -> getargs M.empty argspecs - Just o -> do - x <- option o bracketedToks - getargs (M.singleton 1 x) argspecs - -- first boolean param is true if we're tokenizing - -- an argument (in which case we don't want to - -- expand #1 etc.) - ts' <- getInput - let result = foldr (addTok False args spos) ts' newtoks - case expansionPoint of - ExpandWhenUsed -> - doMacros' (n' + 1) result >>= - maybe (return (Just result)) (return . Just) - ExpandWhenDefined -> return $ Just result + let getargs' = do + args <- case optarg of + Nothing -> getargs M.empty argspecs + Just o -> do + x <- option o bracketedToks + getargs (M.singleton 1 x) argspecs + rest <- getInput + return (args, rest) + lstate <- getState + res <- lift $ runParserT getargs' lstate "args" ts + case res of + Left _ -> fail $ "Could not parse arguments for " ++ + T.unpack name + Right (args, rest) -> do + -- first boolean param is true if we're tokenizing + -- an argument (in which case we don't want to + -- expand #1 etc.) + let result = foldr (addTok False args spos) rest newtoks + case expansionPoint of + ExpandWhenUsed -> + maybe (Just result) Just <$> doMacros' (n' + 1) result + ExpandWhenDefined -> return $ Just result setpos :: SourcePos -> Tok -> Tok setpos spos (Tok _ tt txt) = Tok spos tt txt |