[LyX/master] Add support for MathJax (#8480)
Juergen Spitzmueller
spitz at lyx.org
Sun Aug 16 07:24:12 UTC 2026
commit 14f12a88a4a088a0469685c808f4a5cac3d6d278
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sun Aug 16 09:20:45 2026 +0200
Add support for MathJax (#8480)
File format change.
---
development/FORMAT | 8 ++++++++
lib/lyx2lyx/lyx_2_6.py | 15 +++++++++++++--
src/Buffer.cpp | 10 ++++++++++
src/BufferParams.h | 3 ++-
src/OutputParams.h | 3 ++-
src/frontends/qt/ui/OutputUi.ui | 5 +++++
src/mathed/InsetMathHull.cpp | 16 ++++++++++++++++
src/version.h | 4 ++--
8 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/development/FORMAT b/development/FORMAT
index 1bbe350ffb..a798d73330 100644
--- a/development/FORMAT
+++ b/development/FORMAT
@@ -7,6 +7,14 @@ changes happened in particular if possible. A good example would be
-----------------------
+2026-08-03 Jürgen Spitzmüller <spitz at lyx.org>
+ * Format incremented to 659: Add new option
+ \html_math_output 5
+ (= MathJax)
+
+2026-08-04 Udi Fogiel <ufogiel at lyx.org>
+ * Format incremented to 658: Support for aligned overset.
+
2026-08-03 Jürgen Spitzmüller <spitz at lyx.org>
* Format incremented to 657: Support for \fronmatter, \mainmatter,
and \backmatter via paragraph parameter
diff --git a/lib/lyx2lyx/lyx_2_6.py b/lib/lyx2lyx/lyx_2_6.py
index a1e0171b50..73c5c8b837 100644
--- a/lib/lyx2lyx/lyx_2_6.py
+++ b/lib/lyx2lyx/lyx_2_6.py
@@ -1978,7 +1978,16 @@ def convert_svmatters(document):
document.body[i : i + 1] = ["\\begin_layout Standard", "\\start_of_matter mainmatter"]
elif matter == "Back Matter":
document.body[i : i + 1] = ["\\begin_layout Standard", "\\start_of_matter backmatter"]
-
+
+
+def revert_mathjax(document):
+ """Revert MathJax XHTML math output to default (MathMLCore)"""
+ i = find_token(document.header, "\\html_math_output", 0)
+ if i == -1:
+ return
+
+ if get_value(document.header, "\\html_math_output", i) == "5":
+ document.header[i] = "\\html_math_output 0"
##
# Conversion hub
@@ -2000,11 +2009,13 @@ convert = [
[655, []],
[656, []],
[657, [convert_svmatters]],
- [658, [convert_use_alignedoverset, convert_alignedoverset_body]]
+ [658, [convert_use_alignedoverset, convert_alignedoverset_body]],
+ [659, []]
]
revert = [
+ [658, [revert_mathjax]],
[657, [revert_use_alignedoverset]],
[656, [revert_matters]],
[655, [revert_parfillskip]],
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 64a471a60f..2c8cf086c9 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -2323,6 +2323,13 @@ Buffer::ExportStatus Buffer::writeLyXHTMLSource(odocstream & os,
xml::escapeString(doctitle, XMLStream::ESCAPE_ALL))
<< "</title>\n";
+ if (params().html_math_output == BufferParams::MathJax)
+ os << "\n<script id=\"MathJax-script\" "
+ << "async=\"async\" "
+ << "src=\"https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-chtml.js\">"
+ << "</script>"
+ << "\n\n";
+
docstring styles = features.getTClassHTMLPreamble();
if (!styles.empty())
os << "\n<!-- Text Class Preamble -->\n" << styles << '\n';
@@ -4632,6 +4639,9 @@ void Buffer::setMathFlavor(OutputParams & op) const
case BufferParams::LaTeX:
op.math_flavor = OutputParams::MathAsLaTeX;
break;
+ case BufferParams::MathJax:
+ op.math_flavor = OutputParams::MathAsMathJax;
+ break;
}
}
diff --git a/src/BufferParams.h b/src/BufferParams.h
index 5a1a67341a..41a1c94583 100644
--- a/src/BufferParams.h
+++ b/src/BufferParams.h
@@ -646,7 +646,8 @@ public:
MathML3 = 4,
HTML = 1,
Images = 2,
- LaTeX = 3
+ LaTeX = 3,
+ MathJax = 5
};
/// what to use for math output. present choices are above
MathOutput html_math_output;
diff --git a/src/OutputParams.h b/src/OutputParams.h
index f6d1830dc1..f76f44f177 100644
--- a/src/OutputParams.h
+++ b/src/OutputParams.h
@@ -58,7 +58,8 @@ public:
MathAsMathML3,
MathAsHTML,
MathAsImages,
- MathAsLaTeX
+ MathAsLaTeX,
+ MathAsMathJax
};
enum TableCell {
diff --git a/src/frontends/qt/ui/OutputUi.ui b/src/frontends/qt/ui/OutputUi.ui
index 451ee27bda..958fd52817 100644
--- a/src/frontends/qt/ui/OutputUi.ui
+++ b/src/frontends/qt/ui/OutputUi.ui
@@ -322,6 +322,11 @@
<string>MathML 3</string>
</property>
</item>
+ <item>
+ <property name="text">
+ <string>MathJax</string>
+ </property>
+ </item>
</widget>
</item>
<item>
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index dd980f5640..731c57b06a 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -2803,6 +2803,22 @@ void InsetMathHull::xhtml(XMLStream & xs, OutputParams const & op) const
}
// In case of failure, generate an image.
}
+ if (mathtype == BufferParams::MathJax) {
+ // Unfortunately, we cannot use latexString() because we want
+ // \(...\) rather than $...$.
+ // The returned value already has the correct escaping for HTML.
+ docstring const latex = mathAsLatex();
+
+ // FIXME XHTML
+ // probably should allow for some kind of customization here
+ docstring const starttag = (getType() == hullSimple) ? from_ascii("\\(") : from_ascii("\\[");
+ docstring const endtag = (getType() == hullSimple) ? from_ascii("\\)") : from_ascii("\\]");
+ xs << starttag
+ << XMLStream::ESCAPE_NONE << latex
+ << endtag
+ << xml::CR();
+ success = true;
+ }
// what we actually want is this:
// if (
diff --git a/src/version.h b/src/version.h
index 3a5466b998..0dd6564083 100644
--- a/src/version.h
+++ b/src/version.h
@@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 658 // ufogiel: aligned-overset
-#define LYX_FORMAT_TEX2LYX 658
+#define LYX_FORMAT_LYX 659 // spitz: MathJax
+#define LYX_FORMAT_TEX2LYX 659
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER
More information about the lyx-cvs
mailing list