LaTeX reader/writer: change handling of math environments.

Certain environments in LaTeX will trigger math mode and can't
occur within math mode: e.g., `align` or `equation`.  Previously
we "downshifted" these, parsing an `align` environment as a
Math element with `aligned`, and an `equation` environment as a
regular display math element.  With this shift, we put these in
Math inlines but retain the original environments.

This works because:

1) texmath handles these environments just fine,
2) and so does MathJax;
3) when writing LaTeX we detect these environments in Math elements
   and emit them verbatim instead of putting them in `$..$` or
   `$$..$$`.

Closes #9711. Closes #9296.
This commit is contained in:
John MacFarlane
2025-08-11 17:35:56 -07:00
parent 6b2f66507a
commit 0bbbdbcdb6
8 changed files with 59 additions and 21 deletions
+15 -14
View File
@@ -98,20 +98,21 @@ inlineEnvironments :: PandocMonad m => M.Map Text (LP m Inlines)
inlineEnvironments = M.fromList [
("displaymath", mathEnvWith id Nothing "displaymath")
, ("math", math <$> mathEnv "math")
, ("equation", mathEnvWith id Nothing "equation")
, ("equation*", mathEnvWith id Nothing "equation*")
, ("gather", mathEnvWith id (Just "gathered") "gather")
, ("gather*", mathEnvWith id (Just "gathered") "gather*")
, ("multline", mathEnvWith id (Just "gathered") "multline")
, ("multline*", mathEnvWith id (Just "gathered") "multline*")
, ("eqnarray", mathEnvWith id (Just "aligned") "eqnarray")
, ("eqnarray*", mathEnvWith id (Just "aligned") "eqnarray*")
, ("align", mathEnvWith id (Just "aligned") "align")
, ("align*", mathEnvWith id (Just "aligned") "align*")
, ("alignat", mathEnvWith id (Just "aligned") "alignat")
, ("alignat*", mathEnvWith id (Just "aligned") "alignat*")
, ("flalign", mathEnvWith id (Just "aligned") "flalign")
, ("flalign*", mathEnvWith id (Just "aligned") "flalign*")
, ("equation", mathEnvWith id (Just "equation") "equation")
, ("equation*", mathEnvWith id (Just "equation*") "equation*")
, ("gather", mathEnvWith id (Just "gather") "gather")
, ("gather*", mathEnvWith id (Just "gather*") "gather*")
, ("multline", mathEnvWith id (Just "multline") "multline")
, ("multline*", mathEnvWith id (Just "multline*") "multline*")
, ("eqnarray", mathEnvWith id (Just "eqnarray") "eqnarray")
, ("eqnarray*", mathEnvWith id (Just "eqnarray*") "eqnarray*")
, ("align", mathEnvWith id (Just "align") "align")
, ("align*", mathEnvWith id (Just "align*") "align*")
, ("alignat", mathEnvWith id (Just "alignat") "alignat")
, ("alignat*", mathEnvWith id (Just "alignat*") "alignat*")
, ("flalign", mathEnvWith id (Just "flalign") "flalign")
, ("flalign*", mathEnvWith id (Just "flalign*") "flalign*")
-- the following are not yet handled by texmath, so we use substitutes:
, ("dmath", mathEnvWith id Nothing "dmath")
, ("dmath*", mathEnvWith id Nothing "dmath*")
, ("dgroup", mathEnvWith id (Just "aligned") "dgroup")
+24
View File
@@ -1021,6 +1021,10 @@ inlineToLaTeX (Quoted qt lst) = do
inlineToLaTeX (Str str) = do
setEmptyLine False
liftM literal $ stringToLaTeX TextString str
inlineToLaTeX (Math _ str)
| isMathEnv str -- see #9711
= do setEmptyLine False
pure $ literal str
inlineToLaTeX (Math InlineMath str) = do
setEmptyLine False
inSoul <- gets stInSoulCommand
@@ -1310,3 +1314,23 @@ ldfLanguages =
, "galician"
, "slovene"
]
isMathEnv :: Text -> Bool
isMathEnv t =
case T.stripPrefix "\\begin{" t of
Nothing -> False
Just t' -> T.takeWhile (/= '}') t' `elem`
[ "align", "align*"
, "flalign", "flalign*"
, "alignat", "alignat*"
, "dmath", "dmath*"
, "dgroup", "dgroup*"
, "darray", "darray*"
, "gather", "gather*"
, "multline", "multline*"
, "split"
, "subequations"
, "equation", "equation*"
, "eqnarray"
, "displaymath"
]
+5 -1
View File
@@ -7,5 +7,9 @@
\begin{table}[h]
\end{table}
^D
[ Para [ Math DisplayMath "[0,1)" ] ]
[ Para
[ Math
DisplayMath "\\begin{equation}\n [0,1)\n\\end{equation}"
]
]
```
+1 -1
View File
@@ -11,7 +11,7 @@ E&=&F
[ Para
[ Math
DisplayMath
"\\begin{aligned}\nA&=&B,\\\\\nC&=&D,\\\\\n%\\end{eqnarray}\n%\\begin{eqnarray}\nE&=&F\n\\end{aligned}"
"\\begin{eqnarray}\nA&=&B,\\\\\nC&=&D,\\\\\n%\\end{eqnarray}\n%\\begin{eqnarray}\nE&=&F\n\\end{eqnarray}"
]
]
```
+6 -1
View File
@@ -4,7 +4,12 @@
[d,\delta]=0.
\end{equation*}
^D
[ Para [ Math DisplayMath "[d,\\delta]=0." ] ]
[ Para
[ Math
DisplayMath
"\\begin{equation*}\n[d,\\delta]=0.\n\\end{equation*}"
]
]
```
```
+5 -1
View File
@@ -7,5 +7,9 @@
y=x^2
\EEQ
^D
[ Para [ Math DisplayMath "y=x^2" ] ]
[ Para
[ Math
DisplayMath "\\begin{equation}\ny=x^2\n\\end{equation}"
]
]
```
+2 -2
View File
@@ -61,9 +61,9 @@ x &= y\\
^D
\(5-67\)
\[\begin{aligned}
\begin{align}
x &= y\\
\end{aligned}\]
\end{align}
\emph{hi}
+1 -1
View File
@@ -118,7 +118,7 @@ Accuracy~\eqref{eq:Accuracy} is the proportion, measuring true results among all
, Para
[ Math
DisplayMath
"\\label{eq:Accuracy}\n Accuracy = \\frac{t_p + t_n}{t_p + f_p + f_n + t_n}"
"\\begin{equation}\n \\label{eq:Accuracy}\n Accuracy = \\frac{t_p + t_n}{t_p + f_p + f_n + t_n}\n\\end{equation}"
]
]
```