1 /* This file is part of EdiTeX, an editor of mathematical
2 * expressions based on TeX syntax.
4 * Copyright (C) 2002-2003 Luca Padovani <lpadovan@cs.unibo.it>,
5 * 2003 Paolo Marinelli <pmarinel@cs.unibo.it>.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library 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 GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * For more information, please visit the project's home page
22 * http://helm.cs.unibo.it/editex/
23 * or send an email to <lpadovan@cs.unibo.it>
30 #include <gdome-util.h>
31 #include <GdomeSmartDOM.hh>
33 //#include "gmetadom.hh"
35 namespace DOM = GdomeSmartDOM;
38 getDepth(const DOM::Element& elem)
41 DOM::Element p = elem;
45 p = p.get_parentNode();
53 findCommonAncestor(const DOM::Element& first, const DOM::Element& last)
58 DOM::Element p(first);
63 unsigned pDepth = getDepth(p);
64 unsigned qDepth = getDepth(q);
66 while (p && pDepth > qDepth)
68 p = p.get_parentNode();
72 while (q && qDepth > pDepth)
74 q = q.get_parentNode();
78 assert(pDepth == qDepth);
80 while (p && q && p != q)
82 p = p.get_parentNode();
83 q = q.get_parentNode();
91 findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
92 DOM::Element& firstS, DOM::Element& lastS)
97 DOM::Element p(first);
102 unsigned pDepth = getDepth(p);
103 unsigned qDepth = getDepth(q);
105 while (p && pDepth > qDepth)
107 p = p.get_parentNode();
111 while (q && qDepth > pDepth)
113 q = q.get_parentNode();
117 assert(pDepth == qDepth);
119 while (p && q && p.get_parentNode() != q.get_parentNode())
121 p = p.get_parentNode();
122 q = q.get_parentNode();
131 findElementWithRef(const DOM::Element& el)
134 while (p && !p.hasAttribute("xref")) p = p.get_parentNode();
139 leftmostChild(const DOM::Node& node)
141 if (!node) return node;
143 DOM::Node firstChild = node.get_firstChild();
144 if (!firstChild) return node;
146 return leftmostChild(firstChild);
150 rightmostChild(const DOM::Node& node)
152 if (!node) return node;
154 DOM::Node lastChild = node.get_lastChild();
155 if (!lastChild) return node;
157 return rightmostChild(lastChild);
161 leftSibling(const DOM::Node& node)
167 while (p.get_parentNode() && p.get_parentNode().get_firstChild() == p)
168 p = p.get_parentNode();
170 if (!p.get_parentNode()) return DOM::Node(0);
172 DOM::Node prevSibling = p.get_previousSibling();
175 return rightmostChild(prevSibling);
179 rightSibling(const DOM::Node& node)
185 DOM::Node firstChild = p.get_firstChild();
186 if (firstChild) return firstChild;
188 while (p.get_parentNode() && p.get_parentNode().get_lastChild() == p)
189 p = p.get_parentNode();
191 if (!p.get_parentNode()) return DOM::Node(0);
193 DOM::Node nextSibling = p.get_nextSibling();
196 return leftmostChild(nextSibling);
199 extern "C" GdomeElement*
200 find_common_ancestor(GdomeElement* first, GdomeElement* last)
202 if (GdomeNode* n = findCommonAncestor(DOM::Element(first), DOM::Element(last)).gdome_object())
204 GdomeElement* res = gdome_cast_el(n);
205 g_assert(res != NULL);
213 find_common_siblings(GdomeElement* first, GdomeElement* last,
214 GdomeElement** firstS, GdomeElement** lastS)
219 findCommonSiblings(DOM::Element(first), DOM::Element(last), fs, ls);
221 if (firstS != NULL) *firstS = gdome_cast_el(fs.gdome_object());
222 if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
225 extern "C" GdomeElement*
226 find_element_with_ref(GdomeElement* elem)
228 if (GdomeNode* n = findElementWithRef(DOM::Element(elem)).gdome_object())
230 GdomeElement* res = gdome_cast_el(n);
231 g_assert(res != NULL);
238 extern "C" GdomeElement*
239 find_common_ancestor_with_ref(GdomeElement* first, GdomeElement* last)
241 if (GdomeNode* n = findElementWithRef(findCommonAncestor(DOM::Element(first), DOM::Element(last))).gdome_object())
243 GdomeElement* res = gdome_cast_el(n);
244 g_assert(res != NULL);
252 delete_element(GdomeElement* elem)
254 DOM::Element p(elem);
256 DOM::Element parent = p.get_parentNode();
259 parent.removeChild(p);