--- /dev/null
+
+DOM::Element
+getRightmostChild(const DOM::Element& p)
+{
+ if (p)
+ {
+ if (DOM::Element last = g.get_lastChild())
+ if (last.get_nodeName() == "g" && last.get_firstChild())
+ return getRightmostChild(last);
+ else
+ return last;
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+DOM::Element
+prevLinearSibling(const DOM::Element& p)
+{
+ if (p)
+ {
+ DOM::Element prev = p.get_prevSibling();
+ if (!prev) return 0;
+ else if (prev.get_nodeName() != "g" && prev.get_firstChild()) return prev;
+ else return prevLinearSibling(prev.get_lastChild());
+ }
+ else
+ return 0;
+}
+
+DOM::Element
+getCore(const DOM::Element& p)
+{
+ if (p)
+ {
+ if (p.get_nodeName() == "sb" || p.get_nodeName() == "sp")
+ return getCore(p.get_firstChild());
+ else return p;
+ }
+ else
+ return 0;
+}
+
+void
+replace(const DOM::Element& p0, const DOM::Element& p1)
+{
+ if (DOM::Element parent = p0.get_parentNode())
+ parent.replaceChild(p0, p1);
+}
+
+bool
+isInferred(const DOM::Element& p)
+{
+ if (p) return p.hasAttribute("id");
+ else return false;
+}
+
+bool
+isMacro(const DOM::Element& p, const TString& s)
+{
+ return p && p.get_nodeName() == "m" && p.getAttribute("name") == s;
+}
+
+bool
+isGroup(const DOM::Element& p)
+{
+ return p && p.get_nodeName() == "g";
+}
+
+bool
+isSb(const DOM::Element& p)
+{
+ return p && p.get_nodeName() == "sb";
+}
+
+bool
+isSp(const DOM::Element& p)
+{
+ return p && p.get_nodeName() == "sp";
+}
+
+bool
+isPrimes(const DOM::Element& p)
+{
+ return isGroup(p) && isMacro(p.get_lastChild, "prime");
+}
+
+bool
+isOperator(const DOM::Element& p)
+{
+ if (DOM::Element core = getCore(p))
+ return dictionary.isOperator(core.get_nodeName());
+ else
+ return false;
+}
+
+bool
+isDelimiter(const DOM::Element& p)
+{
+ if (DOM::Element core = getCore(p))
+ return dictionary.isDelimiter(core.get_nodeName());
+ else
+ return false;
+}
+
+bool
+isFunction(const DOM::Element& p)
+{
+ if (DOM::Element core = getCore(p))
+ return dictionary.isFunction(core.get_nodeName());
+ else
+ return false;
+}