Indeed, that worked very well -- thanks a lot!

Attached is the patch that I came up with.

On Tue, Jun 11, 2024, at 10:03 AM, Jean-Marc Lasgouttes wrote:
> Le 11/06/2024 à 15:59, Alexander Dunlap a écrit :
> >> LyX uses either cmake (required for windows) or autoconf[*] (from which
> >> other official releases are done AFAIK). What is your preference for
> >> testing?
> > 
> > I have been using autoconf and qt6.
> 
> So it is the easy case. What you need is around line 420 of config/qt.m4
> I guess you will have no difficulty to add xml there.
> 
> JMarc
> -- 
> lyx-devel mailing list
> lyx-devel@lists.lyx.org
> http://lists.lyx.org/mailman/listinfo/lyx-devel
> 
From 8ce5c986e4d676ee50b7306a83acb4956f3fcc56 Mon Sep 17 00:00:00 2001
From: Alexander Dunlap <alexander.dun...@gmail.com>
Date: Tue, 11 Jun 2024 10:58:36 -0400
Subject: [PATCH] using XML parser in splitAndWrapInMText to fix #13069

---
 config/qt.m4                |  1 +
 src/mathed/InsetMathBox.cpp | 75 ++++++++++++++-----------------------
 2 files changed, 29 insertions(+), 47 deletions(-)

diff --git a/config/qt.m4 b/config/qt.m4
index 7e7ffd6df2..1dfa322b00 100644
--- a/config/qt.m4
+++ b/config/qt.m4
@@ -418,6 +418,7 @@ qtHaveModule(gui)		{QT += gui} else {MISSING += gui}
 qtHaveModule(gui-private)	{QT += gui-private} else {MISSING += gui-private}
 qtHaveModule(svg)		{QT += svg} else {MISSING += svg}
 qtHaveModule(svgwidgets)	{QT += svgwidgets} else {MISSING += svgwidgets}
+qtHaveModule(xml)       	{QT += xml} else {MISSING += xml}
 qtHaveModule(widgets)		{QT += widgets} else {MISSING += widgets}
 percent.target = %
 percent.commands = @echo -n "\$(\$(@))\ "
diff --git a/src/mathed/InsetMathBox.cpp b/src/mathed/InsetMathBox.cpp
index 6feddf9cdd..037c233436 100644
--- a/src/mathed/InsetMathBox.cpp
+++ b/src/mathed/InsetMathBox.cpp
@@ -28,6 +28,10 @@
 #include <iostream>
 #include <ostream>
 
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+#include "support/qstring_helpers.h"
+
 using namespace lyx::support;
 
 namespace lyx {
@@ -74,53 +78,30 @@ void splitAndWrapInMText(MathMLStream & ms, MathData const & cell,
 		inset_contents = ostmp.str();
 	}
 
-	// No tags are allowed within <m:mtext>: split the string if there are tags.
-	std::vector<docstring> parts;
-	while (true) {
-		std::size_t angle_pos = inset_contents.find('<');
-		if (angle_pos == docstring::npos)
-			break;
-
-		// String structure:
-		// - prefix: pure text, no tag
-		// - tag to split: something like <m:mn>1</m:mn> or more complicated
-		//   (like nested tags), with or without name space
-		// - rest to be taken care of in the next iteration
-
-		// Push the part before the tag.
-		parts.emplace_back(inset_contents.substr(0, angle_pos));
-		inset_contents = inset_contents.substr(angle_pos);
-		// Now, inset_contents starts with the tag to isolate, so that
-		//     inset_contents[0] == '<'
-
-		// Push the tag, up to its end. Process: find the tag name (either
-		// before > or the first attribute of the tag), then the matching end
-		// tag, then proceed with pushing.
-		const std::size_t tag_name_end =
-				std::min(inset_contents.find(' ', 1), inset_contents.find('>', 1));
-		const std::size_t tag_name_length = tag_name_end - 1;
-		const docstring tag_name = inset_contents.substr(1, tag_name_length);
-
-		const std::size_t end_tag_start =
-				inset_contents.find(tag_name, tag_name_end + 1);
-		const std::size_t end_tag = inset_contents.find('>', end_tag_start);
-
-		parts.emplace_back(inset_contents.substr(0, end_tag + 1));
-		inset_contents = inset_contents.substr(end_tag + 1);
-	}
-	parts.emplace_back(inset_contents);
-
-	// Finally, output the complete inset: escape the test in <m:mtext>, leave
-	// the other tags untouched.
-	ms << MTag("mrow", attributes);
-	for (std::size_t i = 0; i < parts.size(); i += 2) {
-		ms << MTag("mtext")
-		   << parts[i]
-		   << ETag("mtext");
-		if (parts.size() > i + 1)
-			ms << parts[i + 1];
-	}
-	ms << ETag("mrow");
+        docstring inset_contents_xml = "<root>" + inset_contents + "</root>";
+
+        QDomDocument xml;
+        xml.setContent(toqstr(inset_contents_xml));
+
+        QDomElement docElem = xml.documentElement();
+
+        QDomNode n = docElem.firstChild();
+        while (!n.isNull()) {
+            QDomText text = n.toText();
+            if (!text.isNull()) {
+                QDomElement wrapper = xml.createElement("mtext");
+                docElem.insertBefore(wrapper,n);
+                wrapper.appendChild(n);
+                n = wrapper.nextSibling();
+            } else {
+                n = n.nextSibling();
+            }
+        }
+
+        ms << MTag("mrow", attributes);
+        docstring interior = qstring_to_ucs4(xml.toString(-1));
+        ms << interior.substr(6,interior.length()-13);
+        ms << ETag("mrow");
 }
 }
 
-- 
2.45.2

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to