commit 922c81078b2ad6d515eed146c8767585f52fdb29
Author: Thibaut Cuvelier <[email protected]>
Date: Mon Mar 24 00:28:09 2025 +0100
InsetMathHull: merge the two code paths in `mathAsLatex`.
One path exports raw LaTeX (without any kind of escaping), while the other
returns a mix of XHTML and LaTeX with proper XML escaping. With a single code
path, escaping rules are identical in all cases, which avoids double escaping
in some cases.
---
autotests/export/xhtml/math_output_latex.lyx | 11 +++++
autotests/export/xhtml/math_output_latex.xhtml | 4 ++
src/mathed/InsetMathHull.cpp | 68 +++-----------------------
3 files changed, 23 insertions(+), 60 deletions(-)
diff --git a/autotests/export/xhtml/math_output_latex.lyx
b/autotests/export/xhtml/math_output_latex.lyx
index b1c85b3c97..eb3aa143fd 100644
--- a/autotests/export/xhtml/math_output_latex.lyx
+++ b/autotests/export/xhtml/math_output_latex.lyx
@@ -133,6 +133,17 @@ q & w & e & r
\end_inset
+Worse still:
+\begin_inset Formula
+\[
+\smashoperator{\sum_{\begin{subarray}{c}
+0<k<1000\\
+\\k\,\in\,\mathbb{N}
+\end{subarray}}^{n}}k^{-2}
+\]
+
+\end_inset
+
\end_layout
diff --git a/autotests/export/xhtml/math_output_latex.xhtml
b/autotests/export/xhtml/math_output_latex.xhtml
index f070e9bf9a..2291a0ba3f 100644
--- a/autotests/export/xhtml/math_output_latex.xhtml
+++ b/autotests/export/xhtml/math_output_latex.xhtml
@@ -30,6 +30,10 @@ A & B & C & D\\
\hdotsfor[2]{4}\\
q & w & e & r
\end{array}\right)</div>
+Worse still:<div class='math'>\smashoperator{\sum_{\begin{subarray}{c}
+0<k<1000\\
+\\k\,\in\,\mathbb{N}
+\end{subarray}}^{n}}k^{-2}</div>
</div>
</body>
</html>
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index d9e5c5c67b..e7be2d3a52 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -2604,28 +2604,14 @@ void InsetMathHull::mathmlize(MathMLStream & ms) const
docstring InsetMathHull::mathAsLatex() const
{
- bool const havenumbers = haveNumbers();
- bool const havetable = havenumbers || nrows() > 1 || ncols() > 1;
-
- if (!havetable) {
- odocstringstream ls;
- otexrowstream ots(ls);
- TeXMathStream os(ots, false, true, TeXMathStream::wsPreview);
- ModeSpecifier specifier(os, MATH_MODE);
- MathEnsurer ensurer(os, false);
-
- os << cell(index(0, 0));
- return ls.str();
- }
-
odocstringstream ods;
XMLStream xs(ods);
- xs << xml::StartTag("table", "class='mathtable'");
+ if (haveNumbers()) { xs << xml::StartTag("table", "class='mathtable'");
}
for (row_type row = 0; row < nrows(); ++row) {
- xs << xml::StartTag("tr");
+ if (haveNumbers()) { xs << xml::StartTag("tr"); }
for (col_type col = 0; col < ncols(); ++col) {
- xs << xml::StartTag("td", "class='math'");
+ if (haveNumbers()) { xs << xml::StartTag("td",
"class='math'"); }
odocstringstream ls;
otexrowstream ots(ls);
@@ -2637,9 +2623,9 @@ docstring InsetMathHull::mathAsLatex() const
// ls.str() contains a raw LaTeX string, which might
require some encoding before being valid XML.
xs << ls.str();
- xs << xml::EndTag("td");
+ if (haveNumbers()) { xs << xml::EndTag("td"); }
}
- if (havenumbers) {
+ if (haveNumbers()) {
xs << xml::StartTag("td");
docstring const & num = numbers_[row];
if (!num.empty()) {
@@ -2647,9 +2633,9 @@ docstring InsetMathHull::mathAsLatex() const
}
xs << xml::EndTag("td");
}
- xs << xml::EndTag("tr");
+ if (haveNumbers()) { xs << xml::EndTag("tr"); }
}
- xs << xml::EndTag("table");
+ if (haveNumbers()) { xs << xml::EndTag("table"); }
return ods.str();
}
@@ -2772,51 +2758,13 @@ docstring InsetMathHull::xhtml(XMLStream & xs,
OutputParams const & op) const
// The returned value already has the correct escaping for HTML.
docstring const latex = mathAsLatex();
- // Escaping this string is hairy. `latex` contains some XHTML
and
- // we don't want the output to look like this:
- // <table class='mathtable'>
- // We have to perform some escaping, otherwise a matrix will be
- // output with raw ampersands:
- // \left(\begin{array}{cccc}
- // A & B & C & D\\
- // \hdotsfor[2]{4}\\
- // q & w & e & r
- // \end{array}\right)
- // We cannot perform standard XML escaping, otherwise the XHTML
- // will be off. We must escape at the very least &, as it's
common
- // (not escaping it causes many failures in tests for
doc/Math.lyx).
- // Not escaping < causes problems if it comes from LaTeX.
Escaping >
- // is not really required (but it would be best).
- //
- // Current compromise: only escape &. It is safe to do so.
Unescape
- // some angle brackets too.
- //
- // To get a better result, we would need to have a better
handling
- // of escaping, as `latex` already has some parts that are
escaped.
- // The root cause is that `mathAsLatex` outputs both LaTeX and
XHTML
- // code intertwined in the right way.
- //
- // When debugging this code, pay attention to the differences
- // between exporting and previewing (in preview mode, LyX won't
- // attempt generating an image, thus never exercising this code).
- docstring const latex_escaped = subst(
- subst(
- subst(
- latex,
- from_ascii("&"), from_ascii("&")
- ),
- from_ascii("&lt;"), from_ascii("<")
- ),
- from_ascii("&gt;"), from_ascii(">")
- );
-
// class='math' allows for use of jsMath
// http://www.math.union.edu/~dpvc/jsMath/
// FIXME XHTML
// probably should allow for some kind of customization here
string const tag = (getType() == hullSimple) ? "span" : "div";
xs << xml::StartTag(tag, "class='math'")
- << XMLStream::ESCAPE_NONE << latex_escaped
+ << XMLStream::ESCAPE_NONE << latex
<< xml::EndTag(tag)
<< xml::CR();
}
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs