commit 922c81078b2ad6d515eed146c8767585f52fdb29 Author: Thibaut Cuvelier <tcuvel...@lyx.org> 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 lyx-cvs@lists.lyx.org https://lists.lyx.org/mailman/listinfo/lyx-cvs