]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/test/aux.cc
ocaml 3.09 transition
[helm.git] / helm / DEVEL / mathml_editor / test / aux.cc
1 /* This file is part of EdiTeX, an editor of mathematical
2  * expressions based on TeX syntax.
3  * 
4  * Copyright (C) 2002-2003 Luca Padovani <lpadovan@cs.unibo.it>,
5  *                    2003 Paolo Marinelli <pmarinel@cs.unibo.it>.
6  *
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.
11  *
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.
16  *
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
20  *
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>
24  */
25
26 #include <config.h>
27 #include <assert.h>
28
29 #include <gdome.h>
30 #include <gdome-util.h>
31 #include <GdomeSmartDOM.hh>
32
33 //#include "gmetadom.hh"
34
35 namespace DOM = GdomeSmartDOM;
36
37 static unsigned
38 getDepth(const DOM::Element& elem)
39 {
40   unsigned length = 0;
41   DOM::Element p = elem;
42
43   while (p)
44     {
45       p = p.get_parentNode();
46       length++;
47     }
48
49   return length;
50 }
51
52 static DOM::Element
53 findCommonAncestor(const DOM::Element& first, const DOM::Element& last)
54 {
55   assert(first);
56   assert(last);
57
58   DOM::Element p(first);
59   DOM::Element q(last);
60
61   if (p != q)
62     {
63       unsigned pDepth = getDepth(p);
64       unsigned qDepth  = getDepth(q);
65
66       while (p && pDepth > qDepth)
67         {
68           p = p.get_parentNode();
69           pDepth--;
70         }
71
72       while (q && qDepth > pDepth)
73         {
74           q = q.get_parentNode();
75           qDepth--;
76         }
77
78       assert(pDepth == qDepth);
79
80       while (p && q && p != q)
81         {
82           p = p.get_parentNode();
83           q = q.get_parentNode();
84         }
85     }
86   
87   return p;
88 }
89
90 static void
91 findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
92                    DOM::Element& firstS, DOM::Element& lastS)
93 {
94   assert(first);
95   assert(last);
96
97   DOM::Element p(first);
98   DOM::Element q(last);
99
100   if (p != q)
101     {
102       unsigned pDepth = getDepth(p);
103       unsigned qDepth  = getDepth(q);
104
105       while (p && pDepth > qDepth)
106         {
107           p = p.get_parentNode();
108           pDepth--;
109         }
110
111       while (q && qDepth > pDepth)
112         {
113           q = q.get_parentNode();
114           qDepth--;
115         }
116
117       assert(pDepth == qDepth);
118
119       while (p && q && p.get_parentNode() != q.get_parentNode())
120         {
121           p = p.get_parentNode();
122           q = q.get_parentNode();
123         }
124     }
125
126   firstS = p;
127   lastS = q;
128 }
129
130 static DOM::Element
131 findElementWithRef(const DOM::Element& el)
132 {
133   DOM::Element p = el;
134   while (p && !p.hasAttribute("xref")) p = p.get_parentNode();
135   return p;
136 }
137
138 static DOM::Node
139 leftmostChild(const DOM::Node& node)
140 {
141   if (!node) return node;
142
143   DOM::Node firstChild = node.get_firstChild();
144   if (!firstChild) return node;
145
146   return leftmostChild(firstChild);
147 }
148
149 static DOM::Node
150 rightmostChild(const DOM::Node& node)
151 {
152   if (!node) return node;
153
154   DOM::Node lastChild = node.get_lastChild();
155   if (!lastChild) return node;
156
157   return rightmostChild(lastChild);
158 }
159
160 static DOM::Node
161 leftSibling(const DOM::Node& node)
162 {
163   DOM::Node p = node;
164
165   if (!p) return p;
166
167   while (p.get_parentNode() && p.get_parentNode().get_firstChild() == p)
168     p = p.get_parentNode();
169
170   if (!p.get_parentNode()) return DOM::Node(0);
171
172   DOM::Node prevSibling = p.get_previousSibling();
173   assert(prevSibling);
174
175   return rightmostChild(prevSibling);
176 }
177
178 static DOM::Node
179 rightSibling(const DOM::Node& node)
180 {
181   DOM::Node p = node;
182
183   if (!p) return p;
184
185   DOM::Node firstChild = p.get_firstChild();
186   if (firstChild) return firstChild;
187
188   while (p.get_parentNode() && p.get_parentNode().get_lastChild() == p)
189     p = p.get_parentNode();
190
191   if (!p.get_parentNode()) return DOM::Node(0);
192
193   DOM::Node nextSibling = p.get_nextSibling();
194   assert(nextSibling);
195
196   return leftmostChild(nextSibling);
197 }
198
199 extern "C" GdomeElement*
200 find_common_ancestor(GdomeElement* first, GdomeElement* last)
201 {
202   if (GdomeNode* n = findCommonAncestor(DOM::Element(first), DOM::Element(last)).gdome_object())
203     {
204       GdomeElement* res = gdome_cast_el(n);
205       g_assert(res != NULL);
206       return res;
207     }
208   else
209     return NULL;
210 }
211
212 extern "C" void
213 find_common_siblings(GdomeElement* first, GdomeElement* last,
214                      GdomeElement** firstS, GdomeElement** lastS)
215 {
216   DOM::Element fs(0);
217   DOM::Element ls(0);
218
219   findCommonSiblings(DOM::Element(first), DOM::Element(last), fs, ls);
220
221   if (firstS != NULL) *firstS = gdome_cast_el(fs.gdome_object());
222   if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
223 }
224
225 extern "C" GdomeElement*
226 find_element_with_ref(GdomeElement* elem)
227 {
228   if (GdomeNode* n = findElementWithRef(DOM::Element(elem)).gdome_object())
229     {
230       GdomeElement* res = gdome_cast_el(n);
231       g_assert(res != NULL);
232       return res;
233     }
234   else
235     return NULL;
236 }
237
238 extern "C" GdomeElement*
239 find_common_ancestor_with_ref(GdomeElement* first, GdomeElement* last)
240 {
241   if (GdomeNode* n = findElementWithRef(findCommonAncestor(DOM::Element(first), DOM::Element(last))).gdome_object())
242     {
243       GdomeElement* res = gdome_cast_el(n);
244       g_assert(res != NULL);
245       return res;
246     }
247   else
248     return NULL;
249 }
250
251 extern "C" void
252 delete_element(GdomeElement* elem)
253 {
254   DOM::Element p(elem);
255
256   DOM::Element parent = p.get_parentNode();
257   assert(parent);
258
259   parent.removeChild(p);
260 }
261