]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/test/editor.cc
Now it's possible to insert and delete control sequence with arguments
[helm.git] / helm / DEVEL / mathml_editor / test / editor.cc
1
2 #include "TNode.hh"
3 #include "TToken.hh"
4 #include "TDocument.hh"
5 #include "TPushParser.hh"
6 #include "TPushLexer.hh"
7 #include "TDictionary.hh"
8 #include "TListener.hh"
9 #include <GdomeSmartDOMXSLT.hh>
10
11 #include "guiGTK.h"
12
13 class MyResultListener : public DOM::EventListener
14 {
15 public:
16   MyResultListener(const std::string& s) : msg(s) { };
17
18   virtual void handleEvent(const DOM::Event&);
19
20 private:
21   const std::string msg;
22 };
23
24 void
25 MyResultListener::handleEvent(const DOM::Event& ev)
26 {
27   cout << "RECEIVED EVENT: " << ev.get_type() << " " << msg << " ";
28   const DOM::MutationEvent& me(ev);
29   assert(me);
30   const DOM::Node target(me.get_target());
31   assert(target);
32   cout << "target = " << target.get_nodeName() << " " << target.get_nodeType() << endl;
33 }
34
35 MyResultListener l1("?");
36
37 TDictionary dictionary;
38 DOM::Document result;
39
40 extern void *parseMathMLFile(char *);
41
42 bool
43 subst(const DOM::Element& e1, const DOM::GdomeString& id, const DOM::Element& e2)
44 {
45   assert(e1);
46   assert(e2);
47   if (e1.getAttribute("xref") == id)
48     {
49       DOM::Node parent = e1.get_parentNode();
50       assert(parent);
51       DOM::Node next = e1.get_nextSibling();
52       parent.removeChild(e1);
53       parent.insertBefore(e2, next);
54       //parent.replaceChild(e2, e1);
55       return true;
56     }
57   else
58     {
59       DOM::Node p = e1.get_firstChild();
60       while (p)
61         {
62           while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_nextSibling();
63           if (p)
64             if (subst(p, id, e2)) return true;
65             else p = p.get_nextSibling();
66         }
67       return false;
68     }
69 }
70
71 class MyListener : public TListener
72 {
73 public:
74   MyListener(const DOM::XSLTStylesheet& s) : style(s) { };
75
76   void callback(TDocument& doc)
77   {
78     cout << "listener callback " << static_cast<GdomeNode*>(doc.document()) << endl;
79     TNode dirty = doc.dirtyNode();
80     if (dirty) 
81       {
82         cout << "recreating subtree with id " << std::string(dirty["id"]) << endl;
83         std::vector< std::pair<DOM::GdomeString, DOM::GdomeString> > dirtyId;
84         if (result)
85           dirtyId.push_back(std::make_pair(DOM::GdomeString("id"),
86                                            DOM::GdomeString("'" + std::string(dirty["id"]) + "'")));
87
88         DOM::Document res = style.apply(doc.document(), dirtyId);
89         assert(res);
90         style.save(doc.document(), stdout);
91         //style.save(res, stdout);
92         if (result)
93           {
94             cout << "REPLACING A FRAGMENT OF THE DOCUMENT" << endl;
95             DOM::Element root = res.get_documentElement();
96             assert(root);
97             assert(root.hasAttribute("xref"));
98
99             if (result.get_documentElement().getAttribute("xref") == root.getAttribute("xref"))
100               {
101                 cout << "REPLACING ROOT" << endl;
102                 result.replaceChild(result.importNode(root, true), result.get_documentElement());
103 #if 0
104                 // the following remove should not be necessary
105                 // according to the spec replaceChild should work just fine
106                 result.removeChild(result.get_documentElement());
107                 result.appendChild(result.importNode(root, true));
108 #endif
109               }
110             else
111               try
112                 {
113                   cout << "before" << endl;
114                   bool ok = subst(result.get_documentElement(), root.getAttribute("xref"), result.importNode(root, true));
115                   assert(ok);
116                   cout << "after" << endl;
117                 }
118               catch (DOM::DOMException e)
119                 {
120                   cout << "!!!!!!!!!!!!!!!! EXCEPTION " << e.code << " " << e.msg << endl;
121                   assert(0);
122                 }
123           }
124         else
125           {
126             cout << "SETTING THE DOCUMENT FOR THE FIRST TIME" << endl;
127             result = res;
128
129             DOM::EventTarget et(result);
130             assert(et);
131             cout << "SETTING EVENT LISTENER (EDITOR) ON " << static_cast<GdomeNode*>(result) << endl;
132             et.addEventListener("DOMSubtreeModified", l1, true);
133
134             if (GUI_load_document(gdome_cast_doc(static_cast<GdomeNode*>(result))) < 0)
135               cerr << "c'e' stato un errore" << endl;
136           }
137         style.save(result, stdout);
138
139         doc.clearDirty();
140       }
141   }
142
143 private:
144   const DOM::XSLTStylesheet& style;
145 };
146
147 struct Context
148 {
149   Context(const std::string& s, TPushLexer& l) : buffer(s), i(0), lexer(l) { };
150
151   void send(void)
152   {
153     if (i < buffer.length())
154       {
155         cout << "document is " << static_cast<GdomeNode*>(result) << endl;
156         lexer.push(buffer[i++]);
157       }
158     else lexer.push('\n');
159   }
160
161   std::string buffer;
162   unsigned i;
163   TPushLexer& lexer;
164 };
165
166 extern "C" int
167 edit_timeout(Context* data)
168 {
169   assert(data);
170   GUI_freeze();
171   data->send();
172   GUI_thaw();
173   return 1;
174 }
175
176 extern "C" void
177 push_char(Context* context, gchar ch)
178 {
179   GUI_freeze();
180   cout << "*** SENDING " << ch << endl;
181   context->lexer.push(ch);
182   GUI_thaw();
183 }
184
185 main(int argc, char* argv[])
186 {
187   cout << "loading the dictionary..." << endl;
188   dictionary.load("dictionary.xml");
189
190   cout << "loading the stylesheet..." << endl;
191   DOM::DOMImplementation di;
192   DOM::Document docStyle = di.createDocumentFromURI("./xsl/tml-mmlp.xsl");
193   DOM::XSLTStylesheet style(docStyle);
194   
195   MyListener listener(style);
196   TPushParser parser(dictionary, listener);
197   TPushLexer lexer(parser);
198
199 #if 0
200   lexer.push('$');
201   lexer.push(' ');
202   assert(result);
203 #endif
204
205 #if 0
206   DOM::Document doc = parser.document().document();
207   std::vector< std::pair<DOM::GdomeString, DOM::GdomeString> > np;
208   result = style.apply(doc, np);
209   style.save(result, stdout);
210 #endif
211
212   Context context("", lexer);
213
214   cout << "passing context " << &context << endl;
215   GUI_init(&argc, &argv, "mathmleditor", 500, 600, &context);
216   GUI_run();
217   GUI_uninit();
218   GUI_unload_document();
219 }