--- /dev/null
+
+#include "TNode.hh"
+#include "TToken.hh"
+#include "TDocument.hh"
+#include "TPushParser.hh"
+#include "TPushLexer.hh"
+#include "TDictionary.hh"
+#include "TListener.hh"
+#include <GdomeSmartDOMXSLT.hh>
+
+#include "guiGTK.h"
+
+class MyResultListener : public DOM::EventListener
+{
+public:
+ MyResultListener(const std::string& s) : msg(s) { };
+
+ virtual void handleEvent(const DOM::Event&);
+
+private:
+ const std::string msg;
+};
+
+void
+MyResultListener::handleEvent(const DOM::Event& ev)
+{
+ cout << "RECEIVED EVENT: " << ev.get_type() << " " << msg << " ";
+ const DOM::MutationEvent& me(ev);
+ assert(me);
+ const DOM::Node target(me.get_target());
+ assert(target);
+ cout << "target = " << target.get_nodeName() << " " << target.get_nodeType() << endl;
+}
+
+MyResultListener l1("?");
+
+TDictionary dictionary;
+DOM::Document result;
+
+extern void *parseMathMLFile(char *);
+
+bool
+subst(const DOM::Element& e1, const DOM::GdomeString& id, const DOM::Element& e2)
+{
+ assert(e1);
+ assert(e2);
+ if (e1.getAttribute("xref") == id)
+ {
+ DOM::Node parent = e1.get_parentNode();
+ assert(parent);
+ DOM::Node next = e1.get_nextSibling();
+ parent.removeChild(e1);
+ parent.insertBefore(e2, next);
+ //parent.replaceChild(e2, e1);
+ return true;
+ }
+ else
+ {
+ DOM::Node p = e1.get_firstChild();
+ while (p)
+ {
+ while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_nextSibling();
+ if (p)
+ if (subst(p, id, e2)) return true;
+ else p = p.get_nextSibling();
+ }
+ return false;
+ }
+}
+
+class MyListener : public TListener
+{
+public:
+ MyListener(const DOM::XSLTStylesheet& s) : style(s) { };
+
+ void callback(TDocument& doc)
+ {
+ cout << "listener callback " << static_cast<GdomeNode*>(doc.document()) << endl;
+ TNode dirty = doc.dirtyNode();
+ if (dirty)
+ {
+ cout << "recreating subtree with id " << std::string(dirty["id"]) << endl;
+ std::vector< std::pair<DOM::GdomeString, DOM::GdomeString> > dirtyId;
+ if (result)
+ dirtyId.push_back(std::make_pair(DOM::GdomeString("id"),
+ DOM::GdomeString("'" + std::string(dirty["id"]) + "'")));
+ DOM::Document res = style.apply(doc.document(), dirtyId);
+ assert(res);
+ style.save(doc.document(), stdout);
+ style.save(res, stdout);
+ if (result)
+ {
+ cout << "REPLACING A FRAGMENT OF THE DOCUMENT" << endl;
+ DOM::Element root = res.get_documentElement();
+ assert(root);
+ assert(root.hasAttribute("xref"));
+
+ if (result.get_documentElement().getAttribute("xref") == root.getAttribute("xref"))
+ {
+ cout << "REPLACING ROOT" << endl;
+ // the following remove should not be necessary
+ // according to the spec replaceChild should work just fine
+ result.removeChild(result.get_documentElement());
+ result.appendChild(result.importNode(root, true));
+ }
+ else
+ try
+ {
+ cout << "before" << endl;
+ bool ok = subst(result.get_documentElement(), root.getAttribute("xref"), result.importNode(root, true));
+ assert(ok);
+ cout << "after" << endl;
+ }
+ catch (DOM::DOMException e)
+ {
+ cout << "!!!!!!!!!!!!!!!! EXCEPTION " << e.code << " " << e.msg << endl;
+ assert(0);
+ }
+ }
+ else
+ {
+ cout << "SETTING THE DOCUMENT FOR THE FIRST TIME" << endl;
+ result = res;
+
+ DOM::EventTarget et(result);
+ assert(et);
+ cout << "SETTING EVENT LISTENER (EDITOR) ON " << static_cast<GdomeNode*>(result) << endl;
+ et.addEventListener("DOMSubtreeModified", l1, true);
+
+ if (GUI_load_document(gdome_cast_doc(static_cast<GdomeNode*>(result))) < 0)
+ cerr << "c'e' stato un errore" << endl;
+ }
+
+ doc.clearDirty();
+ }
+ }
+
+private:
+ const DOM::XSLTStylesheet& style;
+};
+
+struct Context
+{
+ Context(const std::string& s, TPushLexer& l) : buffer(s), i(0), lexer(l) { };
+
+ void send(void)
+ {
+ if (i < buffer.length())
+ {
+ cout << "document is " << static_cast<GdomeNode*>(result) << endl;
+ lexer.push(buffer[i++]);
+ }
+ else lexer.push('\n');
+ }
+
+ std::string buffer;
+ unsigned i;
+ TPushLexer& lexer;
+};
+
+extern "C" int
+edit_timeout(Context* data)
+{
+ assert(data);
+ GUI_freeze();
+ data->send();
+ GUI_thaw();
+ return 1;
+}
+
+extern "C" void
+push_char(Context* context, gchar ch)
+{
+ GUI_freeze();
+ cout << "*** SENDING " << ch << endl;
+ context->lexer.push(ch);
+ GUI_thaw();
+}
+
+main(int argc, char* argv[])
+{
+ cout << "loading the dictionary..." << endl;
+ dictionary.load("dictionary.xml");
+
+ cout << "loading the stylesheet..." << endl;
+ DOM::DOMImplementation di;
+ DOM::Document docStyle = di.createDocumentFromURI("./xsl/tml-mmlp.xsl");
+ DOM::XSLTStylesheet style(docStyle);
+
+ MyListener listener(style);
+ TPushParser parser(dictionary, listener);
+ TPushLexer lexer(parser);
+
+#if 0
+ lexer.push('$');
+ lexer.push(' ');
+ assert(result);
+#endif
+
+#if 0
+ DOM::Document doc = parser.document().document();
+ std::vector< std::pair<DOM::GdomeString, DOM::GdomeString> > np;
+ result = style.apply(doc, np);
+ style.save(result, stdout);
+#endif
+
+ Context context("", lexer);
+
+ cout << "passing context " << &context << endl;
+ GUI_init(&argc, &argv, "mathmleditor", 500, 600, &context);
+ GUI_run();
+ GUI_uninit();
+ GUI_unload_document();
+}