@@ -65,7 +65,7 @@ import Text.Pandoc.Parsing hiding (many, optional, withRaw,
6565 mathInline, mathDisplay,
6666 space, (<|>), spaces, blankline)
6767import Text.Pandoc.Shared
68−import Text.Pandoc.Readers.LaTeX.Types (Macro(..), Tok(..),
68+import Text.Pandoc.Readers.LaTeX.Types (Macro(..), ExpansionPoint(..), Tok(..),
6969 TokType(..))
7070import Text.Pandoc.Walk
7171import Text.Pandoc.Error (PandocError(PandocParsecError, PandocMacroLoop))
@@ -375,7 +375,7 @@ doMacros n = do
375375 macros <- sMacros <$> getState
376376 case M.lookup name macros of
377377 Nothing -> return ()
378− Just (Macro numargs optarg newtoks) -> do
378+ Just (Macro expansionPoint numargs optarg newtoks) -> do
379379 setInput ts
380380 let getarg = spaces >> braced
381381 args <- case optarg of
@@ -389,9 +389,12 @@ doMacros n = do
389389 addTok t acc = setpos spos t : acc
390390 ts' <- getInput
391391 setInput $ foldr addTok ts' newtoks
392− if n > 20 -- detect macro expansion loops
393− then throwError $ PandocMacroLoop (T.unpack name)
394− else doMacros (n + 1)
392+ case expansionPoint of
393+ ExpandWhenUsed ->
394+ if n > 20 -- detect macro expansion loops
395+ then throwError $ PandocMacroLoop (T.unpack name)
396+ else doMacros (n + 1)
397+ ExpandWhenDefined -> return ()
395398
396399setpos :: (Line, Column) -> Tok -> Tok
397400setpos spos (Tok _ tt txt) = Tok spos tt txt
@@ -1375,7 +1378,8 @@ isBlockCommand s =
13751378
13761379treatAsBlock :: Set.Set Text
13771380treatAsBlock = Set.fromList
1378− [ "newcommand", "renewcommand"
1381+ [ "let"
1382+ , "newcommand", "renewcommand"
13791383 , "newenvironment", "renewenvironment"
13801384 , "providecommand", "provideenvironment"
13811385 -- newcommand, etc. should be parsed by macroDef, but we need this
@@ -1517,7 +1521,7 @@ macroDef :: PandocMonad m => LP m Blocks
15171521macroDef = do
15181522 mempty <$ ((commandDef <|> environmentDef) <* doMacros 0)
15191523 where commandDef = do
1520− (name, macro') <- newcommand
1524+ (name, macro') <- newcommand <|> letmacro
15211525 guardDisabled Ext_latex_macros <|>
15221526 updateState (\s -> s{ sMacros = M.insert name macro' (sMacros s) })
15231527 environmentDef = do
@@ -1532,6 +1536,15 @@ macroDef = do
15321536 -- @\newcommand{\envname}[n-args][default]{begin}@
15331537 -- @\newcommand{\endenvname}@
15341538
1539+letmacro :: PandocMonad m => LP m (Text, Macro)
1540+letmacro = do
1541+ pos <- getPosition
1542+ controlSeq "let"
1543+ Tok _ (CtrlSeq name) _ <- anyControlSeq
1544+ optional $ symbol '='
1545+ contents <- braced <|> ((:[]) <$> anyControlSeq)
1546+ return (name, Macro ExpandWhenDefined 0 Nothing contents)
1547+
15351548newcommand :: PandocMonad m => LP m (Text, Macro)
15361549newcommand = do
15371550 pos <- getPosition
@@ -1546,13 +1559,15 @@ newcommand = do
15461559 spaces
15471560 optarg <- option Nothing $ Just <$> try bracketedToks
15481561 spaces
1549− contents <- braced
1562+ contents <- withVerbatimMode braced
1563+ -- we use withVerbatimMode, because macros are to be expanded
1564+ -- at point of use, not point of definition
15501565 when (mtype == "newcommand") $ do
15511566 macros <- sMacros <$> getState
15521567 case M.lookup name macros of
15531568 Just _ -> report $ MacroAlreadyDefined (T.unpack txt) pos
15541569 Nothing -> return ()
1555− return (name, Macro numargs optarg contents)
1570+ return (name, Macro ExpandWhenUsed numargs optarg contents)
15561571
15571572newenvironment :: PandocMonad m => LP m (Text, Macro, Macro)
15581573newenvironment = do
@@ -1568,16 +1583,16 @@ newenvironment = do
15681583 spaces
15691584 optarg <- option Nothing $ Just <$> try bracketedToks
15701585 spaces
1571− startcontents <- braced
1586+ startcontents <- withVerbatimMode braced
15721587 spaces
1573− endcontents <- braced
1588+ endcontents <- withVerbatimMode braced
15741589 when (mtype == "newenvironment") $ do
15751590 macros <- sMacros <$> getState
15761591 case M.lookup name macros of
15771592 Just _ -> report $ MacroAlreadyDefined (T.unpack name) pos
15781593 Nothing -> return ()
1579− return (name, Macro numargs optarg startcontents,
1580− Macro 0 Nothing endcontents)
1594+ return (name, Macro ExpandWhenUsed numargs optarg startcontents,
1595+ Macro ExpandWhenUsed 0 Nothing endcontents)
15811596
15821597bracketedToks :: PandocMonad m => LP m [Tok]
15831598bracketedToks = do