[LyX/master] Add support for MathJax (#8480)

Juergen Spitzmueller <[email protected]>
Newsgroups gmane.editors.lyx.cvs
Message-ID <[email protected]>
commit 14f12a88a4a088a0469685c808f4a5cac3d6d278
Author: Juergen Spitzmueller <[email protected]>
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 <[email protected]>
+	* Format incremented to 659: Add new option
+	\html_math_output 5
+	(= MathJax)
+
+2026-08-04 Udi Fogiel <[email protected]>
+	* Format incremented to 658: Support for aligned overset.
+
 2026-08-03 Jürgen Spitzmüller <[email protected]>
 	* 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
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.