1 /* Copyright (C) 2002-2003, Luca Padovani <luca.padovani@cs.unibo.it>,
2 * 2003, Paolo Marinelli <pmarinel@cs.unibo.it>.
4 * This file is part of EdiTeX, an editor of mathematical
5 * expressions based on TeX syntax
7 * EdiTeX is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * EdiTeX is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with EdiTeX; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * For details, see the EdiTeX World-Wide-Web page,
22 * http://helm.cs.unibo.it/editex, or send a mail to
23 * <luca.padovani@cs.unibo.it>
25 // Copyright (C) 2000-2002, Luca Padovani <luca.padovani@cs.unibo.it>.
27 // This file is part of GtkMathView, a Gtk widget for MathML.
29 // GtkMathView is free software; you can redistribute it and/or
30 // modify it under the terms of the GNU General Public License
31 // as published by the Free Software Foundation; either version 2
32 // of the License, or (at your option) any later version.
34 // GtkMathView is distributed in the hope that it will be useful,
35 // but WITHOUT ANY WARRANTY; without even the implied warranty of
36 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 // GNU General Public License for more details.
39 // You should have received a copy of the GNU General Public License
40 // along with GtkMathView; if not, write to the Free Software
41 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43 // For details, see the GtkMathView World-Wide-Web page,
44 // http://www.cs.unibo.it/helm/mml-widget, or send a mail to
45 // <luca.padovani@cs.unibo.it>
51 #include <gdome-util.h>
52 #include <GdomeSmartDOM.hh>
54 //#include "gmetadom.hh"
56 namespace DOM = GdomeSmartDOM;
59 getDepth(const DOM::Element& elem)
62 DOM::Element p = elem;
66 p = p.get_parentNode();
74 findCommonAncestor(const DOM::Element& first, const DOM::Element& last)
79 DOM::Element p(first);
84 unsigned pDepth = getDepth(p);
85 unsigned qDepth = getDepth(q);
87 while (p && pDepth > qDepth)
89 p = p.get_parentNode();
93 while (q && qDepth > pDepth)
95 q = q.get_parentNode();
99 assert(pDepth == qDepth);
101 while (p && q && p != q)
103 p = p.get_parentNode();
104 q = q.get_parentNode();
112 findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
113 DOM::Element& firstS, DOM::Element& lastS)
118 DOM::Element p(first);
119 DOM::Element q(last);
123 unsigned pDepth = getDepth(p);
124 unsigned qDepth = getDepth(q);
126 while (p && pDepth > qDepth)
128 p = p.get_parentNode();
132 while (q && qDepth > pDepth)
134 q = q.get_parentNode();
138 assert(pDepth == qDepth);
140 while (p && q && p.get_parentNode() != q.get_parentNode())
142 p = p.get_parentNode();
143 q = q.get_parentNode();
152 findElementWithRef(const DOM::Element& el)
155 while (p && !p.hasAttribute("xref")) p = p.get_parentNode();
160 leftmostChild(const DOM::Node& node)
162 if (!node) return node;
164 DOM::Node firstChild = node.get_firstChild();
165 if (!firstChild) return node;
167 return leftmostChild(firstChild);
171 rightmostChild(const DOM::Node& node)
173 if (!node) return node;
175 DOM::Node lastChild = node.get_lastChild();
176 if (!lastChild) return node;
178 return rightmostChild(lastChild);
182 leftSibling(const DOM::Node& node)
188 while (p.get_parentNode() && p.get_parentNode().get_firstChild() == p)
189 p = p.get_parentNode();
191 if (!p.get_parentNode()) return DOM::Node(0);
193 DOM::Node prevSibling = p.get_previousSibling();
196 return rightmostChild(prevSibling);
200 rightSibling(const DOM::Node& node)
206 DOM::Node firstChild = p.get_firstChild();
207 if (firstChild) return firstChild;
209 while (p.get_parentNode() && p.get_parentNode().get_lastChild() == p)
210 p = p.get_parentNode();
212 if (!p.get_parentNode()) return DOM::Node(0);
214 DOM::Node nextSibling = p.get_nextSibling();
217 return leftmostChild(nextSibling);
220 extern "C" GdomeElement*
221 find_common_ancestor(GdomeElement* first, GdomeElement* last)
223 if (GdomeNode* n = findCommonAncestor(DOM::Element(first), DOM::Element(last)).gdome_object())
225 GdomeElement* res = gdome_cast_el(n);
226 g_assert(res != NULL);
234 find_common_siblings(GdomeElement* first, GdomeElement* last,
235 GdomeElement** firstS, GdomeElement** lastS)
240 findCommonSiblings(DOM::Element(first), DOM::Element(last), fs, ls);
242 if (firstS != NULL) *firstS = gdome_cast_el(fs.gdome_object());
243 if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
246 extern "C" GdomeElement*
247 find_element_with_ref(GdomeElement* elem)
249 if (GdomeNode* n = findElementWithRef(DOM::Element(elem)).gdome_object())
251 GdomeElement* res = gdome_cast_el(n);
252 g_assert(res != NULL);
259 extern "C" GdomeElement*
260 find_common_ancestor_with_ref(GdomeElement* first, GdomeElement* last)
262 if (GdomeNode* n = findElementWithRef(findCommonAncestor(DOM::Element(first), DOM::Element(last))).gdome_object())
264 GdomeElement* res = gdome_cast_el(n);
265 g_assert(res != NULL);
273 delete_element(GdomeElement* elem)
275 DOM::Element p(elem);
277 DOM::Element parent = p.get_parentNode();
280 parent.removeChild(p);