aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Text/Pandoc/Readers/LaTeX.hs41
-rw-r--r--src/Text/Pandoc/Readers/LaTeX/Types.hs6
-rw-r--r--test/command/macros.md23
3 files changed, 56 insertions, 14 deletions
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
index b06cd7348..7004f2ba5 100644
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -65,7 +65,7 @@ import Text.Pandoc.Parsing hiding (many, optional, withRaw,
mathInline, mathDisplay,
space, (<|>), spaces, blankline)
import Text.Pandoc.Shared
-import Text.Pandoc.Readers.LaTeX.Types (Macro(..), Tok(..),
+import Text.Pandoc.Readers.LaTeX.Types (Macro(..), ExpansionPoint(..), Tok(..),
TokType(..))
import Text.Pandoc.Walk
import Text.Pandoc.Error (PandocError(PandocParsecError, PandocMacroLoop))
@@ -375,7 +375,7 @@ doMacros n = do
macros <- sMacros <$> getState
case M.lookup name macros of
Nothing -> return ()
- Just (Macro numargs optarg newtoks) -> do
+ Just (Macro expansionPoint numargs optarg newtoks) -> do
setInput ts
let getarg = spaces >> braced
args <- case optarg of
@@ -389,9 +389,12 @@ doMacros n = do
addTok t acc = setpos spos t : acc
ts' <- getInput
setInput $ foldr addTok ts' newtoks
- if n > 20 -- detect macro expansion loops
- then throwError $ PandocMacroLoop (T.unpack name)
- else doMacros (n + 1)
+ case expansionPoint of
+ ExpandWhenUsed ->
+ if n > 20 -- detect macro expansion loops
+ then throwError $ PandocMacroLoop (T.unpack name)
+ else doMacros (n + 1)
+ ExpandWhenDefined -> return ()
setpos :: (Line, Column) -> Tok -> Tok
setpos spos (Tok _ tt txt) = Tok spos tt txt
@@ -1375,7 +1378,8 @@ isBlockCommand s =
treatAsBlock :: Set.Set Text
treatAsBlock = Set.fromList
- [ "newcommand", "renewcommand"
+ [ "let"
+ , "newcommand", "renewcommand"
, "newenvironment", "renewenvironment"
, "providecommand", "provideenvironment"
-- newcommand, etc. should be parsed by macroDef, but we need this
@@ -1517,7 +1521,7 @@ macroDef :: PandocMonad m => LP m Blocks
macroDef = do
mempty <$ ((commandDef <|> environmentDef) <* doMacros 0)
where commandDef = do
- (name, macro') <- newcommand
+ (name, macro') <- newcommand <|> letmacro
guardDisabled Ext_latex_macros <|>
updateState (\s -> s{ sMacros = M.insert name macro' (sMacros s) })
environmentDef = do
@@ -1532,6 +1536,15 @@ macroDef = do
-- @\newcommand{\envname}[n-args][default]{begin}@
-- @\newcommand{\endenvname}@
+letmacro :: PandocMonad m => LP m (Text, Macro)
+letmacro = do
+ pos <- getPosition
+ controlSeq "let"
+ Tok _ (CtrlSeq name) _ <- anyControlSeq
+ optional $ symbol '='
+ contents <- braced <|> ((:[]) <$> anyControlSeq)
+ return (name, Macro ExpandWhenDefined 0 Nothing contents)
+
newcommand :: PandocMonad m => LP m (Text, Macro)
newcommand = do
pos <- getPosition
@@ -1546,13 +1559,15 @@ newcommand = do
spaces
optarg <- option Nothing $ Just <$> try bracketedToks
spaces
- contents <- braced
+ contents <- withVerbatimMode braced
+ -- we use withVerbatimMode, because macros are to be expanded
+ -- at point of use, not point of definition
when (mtype == "newcommand") $ do
macros <- sMacros <$> getState
case M.lookup name macros of
Just _ -> report $ MacroAlreadyDefined (T.unpack txt) pos
Nothing -> return ()
- return (name, Macro numargs optarg contents)
+ return (name, Macro ExpandWhenUsed numargs optarg contents)
newenvironment :: PandocMonad m => LP m (Text, Macro, Macro)
newenvironment = do
@@ -1568,16 +1583,16 @@ newenvironment = do
spaces
optarg <- option Nothing $ Just <$> try bracketedToks
spaces
- startcontents <- braced
+ startcontents <- withVerbatimMode braced
spaces
- endcontents <- braced
+ endcontents <- withVerbatimMode braced
when (mtype == "newenvironment") $ do
macros <- sMacros <$> getState
case M.lookup name macros of
Just _ -> report $ MacroAlreadyDefined (T.unpack name) pos
Nothing -> return ()
- return (name, Macro numargs optarg startcontents,
- Macro 0 Nothing endcontents)
+ return (name, Macro ExpandWhenUsed numargs optarg startcontents,
+ Macro ExpandWhenUsed 0 Nothing endcontents)
bracketedToks :: PandocMonad m => LP m [Tok]
bracketedToks = do
diff --git a/src/Text/Pandoc/Readers/LaTeX/Types.hs b/src/Text/Pandoc/Readers/LaTeX/Types.hs
index 6f84ae1f1..2bef3cb1a 100644
--- a/src/Text/Pandoc/Readers/LaTeX/Types.hs
+++ b/src/Text/Pandoc/Readers/LaTeX/Types.hs
@@ -30,6 +30,7 @@ Types for LaTeX tokens and macros.
module Text.Pandoc.Readers.LaTeX.Types ( Tok(..)
, TokType(..)
, Macro(..)
+ , ExpansionPoint(..)
, Line
, Column )
where
@@ -43,6 +44,9 @@ data TokType = CtrlSeq Text | Spaces | Newline | Symbol | Word | Comment |
data Tok = Tok (Line, Column) TokType Text
deriving (Eq, Ord, Show)
-data Macro = Macro Int (Maybe [Tok]) [Tok]
+data ExpansionPoint = ExpandWhenDefined | ExpandWhenUsed
+ deriving (Eq, Ord, Show)
+
+data Macro = Macro ExpansionPoint Int (Maybe [Tok]) [Tok]
deriving Show
diff --git a/test/command/macros.md b/test/command/macros.md
index 055c86d25..49a648c79 100644
--- a/test/command/macros.md
+++ b/test/command/macros.md
@@ -15,3 +15,26 @@ $\my+\my$
\newcommand{\my}{\phi}
$\my+\my$
```
+
+`\let` macros should be expanded at point of
+definition, while `\newcommand` macros should be
+expanded at point of use:
+
+```
+% pandoc -f latex -t latex
+\let\a\b
+\newcommand{\b}{\emph{ouk}}
+\a
+^D
+\b
+```
+
+```
+% pandoc -f latex -t latex
+\newcommand{\a}{\b}
+\newcommand{\b}{\emph{ouk}}
+\a
+^D
+\emph{ouk}
+```
+