From 28b736bf957da0df79ffb211fc5e7ec4ff713c4b Mon Sep 17 00:00:00 2001
From: John MacFarlane <jgm@berkeley.edu>
Date: Fri, 22 Dec 2017 17:59:47 -0800
Subject: [PATCH] `latex_macros` extension changes.

Don't pass through macro definitions themselves when `latex_macros`
is set.  The macros have already been applied.

If `latex_macros` is enabled, then `rawLaTeXBlock` in
Text.Pandoc.Readers.LaTeX will succeed in parsing a macro definition,
and will update pandoc's internal macro map accordingly, but the
empty string will be returned.

Together with earlier changes, this closes #4179.
---
 MANUAL.txt                          | 16 +++++++++-----
 src/Text/Pandoc/Readers/LaTeX.hs    |  6 +++--
 src/Text/Pandoc/Readers/Markdown.hs | 10 ++++++---
 test/command/4159.md                |  3 +--
 test/command/macros.md              | 34 ++++++++++++++++++++++++++++-
 test/markdown-reader-more.native    |  1 -
 6 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/MANUAL.txt b/MANUAL.txt
index 19e1764a1..78bd057ed 100644
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -3195,18 +3195,22 @@ LaTeX macros
 
 #### Extension: `latex_macros` ####
 
-For output formats other than LaTeX, pandoc will parse LaTeX `\newcommand` and
-`\renewcommand` definitions and apply the resulting macros to all LaTeX
-math.  So, for example, the following will work in all output formats,
-not just LaTeX:
+For output formats other than LaTeX, pandoc will parse LaTeX
+macro definitions and apply the resulting macros to all LaTeX
+math and raw LaTeX.  So, for example, the following will work in
+all output formats, not just LaTeX:
 
     \newcommand{\tuple}[1]{\langle #1 \rangle}
 
     $\tuple{a, b, c}$
 
-In LaTeX output, the `\newcommand` definition will simply be passed
-unchanged to the output.
+In LaTeX output, the macro definitions will not be passed
+through as raw LaTeX.
 
+When `latex_macros` is disabled, the macro definitions will
+be passed through as raw LaTeX, and the raw LaTeX and math will
+not have macros applied. This is usually a better approach when
+you are targeting LaTeX or PDF.
 
 Links
 -----
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
index 5299b964f..f7e45e01a 100644
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -272,8 +272,10 @@ rawLaTeXBlock = do
   lookAhead (try (char '\\' >> letter))
   -- we don't want to apply newly defined latex macros to their own
   -- definitions:
-  (snd <$> rawLaTeXParser macroDef) <|>
-     ((snd <$> rawLaTeXParser (environment <|> blockCommand)) >>= applyMacros)
+  (do (_, raw) <- rawLaTeXParser macroDef
+      (guardDisabled Ext_latex_macros >> return raw) <|> return "")
+  <|> (do (_, raw) <- rawLaTeXParser (environment <|> blockCommand)
+          applyMacros raw)
 
 rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
                => ParserT String s m String
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
index af020261b..e7ad9d8ba 100644
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -1120,13 +1120,17 @@ rawVerbatimBlock = htmlInBalanced isVerbTag
 rawTeXBlock :: PandocMonad m => MarkdownParser m (F Blocks)
 rawTeXBlock = do
   guardEnabled Ext_raw_tex
-  result <- (B.rawBlock "context" . trimr . concat <$>
+  result <- (B.rawBlock "context" . trim . concat <$>
                 many1 ((++) <$> (rawConTeXtEnvironment <|> conTeXtCommand)
                             <*> (blanklines <|> many spaceChar)))
-          <|> (B.rawBlock "latex" . trimr . concat <$>
+          <|> (B.rawBlock "latex" . trim . concat <$>
                 many1 ((++) <$> rawLaTeXBlock
                             <*> (blanklines <|> many spaceChar)))
-  return $ return result
+  return $ case B.toList result of
+                [RawBlock _ cs]
+                  | all (`elem` [' ','\t','\n']) cs -> return mempty
+                -- don't create a raw block for suppressed macro defs
+                _ -> return result
 
 conTeXtCommand :: PandocMonad m => MarkdownParser m String
 conTeXtCommand = oneOfStrings ["\\placeformula"]
diff --git a/test/command/4159.md b/test/command/4159.md
index 4881edcc5..81deba53a 100644
--- a/test/command/4159.md
+++ b/test/command/4159.md
@@ -3,6 +3,5 @@
 \newcommand{\gen}{a\ Gen\ b}
 abc
 ^D
-[RawBlock (Format "latex") "\\newcommand{\\gen}{a\\ Gen\\ b}"
-,Para [Str "abc"]]
+[Para [Str "abc"]]
 ```
diff --git a/test/command/macros.md b/test/command/macros.md
index 46179e3c7..4bd2eb00a 100644
--- a/test/command/macros.md
+++ b/test/command/macros.md
@@ -3,7 +3,6 @@
 \newcommand{\my}{\phi}
 $\my+\my$
 ^D
-\newcommand{\my}{\phi}
 $\phi+\phi$
 ```
 
@@ -66,3 +65,36 @@ x &= y\\\end{aligned}\]
 
 \emph{hi--ok}
 ```
+
+```
+% pandoc -f markdown+latex_macros -t markdown
+\newcommand{\my}{\phi}
+\begin{equation}
+\my+\my
+\end{equation}
+^D
+\begin{equation}
+\phi+\phi
+\end{equation}
+```
+
+```
+% pandoc -f markdown-latex_macros -t markdown
+\newcommand{\my}{\phi}
+\begin{equation}
+\my+\my
+\end{equation}
+^D
+\newcommand{\my}{\phi}
+\begin{equation}
+\my+\my
+\end{equation}
+```
+
+```
+% pandoc -f markdown+latex_macros -t markdown
+\newcommand{\my}{\emph{a}}
+\my
+^D
+\emph{a}
+```
diff --git a/test/markdown-reader-more.native b/test/markdown-reader-more.native
index 5f34c7927..742b6187c 100644
--- a/test/markdown-reader-more.native
+++ b/test/markdown-reader-more.native
@@ -54,7 +54,6 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "Author",S
 ,OrderedList (3,Example,TwoParens)
  [[Plain [Str "Third",Space,Str "example."]]]
 ,Header 2 ("macros",[],[]) [Str "Macros"]
-,RawBlock (Format "latex") "\\newcommand{\\tuple}[1]{\\langle #1 \\rangle}"
 ,Para [Math InlineMath "\\langle x,y \\rangle"]
 ,Header 2 ("case-insensitive-references",[],[]) [Str "Case-insensitive",Space,Str "references"]
 ,Para [Link ("",[],[]) [Str "Fum"] ("/fum","")]