]> matita.cs.unibo.it Git - helm.git/commitdiff
This commit was manufactured by cvs2svn to create branch 'start'. start
authorno author <no.author@nowhere.it>
Thu, 9 Jan 2003 11:22:23 +0000 (11:22 +0000)
committerno author <no.author@nowhere.it>
Thu, 9 Jan 2003 11:22:23 +0000 (11:22 +0000)
74 files changed:
helm/DEVEL/mathml_editor/.log [new file with mode: 0644]
helm/DEVEL/mathml_editor/AUTHORS [new file with mode: 0644]
helm/DEVEL/mathml_editor/BROWSE [new file with mode: 0644]
helm/DEVEL/mathml_editor/BUGS-GDOME2 [new file with mode: 0644]
helm/DEVEL/mathml_editor/ChangeLog [new file with mode: 0644]
helm/DEVEL/mathml_editor/LICENSE [new file with mode: 0644]
helm/DEVEL/mathml_editor/MODES [new file with mode: 0644]
helm/DEVEL/mathml_editor/Makefile.am [new file with mode: 0644]
helm/DEVEL/mathml_editor/Makefile.in [new file with mode: 0644]
helm/DEVEL/mathml_editor/NEWS [new file with mode: 0644]
helm/DEVEL/mathml_editor/PATTERNS [new file with mode: 0644]
helm/DEVEL/mathml_editor/README [new file with mode: 0644]
helm/DEVEL/mathml_editor/TML.dtd [new file with mode: 0644]
helm/DEVEL/mathml_editor/configure.ac [new file with mode: 0644]
helm/DEVEL/mathml_editor/dictionary.dtd [new file with mode: 0644]
helm/DEVEL/mathml_editor/dictionary.xml [new file with mode: 0644]
helm/DEVEL/mathml_editor/editex-config.in [new file with mode: 0644]
helm/DEVEL/mathml_editor/examples/abs.tex [new file with mode: 0644]
helm/DEVEL/mathml_editor/examples/big.tex [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/APushLexer.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/APushParser.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/BROWSE [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/Makefile.am [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/Makefile.in [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/Ptr.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TCharStream.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TCharStreamString.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TDictionary.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TDictionary.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TDocument.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TDocument.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TLexerPull.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TLexerPush.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TLexerPush.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TListener.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TNode.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TNode.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TObject.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TPushLexer.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TPushLexer.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TPushParser.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TPushParser.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TToken.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TTokenizer.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/TTokenizer.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/dom.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/domnav.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/globals.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/special.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/texlexer.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/tokenizer.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/Makefile.am [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/Makefile.in [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/aux.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/editor.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/guiGTK.c [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/guiGTK.h [new file with mode: 0644]
helm/DEVEL/mathml_editor/test/main.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/xsl/d-xsl.xsl [new file with mode: 0644]
helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl [new file with mode: 0644]
helm/DEVEL/mathml_editor/xsl/tml-tex.xsl [new file with mode: 0644]
helm/uwobo/.cvsignore [new file with mode: 0644]
helm/uwobo/.cvswrappers [new file with mode: 0644]
helm/uwobo/ant/ant.jar [new file with mode: 0644]
helm/uwobo/ant/jaxp.jar [new file with mode: 0644]
helm/uwobo/ant/parser.jar [new file with mode: 0644]
helm/uwobo/antRun [new file with mode: 0755]
helm/uwobo/antRun.bat [new file with mode: 0644]
helm/uwobo/build.xml [new file with mode: 0644]
helm/uwobo/src/it/unibo/cs/helm/uwobo/Key.java [new file with mode: 0644]
helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java [new file with mode: 0644]
helm/uwobo/src/it/unibo/cs/helm/uwobo/Servlet.java [new file with mode: 0644]
helm/uwobo/src/it/unibo/cs/helm/uwobo/properties.txt [new file with mode: 0644]
helm/uwobo/web.xml [new file with mode: 0644]

diff --git a/helm/DEVEL/mathml_editor/.log b/helm/DEVEL/mathml_editor/.log
new file mode 100644 (file)
index 0000000..3971d5a
--- /dev/null
@@ -0,0 +1,21 @@
+This is TeX, Version 3.14159 (Web2C 7.3.7) (format=tex 2002.8.9)  23 NOV 2002 18:34
+**$$\root 3 \of x+1$$
+(/usr/share/texmf/tex/latex/tools/.tex File ignored)
+! Missing $ inserted.
+<inserted text> 
+                $
+<to be read again> 
+                   \mathchoice 
+\mathpalette #1#2->\mathchoice 
+                               {#1\displaystyle {#2}}{#1\textstyle {#2}}{#1\...
+<*> $$\root 3 \of x
+                   +1$$
+? 
+
+*
+! Emergency stop.
+<*> $$\root 3 \of x+1$$
+                       
+End of file on the terminal!
+
+No pages of output.
diff --git a/helm/DEVEL/mathml_editor/AUTHORS b/helm/DEVEL/mathml_editor/AUTHORS
new file mode 100644 (file)
index 0000000..2ba63d6
--- /dev/null
@@ -0,0 +1 @@
+Luca Padovani <lpadovan@cs.unibo.it>
diff --git a/helm/DEVEL/mathml_editor/BROWSE b/helm/DEVEL/mathml_editor/BROWSE
new file mode 100644 (file)
index 0000000..c14c1d2
--- /dev/null
@@ -0,0 +1,503 @@
+[ebrowse-hs "ebrowse 5.0" " -x" () ()][ebrowse-ts [ebrowse-cs "APushParser" () 0"src/APushParser.hh" "class APushParser
+{" 75"src/APushParser.hh" ]
+([ebrowse-ts [ebrowse-cs "TPushParser" () 0"src/TPushParser.hh" "class TPushParser :" 226"src/TPushParser.hh" ]
+()([ebrowse-ms "buffer" () 0 () "  std::list<TToken> buffer;" 1306 2  () () 0]
+[ebrowse-ms "cursor" () 0 () "  TNode     cursor;" 1363 2  () () 0]
+[ebrowse-ms "doc" () 0 () "  TDocument doc;" 1343 2  () () 0]
+[ebrowse-ms "frames" () 0 () "  std::stack<Frame> frames;" 1278 2  () () 0]
+[ebrowse-ms "nextId" () 0 () "  unsigned  nextId;" 1326 2  () () 0]
+)
+([ebrowse-ms "PRIME" () 4 () "  std::string PRIME(void" 490 2  "src/TPushParser.cc" "TPushParser::PRIME()" 279]
+[ebrowse-ms "TPushParser" () 0 () () 0 0  "src/TPushParser.cc" "TPushParser::TPushParser(const TDictionary& d) :" 58]
+[ebrowse-ms "TPushParser" () 0 () "  TPushParser(const class TDictionary&);" 275 0  () () 0]
+[ebrowse-ms "advance" () 0 () "  void advance(const" 1065 2  "src/TPushParser.cc" "TPushParser::advance(const" 13192]
+[ebrowse-ms "do_active" () 0 () "  void do_active(const" 916 2  "src/TPushParser.cc" "TPushParser::do_active(const" 5602]
+[ebrowse-ms "do_align" () 0 () "  void do_align(void" 624 2  "src/TPushParser.cc" "TPushParser::do_align()" 1530]
+[ebrowse-ms "do_apostrophe" () 0 () "  void do_apostrophe(void" 1042 2  "src/TPushParser.cc" "TPushParser::do_apostrophe()" 4611]
+[ebrowse-ms "do_begin" () 0 () "  void do_begin(void" 557 2  "src/TPushParser.cc" "TPushParser::do_begin()" 461]
+[ebrowse-ms "do_comment" () 0 () "  void do_comment(void" 954 2  "src/TPushParser.cc" "TPushParser::do_comment()" 5668]
+[ebrowse-ms "do_control" () 0 () "  void do_control(const" 980 2  "src/TPushParser.cc" "TPushParser::do_control(const" 6337]
+[ebrowse-ms "do_cr" () 0 () "  void do_cr(void" 1014 2  "src/TPushParser.cc" "TPushParser::do_cr()" 5708]
+[ebrowse-ms "do_digit" () 0 () "  void do_digit(const" 841 2  "src/TPushParser.cc" "TPushParser::do_digit(const" 4072]
+[ebrowse-ms "do_end" () 0 () "  void do_end(void" 578 2  "src/TPushParser.cc" "TPushParser::do_end()" 910]
+[ebrowse-ms "do_eol" () 0 () "  void do_eol(void" 645 2  "src/TPushParser.cc" "TPushParser::do_eol()" 2464]
+[ebrowse-ms "do_letter" () 0 () "  void do_letter(const" 804 2  "src/TPushParser.cc" "TPushParser::do_letter(const" 3902]
+[ebrowse-ms "do_other" () 0 () "  void do_other(const" 878 2  "src/TPushParser.cc" "TPushParser::do_other(const" 5303]
+[ebrowse-ms "do_parameter" () 0 () "  void do_parameter(const" 673 2  "src/TPushParser.cc" "TPushParser::do_parameter(const" 2546]
+[ebrowse-ms "do_shift" () 0 () "  void do_shift(void" 601 2  "src/TPushParser.cc" "TPushParser::do_shift()" 1487]
+[ebrowse-ms "do_space" () 0 () "  void do_space(const" 766 2  "src/TPushParser.cc" "TPushParser::do_space(const" 3794]
+[ebrowse-ms "do_subscript" () 0 () "  void do_subscript(void" 742 2  "src/TPushParser.cc" "TPushParser::do_subscript()" 2609]
+[ebrowse-ms "do_superscript" () 0 () "  void do_superscript(void" 715 2  "src/TPushParser.cc" "TPushParser::do_superscript()" 3204]
+[ebrowse-ms "document" () 4 () "  TDocument document(void" 432 0  () "  TDocument document(void" 432]
+[ebrowse-ms "isPrimes" () 4 () "  bool isPrimes(const" 520 2  "src/TPushParser.cc" "TPushParser::isPrimes(const" 4445]
+[ebrowse-ms "process" () 0 () "  void process(const" 1096 2  "src/TPushParser.cc" "TPushParser::process(const" 8538]
+[ebrowse-ms "push" () 1 () "  virtual void push(const" 349 0  "src/TPushParser.cc" "TPushParser::push(const" 9379]
+[ebrowse-ms "setCursor" () 1 () "  virtual void setCursor(const" 390 0  "src/TPushParser.cc" "TPushParser::setCursor(const" 13865]
+[ebrowse-ms "~TPushParser" () 1 () "  virtual ~TPushParser()" 321 0  "src/TPushParser.cc" "TPushParser::~TPushParser()" 241]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TTokenizer" () 0"src/TTokenizer.hh" "class TTokenizer :" 173"src/TTokenizer.hh" ]
+()([ebrowse-ms "tokens" () 0 () "  std::list<TToken> tokens;" 405 2  () () 0]
+)
+([ebrowse-ms "TTokenizer" () 0 () "  TTokenizer(void) {" 221 0  () "  TTokenizer(void) {" 221]
+[ebrowse-ms "push" () 1 () "  virtual void push(const" 316 2  "src/TTokenizer.cc" "TTokenizer::push(const" 471]
+[ebrowse-ms "setCursor" () 1 () "  virtual void setCursor(const" 357 2  () "  virtual void setCursor(const" 357]
+[ebrowse-ms "tokenize" () 0 () "  std::vector<TToken> tokenize(const" 265 0  "src/TTokenizer.cc" "TTokenizer::tokenize(const" 120]
+)
+()
+()
+()
+()
+()()
+])()
+([ebrowse-ms "APushParser" () 0 () "  APushParser(void) {" 102 0  () "  APushParser(void) {" 102]
+[ebrowse-ms "push" () 9 () "  virtual void push(const" 164 0  () () 0]
+[ebrowse-ms "setCursor" () 9 () "  virtual void setCursor(const" 209 0  () () 0]
+[ebrowse-ms "~APushParser" () 1 () "  virtual ~APushParser()" 133 0  () "  virtual ~APushParser()" 133]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "EmptyBuffer" "TLexerPush" 0"src/TLexerPush.hh" "  class EmptyBuffer {" 271() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "unary_function" "std" 32() () 0() ]
+([ebrowse-ts [ebrowse-cs "StringHash" "TDictionary" 0"src/TDictionary.hh" "  struct StringHash :" 1160"src/TDictionary.hh" ]
+()()
+([ebrowse-ms "operator ()" () 4 () "  { size_t operator()(const" 1238 0  () "  { size_t operator()(const" 1238]
+)
+()
+()
+()
+()
+()()
+])()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TObject" () 0"src/TObject.hh" "class TObject
+{" 63"src/TObject.hh" ]
+()()
+([ebrowse-ms "TObject" () 0 () "  TObject(void) {" 89 1  () "  TObject(void) {" 89]
+[ebrowse-ms "ref" () 4 () "  void ref(coid" 162 0  () "  void ref(coid" 162]
+[ebrowse-ms "unref" () 4 () "  void unref(void" 206 0  () "  void unref(void" 206]
+[ebrowse-ms "~TObject" () 1 () "  virtual ~TObject()" 132 1  () "  virtual ~TObject()" 132]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "std" () 0() () 0() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TLexerPush" () 0"src/TLexerPush.hh" "class TLexerPush
+{" 59"src/TLexerPush.hh" ]
+()([ebrowse-ms "state" () 0 () "  State state;" 388 2  () () 0]
+[ebrowse-ms "tokens" () 0 () "  std::deque<TToken> tokens;" 417 2  () () 0]
+)
+([ebrowse-ms "TLexerPush" () 0 () "  TLexerPush(void);" 85 0  "src/TLexerPush.cc" "TLexerPush::TLexerPush()
+{" 51]
+[ebrowse-ms "ambiguous" () 4 () "  bool   ambiguous(void" 182 0  "src/TLexerPush.cc" "TLexerPush::ambiguous()" 576]
+[ebrowse-ms "empty" () 4 () "  bool   empty(void" 240 0  "src/TLexerPush.cc" "TLexerPush::empty()" 447]
+[ebrowse-ms "front" () 4 () "  TToken front(void" 150 0  "src/TLexerPush.cc" "TLexerPush::front()" 338]
+[ebrowse-ms "pending" () 4 () "  bool   pending(void" 212 0  "src/TLexerPush.cc" "TLexerPush::pending()" 510]
+[ebrowse-ms "pop" () 0 () "  TToken pop(void" 128 0  "src/TLexerPush.cc" "TLexerPush::pop()" 99]
+[ebrowse-ms "push" () 0 () "  void   push(TChar" 108 0  "src/TLexerPush.cc" "TLexerPush::push(TChar" 664]
+)
+()
+()
+()
+([ebrowse-ms "State" () 0 () "    {" 303 2  () "    {" 303]
+)
+()()
+][ebrowse-ts [ebrowse-cs "TLexerPull" () 0() () 0"src/TLexerPull.cc" ]
+()()
+([ebrowse-ms "pop" () 0 () () 0 0  () "TLexerPull::pop(TCharStream" 94]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TDictionary" () 0"src/TDictionary.hh" "class TDictionary
+{" 154"src/TDictionary.hh" ]
+()([ebrowse-ms "entries" () 0 () "  Dictionary entries;" 1560 2  () () 0]
+)
+([ebrowse-ms "TDictionary" () 0 () "  TDictionary(void) {" 181 0  () "  TDictionary(void) {" 181]
+[ebrowse-ms "find" () 4 () "  const Entry& find(const" 1107 0  "src/TDictionary.cc" "TDictionary::find(const" 3723]
+[ebrowse-ms "load" () 0 () "  void load(const" 1069 0  "src/TDictionary.cc" "TDictionary::load(const" 162]
+[ebrowse-ms "~TDictionary" () 0 () "  ~TDictionary()" 204 0  () "  ~TDictionary()" 204]
+)
+()
+()
+()
+([ebrowse-ms "Dictionary" () 0 () "ap< std::string, Entry, StringHash > Dictionary;" 1538 2  () () 0]
+[ebrowse-ms "EntryClass" () 0 () "    {" 301 0  () "    {" 301]
+[ebrowse-ms "Form" () 0 () "    {" 228 0  () "    {" 228]
+)
+()()
+][ebrowse-ts [ebrowse-cs "DOM" () 0() () 0() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "APushLexer" () 0"src/APushLexer.hh" "class APushLexer
+{" 72"src/APushLexer.hh" ]
+([ebrowse-ts [ebrowse-cs "TPushLexer" () 0"src/TPushLexer.hh" "class TPushLexer :" 117"src/TPushLexer.hh" ]
+()([ebrowse-ms "buffer" () 0 () "  std::string buffer;" 483 2  () () 0]
+[ebrowse-ms "state" () 0 () "  State state;" 461 2  () () 0]
+)
+([ebrowse-ms "TPushLexer" () 0 () () 0 0  "src/TPushLexer.cc" "TPushLexer::TPushLexer(APushParser& p) :" 108]
+[ebrowse-ms "TPushLexer" () 0 () "  TPushLexer(class APushParser&);" 164 0  () () 0]
+[ebrowse-ms "error" () 5 () "  virtual bool error(void" 290 0  "src/TPushLexer.cc" "TPushLexer::error()" 2463]
+[ebrowse-ms "push" () 1 () "  virtual void push(char" 234 0  "src/TPushLexer.cc" "TPushLexer::push(char" 1180]
+[ebrowse-ms "reset" () 1 () "  virtual void reset(void" 262 0  "src/TPushLexer.cc" "TPushLexer::reset()" 176]
+[ebrowse-ms "transaction" () 0 () "  void transaction(char" 436 2  "src/TPushLexer.cc" "TPushLexer::transaction(char" 251]
+[ebrowse-ms "~TPushLexer" () 1 () "  virtual ~TPushLexer()" 203 0  () "  virtual ~TPushLexer()" 203]
+)
+()
+()
+()
+([ebrowse-ms "State" () 0 () "    {" 327 2  () "    {" 327]
+)
+()()
+])()
+([ebrowse-ms "APushLexer" () 0 () "  APushLexer(class APushParser& p) :" 99 0  () "  APushLexer(class APushParser& p) :" 99]
+[ebrowse-ms "error" () 13 () "  virtual bool error(void" 251 0  () () 0]
+[ebrowse-ms "push" () 9 () "  virtual void push(char" 187 0  () () 0]
+[ebrowse-ms "reset" () 9 () "  virtual void reset(void" 219 0  () () 0]
+[ebrowse-ms "~APushLexer" () 1 () "  virtual ~APushLexer()" 156 0  () "  virtual ~APushLexer()" 156]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "Ptr" () 32"src/Ptr.hh" "class Ptr
+{" 1067"src/Ptr.hh" ]
+()([ebrowse-ms "ptr" () 0 () "  P* ptr;" 1797 2  () () 0]
+)
+([ebrowse-ms "P" () 4 () "  operator P*()" 1487 0  () "  operator P*()" 1487]
+[ebrowse-ms "Ptr" () 0 () "  Ptr(const Ptr& p) :" 1142 0  () "  Ptr(const Ptr& p) :" 1142]
+[ebrowse-ms "Ptr" () 0 () "  Ptr(P* p = 0) :" 1083 0  () "  Ptr(P* p = 0) :" 1083]
+[ebrowse-ms "Q" () 36 () "  template <class Q> operator Ptr<Q>()" 1747 0  () "  template <class Q> operator Ptr<Q>()" 1747]
+[ebrowse-ms "operator ->" () 4 () "  P* operator->()" 1253 0  () "  P* operator->()" 1253]
+[ebrowse-ms "operator =" () 0 () "  Ptr& operator=(const" 1316 0  () "  Ptr& operator=(const" 1316]
+[ebrowse-ms "~Ptr" () 0 () "  ~Ptr()" 1202 0  () "  ~Ptr()" 1202]
+)
+()
+()
+([ebrowse-ms "is_a" () 32 () "  template <class Q> friend bool is_a(const" 1659 0  () "  template <class Q> friend bool is_a(const" 1659]
+[ebrowse-ms "smart_cast" () 32 () "emplate <class Q> friend Ptr<Q> smart_cast(const" 1561 0  () "emplate <class Q> friend Ptr<Q> smart_cast(const" 1561]
+)
+()
+()()
+][ebrowse-ts [ebrowse-cs "TToken" () 0"src/TToken.hh" "struct TToken
+{" 80"src/TToken.hh" ]
+()([ebrowse-ms "category" () 0 () "  TCat        category;" 627 0  () () 0]
+[ebrowse-ms "value" () 0 () "  std::string value;" 648 0  () () 0]
+)
+([ebrowse-ms "TToken" () 0 () "  TToken(TCat c, const std::string& v) :" 438 0  () "  TToken(TCat c, const std::string& v) :" 438]
+[ebrowse-ms "TToken" () 0 () "  TToken(TCat c, char ch) :" 366 0  () "  TToken(TCat c, char ch) :" 366]
+[ebrowse-ms "TToken" () 0 () "  TToken(TCat c) :" 330 0  () "  TToken(TCat c) :" 330]
+[ebrowse-ms "operator ==" () 4 () "  bool operator==(const" 517 0  () "  bool operator==(const" 517]
+)
+()
+()
+()
+([ebrowse-ms "TCat" () 0 () "    {" 98 0  () "    {" 98]
+)
+()()
+][ebrowse-ts [ebrowse-cs "binary_function" "std" 32() () 0() ]
+([ebrowse-ts [ebrowse-cs "StringEq" "TDictionary" 0"src/TDictionary.hh" "  struct StringEq :" 1327() ]
+()()
+([ebrowse-ms "operator ()" () 4 () "  { bool operator()(const" 1415 0  () () 0]
+)
+()
+()
+()
+()
+()()
+])()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TNode" () 0"src/TNode.hh" "class TNode
+{" 124"src/TNode.hh" ]
+()([ebrowse-ms "node" () 0 () "  DOM::Element node;" 2444 2  () () 0]
+)
+([ebrowse-ms "TNode" () 0 () "  TNode(const TNode& n) :" 270 0  () "  TNode(const TNode& n) :" 270]
+[ebrowse-ms "TNode" () 0 () "  TNode(void) :" 145 0  () "  TNode(void) :" 145]
+[ebrowse-ms "append" () 4 () "  void  append(const" 1667 0  "src/TNode.cc" "TNode::append(const" 2450]
+[ebrowse-ms "append" () 4 () "  void  append(const" 1631 0  "src/TNode.cc" "TNode::append(const" 2348]
+[ebrowse-ms "child" () 4 () "  TNode child(unsigned" 592 0  "src/TNode.cc" "TNode::child(unsigned" 2874]
+[ebrowse-ms "core" () 4 () "  TNode core(void" 425 0  "src/TNode.cc" "TNode::core()" 1413]
+[ebrowse-ms "empty" () 4 () "  bool  empty(void" 648 0  () "  bool  empty(void" 648]
+[ebrowse-ms "first" () 4 () "  TNode first(void" 480 0  "src/TNode.cc" "TNode::first()" 1075]
+[ebrowse-ms "firstL" () 4 () "  TNode firstL(void" 508 0  "src/TNode.cc" "TNode::firstL()" 1259]
+[ebrowse-ms "get" () 4 () "  std::string get(const" 1758 0  "src/TNode.cc" "TNode::get(const" 3007]
+[ebrowse-ms "hasId" () 4 () "  bool  hasId(void" 1994 0  () "  bool  hasId(void" 1994]
+[ebrowse-ms "insert" () 4 () "  void  insert(const" 1595 0  "src/TNode.cc" "TNode::insert(const" 2193]
+[ebrowse-ms "is" () 4 () "  bool  is(const" 2055 0  () "  bool  is(const" 2055]
+[ebrowse-ms "isC" () 4 () "  bool  isC(const" 2303 0  () "  bool  isC(const" 2303]
+[ebrowse-ms "isC" () 4 () "  bool  isC(void" 2258 0  () "  bool  isC(void" 2258]
+[ebrowse-ms "isG" () 4 () "  bool  isG(void" 2119 0  () "  bool  isG(void" 2119]
+[ebrowse-ms "isSb" () 4 () "  bool  isSb(void" 2165 0  () "  bool  isSb(void" 2165]
+[ebrowse-ms "isSp" () 4 () "  bool  isSp(void" 2212 0  () "  bool  isSp(void" 2212]
+[ebrowse-ms "last" () 4 () "  TNode last(void" 534 0  "src/TNode.cc" "TNode::last()" 736]
+[ebrowse-ms "lastL" () 4 () "  TNode lastL(void" 561 0  "src/TNode.cc" "TNode::lastL()" 922]
+[ebrowse-ms "name" () 4 () "  std::string name(void" 1863 0  () "  std::string name(void" 1863]
+[ebrowse-ms "nameC" () 4 () "  std::string nameC(void" 1929 0  () "  std::string nameC(void" 1929]
+[ebrowse-ms "next" () 4 () "  TNode next(void" 319 0  "src/TNode.cc" "TNode::next()" 63]
+[ebrowse-ms "nextL" () 4 () "  TNode nextL(void" 346 0  "src/TNode.cc" "TNode::nextL()" 247]
+[ebrowse-ms "operator !=" () 4 () "  bool operator!=(const" 1295 0  () "  bool operator!=(const" 1295]
+[ebrowse-ms "operator ==" () 4 () "  bool operator==(const" 1227 0  () "  bool operator==(const" 1227]
+[ebrowse-ms "operator []" () 4 () "  ProxyAttr operator[](const" 1422 0  () "  ProxyAttr operator[](const" 1422]
+[ebrowse-ms "operator []" () 4 () "  TNode operator[](int" 1362 0  () "  TNode operator[](int" 1362]
+[ebrowse-ms "parent" () 4 () "  TNode parent(void" 453 0  "src/TNode.cc" "TNode::parent()" 1587]
+[ebrowse-ms "prepend" () 4 () "  void  prepend(const" 1718 0  "src/TNode.cc" "TNode::prepend(const" 2683]
+[ebrowse-ms "prev" () 4 () "  TNode prev(void" 372 0  "src/TNode.cc" "TNode::prev()" 396]
+[ebrowse-ms "prevL" () 4 () "  TNode prevL(void" 399 0  "src/TNode.cc" "TNode::prevL()" 588]
+[ebrowse-ms "remove" () 4 () "  void  remove(void" 1529 0  "src/TNode.cc" "TNode::remove()" 1913]
+[ebrowse-ms "replace" () 4 () "  void  replace(const" 1559 0  "src/TNode.cc" "TNode::replace(const" 2038]
+[ebrowse-ms "set" () 4 () "  void  set(const" 1797 0  "src/TNode.cc" "TNode::set(const" 3109]
+[ebrowse-ms "size" () 4 () "  unsigned size(void" 621 0  "src/TNode.cc" "TNode::size()" 1749]
+[ebrowse-ms "value" () 4 () "  std::string value(void" 707 0  () "  std::string value(void" 707]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "Entry" "TDictionary" 0"src/TDictionary.hh" "  struct Entry
+  {" 405"src/TDictionary.hh" ]
+()([ebrowse-ms "cls" () 0 () "    EntryClass cls;" 806 0  () () 0]
+[ebrowse-ms "delimiter" () 0 () "    unsigned delimiter : 1;" 909 0  () () 0]
+[ebrowse-ms "embellishment" () 0 () "    unsigned embellishment : 1;" 966 0  () () 0]
+[ebrowse-ms "infix" () 0 () "    unsigned infix : 8;" 830 0  () () 0]
+[ebrowse-ms "leftOpen" () 0 () "    unsigned leftOpen : 1;" 993 0  () () 0]
+[ebrowse-ms "limits" () 0 () "    unsigned limits : 1;" 934 0  () () 0]
+[ebrowse-ms "pattern" () 0 () "    std::vector<TToken> pattern;" 597 0  () () 0]
+[ebrowse-ms "postfix" () 0 () "    unsigned postfix : 8;" 881 0  () () 0]
+[ebrowse-ms "prefix" () 0 () "    unsigned prefix : 8;" 855 0  () () 0]
+[ebrowse-ms "rightOpen" () 0 () "    unsigned rightOpen : 1;" 1021 0  () () 0]
+[ebrowse-ms "table" () 0 () "    unsigned table : 1;" 1045 0  () () 0]
+[ebrowse-ms "value" () 0 () "    std::string value;" 620 0  () () 0]
+)
+([ebrowse-ms "Entry" () 0 () "    {" 420 0  () "    {" 420]
+[ebrowse-ms "defined" () 4 () "    bool defined(void" 643 0  () "    bool defined(void" 643]
+[ebrowse-ms "hasArguments" () 4 () "    bool hasArguments(void" 707 0  () "    bool hasArguments(void" 707]
+[ebrowse-ms "paramDelimited" () 4 () "    bool paramDelimited(unsigned" 777 0  "src/TDictionary.cc" "TDictionary::Entry::paramDelimited(unsigned" 4012]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "Frame" "TPushParser" 0"src/TPushParser.hh" "  struct Frame
+  {" 1126"src/TPushParser.hh" ]
+()([ebrowse-ms "entry" () 0 () "    const TDictionary::Entry& entry;" 1226 0  () () 0]
+[ebrowse-ms "pos" () 0 () "    unsigned pos;" 1244 0  () () 0]
+)
+([ebrowse-ms "Frame" () 0 () "    Frame(const TDictionary::Entry& e) :" 1142 0  () "    Frame(const TDictionary::Entry& e) :" 1142]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TCharStream" () 0"src/TCharStream.hh" "class TCharStream
+{" 94"src/TCharStream.hh" ]
+([ebrowse-ts [ebrowse-cs "TCharStreamString" () 0"src/TCharStreamString.hh" "class TCharStreamString :" 120"src/TCharStreamString.hh" ]
+()([ebrowse-ms "buffer" () 0 () "  TString buffer;" 555 2  () () 0]
+[ebrowse-ms "idx" () 0 () "  unsigned long idx;" 536 2  () () 0]
+)
+([ebrowse-ms "TCharStreamString" () 0 () "  TCharStreamString(const TString& s) :" 175 0  () "  TCharStreamString(const TString& s) :" 175]
+[ebrowse-ms "look" () 5 () "  virtual TChar look(void" 343 0  () "  virtual TChar look(void" 343]
+[ebrowse-ms "more" () 5 () "  virtual bool  more(void" 275 0  () "  virtual bool  more(void" 275]
+[ebrowse-ms "next" () 1 () "  virtual TChar next(void" 439 0  () "  virtual TChar next(void" 439]
+[ebrowse-ms "~TCharStreamString" () 1 () "  virtual ~TCharStreamString()" 243 0  () "  virtual ~TCharStreamString()" 243]
+)
+()
+()
+()
+()
+()()
+])()
+([ebrowse-ms "TCharStream" () 0 () "  TCharStream(void) {" 121 0  () "  TCharStream(void) {" 121]
+[ebrowse-ms "look" () 13 () "  virtual TChar look(void" 222 0  () () 0]
+[ebrowse-ms "more" () 13 () "  virtual bool  more(void" 184 0  () () 0]
+[ebrowse-ms "next" () 9 () "  virtual TChar next(void" 260 0  () () 0]
+[ebrowse-ms "~TCharStream" () 1 () "  virtual ~TCharStream()" 152 0  () "  virtual ~TCharStream()" 152]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "EmptyStream" "TCharStream" 0"src/TCharStream.hh" "  class EmptyStream {" 289() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "*Globals*" () 0() () 0"src/APushLexer.hh" ]
+()()
+([ebrowse-ms "dispatch" () 0 "src/special.cc" "dispatch(const" 1012 0  "src/special.cc" "dispatch(const" 1012]
+[ebrowse-ms "do_apostrophe" () 0 "src/special.cc" "do_apostrophe(const" 669 0  "src/special.cc" "do_apostrophe(const" 669]
+[ebrowse-ms "do_bgroup" () 0 "src/special.cc" "do_bgroup(const" 149 0  "src/special.cc" "do_bgroup(const" 149]
+[ebrowse-ms "do_control" () 0 "src/special.cc" "do_control(const" 711 0  "src/special.cc" "do_control(const" 711]
+[ebrowse-ms "do_other" () 0 "src/special.cc" "do_other(const" 776 0  "src/special.cc" "do_other(const" 776]
+[ebrowse-ms "finishG" () 0 "src/special.cc" "void finishG(const" 118 0  () () 0]
+[ebrowse-ms "getCore" () 0 "src/domnav.cc" "getCore(const" 629 0  "src/domnav.cc" "getCore(const" 629]
+[ebrowse-ms "getRightmostChild" () 0 "src/domnav.cc" "getRightmostChild(const" 37 0  "src/domnav.cc" "getRightmostChild(const" 37]
+[ebrowse-ms "isDelimiter" () 0 "src/domnav.cc" "isDelimiter(const" 1716 0  "src/domnav.cc" "isDelimiter(const" 1716]
+[ebrowse-ms "isFunction" () 0 "src/domnav.cc" "isFunction(const" 1879 0  "src/domnav.cc" "isFunction(const" 1879]
+[ebrowse-ms "isGroup" () 0 "src/domnav.cc" "isGroup(const" 1214 0  "src/domnav.cc" "isGroup(const" 1214]
+[ebrowse-ms "isInferred" () 0 "src/domnav.cc" "isInferred(const" 985 0  "src/domnav.cc" "isInferred(const" 985]
+[ebrowse-ms "isMacro" () 0 "src/domnav.cc" "isMacro(const" 1085 0  "src/domnav.cc" "isMacro(const" 1085]
+[ebrowse-ms "isOperator" () 0 "src/domnav.cc" "isOperator(const" 1553 0  "src/domnav.cc" "isOperator(const" 1553]
+[ebrowse-ms "isPrimes" () 0 "src/domnav.cc" "isPrimes(const" 1451 0  "src/domnav.cc" "isPrimes(const" 1451]
+[ebrowse-ms "isSb" () 0 "src/domnav.cc" "isSb(const" 1291 0  "src/domnav.cc" "isSb(const" 1291]
+[ebrowse-ms "isSp" () 0 "src/domnav.cc" "isSp(const" 1369 0  "src/domnav.cc" "isSp(const" 1369]
+[ebrowse-ms "isUnicodeAlpha" () 2 "src/dom.hh" "inline bool isUnicodeAlpha(TChar" 303 0  "src/dom.hh" "inline bool isUnicodeAlpha(TChar" 303]
+[ebrowse-ms "isUnicodeDigit" () 2 "src/dom.hh" "inline bool isUnicodeDigit(TChar" 408 0  "src/dom.hh" "inline bool isUnicodeDigit(TChar" 408]
+[ebrowse-ms "isUnicodeSpace" () 2 "src/dom.hh" "inline bool isUnicodeSpace(TChar" 198 0  "src/dom.hh" "inline bool isUnicodeSpace(TChar" 198]
+[ebrowse-ms "main" () 0 "src/texlexer.cc" "main()" 51 0  "src/texlexer.cc" "main()" 51]
+[ebrowse-ms "prevLinearSibling" () 0 "src/domnav.cc" "prevLinearSibling(const" 324 0  "src/domnav.cc" "prevLinearSibling(const" 324]
+[ebrowse-ms "replace" () 0 "src/domnav.cc" "replace(const" 834 0  "src/domnav.cc" "replace(const" 834]
+[ebrowse-ms "tokenize" () 0 "src/tokenizer.hh" "std::vector<TToken> tokenize(const" 123 0  () () 0]
+)
+([ebrowse-ms "undefinedEntry" () 0 () () 0 0  "src/TDictionary.cc" "static TDictionary::Entry undefinedEntry;" 132]
+)
+()
+([ebrowse-ms "Ptr_hh" () 512 () () 0 0  "src/Ptr.hh" "#define Ptr_hh
+" 1036]
+[ebrowse-ms "TML_NS_URI" () 512 () () 0 0  "src/globals.hh" "#define TML_NS_URI " 67]
+[ebrowse-ms "XMLNS_NS_URI" () 512 () () 0 0  "src/globals.hh" "#define XMLNS_NS_URI " 123]
+[ebrowse-ms "__APushLexer_hh__" () 512 () () 0 0  () "#define __APushLexer_hh__
+" 53]
+[ebrowse-ms "__APushParser_hh__" () 512 () () 0 0  "src/APushParser.hh" "#define __APushParser_hh__
+" 55]
+[ebrowse-ms "__TCharStreamString_hh__" () 512 () () 0 0  "src/TCharStreamString.hh" "#define __TCharStreamString_hh__
+" 67]
+[ebrowse-ms "__TCharStream_hh__" () 512 () () 0 0  "src/TCharStream.hh" "#define __TCharStream_hh__
+" 55]
+[ebrowse-ms "__TDictionary_hh__" () 512 () () 0 0  "src/TDictionary.hh" "#define __TDictionary_hh__
+" 55]
+[ebrowse-ms "__TDocument_hh__" () 512 () () 0 0  "src/TDocument.hh" "#define __TDocument_hh__
+" 51]
+[ebrowse-ms "__TNode_hh__" () 512 () () 0 0  "src/TNode.hh" "#define __TNode_hh__
+" 43]
+[ebrowse-ms "__TObject_hh__" () 512 () () 0 0  "src/TObject.hh" "#define __TObject_hh__
+" 47]
+[ebrowse-ms "__TPushLexer_hh__" () 512 () () 0 0  "src/TPushLexer.hh" "#define __TPushLexer_hh__
+" 53]
+[ebrowse-ms "__TPushParser_hh__" () 512 () () 0 0  "src/TPushParser.hh" "#define __TPushParser_hh__
+" 55]
+[ebrowse-ms "__TToken_hh__" () 512 () () 0 0  "src/TToken.hh" "#define __TToken_hh__
+" 45]
+[ebrowse-ms "__TTokenizer_hh__" () 512 () () 0 0  "src/TTokenizer.hh" "#define __TTokenizer_hh__
+" 53]
+[ebrowse-ms "__dom_hh__" () 512 () () 0 0  "src/dom.hh" "#define __dom_hh__
+" 39]
+[ebrowse-ms "__globals_hh__" () 512 () () 0 0  "src/globals.hh" "#define __globals_hh__
+" 47]
+[ebrowse-ms "__tokenzier_hh__" () 512 () () 0 0  "src/tokenizer.hh" "#define __tokenzier_hh__
+" 51]
+)
+([ebrowse-ms "TChar" () 0 () () 0 0  "src/dom.hh" "typedef DOM::Char32     TChar;" 131]
+[ebrowse-ms "TString" () 0 () () 0 0  "src/dom.hh" "typedef DOM::UCS4String TString;" 164]
+)
+()()
+][ebrowse-ts [ebrowse-cs "ProxyAttr" "TNode" 0"src/TNode.hh" "  class ProxyAttr
+  {" 765"src/TNode.hh" ]
+()([ebrowse-ms "name" () 0 () "    std::string  name;" 1155 2  () () 0]
+[ebrowse-ms "node" () 0 () "    DOM::Element node;" 1132 2  () () 0]
+)
+([ebrowse-ms "ProxyAttr" () 0 () "r(const DOM::Element& n, const std::string& s) :" 795 0  () "r(const DOM::Element& n, const std::string& s) :" 795]
+[ebrowse-ms "operator =" () 0 () "    ProxyAttr& operator=(const" 959 0  () "    ProxyAttr& operator=(const" 959]
+[ebrowse-ms "operator ==" () 0 () "    bool       operator==(const" 1040 0  () "    bool       operator==(const" 1040]
+[ebrowse-ms "string" () 4 () "    operator std::string()" 885 0  () "    operator std::string()" 885]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "EventListener" "DOM" 0() () 0() ]
+([ebrowse-ts [ebrowse-cs "DOMSubtreeModifiedListener" "TDocument" 0"src/TDocument.hh" "  class DOMSubtreeModifiedListener :" 1015"src/TDocument.hh" ]
+()([ebrowse-ms "doc" () 0 () "    TDocument doc;" 1247 2  () () 0]
+)
+([ebrowse-ms "DOMSubtreeModifiedListener" () 0 () "DOMSubtreeModifiedListener(const TDocument& d) :" 1092 0  () "DOMSubtreeModifiedListener(const TDocument& d) :" 1092]
+[ebrowse-ms "handleEvent" () 1 () "    virtual void handleEvent(const" 1202 0  () () 0]
+[ebrowse-ms "~DOMSubtreeModifiedListener" () 1 () "    virtual ~DOMSubtreeModifiedListener()" 1162 0  () "    virtual ~DOMSubtreeModifiedListener()" 1162]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TDocument" () 0"src/TDocument.hh" "class TDocument :" 108"src/TDocument.hh" ]
+()([ebrowse-ms "dirty" () 0 () "  DOM::Element dirty;" 971 2  () () 0]
+[ebrowse-ms "doc" () 0 () "  DOM::Document doc;" 949 2  () () 0]
+)
+([ebrowse-ms "TDocument" () 0 () "  TDocument(void);" 162 0  "src/TDocument.cc" "TDocument::TDocument()
+{" 108]
+[ebrowse-ms "create" () 4 () "  TNode create(const" 202 0  "src/TDocument.cc" "TDocument::create(const" 789]
+[ebrowse-ms "createC" () 4 () "  TNode createC(const" 327 0  "src/TDocument.cc" "TDocument::createC(const" 1062]
+[ebrowse-ms "createG" () 4 () "  TNode createG(unsigned" 262 0  () "  TNode createG(unsigned" 262]
+[ebrowse-ms "createI" () 4 () "  TNode createI(const" 461 0  () "  TNode createI(const" 461]
+[ebrowse-ms "createN" () 4 () "  TNode createN(const" 561 0  () "  TNode createN(const" 561]
+[ebrowse-ms "createO" () 4 () "  TNode createO(const" 661 0  () "  TNode createO(const" 661]
+[ebrowse-ms "createT" () 4 () "  TNode createT(const" 384 0  "src/TDocument.cc" "TDocument::createT(const" 1197]
+[ebrowse-ms "dirtyIdNode" () 4 () "  TNode dirtyIdNode(void" 872 0  "src/TDocument.cc" "TDocument::dirtyIdNode()" 2081]
+[ebrowse-ms "dirtyNode" () 4 () "  TNode dirtyNode(void" 821 0  () "  TNode dirtyNode(void" 821]
+[ebrowse-ms "handleEvent" () 1 () "  virtual void handleEvent(const" 1293 2  "src/TDocument.cc" "TDocument::handleEvent(const" 2348]
+[ebrowse-ms "root" () 0 () "  TNode root(void" 758 0  () "  TNode root(void" 758]
+[ebrowse-ms "serialize" () 4 () "  void serialize(const" 904 0  "src/TDocument.cc" "TDocument::serialize(const" 637]
+[ebrowse-ms "~TDocument" () 0 () "  ~TDocument()" 179 0  "src/TDocument.cc" "TDocument::~TDocument()" 460]
+)
+()
+([ebrowse-ms "findCommonAncestor" () 0 () "  static DOM::Node findCommonAncestor(const" 1398 2  "src/TDocument.cc" "TDocument::findCommonAncestor(const" 1560]
+[ebrowse-ms "nodeDepth" () 0 () "  static unsigned nodeDepth(const" 1341 2  "src/TDocument.cc" "TDocument::nodeDepth(const" 1362]
+)
+()
+()
+()()
+])()
+()
+()
+()
+()
+()
+()()
+]
\ No newline at end of file
diff --git a/helm/DEVEL/mathml_editor/BUGS-GDOME2 b/helm/DEVEL/mathml_editor/BUGS-GDOME2
new file mode 100644 (file)
index 0000000..2b89215
--- /dev/null
@@ -0,0 +1,15 @@
+
+* replaceChild on document root should work, but it is implemented as
+  an insertBefore + removeChild, and the insertBefore is not allowed
+  for the document must have xactly _one_ child
+* the code to dispatch the events is wrong, because it stores
+  xmlNodes and not gdome wrappers, hence the nodes can be deleted
+* when firing events, self is not always reffed, what is the reason for
+  doing it?
+* DOMSubtreeModified must have bubble=yes
+* when setting more event listeners for the same node, with same type
+  and same useCapture, the event listener also matters. It seems like
+  now one can set only one event per combination type/capture
+* /usr/lib is given by gdome-config
+* should optimize event propagation, remember only those nodes with
+  listeners
diff --git a/helm/DEVEL/mathml_editor/ChangeLog b/helm/DEVEL/mathml_editor/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/helm/DEVEL/mathml_editor/LICENSE b/helm/DEVEL/mathml_editor/LICENSE
new file mode 100644 (file)
index 0000000..f67b130
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright (C) 2002, Luca Padovani <luca.padovani@cs.unibo.it>.
+//
+// This file is part of EdiTeX, an editor of mathematical
+// expressions based on TeX syntax
+// 
+// EdiTeX is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// EdiTeX is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with EdiTeX; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// 
+// For details, see the EdiTeX World-Wide-Web page,
+// http://helm.cs.unibo.it/editex, or send a mail to
+// <luca.padovani@cs.unibo.it>
diff --git a/helm/DEVEL/mathml_editor/MODES b/helm/DEVEL/mathml_editor/MODES
new file mode 100644 (file)
index 0000000..39032e3
--- /dev/null
@@ -0,0 +1,25 @@
+
+there are two basic syntactic modes:
+
+TeX mode:
+
+* any letter is an identifier by itself
+
+Program mode:
+
+* sequences of letters (and possibly other characters)
+  are collapsed into a single token. Id tokens are separated
+  by any other character not included in one of the collapsing
+  categories.
+
+The mode is a property of the parser.
+
+there are two basic semantic modes:
+
+math mode:
+
+* implicit operator is multiplication
+
+program mode:
+
+* implicit operator is function application
diff --git a/helm/DEVEL/mathml_editor/Makefile.am b/helm/DEVEL/mathml_editor/Makefile.am
new file mode 100644 (file)
index 0000000..edd3988
--- /dev/null
@@ -0,0 +1,21 @@
+#EXTRA_DIST = BUGS HISTORY LICENSE aclocal.m4 debian/
+SUBDIRS = src test
+CLEANFILES = core
+
+bin_SCRIPTS = editex-config
+
+backup:
+       cd ..; tar cvfz @PACKAGE@-@VERSION@-`date|tr ' ' '_'|tr ':' '_'`.tar.gz @PACKAGE@
+
+cleanbak:
+       -rm -f `find . -name "*~"`
+
+lc:
+       @( \
+       CFILES=`find . -name "*.c"`; \
+       HFILES=`find . -name "*.h"`; \
+       CCFILES=`find . -name "*.cc"`; \
+       HHFILES=`find . -name "*.hh"`; \
+       ICCFILES=`find . -name "*.icc"`; \
+       wc -l $$CFILES $$HFILES $$CCFILES $$HHFILES $$ICCFILES | tail -n 1 \
+       )
diff --git a/helm/DEVEL/mathml_editor/Makefile.in b/helm/DEVEL/mathml_editor/Makefile.in
new file mode 100644 (file)
index 0000000..f68e1f6
--- /dev/null
@@ -0,0 +1,424 @@
+# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+#EXTRA_DIST = BUGS HISTORY LICENSE aclocal.m4 debian/
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EDITEX_VERSION_INFO = @EDITEX_VERSION_INFO@
+EXEEXT = @EXEEXT@
+GDOMEXSLT_CFLAGS = @GDOMEXSLT_CFLAGS@
+GDOMEXSLT_LIBS = @GDOMEXSLT_LIBS@
+GMETADOM_CFLAGS = @GMETADOM_CFLAGS@
+GMETADOM_LIBS = @GMETADOM_LIBS@
+GTKMATHVIEW_CFLAGS = @GTKMATHVIEW_CFLAGS@
+GTKMATHVIEW_LIBS = @GTKMATHVIEW_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+
+SUBDIRS = src test
+CLEANFILES = core
+
+bin_SCRIPTS = editex-config
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =  editex-config
+SCRIPTS =  $(bin_SCRIPTS)
+
+DIST_COMMON =  README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
+Makefile.am Makefile.in NEWS aclocal.m4 config.guess config.h.in \
+config.sub configure configure.ac editex-config.in install-sh ltmain.sh \
+missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4):  configure.ac 
+       cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure.ac $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @if test ! -f $@; then \
+               rm -f stamp-h; \
+               $(MAKE) stamp-h; \
+       else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/stamp-h.in; \
+               $(MAKE) $(srcdir)/stamp-h.in; \
+       else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.ac $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+editex-config: $(top_builddir)/config.status editex-config.in
+       cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+install-binSCRIPTS: $(bin_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(bindir)
+       @list='$(bin_SCRIPTS)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+           $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+         else if test -f $(srcdir)/$$p; then \
+           echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+           $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+         else :; fi; fi; \
+       done
+
+uninstall-binSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       list='$(bin_SCRIPTS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+       done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       dot_seen=no; \
+       rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+         rev="$$subdir $$rev"; \
+         test "$$subdir" = "." && dot_seen=yes; \
+       done; \
+       test "$$dot_seen" = "no" && rev=". $$rev"; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+   if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+   fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) dist
+       -rm -rf $(distdir)
+       @banner="$(distdir).tar.gz is ready for distribution"; \
+       dashes=`echo "$$banner" | sed s/./=/g`; \
+       echo "$$dashes"; \
+       echo "$$banner"; \
+       echo "$$dashes"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+       for subdir in $(SUBDIRS); do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           chmod 777 $(distdir)/$$subdir; \
+           (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+             || exit 1; \
+         fi; \
+       done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-binSCRIPTS
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-binSCRIPTS
+uninstall: uninstall-recursive
+all-am: Makefile $(SCRIPTS) config.h
+all-redirect: all-recursive-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+       $(mkinstalldirs)  $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-hdr mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am:  clean-hdr clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am:  distclean-hdr distclean-tags distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-recursive
+       -rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-hdr maintainer-clean-tags \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+uninstall-binSCRIPTS install-binSCRIPTS install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+backup:
+       cd ..; tar cvfz @PACKAGE@-@VERSION@-`date|tr ' ' '_'|tr ':' '_'`.tar.gz @PACKAGE@
+
+cleanbak:
+       -rm -f `find . -name "*~"`
+
+lc:
+       @( \
+       CFILES=`find . -name "*.c"`; \
+       HFILES=`find . -name "*.h"`; \
+       CCFILES=`find . -name "*.cc"`; \
+       HHFILES=`find . -name "*.hh"`; \
+       ICCFILES=`find . -name "*.icc"`; \
+       wc -l $$CFILES $$HFILES $$CCFILES $$HHFILES $$ICCFILES | tail -n 1 \
+       )
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/helm/DEVEL/mathml_editor/NEWS b/helm/DEVEL/mathml_editor/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/helm/DEVEL/mathml_editor/PATTERNS b/helm/DEVEL/mathml_editor/PATTERNS
new file mode 100644 (file)
index 0000000..0e5814d
--- /dev/null
@@ -0,0 +1,196 @@
+
+identifier #
+
+       insert(<mi>#</mi>)
+
+number #
+
+       insert(<mi>#</mi>)
+
+\sqrt
+
+       replace($, <msqrt>$</msqrt>)
+
+\root
+
+       replace($, <mroot><mrow/><mrow>$</mrow></mroot>)
+
+\of
+
+       when (isa($.parent, "mrow") && isa($.parent.parent, "mroot"))
+       let mroot = $.parent.parent
+       if ($.prev and !$.prev.prev and !$.next) replace($.parent, $.prev)
+       replace(mroot.child[0], $)
+
+\underline
+
+       insert(<munder>[$, <mo>&UnderBar;</mo>]</munder>)
+
+\overline
+
+       insert(<mover>[$, <mo>&OverBar;</mo>]</mover>)
+
+\cases
+
+       replace($, <mrow><mo>{</mo><mtable>$</mtable></mrow>)
+
+\matrix
+
+       replace($, <mtable>$</mtable>)
+
+\over
+
+       if isa($.parent, "mrow")
+               replace($.parent, <mfrac>[$.parent, $]</mfrac>)
+
+
+_      if isa($.parent, "mrow")
+               if eq($.prev, null)
+                       replace($, new(mmultiscripts, [ new mrow, $, new none ]))
+               elseif (isa($.prev, msub))
+                       let base = $.prev.children[0]
+                       let script = $.prev.children[1]
+                       replace($.rev, new(mmultiscripts, [ base, script, new none, $, new none ]))
+               elseif (isa($.prev, msup))
+                       let base = $.prev.children[0]
+                       let script = $.prev.children[1]
+                       replace($.prev, new(msubsup, [ base, $, script ]))
+               elseif (isa($.prev, msubsup))
+                       let base = $.prev.children[0]
+                       let subscript = $.prev.children[1]
+                       let superscript = $.prev.children[2]
+                       replace($.prev, new(mmultiscripts, [ base, subscript, superscript, $, new none ]))
+               elseif isa($.prev, mmultiscripts)
+                       if ($.prev.children[$.prev.children.size - 2] = null)
+                               replace($.prev.children[$.prev.children.size - 2], $)
+                       else
+                               $.prev.children.append([$, new none])
+               else
+                       replace($.prev, new(msub, [ $.prev, $ ]))
+       else if isa($.parent, msub) and $.parent.children[1] = $
+               let base = $.parent.children[0]
+               replace($.parent, new(munder, [ base, $ ]))
+
+               
+_, \sb (subscript)
+
+       if parent.isa(mrow)
+               if cursor is first child then
+                       sub = new mmultiscripts
+                       parent.replace(cursor, sub);
+                       sub.set_base(new mrow);
+                       sub.set_subscript(cursor);
+               else
+                       elem = element prior to cursor in parent
+                       if elem.isa(msub) || elem.isa(msup) || elem.isa(mmultiscripts) then
+                               append script to multiscript and/or replace single script with
+                               multiscript
+                       else if elem.isa(munder) || elem.isa(mover) || elem.isa(munderover) then
+                               creates another munder
+                       else
+                               parent.replace(elem, sub);
+                               sub.set_base(elem);
+                               sub.set_subscript(cursor);
+       else if (parent.isa(msub) and cursor is subscript) or
+               change msub into a munder
+               cursor in same position
+       else
+               replace cursor with msub with empty base
+
+^, \sp (superscript)
+
+       symmetric to subscript
+
+', \prime (prime)
+
+       similar to superscript, but multiple prime superscripts should go
+       together in the same operator
+
+{      (group open)
+
+       replace cursor with mrow, put cursor inside mrow
+       if cursor is inside a table, create a new table row and a new table cell
+       and put the cursor inside the cell
+
+}      (group close)
+
+       remove cursor from mrow
+       mrow.parent.advance(cursor, mrow)
+       if cursor inside a table cell then close table
+       
+\over,\atop,\above (fraction)
+
+       if cursor.parent.isa(mrow) then
+               frac = new mfrac
+               cursor.parent.parent.replace(mrow, frac)
+               numerator is current content of cursor.parent except for the cursor
+               itself.
+               set denominator to cursor
+       else
+
+\choose
+
+       similar to fractions, but with stretchable parentheses around
+
+\sqrt
+
+       parent.replace(cursor, new msqrt)
+       set new msqrt.base to cursor
+
+\root
+
+       parent.replace(cursor, new mroot)
+       set empty base element
+       set root index to cursor
+
+\of
+
+       check if cursor.parent is mroot (or mrow inside mroot index)
+       or and cursor is in index position. move the cursor to the base element
+
+\underline
+
+       create munder element with stretchable horizontal line as underscript
+       substitute cursor with munder
+       move the cursor in the base element
+
+\overline
+
+       symmetric
+
+accents (\hat)
+
+       create an mover with accent=true and the operator has stretchy=false
+
+wide accents (\widehat)
+
+       as accents, but mover has accent=false and the operator has stretchy=true
+
+\scriptstyle, ...
+
+       create an appropriate mstyle, the cursor moves in. However, when the
+       subformula ends one has to skip the mstyle
+
+\cases
+
+       create mrow with stretchable brace and emtpy table, put cursor inside
+       table
+
+\matrix
+
+       create empty table, cursor inside table
+
+&
+
+       check that cursor is inside a table cell
+       create a new cell next to it
+
+\cr
+
+       check that cursor is inside a table cell inside a table row
+       create a new row
+
+\phantom
+
+       create a mphantom element, cursor inside
+
diff --git a/helm/DEVEL/mathml_editor/README b/helm/DEVEL/mathml_editor/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/helm/DEVEL/mathml_editor/TML.dtd b/helm/DEVEL/mathml_editor/TML.dtd
new file mode 100644 (file)
index 0000000..a808c5b
--- /dev/null
@@ -0,0 +1,58 @@
+
+<!ENTITY % TML.node "i|n|o|sp|sb|g|c|row|cell|cursor">
+
+<!ENTITY % TML.common.attrib "
+  id         CDATA #IMPLIED
+  xref       CDATA #IMPLIED
+">
+
+<!ELEMENT tex (math|cursor)>
+
+<!ELEMENT math (g)>
+<!ATTLIST math
+  %TML.common.attrib;
+  display (0|1) true
+>
+
+<!ELEMENT i EMPTY>
+<!ATTLIST i
+  %TML.common.attrib;
+  val     CDATA   #REQUIRED
+  name    NMTOKEN #IMPLIED>
+<!ELEMENT n EMPTY>
+<!ATTLIST n
+  %TML.common.attrib;
+  val     CDATA   #REQUIRED
+  name    NMTOKEN #IMPLIED>
+<!ELEMENT o EMPTY>
+<!ATTLIST o
+  %TML.common.attrib;
+  val     CDATA #REQUIRED
+  name    NMTOKEN #IMPLIED>
+
+<!ELEMENT row (cell)+>
+<!ELEMENT cell (%TML.node;)>
+
+<!ELEMENT sb (%TML.node;,%TML.node;)>
+<!ATTLIST sb
+  %TML.common.attrib;
+  under   (0|1) #IMPLIED
+>
+<!ELEMENT sp (%TML.node;,%TML.node;)>
+<!ATTLIST sp
+  %TML.common.attrib;
+  over    (0|1) #IMPLIED
+>
+
+<!ELEMENT g (%TML.node;)+>
+<!ATTLIST g %TML.common.attrib;>
+
+<!ELEMENT c (%TML.node;)+>
+<!ATTLIST c
+  %TML.common.attrib;
+  name    NMTOKEN #REQUIRED
+  left-open (0|1) #IMPLIED>
+
+<!ELEMENT cursor EMPTY>
+<!ATTLIST %TML.common.attrib; val CDATA #REQUIRED>
+
diff --git a/helm/DEVEL/mathml_editor/configure.ac b/helm/DEVEL/mathml_editor/configure.ac
new file mode 100644 (file)
index 0000000..0dca72c
--- /dev/null
@@ -0,0 +1,181 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT
+AC_CONFIG_SRCDIR([src/TToken.hh])
+
+PACKAGE=editex
+VERSION=0.0.1
+EDITEX_VERSION_INFO=`echo $VERSION | awk -F. '{ printf "%d:%d:%d", $1+$2, $3, $2 }'`
+AC_SUBST(EDITEX_VERSION_INFO)
+
+AC_ARG_ENABLE(
+       profile,
+       [  --enable-profile[=ARG]  include profiling information [default=no]],
+       profile=$enableval,
+       profile=no
+)
+
+AC_ARG_ENABLE(
+       debug,
+       [  --enable-debug[=ARG]    include debugging debug [default=yes]],
+       enable_debug=$enableval,
+       enable_debug=yes
+)
+
+if test "x$enable_debug" = "xyes"; then
+   AC_DEFINE(ENABLE_DEBUG,,[Define to 1 if you want to enable validity checks while running])
+fi
+
+GMETADOM_PREFIX=""
+AC_ARG_WITH(gmetadom-prefix,
+        [  --with-gmetadom-prefix=[PFX]         Specify location of gmetadom],
+       GMETADOM_PREFIX=$withval
+)
+
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
+AM_CONFIG_HEADER(config.h)
+
+AH_TOP([
+/* Copyright (C) 2002, Luca Padovani <luca.padovani@cs.unibo.it>.
+ *
+ * This file is part of EdiTeX, an editor of mathematical
+ * expressions based on TeX syntax
+ * 
+ * EdiTeX is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * EdiTeX is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EdiTeX; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * For details, see the EdiTeX World-Wide-Web page,
+ * http://helm.cs.unibo.it/editex, or send a mail to
+ * <luca.padovani@cs.unibo.it>
+ */
+#ifndef config_h
+#define config_h
+])
+
+AH_BOTTOM([
+#endif /* config_h */
+])
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_HEADER_STDC([])
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+AM_PROG_LIBTOOL
+
+GMETADOM_CONFIG="gmetadom-config"
+GMETADOM_MIN_VERSION=0.1.0
+AC_MSG_CHECKING([for GMetaDOM C++ library] >= $GMETADOM_MIN_VERSION) 
+if test "x$GMETADOM_PREFIX" != "x"
+then
+       if ${GMETADOM_PREFIX}/bin/$GMETADOM_CONFIG --version > /dev/null 2>&1
+       then
+               GMETADOM_CONFIG=${GMETADOM_PREFIX}/bin/$GMETADOM_CONFIG
+        elif ! $GMETADOM_CONFIG --version > /dev/null 2>&1
+        then
+               AC_MSG_ERROR([Could not find gmetadom anywhere (see config.log for details).])
+       fi
+fi
+
+dnl
+dnl test version and init our variables
+dnl
+vers=`$GMETADOM_CONFIG --version | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+minvers=`echo $GMETADOM_MIN_VERSION | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+if test "$vers" -ge "$minvers"
+then
+        GMETADOM_LIBS="`$GMETADOM_CONFIG --module=gdome_cpp_smart --libs`"
+        GMETADOM_CFLAGS="`$GMETADOM_CONFIG --module=gdome_cpp_smart --cflags`"
+        AC_MSG_RESULT(found)
+else
+        AC_MSG_ERROR([You need at least GMetaDOM (C++) $GMETADOM_MIN_VERSION for this version of $PACKAGE])
+fi
+
+AC_SUBST(GMETADOM_CFLAGS)
+AC_SUBST(GMETADOM_LIBS)
+
+GDOMEXSLT_CONFIG="gdome_xslt_cpp_smart-config"
+GDOMEXSLT_MIN_VERSION=0.0.1
+AC_MSG_CHECKING([for gdome_xslt C++ library] >= $GDOMEXSLT_MIN_VERSION) 
+if test "x$GDOMEXSLT_PREFIX" != "x"
+then
+       if ${GDOMEXSLT_PREFIX}/bin/$GDOMEXSLT_CONFIG --version > /dev/null 2>&1
+       then
+               GDOMEXSLT_CONFIG=${GDOMEXSLT_PREFIX}/bin/$GDOMEXSLT_CONFIG
+        elif ! $GDOMEXSLT_CONFIG --version > /dev/null 2>&1
+        then
+               AC_MSG_ERROR([Could not find gdome_xslt anywhere (see config.log for details).])
+       fi
+fi
+
+dnl
+dnl test version and init our variables
+dnl
+vers=`$GDOMEXSLT_CONFIG --version | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+minvers=`echo $GDOMEXSLT_MIN_VERSION | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+if test "$vers" -ge "$minvers"
+then
+        GDOMEXSLT_LIBS="`$GDOMEXSLT_CONFIG --libs`"
+        GDOMEXSLT_CFLAGS="`$GDOMEXSLT_CONFIG --cflags`"
+        AC_MSG_RESULT(found)
+else
+        AC_MSG_ERROR([You need at least gdome_xslt (C++) $GDOMEXSLT_MIN_VERSION for this version of $PACKAGE])
+fi
+
+AC_SUBST(GDOMEXSLT_CFLAGS)
+AC_SUBST(GDOMEXSLT_LIBS)
+
+GTKMATHVIEW_CONFIG="gtkmathview-config"
+GTKMATHVIEW_MIN_VERSION=0.4.0
+AC_MSG_CHECKING([for gtkmathview library] >= $GTKMATHVIEW_MIN_VERSION) 
+if test "x$GTKMATHVIEW_PREFIX" != "x"
+then
+       if ${GTKMATHVIEW_PREFIX}/bin/$GTKMATHVIEW_CONFIG --version > /dev/null 2>&1
+       then
+               GTKMATHVIEW_CONFIG=${GTKMATHVIEW_PREFIX}/bin/$GTKMATHVIEW_CONFIG
+        elif ! $GTKMATHVIEW_CONFIG --version > /dev/null 2>&1
+        then
+               AC_MSG_ERROR([Could not find gtkmathview anywhere (see config.log for details).])
+       fi
+fi
+
+dnl
+dnl test version and init our variables
+dnl
+vers=`$GTKMATHVIEW_CONFIG --version | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+minvers=`echo $GTKMATHVIEW_MIN_VERSION | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+if test "$vers" -ge "$minvers"
+then
+        GTKMATHVIEW_LIBS="`$GTKMATHVIEW_CONFIG --libs`"
+        GTKMATHVIEW_CFLAGS="`$GTKMATHVIEW_CONFIG --cflags`"
+        AC_MSG_RESULT(found)
+else
+        AC_MSG_ERROR([You need at least gtkmathview $GTKMATHVIEW_MIN_VERSION for this version of $PACKAGE])
+fi
+
+AC_SUBST(GTKMATHVIEW_CFLAGS)
+AC_SUBST(GTKMATHVIEW_LIBS)
+
+AC_CONFIG_FILES([
+ Makefile 
+ src/Makefile
+ test/Makefile
+ editex-config
+])
+AC_CONFIG_COMMANDS([default],[[chmod +x editex-config]],[[]])
+AC_OUTPUT
diff --git a/helm/DEVEL/mathml_editor/dictionary.dtd b/helm/DEVEL/mathml_editor/dictionary.dtd
new file mode 100644 (file)
index 0000000..4d092af
--- /dev/null
@@ -0,0 +1,20 @@
+
+<!ELEMENT dictionary (entry)*>
+<!ATTLIST dictionary
+  name      CDATA   #REQUIRED
+>
+
+<!ELEMENT entry EMPTY>
+<!ATTLIST entry
+  name      ID        #REQUIRED
+  pattern   CDATA     #IMPLIED
+  val       CDATA     #IMPLIED
+  class     (m|o|i|n) #IMPLIED
+  table     (0|1)     #IMPLIED
+  delimiter (0|1)     #IMPLIED 
+  limits    (0|1)     #IMPLIED
+  embellishment (0|1) #IMPLIED
+  infix     NMTOKEN   #IMPLIED
+  prefix    NMTOKEN   #IMPLIED
+  postfix   NMTOKEN   #IMPLIED
+>
diff --git a/helm/DEVEL/mathml_editor/dictionary.xml b/helm/DEVEL/mathml_editor/dictionary.xml
new file mode 100644 (file)
index 0000000..664100c
--- /dev/null
@@ -0,0 +1,350 @@
+<?xml version="1.0"?>
+
+<dictionary name="TeX">
+
+  <!-- Greek Letters (lower case) -->
+
+  <entry name="alpha"      class="i" val="&#x03b1;"/>
+  <entry name="beta"       class="i" val="&#x03b2;"/>
+  <entry name="gamma"      class="i" val="&#x03b3;"/>
+  <entry name="delta"      class="i" val="&#x03b4;"/>
+  <entry name="epsilon"    class="i" val="&#x03f5;"/>
+  <entry name="varepsilon" class="i" val="&#x03b5;"/>
+  <entry name="zeta"       class="i" val="&#x03b6;"/>
+  <entry name="eta"        class="i" val="&#x03b7;"/>
+  <entry name="theta"      class="i" val="&#x03b8;"/>
+  <entry name="vartheta"   class="i" val="&#x03d1;"/>
+  <entry name="iota"       class="i" val="&#x03b9;"/>
+  <entry name="kappa"      class="i" val="&#x03ba;"/>
+  <entry name="lambda"     class="i" val="&#x03bb;"/>
+  <entry name="mu"         class="i" val="&#x03bc;"/>
+  <entry name="nu"         class="i" val="&#x03bd;"/>
+  <entry name="xi"         class="i" val="&#x03be;"/>
+  <entry name="o"          class="i" val="&#x03bf;"/>
+  <entry name="pi"         class="i" val="&#x03c0;"/>
+  <entry name="varpi"      class="i" val="&#x03d6;"/>
+  <entry name="rho"        class="i" val="&#x03c1;"/>
+  <entry name="varrho"     class="i" val="&#x03f1;"/>
+  <entry name="sigma"      class="i" val="&#x03c3;"/>
+  <entry name="varsigma"   class="i" val="&#x03c2;"/>
+  <entry name="tau"        class="i" val="&#x03c4;"/>
+  <entry name="upsilon"    class="i" val="&#x03c5;"/>
+  <entry name="phi"        class="i" val="&#x03d5;"/>
+  <entry name="varphi"     class="i" val="&#x03c6;"/>
+  <entry name="chi"        class="i" val="&#x03c7;"/>
+  <entry name="psi"        class="i" val="&#x03c8;"/>
+  <entry name="omega"      class="i" val="&#x03c9;"/>
+
+  <!-- Greek Letters (upper case) -->
+
+  <entry name="Gamma"   class="i" val="&#x0393;"/>
+  <entry name="Delta"   class="i" val="&#x0394;"/>
+  <entry name="Theta"   class="i" val="&#x0398;"/>
+  <entry name="Lambda"  class="i" val="&#x039b;"/>
+  <entry name="Xi"      class="i" val="&#x039e;"/>
+  <entry name="Pi"      class="i" val="&#x03a0;"/>
+  <entry name="Sigma"   class="i" val="&#x03a3;"/>
+  <entry name="Upsilon" class="i" val="&#x03d2;"/>
+  <entry name="Phi"     class="i" val="&#x03a6;"/>
+  <entry name="Psi"     class="i" val="&#x03a8;"/>
+  <entry name="Omega"   class="i" val="&#x03a9;"/>
+
+  <!-- Symbols of Type Ord -->
+
+  <entry name="aleph"       class="i" val="&#x2135;"/>
+  <entry name="hbar"        class="i" val="&#x210f;&#xfe00;"/>
+  <entry name="imath"       class="i" val="&#x0131;"/>
+  <entry name="jmath"       class="i" val="&#x006a;&#xfe00;"/>
+  <entry name="ell"         class="i" val="&#x2113;"/>
+  <entry name="wp"          class="i" val="&#x2118;"/>
+  <entry name="Re"          class="o" val="&#x211c;"/>
+  <entry name="Im"          class="o" val="&#x2111;"/>
+  <entry name="partial"     class="o" val="&#x2202;"/>
+  <entry name="infty"       class="i" val="&#x221e;"/>
+  <entry name="prime"       class="o" val="&#x2032;"/>
+  <entry name="emptyset"    class="i" val="&#x2205;&#xfe00;"/>
+  <entry name="nabla"       class="o" val="&#x2207;"/>
+  <entry name="surd"        class="o" val="????"/>
+  <entry name="top"         class="i" val="&#x22a4;"/>
+  <entry name="bot"         class="i" val="&#x22a5;"/>
+  <entry name="|"           class="o" val="|" delimiter="1"/>
+  <entry name="angle"       class="o" val="&#x2220;"/>
+  <entry name="triangle"    class="o" val="&#x25b5;"/>
+  <entry name="backslash"   class="o" val="\"/>
+  <entry name="forall"      class="o" val="&#x2200;"/>
+  <entry name="exists"      class="o" val="&#x2203;"/>
+  <entry name="neg"         class="o" val="&#x00ac;"/>
+  <entry name="lnot"        class="o" val="&#x00ac;"/>
+  <entry name="flat"        class="i" val="&#x266d;"/>
+  <entry name="natural"     class="i" val="&#x266e;"/>
+  <entry name="sharp"       class="i" val="&#x266f;"/>
+  <entry name="clubsuit"    class="i" val="&#x2663;"/>
+  <entry name="diamondsuit" class="i" val="&#x2662;"/>
+  <entry name="heartsuit"   class="i" val="&#x2661;"/>
+  <entry name="spadesuit"   class="i" val="&#x2660;"/>
+
+  <!-- Large Operators -->
+
+  <entry name="sum"         class="o" val="&#x2211;" limits="1"/>
+  <entry name="prod"        class="o" val="&#x220f;" limits="1"/>
+  <entry name="coprod"      class="o" val="&#x2210;" limits="1"/>
+  <entry name="int"         class="o" val="&#x222b;" limits="1"/>
+  <entry name="oint"        class="o" val="&#x222e;" limits="1"/>
+  <entry name="bigcap"      class="o" val="&#x22c2;" limits="1"/>
+  <entry name="bigcup"      class="o" val="&#x22c3;" limits="1"/>
+  <entry name="bigsqcup"    class="o" val="&#x2294;" limits="1"/>
+  <entry name="bigvee"      class="o" val="&#x22c1;" limits="1"/>
+  <entry name="bigwedge"    class="o" val="&#x22c0;" limits="1"/>
+  <entry name="bigodot"     class="o" val="&#x2299;" limits="1"/>
+  <entry name="bigotimes"   class="o" val="&#x2297;" limits="1"/>
+  <entry name="bigoplus"    class="o" val="&#x2295;" limits="1"/>
+  <entry name="biguplus"    class="o" val="&#x228e;" limits="1"/>
+
+  <!-- Binary Operations -->
+
+  <entry name="pm"              class="o" val="&#x00b1;"/>
+  <entry name="mp"              class="o" val="&#x2213;"/>
+  <entry name="setminus"        class="o" val="&#x2216;"/>
+  <entry name="cdot"            class="o" val="&#x010b;"/>
+  <entry name="times"           class="o" val="&#x00d7;"/>
+  <entry name="ast"             class="o" val="&#x002a;"/>
+  <entry name="star"            class="o" val="&#x22c6;"/>
+  <entry name="diamond"         class="o" val="&#x22c4;"/>
+  <entry name="circ"            class="o" val="&#x005e;"/>
+  <entry name="bullet"          class="o" val="&#x2022;"/>
+  <entry name="div"             class="o" val="&#x00f7;"/>
+  <entry name="cap"             class="o" val="&#x2229;"/>
+  <entry name="cup"             class="o" val="&#x222a;"/>
+  <entry name="uplus"           class="o" val="&#x228e;"/>
+  <entry name="sqcap"           class="o" val="&#x2293;"/>
+  <entry name="sqcup"           class="o" val="&#x2294;"/>
+  <entry name="triangleleft"    class="o" val="&#x25c3;"/>
+  <entry name="triangleright"   class="o" val="&#x25b9;"/>
+  <entry name="wr"              class="o" val="&#x2240;"/>
+  <entry name="bigcirc"         class="o" val="&#x25ef;"/>
+  <entry name="bigtriangleup"   class="o" val="&#x25b3;"/>
+  <entry name="bigtriangledown" class="o" val="&#x25bd;"/>
+  <entry name="vee"             class="o" val="&#x2228;"/>
+  <entry name="lor"             class="o" val="&#x2228;"/>
+  <entry name="wedge"           class="o" val="&#x2227;"/>
+  <entry name="land"            class="o" val="&#x2227;"/>
+  <entry name="oplus"           class="o" val="&#x2295;"/>
+  <entry name="ominus"          class="o" val="&#x2296;"/>
+  <entry name="otimes"          class="o" val="&#x2297;"/>
+  <entry name="oslash"          class="o" val="&#x00f8;"/>
+  <entry name="odot"            class="o" val="&#x2299;"/>
+  <entry name="dagger"          class="o" val="&#x2020;"/>
+  <entry name="ddagger"         class="o" val="&#x2021;"/>
+  <entry name="amalg"           class="o" val="&#x2a3f;"/>
+
+  <!-- Relations -->
+
+  <entry name="leq"            class="o" val="&#x2264;"/>
+  <entry name="le"             class="o" val="&#x2264;"/>
+  <entry name="prec"           class="o" val="&#x227a;"/>
+  <entry name="preceq"         class="o" val="&#x2aaf;"/>
+  <entry name="ll"             class="o" val="&#x226a;"/>
+  <entry name="subset"         class="o" val="&#x2282;"/>
+  <entry name="subseteq"       class="o" val="&#x2286;"/>
+  <entry name="in"             class="o" val="&#x2208;"/>
+  <entry name="vdash"          class="o" val="&#x22a2;"/>
+  <entry name="smile"          class="o" val="&#x2323;"/>
+  <entry name="frown"          class="o" val="&#x2322;"/>
+  <entry name="propto"         class="o" val="&#x221d;"/>
+  <entry name="geq"            class="o" val="&#x2265;"/>
+  <entry name="ge"             class="o" val="&#x2265;"/>
+  <entry name="succ"           class="o" val="&#x227b;"/>
+  <entry name="succeq"         class="o" val="&#x227d;"/>
+  <entry name="gg"             class="o" val="&#x226b;"/>
+  <entry name="supset"         class="o" val="&#x2283;"/>
+  <entry name="supseteq"       class="o" val="&#x2287;"/>
+  <entry name="sqsupseteq"     class="o" val="&#x2292;"/>
+  <entry name="notin"          class="o" val="&#x2209;"/>
+  <entry name="dashv"          class="o" val="&#x22a3;"/>
+  <entry name="mid"            class="o" val="&#x2223;"/>
+  <entry name="parallet"       class="o" val="????;"/>
+  <entry name="equiv"          class="o" val="&#x2261;"/>
+  <entry name="sim"            class="o" val="&#x223c;"/>
+  <entry name="simeq"          class="o" val="&#x2243;"/>
+  <entry name="asymp"          class="o" val="&#x224d;"/>
+  <entry name="approx"         class="o" val="&#x2248;"/>
+  <entry name="cong"           class="o" val="&#x2245;"/>
+  <entry name="bowtie"         class="o" val="&#x22c8;"/>
+  <entry name="ni"             class="o" val="&#x220b;"/>
+  <entry name="owns"           class="o" val="&#x220b;"/>
+  <entry name="models"         class="o" val="&#x22a7;"/>
+  <entry name="doteq"          class="o" val="&#x2250;"/>
+  <entry name="perp"           class="o" val="&#x22a5;"/>
+
+  <entry name="not"            pattern="#1" embellishment="1"/>
+  <entry name="ne"             class="o" val="&#x2260;"/>
+
+  <!-- Arrows -->
+
+  <entry name="leftarrow"                 class="o" val="&#x2190;"/>
+  <entry name="gets"                      class="o" val="&#x2190;"/>
+  <entry name="Leftarrow"                 class="o" val="&#x21d0;"/>
+  <entry name="rightarrow"                class="o" val="&#x2192;"/>
+  <entry name="to"                        class="o" val="&#x2192;"/>
+  <entry name="Rightarrow"                class="o" val="&#x21d2;"/>
+  <entry name="leftrightarrow"            class="o" val="&#x2194;"/>
+  <entry name="Leftrightarrow"            class="o" val="&#x21d4;"/>
+  <entry name="mapsto"                    class="o" val="&#x21a6;"/>
+  <entry name="hookleftarrow"             class="o" val="&#x21a9;"/>
+  <entry name="uparrow"                   class="o" val="&#x2191;"/>
+  <entry name="downarrow"                 class="o" val="&#x2193;"/>
+  <entry name="updownarrow"               class="o" val="&#x2195;"/>
+  <entry name="nearrow"                   class="o" val="&#x2197;"/>
+  <entry name="nwarrow"                   class="o" val="&#x2196;"/>
+  <entry name="longleftarrow"             class="o" val="????;"/>
+  <entry name="Longleftarrow"             class="o" val="????"/>
+  <entry name="longrightarrow"            class="o" val="????"/>
+  <entry name="Longrightarrow"            class="o" val="????"/>
+  <entry name="longleftrightarrow" class="o" val="????"/>
+  <entry name="Longleftrightarrow" class="o" val="????"/>
+  <entry name="longmapsto"                class="o" val="????"/>
+  <entry name="hookrightarrow"            class="o" val="&#x21aa;"/>
+  <entry name="Uparrow"                   class="o" val="&#x21d1;"/>
+  <entry name="Downarrow"                 class="o" val="&#x21d3;"/>
+  <entry name="searrow"                   class="o" val="&#x2198;"/>
+  <entry name="swarrow"                   class="o" val="&#x2199;"/>
+
+  <entry name="buildrel" pattern="#1\over#2" embellishment="1"/>
+
+  <!-- Delimiters -->
+
+  <entry name="lbrack"         class="o" val="[" delimiter="1"/>
+  <entry name="rbrack"         class="o" val="]" delimiter="1"/>
+  <entry name="vert"           class="o" val="|" delimiter="1"/>
+  <entry name="Vert"           class="o" val="&#x2016;" delimiter="1"/>
+  <entry name="lbrace"         class="o" val="{" delimiter="1"/>
+  <entry name="{"              class="o" val="{" delimiter="1"/>
+  <entry name="rbrace"         class="o" val="}" delimiter="1"/>
+  <entry name="}"              class="o" val="}" delimiter="1"/>
+  <entry name="lfloor"         class="o" val="&#x230a;" delimiter="1"/>
+  <entry name="rfloor"         class="o" val="&#x230b;" delimiter="1"/>
+  <entry name="langle"         class="o" val="&#x2329;" delimiter="1"/>
+  <entry name="rangle"         class="o" val="&#x232a;" delimiter="1"/>
+  <entry name="lceil"          class="o" val="&#x2308;" delimiter="1"/>
+  <entry name="rceil"          class="o" val="&#x2309;" delimiter="1"/>
+
+  <entry name="left"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="right"          pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="bigl"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="bigr"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="bigm"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="big"            pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="Bigl"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="Bigr"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="Bigm"           pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="biggl"          pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="biggr"          pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="biggm"          pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="Biggl"          pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="Biggr"          pattern="#1" embellishment="1" delimiter="1"/>
+  <entry name="Biggm"          pattern="#1" embellishment="1" delimiter="1"/>
+
+  <!-- Accents -->
+
+  <entry name="hat"       pattern="#1" embellishment="1"/>
+  <entry name="widehat"   pattern="#1" embellishment="1"/>
+  <entry name="check"     pattern="#1" embellishment="1"/>
+  <entry name="tilde"     pattern="#1" embellishment="1"/>
+  <entry name="widetilde" pattern="#1" embellishment="1"/>
+  <entry name="acute"     pattern="#1" embellishment="1"/>
+  <entry name="grave"     pattern="#1" embellishment="1"/>
+  <entry name="dot"       pattern="#1" embellishment="1"/>
+  <entry name="ddot"      pattern="#1" embellishment="1"/>
+  <entry name="breve"     pattern="#1" embellishment="1"/>
+  <entry name="bar"       pattern="#1" embellishment="1"/>
+  <entry name="vec"       pattern="#1" embellishment="1"/>
+
+  <!-- Elementary Math Control Sequences -->
+
+  <entry name="overline"  pattern="#1"/>
+  <entry name="underline" pattern="#1"/>
+  <entry name="sqrt"      pattern="#1"/>
+  <entry name="root"      pattern="#1\of#2"/>
+  <entry name="over"      pattern="{}"/>
+  <entry name="atop"      pattern="{}"/>
+  <entry name="choose"    pattern="{}"/>
+  <entry name="brace"     pattern="{}"/>
+  <entry name="brack"     pattern="{}"/>
+
+  <!-- Style -->
+
+  <entry name="displaystyle"      pattern="}"/>
+  <entry name="textstyle"         pattern="}"/>
+  <entry name="scriptstyle"       pattern="}"/>
+  <entry name="scriptscriptstyle" pattern="}"/>
+
+  <!-- Non-Italic Function Names -->
+
+  <entry name="arccos" class="i" val="arccos"/>
+  <entry name="arcsin" class="i" val="arcsin"/>
+  <entry name="arctan" class="i" val="arctan"/>
+  <entry name="arg"    class="i" val="arg"/>
+  <entry name="cos"    class="i" val="cos"/>
+  <entry name="cosh"   class="i" val="cosh"/>
+  <entry name="cot"    class="i" val="cot"/>
+  <entry name="coth"   class="i" val="coth"/>
+  <entry name="csc"    class="i" val="csc"/>
+  <entry name="exp"    class="i" val="exp"/>
+  <entry name="deg"    class="i" val="deg"/>
+  <entry name="det"    class="o" val="det" limits="1"/>
+  <entry name="dim"    class="i" val="dim"/>
+  <entry name="gcd"    class="o" val="gcd" limits="1"/>
+  <entry name="hom"    class="i" val="hom"/>
+  <entry name="inf"    class="o" val="inf" limits="1"/>
+  <entry name="ker"    class="i" val="ker"/>
+  <entry name="lg"     class="i" val="lg"/>
+  <entry name="lim"    class="o" val="lim" limits="1"/>
+  <entry name="liminf" class="o" val="liminf" limits="1"/>
+  <entry name="limsup" class="o" val="limsup" limits="1"/>
+  <entry name="ln"     class="i" val="ln"/>
+  <entry name="log"    class="i" val="log"/>
+  <entry name="max"    class="o" val="max" limits="1"/>
+  <entry name="min"    class="o" val="max" limits="1"/>
+  <entry name="Pr"     class="o" val="Pr" limits="1"/>
+  <entry name="sec"    class="i" val="sec"/>
+  <entry name="sin"    class="i" val="sin"/>
+  <entry name="sinh"   class="i" val="sinh"/>
+  <entry name="sup"    class="o" limits="1"/>
+  <entry name="tan"    class="i" val="tan"/>
+  <entry name="tanh"   class="i" val="tanh"/>
+  <entry name="pmod"   pattern="#1"/>
+  <entry name="bmod"   class="o" val="mod"/>
+
+  <!-- Ellipses -->
+
+  <entry name="dots"          class="i" val="&#x2026;"/>
+  <entry name="ldots"         class="i" val="&#x2026;"/>
+  <entry name="cdots"         class="i" val="&#x22ef;"/>
+  <entry name="vdots"         class="i" val="&#x22ee;"/>
+  <entry name="ddots"         class="i" val="&#x22f1;"/>
+
+  <!-- Fonts -->
+
+  <entry name="rm" pattern="}"/>
+  <entry name="bf" pattern="}"/>
+  <entry name="tt" pattern="}"/>
+  <entry name="sl" pattern="}"/>
+  <entry name="it" pattern="}"/>
+
+  <!-- Horizontal Spacing -->
+
+  <entry name=","/>
+  <entry name="&gt;"/>
+  <entry name=";"/>
+  <entry name="!"/>
+
+  <!-- Braces and Matrices -->
+
+  <entry name="matrix"       pattern="#1" table="1"/>
+  <entry name="pmatrix"      pattern="#1" table="1"/>
+  <entry name="bordermatrix" pattern="#1" table="1"/>
+  <entry name="overbrace"    pattern="#1" limits="1"/>
+  <entry name="underbrace"   pattern="#1" limits="1"/>
+  <entry name="cases"        pattern="#1" table="1"/>
+
+</dictionary>
diff --git a/helm/DEVEL/mathml_editor/editex-config.in b/helm/DEVEL/mathml_editor/editex-config.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/helm/DEVEL/mathml_editor/examples/abs.tex b/helm/DEVEL/mathml_editor/examples/abs.tex
new file mode 100644 (file)
index 0000000..6cd86a1
--- /dev/null
@@ -0,0 +1 @@
+$|x|=\matrix{1&0\cr0&1}$
diff --git a/helm/DEVEL/mathml_editor/examples/big.tex b/helm/DEVEL/mathml_editor/examples/big.tex
new file mode 100644 (file)
index 0000000..913a1a1
--- /dev/null
@@ -0,0 +1 @@
+$1+x+x^2+x^3+\cdots+x^n\over{\sqrt 1+y^{-1}+y^{-2}+y^{-3}+\cdots+y^{-m}}$
diff --git a/helm/DEVEL/mathml_editor/src/APushLexer.hh b/helm/DEVEL/mathml_editor/src/APushLexer.hh
new file mode 100644 (file)
index 0000000..2243426
--- /dev/null
@@ -0,0 +1,21 @@
+
+#ifndef __APushLexer_hh__
+#define __APushLexer_hh__
+
+class APushLexer
+{
+public:
+  APushLexer(class APushParser& p) : parser(p) { };
+  virtual ~APushLexer() { };
+
+  virtual void push(char) = 0;
+  virtual void reset(void) = 0;
+  virtual bool error(void) const = 0;
+  //virtual void freeze(void);
+  //virtual void thaw(void);
+
+protected:
+  class APushParser& parser;
+};
+
+#endif // __APushLexer_hh__
diff --git a/helm/DEVEL/mathml_editor/src/APushParser.hh b/helm/DEVEL/mathml_editor/src/APushParser.hh
new file mode 100644 (file)
index 0000000..c297810
--- /dev/null
@@ -0,0 +1,14 @@
+
+#ifndef __APushParser_hh__
+#define __APushParser_hh__
+
+class APushParser
+{
+public:
+  APushParser(void) { };
+  virtual ~APushParser() { };
+  virtual void push(const TToken&) = 0;
+  virtual void setCursor(const std::string&) = 0;
+};
+
+#endif // __APushParser_hh__
diff --git a/helm/DEVEL/mathml_editor/src/BROWSE b/helm/DEVEL/mathml_editor/src/BROWSE
new file mode 100644 (file)
index 0000000..ddd9c44
--- /dev/null
@@ -0,0 +1,503 @@
+[ebrowse-hs "ebrowse 5.0" " -x" () ()][ebrowse-ts [ebrowse-cs "APushParser" () 0"APushParser.hh" "class APushParser
+{" 75"APushParser.hh" ]
+([ebrowse-ts [ebrowse-cs "TPushParser" () 0"TPushParser.hh" "class TPushParser :" 226"TPushParser.hh" ]
+()([ebrowse-ms "buffer" () 0 () "  std::list<TToken> buffer;" 1306 2  () () 0]
+[ebrowse-ms "cursor" () 0 () "  TNode     cursor;" 1363 2  () () 0]
+[ebrowse-ms "doc" () 0 () "  TDocument doc;" 1343 2  () () 0]
+[ebrowse-ms "frames" () 0 () "  std::stack<Frame> frames;" 1278 2  () () 0]
+[ebrowse-ms "nextId" () 0 () "  unsigned  nextId;" 1326 2  () () 0]
+)
+([ebrowse-ms "PRIME" () 4 () "  std::string PRIME(void" 490 2  "TPushParser.cc" "TPushParser::PRIME()" 279]
+[ebrowse-ms "TPushParser" () 0 () () 0 0  "TPushParser.cc" "TPushParser::TPushParser(const TDictionary& d) :" 58]
+[ebrowse-ms "TPushParser" () 0 () "  TPushParser(const class TDictionary&);" 275 0  () () 0]
+[ebrowse-ms "advance" () 0 () "  void advance(const" 1065 2  "TPushParser.cc" "TPushParser::advance(const" 13192]
+[ebrowse-ms "do_active" () 0 () "  void do_active(const" 916 2  "TPushParser.cc" "TPushParser::do_active(const" 5602]
+[ebrowse-ms "do_align" () 0 () "  void do_align(void" 624 2  "TPushParser.cc" "TPushParser::do_align()" 1530]
+[ebrowse-ms "do_apostrophe" () 0 () "  void do_apostrophe(void" 1042 2  "TPushParser.cc" "TPushParser::do_apostrophe()" 4611]
+[ebrowse-ms "do_begin" () 0 () "  void do_begin(void" 557 2  "TPushParser.cc" "TPushParser::do_begin()" 461]
+[ebrowse-ms "do_comment" () 0 () "  void do_comment(void" 954 2  "TPushParser.cc" "TPushParser::do_comment()" 5668]
+[ebrowse-ms "do_control" () 0 () "  void do_control(const" 980 2  "TPushParser.cc" "TPushParser::do_control(const" 6337]
+[ebrowse-ms "do_cr" () 0 () "  void do_cr(void" 1014 2  "TPushParser.cc" "TPushParser::do_cr()" 5708]
+[ebrowse-ms "do_digit" () 0 () "  void do_digit(const" 841 2  "TPushParser.cc" "TPushParser::do_digit(const" 4072]
+[ebrowse-ms "do_end" () 0 () "  void do_end(void" 578 2  "TPushParser.cc" "TPushParser::do_end()" 910]
+[ebrowse-ms "do_eol" () 0 () "  void do_eol(void" 645 2  "TPushParser.cc" "TPushParser::do_eol()" 2464]
+[ebrowse-ms "do_letter" () 0 () "  void do_letter(const" 804 2  "TPushParser.cc" "TPushParser::do_letter(const" 3902]
+[ebrowse-ms "do_other" () 0 () "  void do_other(const" 878 2  "TPushParser.cc" "TPushParser::do_other(const" 5303]
+[ebrowse-ms "do_parameter" () 0 () "  void do_parameter(const" 673 2  "TPushParser.cc" "TPushParser::do_parameter(const" 2546]
+[ebrowse-ms "do_shift" () 0 () "  void do_shift(void" 601 2  "TPushParser.cc" "TPushParser::do_shift()" 1487]
+[ebrowse-ms "do_space" () 0 () "  void do_space(const" 766 2  "TPushParser.cc" "TPushParser::do_space(const" 3794]
+[ebrowse-ms "do_subscript" () 0 () "  void do_subscript(void" 742 2  "TPushParser.cc" "TPushParser::do_subscript()" 2609]
+[ebrowse-ms "do_superscript" () 0 () "  void do_superscript(void" 715 2  "TPushParser.cc" "TPushParser::do_superscript()" 3204]
+[ebrowse-ms "document" () 4 () "  TDocument document(void" 432 0  () "  TDocument document(void" 432]
+[ebrowse-ms "isPrimes" () 4 () "  bool isPrimes(const" 520 2  "TPushParser.cc" "TPushParser::isPrimes(const" 4445]
+[ebrowse-ms "process" () 0 () "  void process(const" 1096 2  "TPushParser.cc" "TPushParser::process(const" 8538]
+[ebrowse-ms "push" () 1 () "  virtual void push(const" 349 0  "TPushParser.cc" "TPushParser::push(const" 9379]
+[ebrowse-ms "setCursor" () 1 () "  virtual void setCursor(const" 390 0  "TPushParser.cc" "TPushParser::setCursor(const" 13865]
+[ebrowse-ms "~TPushParser" () 1 () "  virtual ~TPushParser()" 321 0  "TPushParser.cc" "TPushParser::~TPushParser()" 241]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TTokenizer" () 0"TTokenizer.hh" "class TTokenizer :" 173"TTokenizer.hh" ]
+()([ebrowse-ms "tokens" () 0 () "  std::list<TToken> tokens;" 405 2  () () 0]
+)
+([ebrowse-ms "TTokenizer" () 0 () "  TTokenizer(void) {" 221 0  () "  TTokenizer(void) {" 221]
+[ebrowse-ms "push" () 1 () "  virtual void push(const" 316 2  "TTokenizer.cc" "TTokenizer::push(const" 471]
+[ebrowse-ms "setCursor" () 1 () "  virtual void setCursor(const" 357 2  () "  virtual void setCursor(const" 357]
+[ebrowse-ms "tokenize" () 0 () "  std::vector<TToken> tokenize(const" 265 0  "TTokenizer.cc" "TTokenizer::tokenize(const" 120]
+)
+()
+()
+()
+()
+()()
+])()
+([ebrowse-ms "APushParser" () 0 () "  APushParser(void) {" 102 0  () "  APushParser(void) {" 102]
+[ebrowse-ms "push" () 9 () "  virtual void push(const" 164 0  () () 0]
+[ebrowse-ms "setCursor" () 9 () "  virtual void setCursor(const" 209 0  () () 0]
+[ebrowse-ms "~APushParser" () 1 () "  virtual ~APushParser()" 133 0  () "  virtual ~APushParser()" 133]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "EmptyBuffer" "TLexerPush" 0"TLexerPush.hh" "  class EmptyBuffer {" 271() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "unary_function" "std" 32() () 0() ]
+([ebrowse-ts [ebrowse-cs "StringHash" "TDictionary" 0"TDictionary.hh" "  struct StringHash :" 1160"TDictionary.hh" ]
+()()
+([ebrowse-ms "operator ()" () 4 () "  { size_t operator()(const" 1238 0  () "  { size_t operator()(const" 1238]
+)
+()
+()
+()
+()
+()()
+])()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TObject" () 0"TObject.hh" "class TObject
+{" 63"TObject.hh" ]
+()()
+([ebrowse-ms "TObject" () 0 () "  TObject(void) {" 89 1  () "  TObject(void) {" 89]
+[ebrowse-ms "ref" () 4 () "  void ref(coid" 162 0  () "  void ref(coid" 162]
+[ebrowse-ms "unref" () 4 () "  void unref(void" 206 0  () "  void unref(void" 206]
+[ebrowse-ms "~TObject" () 1 () "  virtual ~TObject()" 132 1  () "  virtual ~TObject()" 132]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "std" () 0() () 0() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TLexerPush" () 0"TLexerPush.hh" "class TLexerPush
+{" 59"TLexerPush.hh" ]
+()([ebrowse-ms "state" () 0 () "  State state;" 388 2  () () 0]
+[ebrowse-ms "tokens" () 0 () "  std::deque<TToken> tokens;" 417 2  () () 0]
+)
+([ebrowse-ms "TLexerPush" () 0 () "  TLexerPush(void);" 85 0  "TLexerPush.cc" "TLexerPush::TLexerPush()
+{" 51]
+[ebrowse-ms "ambiguous" () 4 () "  bool   ambiguous(void" 182 0  "TLexerPush.cc" "TLexerPush::ambiguous()" 576]
+[ebrowse-ms "empty" () 4 () "  bool   empty(void" 240 0  "TLexerPush.cc" "TLexerPush::empty()" 447]
+[ebrowse-ms "front" () 4 () "  TToken front(void" 150 0  "TLexerPush.cc" "TLexerPush::front()" 338]
+[ebrowse-ms "pending" () 4 () "  bool   pending(void" 212 0  "TLexerPush.cc" "TLexerPush::pending()" 510]
+[ebrowse-ms "pop" () 0 () "  TToken pop(void" 128 0  "TLexerPush.cc" "TLexerPush::pop()" 99]
+[ebrowse-ms "push" () 0 () "  void   push(TChar" 108 0  "TLexerPush.cc" "TLexerPush::push(TChar" 664]
+)
+()
+()
+()
+([ebrowse-ms "State" () 0 () "    {" 303 2  () "    {" 303]
+)
+()()
+][ebrowse-ts [ebrowse-cs "TLexerPull" () 0() () 0"TLexerPull.cc" ]
+()()
+([ebrowse-ms "pop" () 0 () () 0 0  () "TLexerPull::pop(TCharStream" 94]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TDictionary" () 0"TDictionary.hh" "class TDictionary
+{" 154"TDictionary.hh" ]
+()([ebrowse-ms "entries" () 0 () "  Dictionary entries;" 1560 2  () () 0]
+)
+([ebrowse-ms "TDictionary" () 0 () "  TDictionary(void) {" 181 0  () "  TDictionary(void) {" 181]
+[ebrowse-ms "find" () 4 () "  const Entry& find(const" 1107 0  "TDictionary.cc" "TDictionary::find(const" 3723]
+[ebrowse-ms "load" () 0 () "  void load(const" 1069 0  "TDictionary.cc" "TDictionary::load(const" 162]
+[ebrowse-ms "~TDictionary" () 0 () "  ~TDictionary()" 204 0  () "  ~TDictionary()" 204]
+)
+()
+()
+()
+([ebrowse-ms "Dictionary" () 0 () "ap< std::string, Entry, StringHash > Dictionary;" 1538 2  () () 0]
+[ebrowse-ms "EntryClass" () 0 () "    {" 301 0  () "    {" 301]
+[ebrowse-ms "Form" () 0 () "    {" 228 0  () "    {" 228]
+)
+()()
+][ebrowse-ts [ebrowse-cs "DOM" () 0() () 0() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "APushLexer" () 0"APushLexer.hh" "class APushLexer
+{" 72"APushLexer.hh" ]
+([ebrowse-ts [ebrowse-cs "TPushLexer" () 0"TPushLexer.hh" "class TPushLexer :" 117"TPushLexer.hh" ]
+()([ebrowse-ms "buffer" () 0 () "  std::string buffer;" 483 2  () () 0]
+[ebrowse-ms "state" () 0 () "  State state;" 461 2  () () 0]
+)
+([ebrowse-ms "TPushLexer" () 0 () () 0 0  "TPushLexer.cc" "TPushLexer::TPushLexer(APushParser& p) :" 108]
+[ebrowse-ms "TPushLexer" () 0 () "  TPushLexer(class APushParser&);" 164 0  () () 0]
+[ebrowse-ms "error" () 5 () "  virtual bool error(void" 290 0  "TPushLexer.cc" "TPushLexer::error()" 2463]
+[ebrowse-ms "push" () 1 () "  virtual void push(char" 234 0  "TPushLexer.cc" "TPushLexer::push(char" 1180]
+[ebrowse-ms "reset" () 1 () "  virtual void reset(void" 262 0  "TPushLexer.cc" "TPushLexer::reset()" 176]
+[ebrowse-ms "transaction" () 0 () "  void transaction(char" 436 2  "TPushLexer.cc" "TPushLexer::transaction(char" 251]
+[ebrowse-ms "~TPushLexer" () 1 () "  virtual ~TPushLexer()" 203 0  () "  virtual ~TPushLexer()" 203]
+)
+()
+()
+()
+([ebrowse-ms "State" () 0 () "    {" 327 2  () "    {" 327]
+)
+()()
+])()
+([ebrowse-ms "APushLexer" () 0 () "  APushLexer(class APushParser& p) :" 99 0  () "  APushLexer(class APushParser& p) :" 99]
+[ebrowse-ms "error" () 13 () "  virtual bool error(void" 251 0  () () 0]
+[ebrowse-ms "push" () 9 () "  virtual void push(char" 187 0  () () 0]
+[ebrowse-ms "reset" () 9 () "  virtual void reset(void" 219 0  () () 0]
+[ebrowse-ms "~APushLexer" () 1 () "  virtual ~APushLexer()" 156 0  () "  virtual ~APushLexer()" 156]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "Ptr" () 32"Ptr.hh" "class Ptr
+{" 1067"Ptr.hh" ]
+()([ebrowse-ms "ptr" () 0 () "  P* ptr;" 1797 2  () () 0]
+)
+([ebrowse-ms "P" () 4 () "  operator P*()" 1487 0  () "  operator P*()" 1487]
+[ebrowse-ms "Ptr" () 0 () "  Ptr(const Ptr& p) :" 1142 0  () "  Ptr(const Ptr& p) :" 1142]
+[ebrowse-ms "Ptr" () 0 () "  Ptr(P* p = 0) :" 1083 0  () "  Ptr(P* p = 0) :" 1083]
+[ebrowse-ms "Q" () 36 () "  template <class Q> operator Ptr<Q>()" 1747 0  () "  template <class Q> operator Ptr<Q>()" 1747]
+[ebrowse-ms "operator ->" () 4 () "  P* operator->()" 1253 0  () "  P* operator->()" 1253]
+[ebrowse-ms "operator =" () 0 () "  Ptr& operator=(const" 1316 0  () "  Ptr& operator=(const" 1316]
+[ebrowse-ms "~Ptr" () 0 () "  ~Ptr()" 1202 0  () "  ~Ptr()" 1202]
+)
+()
+()
+([ebrowse-ms "is_a" () 32 () "  template <class Q> friend bool is_a(const" 1659 0  () "  template <class Q> friend bool is_a(const" 1659]
+[ebrowse-ms "smart_cast" () 32 () "emplate <class Q> friend Ptr<Q> smart_cast(const" 1561 0  () "emplate <class Q> friend Ptr<Q> smart_cast(const" 1561]
+)
+()
+()()
+][ebrowse-ts [ebrowse-cs "TToken" () 0"TToken.hh" "struct TToken
+{" 80"TToken.hh" ]
+()([ebrowse-ms "category" () 0 () "  TCat        category;" 627 0  () () 0]
+[ebrowse-ms "value" () 0 () "  std::string value;" 648 0  () () 0]
+)
+([ebrowse-ms "TToken" () 0 () "  TToken(TCat c, const std::string& v) :" 438 0  () "  TToken(TCat c, const std::string& v) :" 438]
+[ebrowse-ms "TToken" () 0 () "  TToken(TCat c, char ch) :" 366 0  () "  TToken(TCat c, char ch) :" 366]
+[ebrowse-ms "TToken" () 0 () "  TToken(TCat c) :" 330 0  () "  TToken(TCat c) :" 330]
+[ebrowse-ms "operator ==" () 4 () "  bool operator==(const" 517 0  () "  bool operator==(const" 517]
+)
+()
+()
+()
+([ebrowse-ms "TCat" () 0 () "    {" 98 0  () "    {" 98]
+)
+()()
+][ebrowse-ts [ebrowse-cs "binary_function" "std" 32() () 0() ]
+([ebrowse-ts [ebrowse-cs "StringEq" "TDictionary" 0"TDictionary.hh" "  struct StringEq :" 1327() ]
+()()
+([ebrowse-ms "operator ()" () 4 () "  { bool operator()(const" 1415 0  () () 0]
+)
+()
+()
+()
+()
+()()
+])()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TNode" () 0"TNode.hh" "class TNode
+{" 124"TNode.hh" ]
+()([ebrowse-ms "node" () 0 () "  DOM::Element node;" 2444 2  () () 0]
+)
+([ebrowse-ms "TNode" () 0 () "  TNode(const TNode& n) :" 270 0  () "  TNode(const TNode& n) :" 270]
+[ebrowse-ms "TNode" () 0 () "  TNode(void) :" 145 0  () "  TNode(void) :" 145]
+[ebrowse-ms "append" () 4 () "  void  append(const" 1667 0  "TNode.cc" "TNode::append(const" 2450]
+[ebrowse-ms "append" () 4 () "  void  append(const" 1631 0  "TNode.cc" "TNode::append(const" 2348]
+[ebrowse-ms "child" () 4 () "  TNode child(unsigned" 592 0  "TNode.cc" "TNode::child(unsigned" 2874]
+[ebrowse-ms "core" () 4 () "  TNode core(void" 425 0  "TNode.cc" "TNode::core()" 1413]
+[ebrowse-ms "empty" () 4 () "  bool  empty(void" 648 0  () "  bool  empty(void" 648]
+[ebrowse-ms "first" () 4 () "  TNode first(void" 480 0  "TNode.cc" "TNode::first()" 1075]
+[ebrowse-ms "firstL" () 4 () "  TNode firstL(void" 508 0  "TNode.cc" "TNode::firstL()" 1259]
+[ebrowse-ms "get" () 4 () "  std::string get(const" 1758 0  "TNode.cc" "TNode::get(const" 3007]
+[ebrowse-ms "hasId" () 4 () "  bool  hasId(void" 1994 0  () "  bool  hasId(void" 1994]
+[ebrowse-ms "insert" () 4 () "  void  insert(const" 1595 0  "TNode.cc" "TNode::insert(const" 2193]
+[ebrowse-ms "is" () 4 () "  bool  is(const" 2055 0  () "  bool  is(const" 2055]
+[ebrowse-ms "isC" () 4 () "  bool  isC(const" 2303 0  () "  bool  isC(const" 2303]
+[ebrowse-ms "isC" () 4 () "  bool  isC(void" 2258 0  () "  bool  isC(void" 2258]
+[ebrowse-ms "isG" () 4 () "  bool  isG(void" 2119 0  () "  bool  isG(void" 2119]
+[ebrowse-ms "isSb" () 4 () "  bool  isSb(void" 2165 0  () "  bool  isSb(void" 2165]
+[ebrowse-ms "isSp" () 4 () "  bool  isSp(void" 2212 0  () "  bool  isSp(void" 2212]
+[ebrowse-ms "last" () 4 () "  TNode last(void" 534 0  "TNode.cc" "TNode::last()" 736]
+[ebrowse-ms "lastL" () 4 () "  TNode lastL(void" 561 0  "TNode.cc" "TNode::lastL()" 922]
+[ebrowse-ms "name" () 4 () "  std::string name(void" 1863 0  () "  std::string name(void" 1863]
+[ebrowse-ms "nameC" () 4 () "  std::string nameC(void" 1929 0  () "  std::string nameC(void" 1929]
+[ebrowse-ms "next" () 4 () "  TNode next(void" 319 0  "TNode.cc" "TNode::next()" 63]
+[ebrowse-ms "nextL" () 4 () "  TNode nextL(void" 346 0  "TNode.cc" "TNode::nextL()" 247]
+[ebrowse-ms "operator !=" () 4 () "  bool operator!=(const" 1295 0  () "  bool operator!=(const" 1295]
+[ebrowse-ms "operator ==" () 4 () "  bool operator==(const" 1227 0  () "  bool operator==(const" 1227]
+[ebrowse-ms "operator []" () 4 () "  ProxyAttr operator[](const" 1422 0  () "  ProxyAttr operator[](const" 1422]
+[ebrowse-ms "operator []" () 4 () "  TNode operator[](int" 1362 0  () "  TNode operator[](int" 1362]
+[ebrowse-ms "parent" () 4 () "  TNode parent(void" 453 0  "TNode.cc" "TNode::parent()" 1587]
+[ebrowse-ms "prepend" () 4 () "  void  prepend(const" 1718 0  "TNode.cc" "TNode::prepend(const" 2683]
+[ebrowse-ms "prev" () 4 () "  TNode prev(void" 372 0  "TNode.cc" "TNode::prev()" 396]
+[ebrowse-ms "prevL" () 4 () "  TNode prevL(void" 399 0  "TNode.cc" "TNode::prevL()" 588]
+[ebrowse-ms "remove" () 4 () "  void  remove(void" 1529 0  "TNode.cc" "TNode::remove()" 1913]
+[ebrowse-ms "replace" () 4 () "  void  replace(const" 1559 0  "TNode.cc" "TNode::replace(const" 2038]
+[ebrowse-ms "set" () 4 () "  void  set(const" 1797 0  "TNode.cc" "TNode::set(const" 3109]
+[ebrowse-ms "size" () 4 () "  unsigned size(void" 621 0  "TNode.cc" "TNode::size()" 1749]
+[ebrowse-ms "value" () 4 () "  std::string value(void" 707 0  () "  std::string value(void" 707]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "Entry" "TDictionary" 0"TDictionary.hh" "  struct Entry
+  {" 405"TDictionary.hh" ]
+()([ebrowse-ms "cls" () 0 () "    EntryClass cls;" 806 0  () () 0]
+[ebrowse-ms "delimiter" () 0 () "    unsigned delimiter : 1;" 909 0  () () 0]
+[ebrowse-ms "embellishment" () 0 () "    unsigned embellishment : 1;" 966 0  () () 0]
+[ebrowse-ms "infix" () 0 () "    unsigned infix : 8;" 830 0  () () 0]
+[ebrowse-ms "leftOpen" () 0 () "    unsigned leftOpen : 1;" 993 0  () () 0]
+[ebrowse-ms "limits" () 0 () "    unsigned limits : 1;" 934 0  () () 0]
+[ebrowse-ms "pattern" () 0 () "    std::vector<TToken> pattern;" 597 0  () () 0]
+[ebrowse-ms "postfix" () 0 () "    unsigned postfix : 8;" 881 0  () () 0]
+[ebrowse-ms "prefix" () 0 () "    unsigned prefix : 8;" 855 0  () () 0]
+[ebrowse-ms "rightOpen" () 0 () "    unsigned rightOpen : 1;" 1021 0  () () 0]
+[ebrowse-ms "table" () 0 () "    unsigned table : 1;" 1045 0  () () 0]
+[ebrowse-ms "value" () 0 () "    std::string value;" 620 0  () () 0]
+)
+([ebrowse-ms "Entry" () 0 () "    {" 420 0  () "    {" 420]
+[ebrowse-ms "defined" () 4 () "    bool defined(void" 643 0  () "    bool defined(void" 643]
+[ebrowse-ms "hasArguments" () 4 () "    bool hasArguments(void" 707 0  () "    bool hasArguments(void" 707]
+[ebrowse-ms "paramDelimited" () 4 () "    bool paramDelimited(unsigned" 777 0  "TDictionary.cc" "TDictionary::Entry::paramDelimited(unsigned" 4012]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "Frame" "TPushParser" 0"TPushParser.hh" "  struct Frame
+  {" 1126"TPushParser.hh" ]
+()([ebrowse-ms "entry" () 0 () "    const TDictionary::Entry& entry;" 1226 0  () () 0]
+[ebrowse-ms "pos" () 0 () "    unsigned pos;" 1244 0  () () 0]
+)
+([ebrowse-ms "Frame" () 0 () "    Frame(const TDictionary::Entry& e) :" 1142 0  () "    Frame(const TDictionary::Entry& e) :" 1142]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TCharStream" () 0"TCharStream.hh" "class TCharStream
+{" 94"TCharStream.hh" ]
+([ebrowse-ts [ebrowse-cs "TCharStreamString" () 0"TCharStreamString.hh" "class TCharStreamString :" 120"TCharStreamString.hh" ]
+()([ebrowse-ms "buffer" () 0 () "  TString buffer;" 555 2  () () 0]
+[ebrowse-ms "idx" () 0 () "  unsigned long idx;" 536 2  () () 0]
+)
+([ebrowse-ms "TCharStreamString" () 0 () "  TCharStreamString(const TString& s) :" 175 0  () "  TCharStreamString(const TString& s) :" 175]
+[ebrowse-ms "look" () 5 () "  virtual TChar look(void" 343 0  () "  virtual TChar look(void" 343]
+[ebrowse-ms "more" () 5 () "  virtual bool  more(void" 275 0  () "  virtual bool  more(void" 275]
+[ebrowse-ms "next" () 1 () "  virtual TChar next(void" 439 0  () "  virtual TChar next(void" 439]
+[ebrowse-ms "~TCharStreamString" () 1 () "  virtual ~TCharStreamString()" 243 0  () "  virtual ~TCharStreamString()" 243]
+)
+()
+()
+()
+()
+()()
+])()
+([ebrowse-ms "TCharStream" () 0 () "  TCharStream(void) {" 121 0  () "  TCharStream(void) {" 121]
+[ebrowse-ms "look" () 13 () "  virtual TChar look(void" 222 0  () () 0]
+[ebrowse-ms "more" () 13 () "  virtual bool  more(void" 184 0  () () 0]
+[ebrowse-ms "next" () 9 () "  virtual TChar next(void" 260 0  () () 0]
+[ebrowse-ms "~TCharStream" () 1 () "  virtual ~TCharStream()" 152 0  () "  virtual ~TCharStream()" 152]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "EmptyStream" "TCharStream" 0"TCharStream.hh" "  class EmptyStream {" 289() ]
+()()
+()
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "*Globals*" () 0() () 0"APushLexer.hh" ]
+()()
+([ebrowse-ms "dispatch" () 0 "special.cc" "dispatch(const" 1012 0  "special.cc" "dispatch(const" 1012]
+[ebrowse-ms "do_apostrophe" () 0 "special.cc" "do_apostrophe(const" 669 0  "special.cc" "do_apostrophe(const" 669]
+[ebrowse-ms "do_bgroup" () 0 "special.cc" "do_bgroup(const" 149 0  "special.cc" "do_bgroup(const" 149]
+[ebrowse-ms "do_control" () 0 "special.cc" "do_control(const" 711 0  "special.cc" "do_control(const" 711]
+[ebrowse-ms "do_other" () 0 "special.cc" "do_other(const" 776 0  "special.cc" "do_other(const" 776]
+[ebrowse-ms "finishG" () 0 "special.cc" "void finishG(const" 118 0  () () 0]
+[ebrowse-ms "getCore" () 0 "domnav.cc" "getCore(const" 629 0  "domnav.cc" "getCore(const" 629]
+[ebrowse-ms "getRightmostChild" () 0 "domnav.cc" "getRightmostChild(const" 37 0  "domnav.cc" "getRightmostChild(const" 37]
+[ebrowse-ms "isDelimiter" () 0 "domnav.cc" "isDelimiter(const" 1716 0  "domnav.cc" "isDelimiter(const" 1716]
+[ebrowse-ms "isFunction" () 0 "domnav.cc" "isFunction(const" 1879 0  "domnav.cc" "isFunction(const" 1879]
+[ebrowse-ms "isGroup" () 0 "domnav.cc" "isGroup(const" 1214 0  "domnav.cc" "isGroup(const" 1214]
+[ebrowse-ms "isInferred" () 0 "domnav.cc" "isInferred(const" 985 0  "domnav.cc" "isInferred(const" 985]
+[ebrowse-ms "isMacro" () 0 "domnav.cc" "isMacro(const" 1085 0  "domnav.cc" "isMacro(const" 1085]
+[ebrowse-ms "isOperator" () 0 "domnav.cc" "isOperator(const" 1553 0  "domnav.cc" "isOperator(const" 1553]
+[ebrowse-ms "isPrimes" () 0 "domnav.cc" "isPrimes(const" 1451 0  "domnav.cc" "isPrimes(const" 1451]
+[ebrowse-ms "isSb" () 0 "domnav.cc" "isSb(const" 1291 0  "domnav.cc" "isSb(const" 1291]
+[ebrowse-ms "isSp" () 0 "domnav.cc" "isSp(const" 1369 0  "domnav.cc" "isSp(const" 1369]
+[ebrowse-ms "isUnicodeAlpha" () 2 "dom.hh" "inline bool isUnicodeAlpha(TChar" 303 0  "dom.hh" "inline bool isUnicodeAlpha(TChar" 303]
+[ebrowse-ms "isUnicodeDigit" () 2 "dom.hh" "inline bool isUnicodeDigit(TChar" 408 0  "dom.hh" "inline bool isUnicodeDigit(TChar" 408]
+[ebrowse-ms "isUnicodeSpace" () 2 "dom.hh" "inline bool isUnicodeSpace(TChar" 198 0  "dom.hh" "inline bool isUnicodeSpace(TChar" 198]
+[ebrowse-ms "main" () 0 "texlexer.cc" "main()" 51 0  "texlexer.cc" "main()" 51]
+[ebrowse-ms "prevLinearSibling" () 0 "domnav.cc" "prevLinearSibling(const" 324 0  "domnav.cc" "prevLinearSibling(const" 324]
+[ebrowse-ms "replace" () 0 "domnav.cc" "replace(const" 834 0  "domnav.cc" "replace(const" 834]
+[ebrowse-ms "tokenize" () 0 "tokenizer.hh" "std::vector<TToken> tokenize(const" 123 0  () () 0]
+)
+([ebrowse-ms "undefinedEntry" () 0 () () 0 0  "TDictionary.cc" "static TDictionary::Entry undefinedEntry;" 132]
+)
+()
+([ebrowse-ms "Ptr_hh" () 512 () () 0 0  "Ptr.hh" "#define Ptr_hh
+" 1036]
+[ebrowse-ms "TML_NS_URI" () 512 () () 0 0  "globals.hh" "#define TML_NS_URI " 67]
+[ebrowse-ms "XMLNS_NS_URI" () 512 () () 0 0  "globals.hh" "#define XMLNS_NS_URI " 123]
+[ebrowse-ms "__APushLexer_hh__" () 512 () () 0 0  () "#define __APushLexer_hh__
+" 53]
+[ebrowse-ms "__APushParser_hh__" () 512 () () 0 0  "APushParser.hh" "#define __APushParser_hh__
+" 55]
+[ebrowse-ms "__TCharStreamString_hh__" () 512 () () 0 0  "TCharStreamString.hh" "#define __TCharStreamString_hh__
+" 67]
+[ebrowse-ms "__TCharStream_hh__" () 512 () () 0 0  "TCharStream.hh" "#define __TCharStream_hh__
+" 55]
+[ebrowse-ms "__TDictionary_hh__" () 512 () () 0 0  "TDictionary.hh" "#define __TDictionary_hh__
+" 55]
+[ebrowse-ms "__TDocument_hh__" () 512 () () 0 0  "TDocument.hh" "#define __TDocument_hh__
+" 51]
+[ebrowse-ms "__TNode_hh__" () 512 () () 0 0  "TNode.hh" "#define __TNode_hh__
+" 43]
+[ebrowse-ms "__TObject_hh__" () 512 () () 0 0  "TObject.hh" "#define __TObject_hh__
+" 47]
+[ebrowse-ms "__TPushLexer_hh__" () 512 () () 0 0  "TPushLexer.hh" "#define __TPushLexer_hh__
+" 53]
+[ebrowse-ms "__TPushParser_hh__" () 512 () () 0 0  "TPushParser.hh" "#define __TPushParser_hh__
+" 55]
+[ebrowse-ms "__TToken_hh__" () 512 () () 0 0  "TToken.hh" "#define __TToken_hh__
+" 45]
+[ebrowse-ms "__TTokenizer_hh__" () 512 () () 0 0  "TTokenizer.hh" "#define __TTokenizer_hh__
+" 53]
+[ebrowse-ms "__dom_hh__" () 512 () () 0 0  "dom.hh" "#define __dom_hh__
+" 39]
+[ebrowse-ms "__globals_hh__" () 512 () () 0 0  "globals.hh" "#define __globals_hh__
+" 47]
+[ebrowse-ms "__tokenzier_hh__" () 512 () () 0 0  "tokenizer.hh" "#define __tokenzier_hh__
+" 51]
+)
+([ebrowse-ms "TChar" () 0 () () 0 0  "dom.hh" "typedef DOM::Char32     TChar;" 131]
+[ebrowse-ms "TString" () 0 () () 0 0  "dom.hh" "typedef DOM::UCS4String TString;" 164]
+)
+()()
+][ebrowse-ts [ebrowse-cs "ProxyAttr" "TNode" 0"TNode.hh" "  class ProxyAttr
+  {" 765"TNode.hh" ]
+()([ebrowse-ms "name" () 0 () "    std::string  name;" 1155 2  () () 0]
+[ebrowse-ms "node" () 0 () "    DOM::Element node;" 1132 2  () () 0]
+)
+([ebrowse-ms "ProxyAttr" () 0 () "r(const DOM::Element& n, const std::string& s) :" 795 0  () "r(const DOM::Element& n, const std::string& s) :" 795]
+[ebrowse-ms "operator =" () 0 () "    ProxyAttr& operator=(const" 959 0  () "    ProxyAttr& operator=(const" 959]
+[ebrowse-ms "operator ==" () 0 () "    bool       operator==(const" 1040 0  () "    bool       operator==(const" 1040]
+[ebrowse-ms "string" () 4 () "    operator std::string()" 885 0  () "    operator std::string()" 885]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "EventListener" "DOM" 0() () 0() ]
+([ebrowse-ts [ebrowse-cs "DOMSubtreeModifiedListener" "TDocument" 0"TDocument.hh" "  class DOMSubtreeModifiedListener :" 1015"TDocument.hh" ]
+()([ebrowse-ms "doc" () 0 () "    TDocument doc;" 1247 2  () () 0]
+)
+([ebrowse-ms "DOMSubtreeModifiedListener" () 0 () "DOMSubtreeModifiedListener(const TDocument& d) :" 1092 0  () "DOMSubtreeModifiedListener(const TDocument& d) :" 1092]
+[ebrowse-ms "handleEvent" () 1 () "    virtual void handleEvent(const" 1202 0  () () 0]
+[ebrowse-ms "~DOMSubtreeModifiedListener" () 1 () "    virtual ~DOMSubtreeModifiedListener()" 1162 0  () "    virtual ~DOMSubtreeModifiedListener()" 1162]
+)
+()
+()
+()
+()
+()()
+][ebrowse-ts [ebrowse-cs "TDocument" () 0"TDocument.hh" "class TDocument :" 108"TDocument.hh" ]
+()([ebrowse-ms "dirty" () 0 () "  DOM::Element dirty;" 971 2  () () 0]
+[ebrowse-ms "doc" () 0 () "  DOM::Document doc;" 949 2  () () 0]
+)
+([ebrowse-ms "TDocument" () 0 () "  TDocument(void);" 162 0  "TDocument.cc" "TDocument::TDocument()
+{" 108]
+[ebrowse-ms "create" () 4 () "  TNode create(const" 202 0  "TDocument.cc" "TDocument::create(const" 789]
+[ebrowse-ms "createC" () 4 () "  TNode createC(const" 327 0  "TDocument.cc" "TDocument::createC(const" 1062]
+[ebrowse-ms "createG" () 4 () "  TNode createG(unsigned" 262 0  () "  TNode createG(unsigned" 262]
+[ebrowse-ms "createI" () 4 () "  TNode createI(const" 461 0  () "  TNode createI(const" 461]
+[ebrowse-ms "createN" () 4 () "  TNode createN(const" 561 0  () "  TNode createN(const" 561]
+[ebrowse-ms "createO" () 4 () "  TNode createO(const" 661 0  () "  TNode createO(const" 661]
+[ebrowse-ms "createT" () 4 () "  TNode createT(const" 384 0  "TDocument.cc" "TDocument::createT(const" 1197]
+[ebrowse-ms "dirtyIdNode" () 4 () "  TNode dirtyIdNode(void" 872 0  "TDocument.cc" "TDocument::dirtyIdNode()" 2081]
+[ebrowse-ms "dirtyNode" () 4 () "  TNode dirtyNode(void" 821 0  () "  TNode dirtyNode(void" 821]
+[ebrowse-ms "handleEvent" () 1 () "  virtual void handleEvent(const" 1293 2  "TDocument.cc" "TDocument::handleEvent(const" 2348]
+[ebrowse-ms "root" () 0 () "  TNode root(void" 758 0  () "  TNode root(void" 758]
+[ebrowse-ms "serialize" () 4 () "  void serialize(const" 904 0  "TDocument.cc" "TDocument::serialize(const" 637]
+[ebrowse-ms "~TDocument" () 0 () "  ~TDocument()" 179 0  "TDocument.cc" "TDocument::~TDocument()" 460]
+)
+()
+([ebrowse-ms "findCommonAncestor" () 0 () "  static DOM::Node findCommonAncestor(const" 1398 2  "TDocument.cc" "TDocument::findCommonAncestor(const" 1560]
+[ebrowse-ms "nodeDepth" () 0 () "  static unsigned nodeDepth(const" 1341 2  "TDocument.cc" "TDocument::nodeDepth(const" 1362]
+)
+()
+()
+()()
+])()
+()
+()
+()
+()
+()
+()()
+]
\ No newline at end of file
diff --git a/helm/DEVEL/mathml_editor/src/Makefile.am b/helm/DEVEL/mathml_editor/src/Makefile.am
new file mode 100644 (file)
index 0000000..f440e52
--- /dev/null
@@ -0,0 +1,27 @@
+
+lib_LTLIBRARIES = libeditex.la
+
+libeditex_la_LDFLAGS = -version-info @EDITEX_VERSION_INFO@
+
+libeditex_la_SOURCES = \
+  TPushLexer.cc \
+  TPushParser.cc \
+  TDictionary.cc \
+  TDocument.cc \
+  TNode.cc \
+  TTokenizer.cc
+
+pkginclude_HEADERS = \
+  APushLexer.hh \
+  APushParser.hh \
+  TPushLexer.hh \
+  TPushParser.hh \
+  TTokenizer.hh \
+  TDictionary.hh \
+  TDocument.hh \
+  TNode.hh \
+  TListener.hh \
+  dom.hh
+
+INCLUDES = $(GMETADOM_CFLAGS) $(GDOMEXSLT_CFLAGS)
+
diff --git a/helm/DEVEL/mathml_editor/src/Makefile.in b/helm/DEVEL/mathml_editor/src/Makefile.in
new file mode 100644 (file)
index 0000000..b614c8f
--- /dev/null
@@ -0,0 +1,408 @@
+# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EDITEX_VERSION_INFO = @EDITEX_VERSION_INFO@
+EXEEXT = @EXEEXT@
+GDOMEXSLT_CFLAGS = @GDOMEXSLT_CFLAGS@
+GDOMEXSLT_LIBS = @GDOMEXSLT_LIBS@
+GMETADOM_CFLAGS = @GMETADOM_CFLAGS@
+GMETADOM_LIBS = @GMETADOM_LIBS@
+GTKMATHVIEW_CFLAGS = @GTKMATHVIEW_CFLAGS@
+GTKMATHVIEW_LIBS = @GTKMATHVIEW_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+
+lib_LTLIBRARIES = libeditex.la
+
+libeditex_la_LDFLAGS = -version-info @EDITEX_VERSION_INFO@
+
+libeditex_la_SOURCES =    TPushLexer.cc   TPushParser.cc   TDictionary.cc   TDocument.cc   TNode.cc   TTokenizer.cc
+
+
+pkginclude_HEADERS =    APushLexer.hh   APushParser.hh   TPushLexer.hh   TPushParser.hh   TTokenizer.hh   TDictionary.hh   TDocument.hh   TNode.hh   TListener.hh   dom.hh
+
+
+INCLUDES = $(GMETADOM_CFLAGS) $(GDOMEXSLT_CFLAGS)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+LIBS = @LIBS@
+libeditex_la_LIBADD = 
+libeditex_la_OBJECTS =  TPushLexer.lo TPushParser.lo TDictionary.lo \
+TDocument.lo TNode.lo TTokenizer.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+HEADERS =  $(pkginclude_HEADERS)
+
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES =  .deps/TDictionary.P .deps/TDocument.P .deps/TNode.P \
+.deps/TPushLexer.P .deps/TPushParser.P .deps/TTokenizer.P
+SOURCES = $(libeditex_la_SOURCES)
+OBJECTS = $(libeditex_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .obj .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+           $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+         else :; fi; \
+       done
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+       done
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+       $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+       -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libeditex.la: $(libeditex_la_OBJECTS) $(libeditex_la_DEPENDENCIES)
+       $(CXXLINK) -rpath $(libdir) $(libeditex_la_LDFLAGS) $(libeditex_la_OBJECTS) $(libeditex_la_LIBADD) $(LIBS)
+.cc.o:
+       $(CXXCOMPILE) -c $<
+.cc.obj:
+       $(CXXCOMPILE) -c `cygpath -w $<`
+.cc.lo:
+       $(LTCXXCOMPILE) -c $<
+
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(pkgincludedir)
+       @list='$(pkginclude_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+         echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p"; \
+         $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p; \
+       done
+
+uninstall-pkgincludeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       list='$(pkginclude_HEADERS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkgincludedir)/$$p; \
+       done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = src
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu src/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cc
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cc
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am: install-pkgincludeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+       $(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(pkgincludedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-libLTLIBRARIES mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+               clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-libLTLIBRARIES distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-libLTLIBRARIES \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool uninstall-pkgincludeHEADERS \
+install-pkgincludeHEADERS tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/helm/DEVEL/mathml_editor/src/Ptr.hh b/helm/DEVEL/mathml_editor/src/Ptr.hh
new file mode 100644 (file)
index 0000000..9330c96
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2000-2002, Luca Padovani <luca.padovani@cs.unibo.it>.
+//
+// This file is part of GtkMathView, a Gtk widget for MathML.
+// 
+// GtkMathView is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// GtkMathView is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GtkMathView; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// 
+// For details, see the GtkMathView World-Wide-Web page,
+// http://www.cs.unibo.it/helm/mml-widget, or send a mail to
+// <luca.padovani@cs.unibo.it>
+
+#ifndef Ptr_hh
+#define Ptr_hh
+
+template <class P>
+class Ptr
+{
+public:
+  Ptr(P* p = 0) : ptr(p) { if (ptr != 0) ptr->ref(); }
+  Ptr(const Ptr& p) : ptr(p.ptr) { if (ptr != 0) ptr->ref(); }
+  ~Ptr() { if (ptr != 0) ptr->unref(); }
+
+  P* operator->() const { assert(ptr != 0); return ptr; }
+  Ptr& operator=(const Ptr& p)
+  { 
+    if (ptr == p.ptr) return *this;
+    if (p.ptr != 0) p.ptr->ref();
+    if (ptr != 0) ptr->unref();
+    ptr = p.ptr;
+    return *this;
+  }
+
+  operator P*() const { return ptr; }
+  template <class Q> friend Ptr<Q> smart_cast(const Ptr& p) { return Ptr<Q>(dynamic_cast<Q*>(p.ptr)); }  
+  template <class Q> friend bool is_a(const Ptr& p) { return dynamic_cast<Q*>(p.ptr) != 0; }
+  template <class Q> operator Ptr<Q>() const { return Ptr<Q>(ptr); }
+
+private:
+  P* ptr;
+};
+
+#endif // Ptr_hh
diff --git a/helm/DEVEL/mathml_editor/src/TCharStream.hh b/helm/DEVEL/mathml_editor/src/TCharStream.hh
new file mode 100644 (file)
index 0000000..47b01ff
--- /dev/null
@@ -0,0 +1,20 @@
+
+#ifndef __TCharStream_hh__
+#define __TCharStream_hh__
+
+#include "dom.hh"
+
+class TCharStream
+{
+public:
+  TCharStream(void) { };
+  virtual ~TCharStream() { };
+
+  virtual bool  more(void) const = 0;
+  virtual TChar look(void) const = 0;
+  virtual TChar next(void) = 0;
+
+  class EmptyStream { };
+};
+
+#endif // __TCharStream_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TCharStreamString.hh b/helm/DEVEL/mathml_editor/src/TCharStreamString.hh
new file mode 100644 (file)
index 0000000..3630627
--- /dev/null
@@ -0,0 +1,22 @@
+
+#ifndef __TCharStreamString_hh__
+#define __TCharStreamString_hh__
+
+#include "TCharStream.hh"
+
+class TCharStreamString : public TCharStream
+{
+public:
+  TCharStreamString(const TString& s) : buffer(s), idx(0) { };
+  virtual ~TCharStreamString() { };
+
+  virtual bool  more(void) const { return idx < buffer.length(); };
+  virtual TChar look(void) const { if (more()) return buffer[idx]; else throw EmptyStream(); };
+  virtual TChar next(void) { if (more()) return buffer[idx++]; else throw EmptyStream(); };
+
+private:
+  unsigned long idx; 
+  TString buffer;
+};
+
+#endif // __TCharStreamString_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TDictionary.cc b/helm/DEVEL/mathml_editor/src/TDictionary.cc
new file mode 100644 (file)
index 0000000..303d743
--- /dev/null
@@ -0,0 +1,168 @@
+
+#include <sstream>
+
+#include "dom.hh"
+#include "TDictionary.hh"
+#include "TTokenizer.hh"
+
+static TDictionary::Entry undefinedEntry;
+
+void
+TDictionary::load(const char* uri)
+{
+  DOM::DOMImplementation di;
+
+  DOM::Document doc = di.createDocumentFromURI(uri);
+  assert(doc);
+
+  DOM::Element root = doc.get_documentElement();
+  assert(root);
+
+  TTokenizer tokenizer;
+
+  for (DOM::Node p = root.get_firstChild(); p; p = p.get_nextSibling())
+    if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "entry")
+      {
+       DOM::Element el = p;
+       assert(el);
+       assert(el.hasAttribute("name"));
+
+       std::string name = el.getAttribute("name");
+       if (entries.find(name) != entries.end())
+         cerr << "WARNING: entry `" << name << "' is being redefined" << endl;
+
+       Entry entry;
+
+       if (el.hasAttribute("class"))
+         {
+           std::string cls = el.getAttribute("class");
+           if (cls == "o") entry.cls = OPERATOR;
+           else if (cls == "i") entry.cls = IDENTIFIER;
+           else if (cls == "n") entry.cls == NUMBER;
+           else entry.cls = MACRO;
+         }
+       else
+         entry.cls = MACRO;
+
+       if (el.hasAttribute("val"))
+         {
+           entry.value = el.getAttribute("val");
+           if (entry.cls == MACRO)
+             cerr << "WARNING: `" << name << "' has a specified value, but is classified as macro" << endl;
+         }
+
+       if (el.hasAttribute("pattern"))
+         {
+           if (entry.cls != MACRO)
+             cerr << "WARNING: `" << name << "' has a specified pattern, but is not classified as macro" << endl;
+
+           std::string pattern = el.getAttribute("pattern");
+           if (pattern == "{}")
+             entry.leftOpen = entry.rightOpen = 1;
+           else if (pattern == "{")
+             entry.leftOpen = 1;
+           else if (pattern == "}")
+             entry.rightOpen = 1;
+           else
+             entry.pattern = tokenizer.tokenize(pattern);
+         }
+
+       if (el.hasAttribute("infix"))
+         {
+           std::istringstream is(el.getAttribute("infix"));
+           unsigned infix;
+           is >> infix;
+           entry.infix = infix;
+           if (!el.hasAttribute("prefix")) entry.prefix = infix;
+           if (!el.hasAttribute("postfix")) entry.postfix = infix;
+         }
+
+       if (el.hasAttribute("prefix"))
+         {
+           std::istringstream is(el.getAttribute("prefix"));
+           unsigned prefix;
+           is >> prefix;
+           entry.prefix = prefix;
+           if (!el.hasAttribute("infix"))
+             {
+               entry.infix = prefix;
+               if (!el.hasAttribute("postfix")) entry.postfix = prefix;
+             }
+         }
+
+       if (el.hasAttribute("postfix"))
+         {
+           std::istringstream is(el.getAttribute("postfix"));
+           unsigned postfix;
+           is >> postfix;
+           entry.postfix = postfix;
+           if (!el.hasAttribute("infix"))
+             {
+               entry.infix = postfix;
+               if (!el.hasAttribute("prefix")) entry.prefix = postfix;
+             }
+         }
+
+       if (el.hasAttribute("limits"))
+         {
+           std::istringstream is(el.getAttribute("limits"));
+           unsigned limits;
+           is >> limits;
+           entry.limits = limits;
+         }
+
+       if (el.hasAttribute("embellishment"))
+         {
+           std::istringstream is(el.getAttribute("embellishment"));
+           unsigned embellishment;
+           is >> embellishment;
+           entry.embellishment = embellishment;
+         }
+
+       if (el.hasAttribute("delimiter"))
+         {
+           if (entry.cls != OPERATOR && !entry.embellishment)
+             cerr << "WARNING: `" << name << "' delimiter ignored for non-operator" << endl;
+
+           std::istringstream is(el.getAttribute("delimiter"));
+           unsigned delimiter;
+           is >> delimiter;
+           entry.delimiter = delimiter;
+         }
+
+       if (el.hasAttribute("table"))
+         {
+           if (entry.cls != MACRO)
+             cerr << "WARNING: `" << name << "' table ignored for non-macro" << endl;
+           
+           std::istringstream is(el.getAttribute("table"));
+           unsigned table;
+           is >> table;
+           entry.table = table;
+         }
+
+       entries[name] = entry;
+      }
+}
+
+const TDictionary::Entry&
+TDictionary::find(const std::string& name) const
+{
+  Dictionary::const_iterator p = entries.find(name);
+  if (p != entries.end()) return (*p).second;
+  else
+    {
+      cerr << "ERROR: unknown entry `" << name << "'" << endl;
+      return undefinedEntry;
+    }
+}
+
+bool
+TDictionary::Entry::paramDelimited(unsigned i) const
+{
+  assert(i < pattern.size());
+  assert(pattern[i].category == TToken::PARAMETER);
+  // a parameter is delimited if it is NOT the last one
+  // AND the next argument is not a parameter
+  return i + 1 < pattern.size() && pattern[i + 1].category != TToken::PARAMETER;
+}
diff --git a/helm/DEVEL/mathml_editor/src/TDictionary.hh b/helm/DEVEL/mathml_editor/src/TDictionary.hh
new file mode 100644 (file)
index 0000000..44c020c
--- /dev/null
@@ -0,0 +1,78 @@
+
+#ifndef __TDictionary_hh__
+#define __TDictionary_hh__
+
+#include <string>
+#include <vector>
+#include <hash_map>
+
+#include "TToken.hh"
+
+class TDictionary
+{
+public:
+  TDictionary(void) { };
+  ~TDictionary() { };
+
+  enum Form
+    {
+      INFIX,
+      PREFIX,
+      POSTFIX
+    };
+
+  enum EntryClass
+    {
+      UNDEFINED,
+      MACRO,
+      OPERATOR,
+      IDENTIFIER,
+      NUMBER
+    };
+
+  struct Entry
+  {
+    Entry(void)
+    { 
+      cls = UNDEFINED;
+      infix = prefix = postfix = 0;
+      delimiter = limits = embellishment = leftOpen = rightOpen = 0;
+    };
+
+    std::vector<TToken> pattern;
+    std::string value;
+
+    bool defined(void) const { return cls != UNDEFINED; };
+    bool hasArguments(void) const { return !pattern.empty(); };
+    bool paramDelimited(unsigned) const;
+
+    EntryClass cls;
+    unsigned infix : 8;
+    unsigned prefix : 8;
+    unsigned postfix : 8;
+    unsigned delimiter : 1;
+    unsigned limits : 1;
+    unsigned embellishment : 1;
+    unsigned leftOpen : 1;
+    unsigned rightOpen : 1;
+    unsigned table : 1;
+  };
+
+  void load(const char* uri);
+  const Entry& find(const std::string&) const;
+
+private:
+  struct StringHash : public std::unary_function< std::string, size_t >
+  { size_t operator()(const std::string& s) const { return hash<char*>()(s.c_str()); } };
+
+#if 0
+  struct StringEq : public std::binary_function< std::string, std::string, bool >
+  { bool operator()(const std::string&, const class String*) const; };
+#endif
+
+  typedef std::hash_map< std::string, Entry, StringHash > Dictionary;
+  Dictionary entries;
+};
+
+#endif // __TDictionary_hh__
+
diff --git a/helm/DEVEL/mathml_editor/src/TDocument.cc b/helm/DEVEL/mathml_editor/src/TDocument.cc
new file mode 100644 (file)
index 0000000..4c3bbba
--- /dev/null
@@ -0,0 +1,155 @@
+
+#include <sstream>
+
+#include "globals.hh"
+#include "dom.hh"
+#include "TDocument.hh"
+
+TDocument::TDocument()
+{
+  DOM::DOMImplementation di;
+  DOM::DocumentType dt;
+  doc = di.createDocument(TML_NS_URI, "tml:tex", dt);
+  DOM::Element root = doc.get_documentElement();
+  root.setAttributeNS(XMLNS_NS_URI, "xmlns:tml", TML_NS_URI);
+  assert(root);
+
+  DOM::EventTarget et(doc);
+  assert(et);
+  et.addEventListener("DOMSubtreeModified", *this, false);
+}
+
+TDocument::~TDocument()
+{
+  //DOM::Element root = doc.get_documentElement();
+  DOM::EventTarget et(doc);
+  assert(doc);
+  et.removeEventListener("DOMSubtreeModified", *this, false);
+}
+
+void
+TDocument::serialize(const char* filename) const
+{
+  DOM::DOMImplementation di;
+  di.saveDocumentToFile(doc, filename, GDOME_SAVE_LIBXML_INDENT);
+}
+
+TNode
+TDocument::create(const std::string& name, unsigned id) const
+{
+  DOM::Element elem = doc.createElementNS(TML_NS_URI, "tml:" + name);
+  if (id > 0)
+    {
+      ostringstream os;
+      os << "I" << id;
+      elem.setAttribute("id", os.str());
+    }
+  return elem;
+}
+
+TNode
+TDocument::createC(const std::string& name, unsigned id) const
+{
+  TNode m = create("c", id);
+  m["name"] = name;
+  return m;
+}
+
+TNode
+TDocument::createT(const std::string& name, const std::string& text, unsigned id) const
+{
+  TNode t = create(name, id);
+  t["val"] = text;
+  return t;
+}
+
+unsigned
+TDocument::nodeDepth(const DOM::Node& node)
+{
+  DOM::Node n = node;
+
+  unsigned depth = 0;
+  while (n)
+    {
+      depth++;
+      n = n.get_parentNode();
+    }
+  return depth;
+}
+
+DOM::Node
+TDocument::findCommonAncestor(const DOM::Node& node1, const DOM::Node& node2)
+{
+  DOM::Node n1 = node1;
+  DOM::Node n2 = node2;
+
+  unsigned d1 = nodeDepth(n1);
+  unsigned d2 = nodeDepth(n2);
+
+  cout << "finding common ancestor " << d1 << " " << d2 << endl;
+
+  while (d1 < d2)
+    {
+      assert(n2);
+      n2 = n2.get_parentNode();
+      d2--;
+    }
+
+  while (d1 > d2)
+    {
+      assert(n1);
+      n1 = n1.get_parentNode();
+      d1--;
+    }
+
+  while (n1 != n2)
+    {
+      assert(n1);
+      assert(n2);
+      n1 = n1.get_parentNode();
+      n2 = n2.get_parentNode();
+    }
+
+  return n1;
+}
+
+DOM::Node
+TDocument::findIdNode(const DOM::Node& node)
+{
+  DOM::Node n = node;
+  while (n)
+    {
+      if (n.get_nodeType() == DOM::Node::ELEMENT_NODE)
+       {
+         DOM::Element el = n;
+         if (el.hasAttribute("id")) return el;
+       }
+      n = n.get_parentNode();
+    }
+
+  return DOM::Node(0);
+}
+
+void
+TDocument::handleEvent(const DOM::Event& ev)
+{
+  DOM::MutationEvent me(ev);
+  assert(me);
+
+  if (dirty)
+    cout << "TDocument::handleEvent DIRTY BEFORE = " << dirty.getAttribute("id") << endl;
+  else
+    cout << "TDocument::handleEvent DIRTY BEFORE = (nil)" << endl;
+
+  if (DOM::Node node = me.get_target())
+    if (dirty)
+      dirty = findIdNode(findCommonAncestor(dirty, node));
+    else
+      dirty = findIdNode(node);
+  else
+    assert(0);
+
+  cout << "TDocument::handleEvent target = " << DOM::Node(me.get_target()).get_nodeName() << " DIRTY AFTER = "
+       << dirty.getAttribute("id") << " ME = " << DOM::Node(me.get_target()).get_nodeName() << endl;
+  
+}
diff --git a/helm/DEVEL/mathml_editor/src/TDocument.hh b/helm/DEVEL/mathml_editor/src/TDocument.hh
new file mode 100644 (file)
index 0000000..cf4b7c3
--- /dev/null
@@ -0,0 +1,40 @@
+
+#ifndef __TDocument_hh__
+#define __TDocument_hh__
+
+#include "dom.hh"
+#include "TNode.hh"
+
+class TDocument : private DOM::EventListener
+{
+public:
+  TDocument(void);
+  ~TDocument();
+
+  TNode create(const std::string&, unsigned = 0) const;
+  TNode createG(unsigned id = 0) const { return create("g", id); };
+  TNode createC(const std::string&, unsigned = 0) const;
+  TNode createT(const std::string&, const std::string&, unsigned = 0) const;
+  TNode createI(const std::string& text, unsigned id = 0) const { return createT("i", text, id); };
+  TNode createN(const std::string& text, unsigned id = 0) const { return createT("n", text, id); };
+  TNode createO(const std::string& text, unsigned id = 0) const { return createT("o", text, id); };
+
+  DOM::Document document(void) const { return doc; };
+
+  TNode root(void) { return doc.get_documentElement(); };
+  TNode dirtyNode(void) const { return dirty; };
+  void  clearDirty(void) { dirty = DOM::Element(0); };
+
+  void  serialize(const char*) const;
+
+private:
+  DOM::Document doc;
+  DOM::Element dirty;
+
+  virtual void handleEvent(const DOM::Event&);
+  static unsigned nodeDepth(const DOM::Node&);
+  static DOM::Node findCommonAncestor(const DOM::Node&, const DOM::Node&);
+  static DOM::Node findIdNode(const DOM::Node&);
+};
+
+#endif // __TDocument_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TLexerPull.cc b/helm/DEVEL/mathml_editor/src/TLexerPull.cc
new file mode 100644 (file)
index 0000000..0eb3a3c
--- /dev/null
@@ -0,0 +1,35 @@
+
+#include "TCharStream.hh"
+#include "TCharStreamString.hh"
+
+TToken
+TLexerPull::pop(TCharStream& stream)
+{
+  if (stream.more())
+    {
+      TChar ch = stream.next();
+      if (ch == '\\')
+       {
+         if (stream.more())
+           {
+             if (isUnicodeAlpha(stream.look()))
+               {
+                 TString s;
+                 while (stream.more() && isUnicodeAlpha(stream.look()))
+                   s.push_back(stream.next());
+                 TToken res(TToken::CONTROL, s);
+                 while (stream.more() && isUnicodeSpace(stream.look()))
+                   stream.next();
+                 return res;
+               }
+             else
+               return TToken(TToken::CONTROL, TString(1, stream.next()));
+           }
+         else
+           return TToken(TToken::INVALID_CHAR, TString(1, ch));
+       }
+      else return TToken(ch);
+    }
+  else return TToken(TToken::END_OF_BUFFER);
+}
+
diff --git a/helm/DEVEL/mathml_editor/src/TLexerPush.cc b/helm/DEVEL/mathml_editor/src/TLexerPush.cc
new file mode 100644 (file)
index 0000000..6b2acae
--- /dev/null
@@ -0,0 +1,82 @@
+
+#include "TLexerPush.hh"
+
+TLexerPush::TLexerPush()
+{
+  state = ACCEPT;
+}
+
+TToken
+TLexerPush::pop()
+{
+  if (tokens.empty()) throw EmptyBuffer();
+  else
+    {
+      TToken res = tokens.front();
+      tokens.pop_front();
+      if (tokens.size() == 1 && state == CONTROL) state = ACCEPT;
+      return res;
+    }
+}
+
+TToken
+TLexerPush::front() const
+{
+  if (tokens.empty()) throw EmptyBuffer();
+  else return tokens.front();
+}
+
+bool
+TLexerPush::empty() const
+{
+  return tokens.empty();
+}
+
+bool
+TLexerPush::pending() const
+{
+  return state == ESCAPE;
+}
+
+bool
+TLexerPush::ambiguous() const
+{
+  return tokens.size() == 1 && state == CONTROL;
+}
+
+void
+TLexerPush::push(TChar ch)
+{
+  switch (state)
+    {
+    case ACCEPT:
+      if (ch == '\\') state = ESCAPE;
+      else tokens.push_back(TToken(ch));
+      break;
+    case ESCAPE:
+      tokens.push_back(TToken(TToken::CONTROL, std::string(1, ch)));
+      if (isUnicodeAlpha(ch)) state = CONTROL;
+      else state = ACCEPT;
+      break;
+    case CONTROL:
+      if (ch == '\\') state = ESCAPE;
+      else if (isUnicodeAlpha(ch))
+       {
+         assert(!tokens.empty());
+         TToken& tok = tokens.back();
+         tok.value.push_back(ch);
+       }
+      else if (isUnicodeSpace(ch)) state = IGNORE_SPACE;
+      else
+       {
+         tokens.push_back(TToken(ch));
+         state = ACCEPT;
+       }
+      break;
+    case IGNORE_SPACE:
+      if (ch == '\\') state = ESCAPE;
+      else if (isUnicodeSpace(ch)) ;
+      else tokens.push_back(TToken(ch));
+      break;
+    }
+}
diff --git a/helm/DEVEL/mathml_editor/src/TLexerPush.hh b/helm/DEVEL/mathml_editor/src/TLexerPush.hh
new file mode 100644 (file)
index 0000000..f47def4
--- /dev/null
@@ -0,0 +1,31 @@
+
+#include <deque>
+
+#include "TToken.hh"
+
+class TLexerPush
+{
+public:
+  TLexerPush(void);
+
+  void   push(TChar);
+  TToken pop(void);
+  TToken front(void) const;
+  bool   ambiguous(void) const;
+  bool   pending(void) const;
+  bool   empty(void) const;
+
+  class EmptyBuffer { };
+
+private:
+  enum State
+    {
+      ACCEPT,
+      ESCAPE,
+      CONTROL,
+      IGNORE_SPACE
+    };
+
+  State state;
+  std::deque<TToken> tokens;
+};
diff --git a/helm/DEVEL/mathml_editor/src/TListener.hh b/helm/DEVEL/mathml_editor/src/TListener.hh
new file mode 100644 (file)
index 0000000..db93261
--- /dev/null
@@ -0,0 +1,11 @@
+
+#ifndef __TListener_hh__
+#define __TListener_hh__
+
+class TListener
+{
+public:
+  virtual void callback(TDocument&) = 0;
+};
+
+#endif // __TListener_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TNode.cc b/helm/DEVEL/mathml_editor/src/TNode.cc
new file mode 100644 (file)
index 0000000..4235f37
--- /dev/null
@@ -0,0 +1,195 @@
+
+#include "globals.hh"
+#include "TNode.hh"
+
+TNode
+TNode::next() const
+{
+  assert(node);
+  DOM::Node p = node.get_nextSibling();
+  while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_nextSibling();
+  return p;
+}
+
+TNode
+TNode::nextL() const
+{
+  assert(node);
+  if (TNode n = next())
+    if (n.isG()) return n.firstL();
+    else return n;
+  else return TNode();
+}
+
+TNode
+TNode::prev() const
+{
+  assert(node);
+  DOM::Node p = node.get_previousSibling();
+  while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_previousSibling();
+  return p;
+}
+
+TNode
+TNode::prevL() const
+{
+  assert(node);
+  if (TNode n = prev())
+    if (n.isG()) return n.lastL();
+    else return n;
+  else return TNode();
+}
+
+TNode
+TNode::last() const
+{
+  assert(node);
+  DOM::Node p = node.get_lastChild();
+  while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_previousSibling();
+  return p;
+}
+
+TNode
+TNode::lastL() const
+{
+  assert(node);
+  if (TNode n = last())
+    if (n.isG()) return n.lastL();
+    else return n;
+  else
+    return TNode();
+}
+
+TNode
+TNode::first() const
+{
+  assert(node);
+  DOM::Node p = node.get_firstChild();
+  while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_nextSibling();
+  return p;
+}
+
+TNode
+TNode::firstL() const
+{
+  assert(node);
+  if (TNode n = first())
+    if (n.isG()) return n.firstL();
+    else return n;
+  else
+    return TNode();
+}
+
+TNode
+TNode::core() const
+{
+  assert(node);
+  // check also if there is a macro embellishment (\not)
+  if (isSb() || isSp()) return first().core();
+  else return *this;
+}
+
+TNode
+TNode::parent() const
+{
+  assert(node);
+  DOM::Node p = node.get_parentNode();
+  assert(!p || p.get_nodeType() == DOM::Node::ELEMENT_NODE);
+  return p;
+}
+
+unsigned
+TNode::size() const
+{
+  assert(node);
+  unsigned size = 0;
+  TNode p = first();
+  while (p)
+    {
+      p = p.next();
+      size++;
+    }
+
+  return size;
+}
+
+void
+TNode::remove() const
+{
+  assert(node);
+  DOM::Node parent = node.get_parentNode();
+  parent.removeChild(node);
+}
+
+void
+TNode::replace(const TNode& newNode) const
+{
+  assert(node);
+  DOM::Node parent = node.get_parentNode();
+  parent.replaceChild(newNode.node, node);
+}
+
+void
+TNode::insert(const TNode& newNode) const
+{
+  assert(node);
+  DOM::Node parent = node.get_parentNode();
+  parent.insertBefore(newNode.node, node);
+}
+
+void
+TNode::append(const TNode& newNode) const
+{
+  assert(node);
+  node.appendChild(newNode.node);
+}
+
+void
+TNode::append(const TNode& first, const TNode& last) const
+{
+  assert(node);
+  assert(first);
+  assert(last);
+
+  TNode p = first;
+  while (p != last)
+    {
+      TNode next = p.next();
+      append(p);
+      p = next;
+    }
+}
+
+void
+TNode::prepend(const TNode& newNode) const
+{
+  assert(node);
+  DOM::Node parent = node.get_parentNode();
+  parent.insertBefore(newNode.node, parent.get_firstChild());
+}
+
+#if 0
+#endif
+
+TNode
+TNode::child(unsigned pos) const
+{
+  assert(node);
+  TNode p = first();
+  while (p && pos-- > 0) p = p.next();
+  return p;
+}
+
+std::string
+TNode::get(const std::string& name) const
+{
+  assert(node);
+  return node.getAttribute(name);
+}
+
+void
+TNode::set(const std::string& name, const std::string& value) const
+{
+  assert(node);
+  node.setAttribute(name, value);
+}
diff --git a/helm/DEVEL/mathml_editor/src/TNode.hh b/helm/DEVEL/mathml_editor/src/TNode.hh
new file mode 100644 (file)
index 0000000..dde315d
--- /dev/null
@@ -0,0 +1,80 @@
+
+#ifndef __TNode_hh__
+#define __TNode_hh__
+
+#include "dom.hh"
+#include "globals.hh"
+#include "TDictionary.hh"
+
+class TNode
+{
+public:
+  TNode(void) : node(0) { };
+  TNode(const DOM::Node& n) : node(n) { };
+  TNode(const DOM::Element& elem) : node(elem) { };
+  TNode(const TNode& n) : node(n.node) { };
+
+  TNode next(void) const;
+  TNode nextL(void) const;
+  TNode prev(void) const;
+  TNode prevL(void) const;
+  TNode core(void) const;
+  TNode parent(void) const;
+  TNode first(void) const;
+  TNode firstL(void) const;
+  TNode last(void) const;
+  TNode lastL(void) const;
+  TNode child(unsigned) const;
+  unsigned size(void) const;
+  bool  empty(void) const { return !first().node; };
+  std::string value(void) const { return (*this)["val"]; };
+
+  class ProxyAttr
+  {
+  public:
+    ProxyAttr(const DOM::Element& n, const std::string& s) : node(n), name(s) { };
+    operator std::string() const { return node.getAttribute(name); };
+    ProxyAttr& operator=(const std::string& v) { node.setAttribute(name, v); };
+    bool       operator==(const std::string& v) const { return node.getAttribute(name) == v; };
+    bool       operator!=(const std::string& v) const { return node.getAttribute(name) != v; };
+  private:
+    DOM::Element node;
+    std::string  name;
+  };
+
+  operator bool() const { return node; };
+  DOM::Element element(void) const { return node; };
+  bool operator==(const TNode& n) const { return node == n.node; };
+  bool operator!=(const TNode& n) const { return node != n.node; };
+  TNode operator[](int i) const { return child(i); };
+  ProxyAttr operator[](const char* s) const { return ProxyAttr(node, s); };
+
+  //void  advance(const TNode&) const;
+  void  remove(void) const;
+  void  replace(const TNode&) const;
+  void  insert(const TNode&) const;
+  void  append(const TNode&) const;
+  void  append(const TNode&, const TNode&) const;
+  void  prepend(const TNode&) const;
+
+  std::string get(const std::string&) const;
+  void  set(const std::string&, const std::string&) const;
+
+  std::string name(void) const { return node.get_localName(); };
+  std::string nameC(void) const { return node.getAttribute("name"); };
+  bool  hasId(void) const { return node.hasAttribute("id"); };
+  bool  is(const std::string& s) const { return name() == s; };
+  bool  isG(void) const { return is("g"); };
+  bool  isSb(void) const { return is("sb"); };
+  bool  isSp(void) const { return is("sp"); };
+  bool  isC(void) const { return is("c"); }
+  bool  isC(const std::string& name) const
+  { return isC() && node.getAttribute("name") == name; };
+
+  friend class TDocument;
+
+private:
+  DOM::Element node;
+};
+
+#endif // __TNode_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TObject.hh b/helm/DEVEL/mathml_editor/src/TObject.hh
new file mode 100644 (file)
index 0000000..c4b4e9e
--- /dev/null
@@ -0,0 +1,16 @@
+
+#ifndef __TObject_hh__
+#define __TObject_hh__
+
+class TObject
+{
+protected:
+  TObject(void) { refCounter = 1; };
+  virtual ~TObject() { };
+
+public:
+  void ref(coid) const { refCounter++; };
+  void unref(void) const { if (--refCounter) delete this; };
+};
+
+#endif // __TObject_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TPushLexer.cc b/helm/DEVEL/mathml_editor/src/TPushLexer.cc
new file mode 100644 (file)
index 0000000..b943877
--- /dev/null
@@ -0,0 +1,117 @@
+
+#include "TToken.hh"
+#include "TPushLexer.hh"
+#include "APushParser.hh"
+
+TPushLexer::TPushLexer(APushParser& p) : APushLexer(p)
+{
+  state = ACCEPT;
+}
+
+void
+TPushLexer::reset()
+{
+  buffer.erase();
+  state = ACCEPT;
+}
+
+void
+TPushLexer::transaction(char ch, State newState)
+{
+  switch (ch)
+    {
+    case '{': parser.push(TToken(TToken::BEGIN)); break;
+    case '}': parser.push(TToken(TToken::END)); break;
+    case '$': parser.push(TToken(TToken::SHIFT)); break;
+    case '&': parser.push(TToken(TToken::ALIGN)); break;
+    case '\n':
+    case '\r': parser.push(TToken(TToken::EOL, ch)); break;
+    case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break;
+    case '_': parser.push(TToken(TToken::SUBSCRIPT)); break;
+    case '\t':
+    case ' ': parser.push(TToken(TToken::SPACE, ch)); break;
+    case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
+    case '%': parser.push(TToken(TToken::COMMENT)); break;
+    default:
+      if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
+      else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
+      else parser.push(TToken(TToken::OTHER, ch));
+      break;
+    }
+  state = newState;
+}
+
+void
+TPushLexer::push(char ch)
+{
+  switch (state)
+    {
+    case ACCEPT:
+      if (ch == '\\') state = ESCAPE;
+      else if (ch == '#') state = PARAMETER;
+      else transaction(ch, ACCEPT);
+      break;
+    case ESCAPE:
+      if (isalpha(ch))
+       {
+         buffer.push_back(ch);
+         state = MACRO;
+       }
+      else
+       {
+         parser.push(TToken(TToken::CONTROL, ch));
+         state = ACCEPT;
+       }
+      break;
+    case MACRO:
+      if (ch == '\\')
+       {
+         parser.push(TToken(TToken::CONTROL, buffer));
+         buffer.erase();
+         state = ESCAPE;
+       }
+      else if (ch == '#')
+       {
+         parser.push(TToken(TToken::CONTROL, buffer));
+         buffer.erase();
+         state = PARAMETER;
+       }
+      else if (isalpha(ch))
+       buffer.push_back(ch);
+      else
+       {
+         parser.push(TToken(TToken::CONTROL, buffer));
+         buffer.erase();
+         if (isspace(ch)) state = IGNORE_SPACE;
+         else transaction(ch, ACCEPT);
+       }
+      break;
+    case IGNORE_SPACE:
+      if (ch == '\\') state = ESCAPE;
+      else if (ch == '#') state = PARAMETER;
+      else if (isspace(ch)) ;
+      else transaction(ch, ACCEPT);
+      break;
+    case PARAMETER:
+      parser.push(TToken(TToken::PARAMETER, ch));
+      state = ACCEPT;
+      break;
+    default:
+      assert(0);
+      break;
+    }
+
+  switch (state)
+    {
+    case ESCAPE: parser.setCursor("\\"); break;
+    case MACRO: parser.setCursor("\\" + buffer); break;
+    case PARAMETER: parser.setCursor("#"); break;
+    default: parser.setCursor("?"); break;
+    }
+}
+
+bool
+TPushLexer::error() const
+{
+  return false;
+}
diff --git a/helm/DEVEL/mathml_editor/src/TPushLexer.hh b/helm/DEVEL/mathml_editor/src/TPushLexer.hh
new file mode 100644 (file)
index 0000000..ff61561
--- /dev/null
@@ -0,0 +1,35 @@
+
+#ifndef __TPushLexer_hh__
+#define __TPushLexer_hh__
+
+#include <string>
+
+#include "APushLexer.hh"
+
+class TPushLexer : public APushLexer
+{
+public:
+  TPushLexer(class APushParser&);
+  virtual ~TPushLexer() { };
+
+  virtual void push(char);
+  virtual void reset(void);
+  virtual bool error(void) const;
+
+private:
+  enum State
+    {
+      ACCEPT,
+      ESCAPE,
+      MACRO,
+      IGNORE_SPACE,
+      PARAMETER
+    };
+
+  void transaction(char, State);
+
+  State state;
+  std::string buffer;
+};
+
+#endif // __TPushLexer_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TPushParser.cc b/helm/DEVEL/mathml_editor/src/TPushParser.cc
new file mode 100644 (file)
index 0000000..ea82cf3
--- /dev/null
@@ -0,0 +1,668 @@
+
+#include "TPushParser.hh"
+#include "TListener.hh"
+
+TPushParser::TPushParser(const TDictionary& d) : dictionary(d), listener(0)
+{
+  init();
+}
+
+TPushParser::TPushParser(const TDictionary& d, TListener& l) : dictionary(d), listener(&l)
+{
+  init();
+}
+
+void
+TPushParser::init()
+{
+  nextId = 1;
+  cursor = doc.create("cursor");
+  cursor["id"] = "I0";
+  doc.clearDirty();
+  doc.root().append(cursor);
+}
+
+TPushParser::~TPushParser()
+{
+}
+
+std::string
+TPushParser::PRIME() const
+{
+  const TDictionary::Entry entry = dictionary.find("prime");
+  if (entry.cls == TDictionary::OPERATOR) return entry.value;
+  else return "?";
+}
+
+void
+TPushParser::do_begin()
+{
+  TNode parent = cursor.parent();
+  if (parent.isC() && dictionary.find(parent.nameC()).table)
+    {
+      TNode row = doc.create("row");
+      TNode cell = doc.create("cell");
+      TNode g = doc.createG();
+      row.append(cell);
+      cell.append(g);
+      g.append(cursor);
+      parent.append(row);
+    }
+  else
+    {
+      TNode g = doc.createG(nextId++);
+      cursor.replace(g);
+      g.append(cursor);
+    }
+}
+
+void
+TPushParser::do_end()
+{
+  TNode parent = cursor.parent();
+  if (parent && parent.isG() && parent.hasId())
+    {
+      // normal closing brace for an explicitly open group
+      cursor.remove();
+      advance(parent);
+    }
+  else if (parent && parent.isG() && parent.parent() && parent.parent().is("cell"))
+    {
+      // closing brace for a structure in which & or \cr have been used
+      TNode row = parent.parent().parent();
+      assert(row && row.is("row"));
+      TNode table = row.parent();
+      assert(table);
+      advance(table);
+    }
+  else if (parent && parent.isG() && !parent.hasId() && parent.parent())
+    {
+      // closing brace for a right-open macro (like \over)
+      cursor.remove();
+      advance(parent.parent());
+    }
+  else
+    {
+      // ???
+      assert(0);
+    }
+}
+
+void
+TPushParser::do_shift()
+{
+  TNode parent = cursor.parent();
+  assert(parent);
+  if (parent.is("tex"))
+    {
+      TNode math = doc.create("math", nextId++);
+      TNode g = doc.createG();
+      cursor.replace(math);
+      math.append(g);
+      g.append(cursor);
+    }
+  else if (parent.isG() && !parent.hasId() && parent.parent() && parent.parent().is("math"))
+    {
+      if (cursor.prev())
+       {
+         // there is something before the cursor, hence this is the
+         // closing math shift
+         if (parent.parent()["display"] != "1")
+           {
+             // one math shift is enough to close it
+             cursor.remove();
+           }
+         else
+           {
+             // we need two closing math shifts
+             parent.parent().append(cursor);
+           }
+       }
+      else if (parent.parent()["display"] != "1")
+       {
+         // there is nothing before the cursor, and the math is not
+         // in display mode, so this must be a double math shift
+         parent.parent()["display"] = "1";
+       }
+      else
+       {
+         parent.parent().append(cursor);
+       }
+    }
+  else if (parent.is("math"))
+    {
+      cursor.remove();
+    }
+  else
+    {
+      cerr << "ERROR: math shift" << endl;
+    }
+}
+
+void
+TPushParser::do_align()
+{
+  TNode parent = cursor.parent();
+  if (parent && parent.isG() && parent.hasId())
+    {
+      // alignment tab used for the first time inside a group
+      TNode row = doc.create("row");
+      TNode cell = doc.create("cell");
+      TNode g = doc.createG();
+      row.append(cell);
+      cell.append(g);
+      g.append(parent.first(), cursor);
+    }
+  else if (parent && parent.isG() && parent.parent().is("cell"))
+    {
+      // alignment tab used within a cell
+      TNode oldCell = parent.parent();
+      assert(oldCell && oldCell.is("cell"));
+      TNode row = oldCell.parent();
+      assert(row && row.is("row"));
+      TNode cell = doc.create("cell");
+      if (oldCell.next()) oldCell.next().insert(cell);
+      else row.append(cell);
+      TNode g = doc.createG();
+      cell.append(g);
+      g.append(cursor);
+    }
+  else
+    {
+      cerr << "alignment tab used outside matrix" << endl;
+    }
+}
+
+void
+TPushParser::do_eol()
+{
+  //if (cursor.parent()) cursor.remove();
+}
+
+void
+TPushParser::do_parameter(const std::string& p)
+{
+  // ???
+}
+
+void
+TPushParser::do_subscript()
+{
+  TNode parent = cursor.parent();
+  if (parent.isG())
+    {
+      TNode prev = cursor.prev();
+      if (!prev)
+       {
+         TNode elem = doc.create("sb", nextId++);
+         TNode g = doc.createG();
+         cursor.replace(elem);
+         elem.append(g);
+         elem.append(cursor);
+       }
+      else
+       {
+         TNode elem = doc.create("sb", nextId++);
+         prev.replace(elem);
+         elem.append(prev);
+         elem.append(cursor);
+       }
+    }
+  else if (parent.isSb() && cursor == parent[1])
+    {
+      if (parent["under"] == "1") cerr << "already under" << endl;
+      else parent["under"] = "1";
+    }
+}
+
+void
+TPushParser::do_superscript()
+{
+  TNode parent = cursor.parent();
+  if (parent.isG())
+    {
+      TNode prev = cursor.prev();
+      if (!prev)
+       {
+         TNode elem = doc.create("sp", nextId++);
+         TNode g = doc.createG();
+         cursor.replace(elem);
+         elem.append(g);
+         elem.append(cursor);
+       }
+      else
+       {
+         TNode elem = doc.create("sp", nextId++);
+         prev.replace(elem);
+         elem.append(prev);
+         elem.append(cursor);
+       }
+    }
+  else if (parent.isSp() && cursor == parent[1])
+    {
+      if (parent["over"] == "1") cerr << "already over" << endl;
+      else parent["over"] = "1";
+    }
+}
+
+void
+TPushParser::do_space(const std::string&)
+{
+  // ? may be used to distinguish tokens in some mode?
+}
+
+void
+TPushParser::do_letter(const std::string& s)
+{
+  TNode parent = cursor.parent();
+  TNode elem = doc.createI(s, nextId++);
+  cursor.replace(elem);
+  advance(elem);
+}
+
+void
+TPushParser::do_digit(const std::string& s)
+{
+  TNode parent = cursor.parent();
+  TNode prev = cursor.prev();
+  if (prev && parent.isG() && prev.is("n"))
+    {
+      TNode elem = doc.createN(prev.value() + s, nextId++);
+      prev.replace(elem);
+    }
+  else
+    {
+      TNode elem = doc.createN(s, nextId++);
+      cursor.replace(elem);
+      advance(elem);
+    }
+}
+
+bool
+TPushParser::isPrimes(const TNode& node) const
+{
+  assert(node);
+  return node.isG() && node.last() && node.last().is("o") && node.last()["val"] == PRIME();
+}
+
+void
+TPushParser::do_apostrophe()
+{
+  if (cursor.parent() && cursor.parent().isG())
+    {
+      if (TNode prev = cursor.prev())
+       {
+         if (prev.isSp() && prev[1] && isPrimes(prev[1]))
+           prev[1].append(doc.createO(PRIME(), nextId++));
+         else if (prev.isSb() && prev[0] &&
+                  prev[0].isSp() && prev[0][1] &&
+                  isPrimes(prev[0][1]))
+           prev[0][1].append(doc.createO(PRIME(), nextId++));
+         else
+           {
+             TNode elem = doc.create("sp");
+             TNode g = doc.createG();
+             prev.replace(elem);
+             elem.append(prev);
+             elem.append(g);
+             g.append(doc.createO(PRIME(), nextId++));
+           }
+       }
+      else
+       {
+         // error ???
+       }
+    }
+  else
+    {
+      // error ??
+    }
+}
+
+void
+TPushParser::do_other(const std::string& s)
+{
+  switch (s[0])
+    {
+    case '\'':
+      do_apostrophe();
+      break;
+    default:
+      cout << "TPushParser::do_other " << s << endl;
+      cout << "DOCUMENT: " << static_cast<GdomeNode*>(cursor.element().get_ownerDocument()) << endl;
+      TNode elem = doc.createT("o", s, nextId++);
+      cursor.replace(elem);
+      advance(elem);  
+      break;
+    }
+}
+
+void
+TPushParser::do_active(const std::string&)
+{
+  // ??? space?
+}
+
+void
+TPushParser::do_comment()
+{
+  // ???
+}
+
+void
+TPushParser::do_cr()
+{
+  TNode parent = cursor.parent();
+  if (parent && parent.isG() &&
+      parent.parent() && parent.parent().is("cell") &&
+      parent.parent().parent() && parent.parent().parent().is("row"))
+    {
+      TNode oldRow = parent.parent().parent();
+      assert(oldRow);
+      TNode table = oldRow.parent();
+      assert(table);
+      TNode row = doc.create("row");
+      TNode cell = doc.create("cell");
+      TNode g = doc.createG();
+      if (oldRow.next()) oldRow.next().insert(row);
+      else table.append(row);
+      row.append(cell);
+      cell.append(g);
+      g.append(cursor);
+    }
+}
+
+void
+TPushParser::do_control(const std::string& name)
+{
+  if (name == "cr") do_cr();
+  else
+    {
+      TNode parent = cursor.parent();
+      const TDictionary::Entry& entry = dictionary.find(name);
+      switch (entry.cls)
+       {
+       case TDictionary::IDENTIFIER:
+         {
+           TNode t = doc.createI(entry.value, nextId++);
+           t["name"] = name;
+           cursor.replace(t);
+           advance(t);
+         }
+         break;
+       case TDictionary::OPERATOR:
+         {
+           TNode t = doc.createO(entry.value, nextId++);
+           t["name"] = name;
+           cursor.replace(t);
+           advance(t);
+         }
+         break;
+       case TDictionary::NUMBER:
+         {
+           TNode t = doc.createN(entry.value, nextId++);
+           t["name"] = name;
+           cursor.replace(t);
+           advance(t);
+         }
+         break;
+       case TDictionary::MACRO:
+         {
+           TNode m = doc.createC(name, nextId++);
+           cursor.replace(m);
+           if (entry.leftOpen && entry.rightOpen)
+             {
+               assert(entry.pattern.empty());
+               assert(parent.isG());
+               TNode g1 = doc.createG();
+               g1["left-open"] = "1";
+               g1.append(parent.first(), m);
+               m.append(g1);
+               TNode g2 = doc.createG();
+               g2.append(cursor);
+               m.append(g2);
+               frames.push(Frame(entry));
+             }
+           else if (entry.leftOpen)
+             {
+               assert(parent.isG());
+               TNode g = doc.createG();
+               g["left-open"] = "1";
+               g.append(parent.first(), m);
+               m.append(g);
+               advance(m);
+             }
+           else if (entry.rightOpen)
+             {
+               assert(entry.pattern.empty());
+               assert(parent.isG());
+               TNode g = doc.createG();
+               g.append(cursor);
+               m.append(g);
+               frames.push(Frame(entry));
+             }
+           else if (!entry.pattern.empty())
+             {
+               if (parent.isG())
+                 {
+                   frames.push(Frame(entry));
+                   if (entry.paramDelimited(0))
+                     {
+                       TNode g = doc.createG();
+                       m.append(g);
+                       g.append(cursor);
+                     }
+                   else
+                     m.append(cursor);
+                 }
+               else
+                 {
+                   // error, but we could handle this very easily
+                   cerr << "error, but we could handle this easily" << endl;
+                 }
+             }
+           else advance(m);
+         }
+         break;
+       case TDictionary::UNDEFINED:
+         {
+           cerr << "ERROR: using undefined macro `" << name << "'" << endl;
+           TNode m = doc.createC(name, nextId++);
+           cursor.replace(m);
+           advance(m);
+         }
+         break;
+       default:
+         assert(0);
+       }
+    }
+}
+
+void
+TPushParser::process(const TToken& token)
+{
+  switch (token.category)
+    {
+    case TToken::BEGIN: do_begin(); break;
+    case TToken::END: do_end(); break;
+    case TToken::SHIFT: do_shift(); break;
+    case TToken::ALIGN: do_align(); break;
+    case TToken::EOL: do_eol(); break;
+    case TToken::PARAMETER: do_parameter(token.value); break;
+    case TToken::SUPERSCRIPT: do_superscript(); break;
+    case TToken::SUBSCRIPT: do_subscript(); break;
+    case TToken::SPACE: do_space(token.value); break;
+    case TToken::LETTER: do_letter(token.value); break;
+    case TToken::DIGIT: do_digit(token.value); break;
+    case TToken::OTHER: do_other(token.value); break;
+    case TToken::ACTIVE: do_active(token.value); break;
+    case TToken::COMMENT: do_comment(); break;
+    case TToken::CONTROL: do_control(token.value); break;
+    }
+}
+
+void
+TPushParser::push(const TToken& token)
+{
+  cerr << "TPushParser::push " << token.value << " (cat: " << token.category << ")" << endl;
+  TNode parent = cursor.parent();
+  // If the cursor has no parent then it is detached from the editing
+  // tree, which means this token will be ignored
+  if (parent)
+    // If the parent is a phantom group and the grand-parent is a
+    // control sequence, there are two cases:
+    // a. we are parsing a delimited argument of a entry
+    // b. we are parsing a side of a right- or left-open entry
+    if (parent.isG() && !parent.hasId() && parent.parent().isC())
+      {
+       // There must be an open frame, for the grand-parent is a control sequence
+       assert(!frames.empty());
+       Frame& frame = frames.top();
+       if (!frame.entry.pattern.empty())
+         {
+           // The entry pattern is not empty. By our conventions this means
+           // the entry cannot be open at either end, hence we are parsing
+           // a delimited argument
+           assert(frame.pos + 1 < frame.entry.pattern.size());
+           assert(frame.entry.pattern[frame.pos + 1].category != TToken::PARAMETER);
+           if (frame.entry.pattern[frame.pos + 1] == token)
+             {
+               // The token matches with the delimiter of the argument.
+               cursor.remove();
+
+               // If the phantom group has just one child, it is not necessary
+               // and can be removed. However, this would complicate
+               // all the code that follows, so given it is a rare case we
+               // leave it alone
+               // if (parent.size() == 1) parent.replace(parent[0]);
+
+               // Eat both the argument and its delimiter
+               frame.pos += 2;
+               if (frame.pos == frame.entry.pattern.size())
+                 {
+                   // This token has completed the entry
+                   advance(parent.parent());
+                 }
+               else if (frame.entry.paramDelimited(frame.pos))
+                 {
+                   // For the next is a delimited argument we have to place
+                   // a suitable phantom group with the cursor inside
+                   TNode g = doc.createG();
+                   parent.parent().append(g);
+                   g.append(cursor);
+                 }
+               else
+                 parent.parent().append(cursor);
+             }
+           else
+             {
+               // Delimiter mismatch. Since we are parsing a delimited
+               // argument we just process the token
+               process(token);
+             }
+         }
+       else
+         {
+           // The entry pattern is empty, hence we are parsing a right-open
+           // entry. What happens if we actually are in the left side?
+           // This could happen only when re-editing an entered expression
+           // We'll see...
+           assert(frame.entry.rightOpen);
+           process(token);
+         }
+      }
+    else if (parent.isC())
+      {
+       // We are parsing a non-delimited argument entry
+       // or a fixed token
+       Frame& frame = frames.top();
+       assert(frame.pos < frame.entry.pattern.size());
+       if (frame.entry.pattern[frame.pos].category == TToken::PARAMETER)
+         {
+           // As by the TeX parsing rules of undelimited parameters,
+           // empty spaces are ignored
+           if (token.category != TToken::SPACE)
+             {
+               // We need to increase the frame position here, becase inside
+               // process the function advance will be called. At that point
+               // it will be important for the parser to know that the entry
+               // has been completed in order to place the cursor correctly
+               // in the next position
+               frame.pos++;
+               process(token);
+             }
+         }
+       else if (frame.entry.pattern[frame.pos] == token)
+         {
+           // The token has been accepted
+           frame.pos++;
+           if (frame.pos < frame.entry.pattern.size() &&
+               frame.entry.paramDelimited(frame.pos))
+             {
+               // If the next is a delimited argument we have to place
+               // the phantom group with the cursor inside
+               TNode g = doc.createG();
+               cursor.replace(g);
+               g.append(cursor);
+             }
+           else
+             advance(parent);
+         }
+       else
+         {
+           // There is a mismatch. Emit an error and ignore the token?
+           cerr << "ERROR: token ignored: " << token.value << " (cat: " << token.category << ")" << endl;
+         }
+
+      }
+    else
+      process(token);
+  else
+    {
+      cout << "ignored token" << endl;
+    }
+
+  if (listener) listener->callback(doc);
+}
+
+void
+TPushParser::advance(const TNode& node)
+{
+  assert(node);
+  TNode parent = node.parent();
+  if (!parent)
+    ; // nothing to do, the cursor is not in the document any more
+  else if (parent.isG())
+    {
+      TNode next = node.next();
+      if (next) next.insert(cursor);
+      else parent.append(cursor);
+    }
+  else if (parent.isC())
+    {
+      if (node.next())
+       ; // cursor removed
+      else
+       {
+         Frame& frame = frames.top();
+         if (frame.pos == frame.entry.pattern.size())
+           {
+             frames.pop();
+             advance(parent);
+           }
+         else
+           parent.append(cursor);
+       }
+    }
+  else if (parent.is("math"))
+    ; // we are done
+  else
+    advance(parent);
+}
+
+void
+TPushParser::setCursor(const std::string& c)
+{
+  cursor["val"] = c;
+  if (listener) listener->callback(doc);
+}
diff --git a/helm/DEVEL/mathml_editor/src/TPushParser.hh b/helm/DEVEL/mathml_editor/src/TPushParser.hh
new file mode 100644 (file)
index 0000000..bb659c3
--- /dev/null
@@ -0,0 +1,70 @@
+
+#ifndef __TPushParser_hh__
+#define __TPushParser_hh__
+
+#include <list>
+#include <stack>
+#include "TToken.hh"
+#include "APushParser.hh"
+#include "TDictionary.hh"
+#include "TDocument.hh"
+#include "TNode.hh"
+
+class TPushParser : public APushParser
+{
+public:
+  TPushParser(const class TDictionary&);
+  TPushParser(const class TDictionary&, class TListener&);
+  virtual ~TPushParser();
+
+  virtual void push(const TToken&);
+  virtual void setCursor(const std::string&);
+
+  TDocument document(void) const { return doc; }
+
+private:
+  void init(void);
+
+  std::string PRIME(void) const;
+  bool isPrimes(const TNode&) const;
+
+  void do_begin(void);
+  void do_end(void);
+  void do_shift(void);
+  void do_align(void);
+  void do_eol(void);
+  void do_parameter(const std::string&);
+  void do_superscript(void);
+  void do_subscript(void);
+  void do_space(const std::string&);
+  void do_letter(const std::string&);
+  void do_digit(const std::string&);
+  void do_other(const std::string&);
+  void do_active(const std::string&);
+  void do_comment(void);
+  void do_control(const std::string&);
+
+  void do_cr(void);
+  void do_apostrophe(void);
+  void advance(const TNode&);
+
+  void process(const TToken&);
+
+  struct Frame
+  {
+    Frame(const TDictionary::Entry& e) : entry(e), pos(0) { };
+    const TDictionary::Entry& entry;
+    unsigned pos;
+  };
+
+  std::stack<Frame> frames;
+  std::list<TToken> buffer;
+  unsigned  nextId;
+  TDocument doc;
+  TNode     cursor;
+
+  const class TDictionary& dictionary;
+  class TListener* listener;
+};
+
+#endif // __TPushParser_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TToken.hh b/helm/DEVEL/mathml_editor/src/TToken.hh
new file mode 100644 (file)
index 0000000..1cb6ca1
--- /dev/null
@@ -0,0 +1,38 @@
+
+#ifndef __TToken_hh__
+#define __TToken_hh__
+
+#include <string>
+
+struct TToken
+{
+  enum TCat
+    {
+      BEGIN,
+      END,
+      SHIFT,
+      ALIGN,
+      EOL,
+      PARAMETER,
+      SUPERSCRIPT,
+      SUBSCRIPT,
+      SPACE,
+      LETTER,
+      DIGIT,
+      OTHER,
+      ACTIVE,
+      COMMENT,
+      CONTROL
+    };
+
+  TToken(TCat c) : category(c) { };
+  TToken(TCat c, char ch) : category(c), value(std::string(1, ch)) { };
+  TToken(TCat c, const std::string& v) : category(c), value(v) { };
+
+  bool operator==(const TToken& token) const { return category == token.category && value == token.value; };
+
+  TCat        category;
+  std::string value;
+};
+
+#endif // __TToken_hh__
diff --git a/helm/DEVEL/mathml_editor/src/TTokenizer.cc b/helm/DEVEL/mathml_editor/src/TTokenizer.cc
new file mode 100644 (file)
index 0000000..cf74c1d
--- /dev/null
@@ -0,0 +1,31 @@
+
+#include <algorithm>
+
+#include "TTokenizer.hh"
+#include "TPushLexer.hh"
+
+std::vector<TToken>
+TTokenizer::tokenize(const std::string& s)
+{
+  TPushLexer lexer(*this);
+
+  tokens.clear();
+  for (std::string::const_iterator p = s.begin();
+       p != s.end();
+       p++)
+    lexer.push(*p);
+  //lexer.push('\n');
+
+  std::vector<TToken> res;
+  res.reserve(tokens.size());
+  copy(tokens.begin(), tokens.end(), back_inserter(res));
+
+  return res;
+}
+
+void
+TTokenizer::push(const TToken& token)
+{
+  tokens.push_back(token);
+}
+
diff --git a/helm/DEVEL/mathml_editor/src/TTokenizer.hh b/helm/DEVEL/mathml_editor/src/TTokenizer.hh
new file mode 100644 (file)
index 0000000..d0a54bf
--- /dev/null
@@ -0,0 +1,26 @@
+
+#ifndef __TTokenizer_hh__
+#define __TTokenizer_hh__
+
+#include <string>
+#include <vector>
+#include <list>
+
+#include "TToken.hh"
+#include "APushParser.hh"
+
+class TTokenizer : private APushParser
+{
+public:
+  TTokenizer(void) { };
+
+  std::vector<TToken> tokenize(const std::string&);
+
+private:
+  virtual void push(const TToken&);
+  virtual void setCursor(const std::string&) { };
+
+  std::list<TToken> tokens;
+};
+
+#endif // __TTokenizer_hh__
diff --git a/helm/DEVEL/mathml_editor/src/dom.hh b/helm/DEVEL/mathml_editor/src/dom.hh
new file mode 100644 (file)
index 0000000..f2c42db
--- /dev/null
@@ -0,0 +1,27 @@
+
+#ifndef __dom_hh__
+#define __dom_hh__
+
+#include <GdomeSmartDOM.hh>
+
+namespace DOM = GdomeSmartDOM;
+
+typedef DOM::Char32     TChar;
+typedef DOM::UCS4String TString;
+
+inline bool isUnicodeSpace(TChar ch)
+{
+  return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';;
+}
+
+inline bool isUnicodeAlpha(TChar ch)
+{
+  return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
+}
+
+inline bool isUnicodeDigit(TChar ch)
+{
+  return (ch >= '0' && ch <= '9');
+}
+
+#endif // __dom_hh__
diff --git a/helm/DEVEL/mathml_editor/src/domnav.cc b/helm/DEVEL/mathml_editor/src/domnav.cc
new file mode 100644 (file)
index 0000000..720aeb9
--- /dev/null
@@ -0,0 +1,115 @@
+
+DOM::Element
+getRightmostChild(const DOM::Element& p)
+{
+  if (p)
+    {
+      if (DOM::Element last = g.get_lastChild())
+       if (last.get_nodeName() == "g" && last.get_firstChild())
+         return getRightmostChild(last);
+       else
+         return last;
+      else
+       return 0;
+    }
+  else
+    return 0;
+}
+
+DOM::Element
+prevLinearSibling(const DOM::Element& p)
+{
+  if (p)
+    {
+      DOM::Element prev = p.get_prevSibling();
+      if (!prev) return 0;
+      else if (prev.get_nodeName() != "g" && prev.get_firstChild()) return prev;
+      else return prevLinearSibling(prev.get_lastChild());
+    }
+  else
+    return 0;
+}
+
+DOM::Element
+getCore(const DOM::Element& p)
+{
+  if (p)
+    {
+      if (p.get_nodeName() == "sb" || p.get_nodeName() == "sp")
+       return getCore(p.get_firstChild());
+      else return p;
+    }
+  else
+    return 0;
+}
+
+void
+replace(const DOM::Element& p0, const DOM::Element& p1)
+{
+  if (DOM::Element parent = p0.get_parentNode())
+    parent.replaceChild(p0, p1);
+}
+
+bool
+isInferred(const DOM::Element& p)
+{
+  if (p) return p.hasAttribute("id");
+  else return false;
+}
+
+bool
+isMacro(const DOM::Element& p, const TString& s)
+{
+  return p && p.get_nodeName() == "m" && p.getAttribute("name") == s;
+}
+
+bool
+isGroup(const DOM::Element& p)
+{
+  return p && p.get_nodeName() == "g";
+}
+
+bool
+isSb(const DOM::Element& p)
+{
+  return p && p.get_nodeName() == "sb";
+}
+
+bool
+isSp(const DOM::Element& p)
+{
+  return p && p.get_nodeName() == "sp";
+}
+
+bool
+isPrimes(const DOM::Element& p)
+{
+  return isGroup(p) && isMacro(p.get_lastChild, "prime");
+}
+
+bool
+isOperator(const DOM::Element& p)
+{
+  if (DOM::Element core = getCore(p))
+    return dictionary.isOperator(core.get_nodeName());
+  else
+    return false;
+}
+
+bool
+isDelimiter(const DOM::Element& p)
+{
+  if (DOM::Element core = getCore(p))
+    return dictionary.isDelimiter(core.get_nodeName());
+  else
+    return false;
+}
+
+bool
+isFunction(const DOM::Element& p)
+{
+  if (DOM::Element core = getCore(p))
+    return dictionary.isFunction(core.get_nodeName());
+  else
+    return false;
+}
diff --git a/helm/DEVEL/mathml_editor/src/globals.hh b/helm/DEVEL/mathml_editor/src/globals.hh
new file mode 100644 (file)
index 0000000..2f26a91
--- /dev/null
@@ -0,0 +1,8 @@
+
+#ifndef __globals_hh__
+#define __globals_hh__
+
+#define TML_NS_URI "http://helm.cs.unibo.it/2002/TML"
+#define XMLNS_NS_URI "http://www.w3.org/2000/xmlns/"
+
+#endif // __globals_hh__
diff --git a/helm/DEVEL/mathml_editor/src/special.cc b/helm/DEVEL/mathml_editor/src/special.cc
new file mode 100644 (file)
index 0000000..d794ffd
--- /dev/null
@@ -0,0 +1,62 @@
+
+#include <list>
+
+#include "dom.hh"
+#include "globals.hh"
+#include "TNode.hh"
+#include "TToken.hh"
+
+void finishG(const TNode&);
+
+void
+do_bgroup(const TNode& cursor)
+{
+  TNode parent = cursor.parent();
+  if (parent.isM("matrix") || parent.isM("pmatrix") ||
+      parent.isM("bordermatrix") || parent.isM("cases"))
+    {
+      TNode row = cursor.create("row");
+      TNode cell = cursor.create("cell");
+      TNode g = cursor.createG();
+      row.append(cell);
+      cell.append(g);
+      g.append(cursor);
+      parent.append(row);
+    }
+  else
+    {
+      TNode g = cursor.createG();
+      cursor.replace(g);
+      g.append(cursor);
+    }
+}
+
+
+
+
+void
+do_apostrophe(const TNode& cursor)
+{
+}
+
+void
+do_control(const TNode& cursor, const std::string& name)
+{
+}
+
+void
+do_other(const TNode& cursor, const std::string& s)
+{
+  switch (s[0])
+    {
+    case '\'': do_apostrophe(cursor); break;
+    default:
+      if (isUnicodeDigit(s[0])) do_number(cursor, s);
+      else do_control(cursor, s);
+    }
+}
+
+void
+dispatch(const TNode& cursor, const TToken& token)
+{
+
diff --git a/helm/DEVEL/mathml_editor/src/texlexer.cc b/helm/DEVEL/mathml_editor/src/texlexer.cc
new file mode 100644 (file)
index 0000000..f062732
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "dom.hh"
+#include "TLexerPush.hh"
+
+main()
+{
+  std::string s;
+  while (getline(std::cin, s))
+    {
+      TLexerPush lexer;
+      for (unsigned long i = 0; i < s.length(); i++)
+       {
+         lexer.push(s[i]);
+         cout << "pending: " << lexer.pending()
+              << " amb: " << lexer.ambiguous();
+         if (!lexer.empty())
+           {
+             TToken tok = lexer.front();
+             DOM::GdomeString v(tok.value);
+             cout << " cat: " << tok.category << " value: " << v << " length: " << v.length();
+             if (!lexer.ambiguous()) lexer.pop();
+           }
+         cout << endl;
+       }
+    }
+}
diff --git a/helm/DEVEL/mathml_editor/src/tokenizer.hh b/helm/DEVEL/mathml_editor/src/tokenizer.hh
new file mode 100644 (file)
index 0000000..06731b9
--- /dev/null
@@ -0,0 +1,10 @@
+
+#ifndef __tokenzier_hh__
+#define __tokenzier_hh__
+
+#include <string>
+#include <vector>
+
+std::vector<TToken> tokenize(const std::string&);
+
+#endif // __tokenzier_hh__
diff --git a/helm/DEVEL/mathml_editor/test/Makefile.am b/helm/DEVEL/mathml_editor/test/Makefile.am
new file mode 100644 (file)
index 0000000..24ebd7c
--- /dev/null
@@ -0,0 +1,21 @@
+
+noinst_PROGRAMS = test editor
+
+test_SOURCES = main.cc
+editor_SOURCES = editor.cc guiGTK.c aux.cc
+
+LDADDS = \
+  $(GMETADOM_LIBS) \
+  $(GDOMEXSLT_LIBS) \
+  $(GTKMATHVIEW_LIBS) \
+  $(top_builddir)/src/.libs/libeditex.a
+
+test_LDADD = $(LDADDS)
+editor_LDADD = $(LDADDS)
+
+INCLUDES = \
+  $(GMETADOM_CFLAGS) \
+  $(GDOMEXSLT_CFLAGS) \
+  $(GTKMATHVIEW_CFLAGS) \
+  -I$(top_srcdir)/src
+
diff --git a/helm/DEVEL/mathml_editor/test/Makefile.in b/helm/DEVEL/mathml_editor/test/Makefile.in
new file mode 100644 (file)
index 0000000..3c69a2a
--- /dev/null
@@ -0,0 +1,387 @@
+# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EDITEX_VERSION_INFO = @EDITEX_VERSION_INFO@
+EXEEXT = @EXEEXT@
+GDOMEXSLT_CFLAGS = @GDOMEXSLT_CFLAGS@
+GDOMEXSLT_LIBS = @GDOMEXSLT_LIBS@
+GMETADOM_CFLAGS = @GMETADOM_CFLAGS@
+GMETADOM_LIBS = @GMETADOM_LIBS@
+GTKMATHVIEW_CFLAGS = @GTKMATHVIEW_CFLAGS@
+GTKMATHVIEW_LIBS = @GTKMATHVIEW_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+
+noinst_PROGRAMS = test editor
+
+test_SOURCES = main.cc
+editor_SOURCES = editor.cc guiGTK.c aux.cc
+
+LDADDS =    $(GMETADOM_LIBS)   $(GDOMEXSLT_LIBS)   $(GTKMATHVIEW_LIBS)   $(top_builddir)/src/.libs/libeditex.a
+
+
+test_LDADD = $(LDADDS)
+editor_LDADD = $(LDADDS)
+
+INCLUDES =    $(GMETADOM_CFLAGS)   $(GDOMEXSLT_CFLAGS)   $(GTKMATHVIEW_CFLAGS)   -I$(top_srcdir)/src
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+noinst_PROGRAMS =  test$(EXEEXT) editor$(EXEEXT)
+PROGRAMS =  $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+LIBS = @LIBS@
+test_OBJECTS =  main.$(OBJEXT)
+test_DEPENDENCIES =  $(top_builddir)/src/.libs/libeditex.a
+test_LDFLAGS = 
+editor_OBJECTS =  editor.$(OBJEXT) guiGTK.$(OBJEXT) aux.$(OBJEXT)
+editor_DEPENDENCIES =  $(top_builddir)/src/.libs/libeditex.a
+editor_LDFLAGS = 
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES =  .deps/aux.P .deps/editor.P .deps/guiGTK.P .deps/main.P
+SOURCES = $(test_SOURCES) $(editor_SOURCES)
+OBJECTS = $(test_OBJECTS) $(editor_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .obj .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+       $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+       -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES)
+       @rm -f test$(EXEEXT)
+       $(CXXLINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+editor$(EXEEXT): $(editor_OBJECTS) $(editor_DEPENDENCIES)
+       @rm -f editor$(EXEEXT)
+       $(CXXLINK) $(editor_LDFLAGS) $(editor_OBJECTS) $(editor_LDADD) $(LIBS)
+.cc.o:
+       $(CXXCOMPILE) -c $<
+.cc.obj:
+       $(CXXCOMPILE) -c `cygpath -w $<`
+.cc.lo:
+       $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = test
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu test/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cc
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cc
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstPROGRAMS mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \
+               clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstPROGRAMS distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstPROGRAMS \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/helm/DEVEL/mathml_editor/test/aux.cc b/helm/DEVEL/mathml_editor/test/aux.cc
new file mode 100644 (file)
index 0000000..61f9e5d
--- /dev/null
@@ -0,0 +1,227 @@
+// Copyright (C) 2000-2002, Luca Padovani <luca.padovani@cs.unibo.it>.
+//
+// This file is part of GtkMathView, a Gtk widget for MathML.
+// 
+// GtkMathView is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// GtkMathView is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GtkMathView; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// 
+// For details, see the GtkMathView World-Wide-Web page,
+// http://www.cs.unibo.it/helm/mml-widget, or send a mail to
+// <luca.padovani@cs.unibo.it>
+
+#include <config.h>
+#include <assert.h>
+
+#include <gdome.h>
+#include <gdome-util.h>
+#include <GdomeSmartDOM.hh>
+
+//#include "gmetadom.hh"
+
+namespace DOM = GdomeSmartDOM;
+
+static unsigned
+getDepth(const DOM::Element& elem)
+{
+  unsigned length = 0;
+  DOM::Element p = elem;
+
+  while (p)
+    {
+      p = p.get_parentNode();
+      length++;
+    }
+
+  return length;
+}
+
+static DOM::Element
+findCommonAncestor(const DOM::Element& first, const DOM::Element& last)
+{
+  assert(first);
+  assert(last);
+
+  DOM::Element p(first);
+  DOM::Element q(last);
+
+  if (p != q)
+    {
+      unsigned pDepth = getDepth(p);
+      unsigned qDepth  = getDepth(q);
+
+      while (p && pDepth > qDepth)
+       {
+         p = p.get_parentNode();
+         pDepth--;
+       }
+
+      while (q && qDepth > pDepth)
+       {
+         q = q.get_parentNode();
+         qDepth--;
+       }
+
+      assert(pDepth == qDepth);
+
+      while (p && q && p != q)
+       {
+         p = p.get_parentNode();
+         q = q.get_parentNode();
+       }
+    }
+  
+  return p;
+}
+
+static void
+findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
+                  DOM::Element& firstS, DOM::Element& lastS)
+{
+  assert(first);
+  assert(last);
+
+  DOM::Element p(first);
+  DOM::Element q(last);
+
+  if (p != q)
+    {
+      unsigned pDepth = getDepth(p);
+      unsigned qDepth  = getDepth(q);
+
+      while (p && pDepth > qDepth)
+       {
+         p = p.get_parentNode();
+         pDepth--;
+       }
+
+      while (q && qDepth > pDepth)
+       {
+         q = q.get_parentNode();
+         qDepth--;
+       }
+
+      assert(pDepth == qDepth);
+
+      while (p && q && p.get_parentNode() != q.get_parentNode())
+       {
+         p = p.get_parentNode();
+         q = q.get_parentNode();
+       }
+    }
+
+  firstS = p;
+  lastS = q;
+}
+
+static DOM::Node
+leftmostChild(const DOM::Node& node)
+{
+  if (!node) return node;
+
+  DOM::Node firstChild = node.get_firstChild();
+  if (!firstChild) return node;
+
+  return leftmostChild(firstChild);
+}
+
+static DOM::Node
+rightmostChild(const DOM::Node& node)
+{
+  if (!node) return node;
+
+  DOM::Node lastChild = node.get_lastChild();
+  if (!lastChild) return node;
+
+  return rightmostChild(lastChild);
+}
+
+static DOM::Node
+leftSibling(const DOM::Node& node)
+{
+  DOM::Node p = node;
+
+  if (!p) return p;
+
+  while (p.get_parentNode() && p.get_parentNode().get_firstChild() == p)
+    p = p.get_parentNode();
+
+  if (!p.get_parentNode()) return DOM::Node(0);
+
+  DOM::Node prevSibling = p.get_previousSibling();
+  assert(prevSibling);
+
+  return rightmostChild(prevSibling);
+}
+
+static DOM::Node
+rightSibling(const DOM::Node& node)
+{
+  DOM::Node p = node;
+
+  if (!p) return p;
+
+  DOM::Node firstChild = p.get_firstChild();
+  if (firstChild) return firstChild;
+
+  while (p.get_parentNode() && p.get_parentNode().get_lastChild() == p)
+    p = p.get_parentNode();
+
+  if (!p.get_parentNode()) return DOM::Node(0);
+
+  DOM::Node nextSibling = p.get_nextSibling();
+  assert(nextSibling);
+
+  return leftmostChild(nextSibling);
+}
+
+extern "C" GdomeElement*
+find_common_ancestor(GdomeElement* first, GdomeElement* last)
+{
+  DOM::Element p(first);
+  DOM::Element q(last);
+  if (GdomeElement* res = gdome_cast_el(findCommonAncestor(p, q).gdome_object()))
+    {
+      GdomeException exc = 0;
+      gdome_el_ref(res, &exc);
+      assert(exc == 0);
+      return res;
+    }
+  else
+    return 0;
+}
+
+extern "C" void
+find_common_siblings(GdomeElement* first, GdomeElement* last,
+                    GdomeElement** firstS, GdomeElement** lastS)
+{
+  DOM::Element fs(0);
+  DOM::Element ls(0);
+
+  findCommonSiblings(DOM::Element(first), DOM::Element(last), fs, ls);
+
+  if (firstS != NULL) *firstS = gdome_cast_el(fs.gdome_object());
+  if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
+}
+
+extern "C" void
+delete_element(GdomeElement* elem)
+{
+  DOM::Element p(elem);
+
+  DOM::Element parent = p.get_parentNode();
+  assert(parent);
+
+  parent.removeChild(p);
+}
+
diff --git a/helm/DEVEL/mathml_editor/test/editor.cc b/helm/DEVEL/mathml_editor/test/editor.cc
new file mode 100644 (file)
index 0000000..265d35e
--- /dev/null
@@ -0,0 +1,214 @@
+
+#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();
+}
diff --git a/helm/DEVEL/mathml_editor/test/guiGTK.c b/helm/DEVEL/mathml_editor/test/guiGTK.c
new file mode 100644 (file)
index 0000000..53bbd74
--- /dev/null
@@ -0,0 +1,686 @@
+
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gtkmathview.h"
+#include "guiGTK.h"
+
+#define XLINK_NS_URI "http://www.w3.org/1999/xlink"
+
+static GtkWidget* window;
+static GtkWidget* main_area;
+static GtkWidget* scrolled_area;
+static GtkWidget* status_bar;
+static GtkMenuItem* anti_aliasing_item;
+static GtkMenuItem* transparency_item;
+static GtkMenuItem* font_size_item;
+static GdkCursor* normal_cursor;
+static GdkCursor* link_cursor;  
+
+static gchar* doc_name = NULL;
+static GdomeElement* root_selected = NULL;
+static GdomeElement* first_selected = NULL;
+static GdomeElement* last_selected = NULL;
+static GdomeElement* cursor = NULL;
+static gboolean selecting = FALSE;
+static gboolean button_pressed = FALSE;
+
+static guint statusbar_context;
+
+static guint         edit_timeout_id;
+static GdomeElement* cursor_ptr = NULL;
+static gboolean      cursor_active = FALSE;
+
+static void create_widget_set(gpointer);
+static GtkWidget* get_main_menu(void);
+static void options_selection_mode(GtkWidget*, guint);
+static void options_font_size(GtkWidget*, guint);
+static void options_verbosity(GtkWidget*, guint);
+static void options_anti_aliasing(GtkWidget*, gpointer);
+static void options_transparency(GtkWidget*, gpointer);
+static void edit_delete_selection(GtkWidget*, gpointer);
+static void edit_select_parent(GtkWidget*, gpointer);
+static void help_about(GtkWidget*, gpointer);
+
+extern int edit_timeout(gpointer);
+extern void push_char(gpointer, gchar);
+
+static GtkItemFactoryEntry menu_items[] = {
+  { "/_File",                          NULL,         NULL,          0, "<Branch>" },
+  { "/File/_Quit",                     "<control>Q", gtk_main_quit, 0, NULL },
+
+  { "/_Edit",                          NULL, NULL,                  0,  "<Branch>" },
+  { "/Edit/Delete Selection",          NULL, edit_delete_selection, 0,  NULL },
+  { "/Edit/Select Parent",             NULL, edit_select_parent,    0,  NULL },
+
+  { "/_Options",                       NULL, NULL,                  0,  "<Branch>" },
+  { "/Options/_Selection Mode",        NULL, NULL,                  0,  "<Branch>" },
+  { "/Options/Selection Mode/_Structure", NULL, options_selection_mode, 0, "<RadioItem>" },
+  { "/Options/Selection Mode/_Linear",  NULL, options_selection_mode, 1, "/Options/Selection Mode/Structure" },
+  { "/Options/Default _Font Size",     NULL, NULL,                  0,  "<Branch>" },
+  { "/Options/Default Font Size/8pt",  NULL, options_font_size,     8,  "<RadioItem>" },
+  { "/Options/Default Font Size/10pt", NULL, options_font_size,     10, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/12pt", NULL, options_font_size,     12, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/14pt", NULL, options_font_size,     14, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/18pt", NULL, options_font_size,     18, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/24pt", NULL, options_font_size,     24, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/48pt", NULL, options_font_size,     48, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/72pt", NULL, options_font_size,     72, "/Options/Default Font Size/8pt" },
+  { "/Options/Verbosity",              NULL, NULL,                  0,  "<Branch>" },
+  { "/Options/Verbosity/_Errors",      NULL, options_verbosity,     0,  "<RadioItem>" },
+  { "/Options/Verbosity/_Warnings",    NULL, options_verbosity,     1,  "/Options/Verbosity/Errors" },
+  { "/Options/Verbosity/_Info",        NULL, options_verbosity,     2,  "/Options/Verbosity/Errors" },
+  { "/Options/Verbosity/_Debug",       NULL, options_verbosity,     3,  "/Options/Verbosity/Errors" },
+  { "/Options/sep1",                   NULL, NULL,                  0,  "<Separator>" },
+  { "/Options/_Anti Aliasing",         NULL, options_anti_aliasing, 0,  "<ToggleItem>" },
+  { "/Options/_Transparency",          NULL, options_transparency,  0,  "<ToggleItem>" },
+
+  { "/_Help" ,        NULL,         NULL,          0, "<LastBranch>" },
+  { "/Help/About...", NULL,         help_about,    0, NULL }
+};
+
+static void
+quick_message(const char* msg)
+{
+  GtkWidget* dialog;
+  GtkWidget* label;
+  GtkWidget* okay_button;
+     
+  /* Create the widgets */
+     
+  dialog = gtk_dialog_new();
+  label = gtk_label_new (msg);
+  okay_button = gtk_button_new_with_label("OK");
+
+  gtk_widget_set_usize(dialog, 300, 100);
+
+  /* Ensure that the dialog box is destroyed when the user clicks ok. */
+     
+  gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), dialog);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
+                    okay_button);
+  
+  /* Add the label, and show everything we've added to the dialog. */
+  
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
+  gtk_widget_show_all (dialog);
+}
+
+static void
+load_error_msg(const char* name)
+{
+  char* msg = g_strdup_printf("Could not load\n`%s'", name);
+  quick_message(msg);
+  g_free(msg);
+}
+
+static void
+cursor_off()
+{
+  if (cursor_active)
+    {
+      cursor_active = FALSE;
+      if (cursor_ptr != NULL &&
+         gtk_math_view_is_selected(main_area, cursor_ptr))
+       gtk_math_view_reset_selection(main_area, cursor_ptr);
+    }
+}
+
+static void
+cursor_on()
+{
+  if (!cursor_active)
+    {
+      cursor_active = FALSE;
+      if (cursor_ptr != NULL &&
+         !gtk_math_view_is_selected(main_area, cursor_ptr))
+       gtk_math_view_set_selection(main_area, cursor_ptr);
+      cursor_active = TRUE;
+    }
+}
+
+void
+GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpointer context)
+{
+  gtk_init(argc, argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(window), title);
+  gtk_window_set_default_size(GTK_WINDOW(window), width, height);
+  gtk_signal_connect(GTK_OBJECT(window), "delete_event", (GtkSignalFunc) gtk_main_quit, NULL);
+  create_widget_set(context);
+
+  gtk_widget_show(window);
+
+  normal_cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
+  link_cursor = gdk_cursor_new(GDK_HAND2);
+
+  /*edit_timeout_id = gtk_timeout_add(400, edit_timeout, context);*/
+}
+
+void
+GUI_uninit()
+{
+  gtk_timeout_remove(edit_timeout_id);
+}
+
+int
+GUI_load_document(GdomeDocument* doc)
+{
+  GtkMathView* math_view;
+
+  g_return_val_if_fail(doc != NULL, -1);
+  g_return_val_if_fail(main_area != NULL, -1);
+  g_return_val_if_fail(GTK_IS_MATH_VIEW(main_area), -1);
+
+  math_view = GTK_MATH_VIEW(main_area);
+
+  if (!gtk_math_view_load_doc(math_view, doc)) return -1;
+
+  return 0;
+}
+
+int
+GUI_load_uri(const char* uri)
+{
+  GtkMathView* math_view;
+
+  g_return_val_if_fail(uri != NULL, -1);
+  g_return_val_if_fail(main_area != NULL, -1);
+  g_return_val_if_fail(GTK_IS_MATH_VIEW(main_area), -1);
+
+  math_view = GTK_MATH_VIEW(main_area);
+
+  if (!gtk_math_view_load_uri(math_view, uri)) return -1;
+
+  return 0;
+}
+
+void
+GUI_freeze()
+{
+  gtk_math_view_freeze(GTK_MATH_VIEW(main_area));
+}
+
+void
+GUI_thaw()
+{
+  gtk_math_view_thaw(GTK_MATH_VIEW(main_area));
+}
+
+void
+GUI_unload_document()
+{
+  GtkMathView* math_view;
+
+  g_return_if_fail(main_area != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
+
+  math_view = GTK_MATH_VIEW(main_area);
+
+  gtk_math_view_unload(math_view);
+
+  if (doc_name != NULL) g_free(doc_name);
+  doc_name = NULL;
+
+  gtk_statusbar_pop(GTK_STATUSBAR(status_bar), statusbar_context);
+  gtk_statusbar_push(GTK_STATUSBAR(status_bar), statusbar_context, "");
+}
+
+void
+GUI_run()
+{
+  gtk_main();
+}
+
+static void
+options_selection_mode(GtkWidget* widget, guint mode)
+{
+}
+
+static void
+options_font_size(GtkWidget* widget, guint size)
+{
+  GtkMathView* math_view;
+
+  g_return_if_fail(main_area != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
+
+  math_view = GTK_MATH_VIEW(main_area);
+
+  gtk_math_view_set_font_size(math_view, size);
+}
+
+static void
+options_anti_aliasing(GtkWidget* widget, gpointer data)
+{
+  gboolean aa = gtk_math_view_get_anti_aliasing(GTK_MATH_VIEW(main_area));
+  gtk_math_view_set_anti_aliasing(GTK_MATH_VIEW(main_area), !aa);
+}
+
+static void
+options_transparency(GtkWidget* widget, gpointer data)
+{
+  gboolean t = gtk_math_view_get_transparency(GTK_MATH_VIEW(main_area));
+  gtk_math_view_set_transparency(GTK_MATH_VIEW(main_area), !t);
+}
+
+static void
+options_verbosity(GtkWidget* widget, guint level)
+{
+  gtk_math_view_set_log_verbosity(GTK_MATH_VIEW(main_area), level);
+}
+
+static void
+edit_delete_selection(GtkWidget* widget, gpointer data)
+{
+  if (root_selected != NULL)
+    {
+      GdomeException exc;
+      gtk_math_view_freeze(GTK_MATH_VIEW(main_area));
+      printf("about to remove element %p\n", root_selected);
+      delete_element(root_selected);
+      gdome_el_unref(root_selected, &exc);
+      g_assert(exc == 0);
+      root_selected = NULL;
+      gtk_math_view_thaw(GTK_MATH_VIEW(main_area));
+    }
+}
+
+static void
+edit_select_parent(GtkWidget* widget, gpointer data)
+{
+  if (root_selected != NULL)
+    {
+      GdomeException exc = 0;
+      GdomeElement* parent = gdome_cast_el(gdome_n_parentNode(root_selected, &exc));
+      g_assert(exc == 0);
+      gdome_el_unref(root_selected, &exc);
+      g_assert(exc == 0);
+      root_selected = parent;
+      gtk_math_view_set_selection(GTK_MATH_VIEW(main_area), root_selected);
+    }
+}
+
+static void
+help_about(GtkWidget* widget, gpointer data)
+{
+  GtkWidget* dialog;
+  GtkWidget* label;
+  GtkWidget* ok;
+
+  dialog = gtk_dialog_new();
+  label = gtk_label_new("\n    MathML Viewer    \n    Copyright (C) 2000-2002 Luca Padovani    \n");
+  ok = gtk_button_new_with_label("Close");
+
+  gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
+                    ok);
+
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
+
+  gtk_widget_show_all (dialog);
+}
+
+#if 0
+#if defined(HAVE_GMETADOM)
+static void
+element_changed(GtkMathView* math_view, GdomeElement* node)
+{
+  GdomeException exc;
+  GdomeDOMString* name;
+  GdomeDOMString* ns_uri;
+
+  g_return_if_fail(math_view != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+
+  name = gdome_str_mkref("href");
+  ns_uri = gdome_str_mkref(XLINK_NS_URI);
+
+  while (node != NULL && !gdome_el_hasAttributeNS(node, ns_uri, name, &exc))
+    node = gdome_cast_el(gdome_el_parentNode(node, &exc));
+
+  if (node != NULL && gdome_el_hasAttributeNS(node, ns_uri, name, &exc))
+    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, link_cursor);
+  else
+    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, normal_cursor);
+
+  gdome_str_unref(name);
+  gdome_str_unref(ns_uri);
+}
+#endif
+
+static void
+#if defined(HAVE_GMETADOM)
+action_changed(GtkMathView* math_view, GdomeElement* node)
+#endif
+{
+  g_return_if_fail(math_view != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+}
+
+static void
+#if defined(HAVE_GMETADOM)
+selection_changed(GtkMathView* math_view, GdomeElement* node)
+#endif
+{
+  g_return_if_fail(math_view != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+  gtk_math_view_set_selection(math_view, node);
+
+  cursor_off();
+  cursor_ptr = node;
+  cursor_on();
+}
+
+#if defined(HAVE_GMETADOM)
+static void
+clicked(GtkMathView* math_view, gpointer user_data)
+{
+  GdomeException exc;
+  GdomeDOMString* name;
+  GdomeDOMString* ns_uri;
+  GdomeElement* p;
+
+  g_return_if_fail(math_view != NULL);
+
+  name = gdome_str_mkref("href");
+  ns_uri = gdome_str_mkref(XLINK_NS_URI);
+
+  p = gtk_math_view_get_element(math_view);
+  while (p != NULL && !gdome_el_hasAttributeNS(p, ns_uri, name, &exc))
+    p = gdome_cast_el(gdome_el_parentNode(p, &exc));
+
+  if (p != NULL) {
+    GdomeDOMString* href = gdome_el_getAttributeNS(p, ns_uri, name, &exc);
+    g_assert(href != NULL);
+
+    GUI_load_document(href->str);
+    gdome_str_unref(href);
+  } else if (gtk_math_view_get_action(math_view) != NULL)
+    gtk_math_view_action_toggle(math_view);
+}
+#endif
+#endif
+
+static gint
+button_press_event(GtkWidget* widget,
+                  GdkEventButton* event,
+                  GtkMathView* math_view)
+{
+  g_return_val_if_fail(event != NULL, FALSE);
+  g_return_val_if_fail(math_view != NULL, FALSE);
+  
+  if (event->button == 1)
+    {
+      GdomeException exc;
+
+      cursor_off();
+
+      if (root_selected != NULL)
+       {
+         gtk_math_view_reset_selection(math_view, root_selected);
+         gdome_el_unref(root_selected, &exc);
+         g_assert(exc == 0);
+         root_selected = NULL;
+       }
+
+      if (first_selected != NULL)
+       {
+         gdome_el_unref(first_selected, &exc);
+         g_assert(exc == 0);
+       }
+
+      if (last_selected != NULL)
+       {
+         gdome_el_unref(last_selected, &exc);
+         g_assert(exc == 0);
+         last_selected = NULL;
+       }
+
+      first_selected = gtk_math_view_get_element_at(math_view, event->x, event->y);
+      button_pressed = TRUE;
+      selecting = FALSE;
+    }
+
+  return FALSE;
+}
+
+static gint
+motion_notify_event(GtkWidget* widget,
+                   GdkEventMotion* event,
+                   GtkMathView* math_view)
+{
+  g_return_val_if_fail(event != NULL, FALSE);
+  g_return_val_if_fail(math_view != NULL, FALSE);
+
+  if (button_pressed && first_selected != NULL)
+    {
+      GdomeException exc;
+      GdomeElement* el = gtk_math_view_get_element_at(math_view, event->x, event->y);
+      GdomeElement* root;
+
+      selecting = TRUE;
+
+      if (el != NULL && el != last_selected)
+       {
+         if (last_selected != NULL)
+           {
+             gdome_el_unref(last_selected, &exc);
+             g_assert(exc == 0);
+           }
+
+         last_selected = el;
+       }
+
+      if (last_selected != NULL)
+       {
+         root = find_common_ancestor(first_selected, last_selected);
+         g_assert(root != NULL);
+
+         if (root != root_selected)
+           {
+             gtk_math_view_freeze(math_view);
+             if (root_selected != NULL)
+               {
+                 gtk_math_view_reset_selection(math_view, root_selected);
+                 gdome_el_unref(root_selected, &exc);
+                 g_assert(exc == 0);
+               }
+             root_selected = root;
+             gtk_math_view_set_selection(math_view, root_selected);
+             gtk_math_view_thaw(math_view);
+           }
+         else
+           {
+             gdome_el_unref(root, &exc);
+             g_assert(exc == 0);
+           }
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+button_release_event(GtkWidget* widget,
+                    GdkEventButton* event,
+                    GtkMathView* math_view)
+{
+  g_return_val_if_fail(event != NULL, FALSE);
+  g_return_val_if_fail(math_view != NULL, FALSE);
+  
+  if (event->button == 1)
+    {
+      if (!selecting)
+       {
+         cursor_ptr = first_selected;
+         cursor_on();
+       }
+
+      button_pressed = FALSE;
+      selecting = FALSE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+key_press_event(gpointer context,
+               GdkEventKey* event,
+               GtkWidget* widget)
+{
+  g_return_val_if_fail(widget != NULL, FALSE);
+  g_return_val_if_fail(event != NULL, FALSE);
+  g_return_val_if_fail(context != NULL, FALSE);
+
+  if (event->type != GDK_KEY_PRESS) return FALSE;
+
+  switch (event->keyval) {
+  case GDK_Up:
+  case GDK_KP_Up:
+    break;
+  case GDK_Down:
+  case GDK_KP_Down:
+    break;
+  case GDK_Left:
+  case GDK_KP_Left:
+    break;
+  case GDK_Right:
+  case GDK_KP_Right:
+    break;
+  case GDK_Page_Up:
+  case GDK_KP_Page_Up:
+    break;
+  case GDK_Page_Down:
+  case GDK_KP_Page_Down:
+    break;
+  case GDK_Home:
+  case GDK_KP_Home:
+    break;
+  case GDK_End:
+  case GDK_KP_End:
+    break;
+  default:
+    if (event->keyval < 0x80) push_char(context, event->keyval);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static void
+create_widget_set(gpointer context)
+{
+  GtkWidget* main_vbox;
+  GtkWidget* menu_bar;
+
+  main_vbox = gtk_vbox_new(FALSE, 1);
+  gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
+  gtk_container_add(GTK_CONTAINER(window), main_vbox);
+  gtk_widget_show(main_vbox);
+
+  menu_bar = get_main_menu();
+  gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
+  gtk_widget_show(menu_bar);
+
+  main_area = gtk_math_view_new(NULL, NULL);
+  gtk_widget_show(main_area);
+
+  //gtk_math_view_set_log_verbosity(GTK_MATH_VIEW(main_area), 3);
+
+#if 0
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "selection_changed", GTK_SIGNAL_FUNC (selection_changed),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "element_changed", GTK_SIGNAL_FUNC (element_changed),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "action_changed", GTK_SIGNAL_FUNC (action_changed),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area), 
+                            "clicked", GTK_SIGNAL_FUNC(clicked),
+                            (gpointer) main_area);
+#endif
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "button_press_event", GTK_SIGNAL_FUNC(button_press_event),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "button_release_event", GTK_SIGNAL_FUNC(button_release_event),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "motion_notify_event", GTK_SIGNAL_FUNC(motion_notify_event),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT(window),
+                            "key_press_event", GTK_SIGNAL_FUNC(key_press_event),
+                            context);
+
+  gtk_widget_add_events(GTK_WIDGET(main_area),
+                       GDK_BUTTON_PRESS_MASK
+                       | GDK_BUTTON_RELEASE_MASK
+                       | GDK_POINTER_MOTION_MASK
+                       | GDK_KEY_PRESS_MASK);
+
+  scrolled_area = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area),
+                                GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+
+  gtk_widget_show(scrolled_area);
+  gtk_container_add(GTK_CONTAINER(scrolled_area), main_area);
+  gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_area, TRUE, TRUE, 0);
+
+  status_bar = gtk_statusbar_new();
+  gtk_widget_show(status_bar);
+  gtk_box_pack_start(GTK_BOX(main_vbox), status_bar, FALSE, TRUE, 0);
+  statusbar_context = gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar), "filename");
+
+  gtk_widget_show(main_vbox);
+
+  if (gtk_math_view_get_anti_aliasing(GTK_MATH_VIEW(main_area)))
+    gtk_menu_item_activate(anti_aliasing_item);
+
+  gtk_menu_item_activate(font_size_item);
+}
+
+GtkWidget*
+get_main_menu()
+{
+  GtkItemFactory* item_factory;
+  GtkAccelGroup* accel_group;
+  GtkWidget* menu_item;
+
+  gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
+
+  accel_group = gtk_accel_group_new();
+
+  item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
+
+  gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL);
+
+  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
+
+  menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Anti Aliasing");
+  anti_aliasing_item = GTK_MENU_ITEM(menu_item);
+
+  menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Transparency");
+  transparency_item = GTK_MENU_ITEM(menu_item);
+
+  /* !!!BEWARE!!! the default font size must be kept aligned with the definition
+   * in math-engine-configuration.xml
+   */
+  menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Default Font Size/12pt");
+  font_size_item = GTK_MENU_ITEM(menu_item);
+
+  return gtk_item_factory_get_widget(item_factory, "<main>");
+}
diff --git a/helm/DEVEL/mathml_editor/test/guiGTK.h b/helm/DEVEL/mathml_editor/test/guiGTK.h
new file mode 100644 (file)
index 0000000..7147554
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2000, Luca Padovani <luca.padovani@cs.unibo.it>.
+ * 
+ * This file is part of GtkMathView, a Gtk widget for MathML.
+ * 
+ * GtkMathView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * GtkMathView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GtkMathView; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * For details, see the GtkMathView World-Wide-Web page,
+ * http://cs.unibo.it/~lpadovan/mml-widget, or send a mail to
+ * <luca.padovani@cs.unibo.it>
+ */
+
+#ifndef guiGTK_h
+#define guiGTK_h
+
+#include <glib.h>
+
+#include "gtkmathview.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* initGUI: some initialization stuff, creates the main window, sets it with a title */
+  void GUI_init(int *, char ***, char *, guint, guint, gpointer);
+  void GUI_uninit(void);
+
+  int  GUI_load_document(GdomeDocument*);
+  int  GUI_load_uri(const char*);
+  void GUI_unload_document(void);
+  void GUI_dump_entities(void);
+
+  /* main: this is the main event loop, to be called when the program is ready to run */
+  void GUI_run(void);
+
+  void GUI_freeze(void);
+  void GUI_thaw(void);
+
+  void GUI_set_font_manager(FontManagerId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* guiGTK_h */
diff --git a/helm/DEVEL/mathml_editor/test/main.cc b/helm/DEVEL/mathml_editor/test/main.cc
new file mode 100644 (file)
index 0000000..3122d52
--- /dev/null
@@ -0,0 +1,158 @@
+
+#include "TNode.hh"
+#include "TToken.hh"
+#include "TDocument.hh"
+#include "TPushParser.hh"
+#include "TPushLexer.hh"
+#include "TDictionary.hh"
+#include "TListener.hh"
+#include <GdomeSmartDOMXSLT.hh>
+
+TDictionary dictionary;
+DOM::Document result;
+
+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);
+      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;
+    }
+}
+
+#if 0
+bool
+subst(const DOM::Node& parent, const DOM::GdomeString& id, const DOM::Element& newElem)
+{
+  assert(parent);
+  assert(newElem);
+
+  DOM::Node p = parent.get_firstChild();
+  while (p)
+    {
+      while (p && p.get_nodeType() != DOM::Node::ELEMENT_NODE) p = p.get_nextSibling();
+      if (p)
+       {
+         DOM::Element el = p;
+         assert(el);
+         if (el.getAttribute("xref") == id)
+           {
+             parent.replaceChild(el, newElem);
+             return true;
+           }
+         else if (subst(el, id, newElem))
+           return true;
+         else
+           p = p.get_nextSibling();
+       }
+    }
+
+  return false;
+}
+#endif
+
+class MyListener : public TListener
+{
+public:
+  MyListener(const DOM::XSLTStylesheet& s) : style(s) { };
+
+  void callback(TDocument& doc)
+  {
+    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(res, stdout);
+       if (result)
+         {
+           DOM::Element root = res.get_documentElement();
+           assert(root);
+           assert(root.hasAttribute("xref"));
+
+           if (result.get_documentElement().getAttribute("xref") == root.getAttribute("xref"))
+             {
+               // 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)
+               {
+                 cerr << "exception " << e.code << " " << e.msg << endl;
+                 assert(0);
+               }
+         }
+       else
+         result = res;
+
+       doc.clearDirty();
+      }
+  }
+
+private:
+  const DOM::XSLTStylesheet& style;
+};
+
+main(int argc, char* argv[])
+{
+  if (argc != 2)
+    {
+      cerr << "specify a string, please" << endl;
+      return -1;
+    }
+
+  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);
+
+  std::string s = argv[1];
+  for (unsigned long i = 0; i < s.length(); i++)
+    lexer.push(s[i]);
+  lexer.push('\n');
+  
+  cout << "finished" << endl;
+  di.saveDocumentToFile(result, "result.xml", GDOME_SAVE_LIBXML_INDENT);
+
+  cout << "done" << endl;
+
+  parser.document().serialize("output.xml");
+}
diff --git a/helm/DEVEL/mathml_editor/xsl/d-xsl.xsl b/helm/DEVEL/mathml_editor/xsl/d-xsl.xsl
new file mode 100644 (file)
index 0000000..2ef6083
--- /dev/null
@@ -0,0 +1,131 @@
+<xsl2:stylesheet
+  version="1.0"
+  xmlns:xsl2="http://www.w3.org/1999/XSL/Transform"
+  xmlns:xsl="http://www.w3.org/1999/XSL/TransformAlias"
+  xmlns:tml="http://helm.cs.unibo.it/2002/TML">
+
+<xsl:namespace-alias stylesheet-prefix="xsl" result-prefix="xsl2"/>
+
+<xsl2:template match="/">
+  <xsl:stylesheet version="1.0">
+    <xsl:template match="tml:tex">
+      <xsl:apply-templates select="*"/>
+    </xsl:template>
+
+    <xsl:template match="tml:i">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:value-of select="@val"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:n">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:value-of select="@val"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:o">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:value-of select="@val"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:cursor">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:value-of select="@val"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:sb[@under='1']">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:sb">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:sb[@over='1']">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:sp">
+      <xsl:element name="xxx">
+        <xsl:if test="@id">
+          <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        </xsl:if>
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:g[@id]">
+      <xsl:element name="xxx">
+        <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+        <xsl:apply-templates select="*"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:g">
+      <xsl:element name="xxx">
+        <xsl:apply-templates select="*"/>
+      </xsl:element>
+    </xsl:template>
+
+    <xsl:template match="tml:row">
+      <xsl:apply-templates select="cell"/>
+    </xsl:template>
+
+    <xsl:template match="tml:cell">
+      <xsl:apply-templates select="*"/>
+    </xsl:template>
+    
+    <xsl2:comment>/// CONTROL SEQUENCES ///</xsl2:comment>
+
+    <xsl2:apply-templates/>
+  </xsl:stylesheet>
+</xsl2:template>
+
+<xsl2:template match="entry[not(@class) or @class='m']">
+  <xsl:template match="tml:c[@name='{@name}']">
+    <xsl2:comment><xsl2:value-of select="concat(' ',@name,' ')"/></xsl2:comment>
+    <xsl:element name="xxx">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref"><xsl:value-of select="@id"/></xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*"/>
+    </xsl:element>
+  </xsl:template>
+</xsl2:template>
+
+</xsl2:stylesheet>
+
diff --git a/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl b/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl
new file mode 100644 (file)
index 0000000..8b23738
--- /dev/null
@@ -0,0 +1,949 @@
+<?xml version="1.0"?>
+<xsl:stylesheet
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+     xmlns:tml="http://helm.cs.unibo.it/2002/TML"
+     xmlns:m="http://www.w3.org/1998/Math/MathML"
+     version="1.0">
+
+  <xsl:output indent="yes"/>
+
+  <xsl:param name="id" select="/.."/>
+
+  <xsl:template match="/">
+    <xsl:choose>
+      <xsl:when test="$id">
+        <xsl:apply-templates select="descendant::*[@id=$id]"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:math">
+    <m:math>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+       <xsl:if test="@display='1'">
+        <xsl:attribute name="display">block</xsl:attribute>
+      </xsl:if>
+      <xsl:attribute name="display">block</xsl:attribute>
+      <xsl:apply-templates select="*"/>
+    </m:math>
+  </xsl:template>
+
+  <xsl:template match="tml:i">
+    <m:mi>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="@val"/>
+    </m:mi>
+  </xsl:template>
+
+  <xsl:template match="tml:n">
+    <m:mn>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="@val"/>
+    </m:mn>
+  </xsl:template>
+
+  <xsl:template match="tml:o">
+    <m:mo>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="@val"/>
+    </m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:cursor">
+    <xsl:choose>
+      <xsl:when test="substring(@val,1,1)='\'">
+        <m:mrow>
+          <xsl:if test="@id">
+            <xsl:attribute name="xref">
+              <xsl:value-of select="@id"/>
+            </xsl:attribute>
+          </xsl:if>
+          <m:mo stretchy="false">&#x2329;</m:mo>
+          <m:mtext mathcolor="blue"><xsl:value-of select="@val"/></m:mtext>
+          <m:mo stretchy="false">&#x232a;</m:mo>
+        </m:mrow>
+      </xsl:when>
+      <xsl:otherwise>
+        <m:mtext mathcolor="blue">
+          <xsl:if test="@id">
+            <xsl:attribute name="xref">
+              <xsl:value-of select="@id"/>
+            </xsl:attribute>
+          </xsl:if>
+         <xsl:value-of select="@val"/>
+       </m:mtext>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:sb[@under='1'][*[1]/tml:sp[@over='1']]">
+    <m:munderover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]/*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+      <xsl:apply-templates select="*[1]/*[2]"/>
+    </m:munderover>
+  </xsl:template>
+
+  <xsl:template match="tml:sb[@under='1']">
+    <m:munder>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:munder>
+  </xsl:template>
+
+  <xsl:template match="tml:sb[*[1][self::tml:sp[not(@over) or @over='0']]]">
+    <m:msubsup>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]/*[1]"/>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[1]/*[2]"/>
+    </m:msubsup>
+  </xsl:template>
+
+  <xsl:template match="tml:sb">
+    <m:msub>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:msub>
+  </xsl:template>
+
+  <xsl:template match="tml:sp[@over='1'][*[1]/tml:sb[@under='1']]">
+    <m:munderover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]/*[1]"/>
+      <xsl:apply-templates select="*[1]/*[2]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:munderover>
+  </xsl:template>
+
+  <xsl:template match="tml:sp[@over='1']">
+    <m:mover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:sp[*[1][self::tml:sb[not(@over) or @over='0']]]">
+    <m:msubsup>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]/*[1]"/>
+      <xsl:apply-templates select="*[1]/*[2]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:msubsup>
+  </xsl:template>
+
+  <xsl:template match="tml:sp">
+    <m:msup>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:msup>
+  </xsl:template>
+
+  <xsl:template match="tml:g">
+    <xsl:choose>
+      <xsl:when test="not(@id) and count(*) = 1">
+        <xsl:apply-templates select="*[1]"/>
+      </xsl:when>
+      <xsl:when test="tml:cursor">
+       <m:mstyle mathbackground="#e0e0e0">
+          <xsl:if test="@id">
+            <xsl:attribute name="xref">
+              <xsl:value-of select="@id"/>
+            </xsl:attribute>
+         </xsl:if>
+         <m:mrow>
+           <xsl:apply-templates select="*"/>
+         </m:mrow>
+       </m:mstyle>
+      </xsl:when>
+       <xsl:otherwise>
+       <m:mrow>
+         <xsl:if test="@id">
+            <xsl:attribute name="xref">
+              <xsl:value-of select="@id"/>
+            </xsl:attribute>
+         </xsl:if>
+         <xsl:apply-templates select="*"/>
+       </m:mrow>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:row">
+    <m:mtr>
+      <xsl:apply-templates select="cell"/>
+    </m:mtr>
+  </xsl:template>
+
+  <xsl:template match="tml:cell">
+    <m:mtd>
+      <xsl:apply-templates select="*"/>
+    </m:mtd>
+  </xsl:template>
+
+<!--/// CONTROL SEQUENCES ///-->
+
+  <xsl:template match="tml:c">
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mtext mathcolor="blue">\<xsl:value-of select="@name"/></m:mtext>
+      <xsl:apply-templates select="*"/>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='fun' and count(*)=3]">
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo mathcolor="red">&#x03bb;</m:mo>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>:</m:mo>
+      <xsl:apply-templates select="*[2]"/>
+      <m:mo>.</m:mo>
+      <xsl:apply-templates select="*[3]"/>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='not'][*[1][self::tml:o]]">
+<!-- not -->
+    <m:mo>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="*[1]/@val"/>&#x0338;</m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='buildrel']">
+<!-- buildrel -->
+    <m:mover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[2]"/>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='left' or @name='right'][*[1][self::tml:o]]">
+<!-- left -->
+    <m:mo stretchy="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="*[1]/@val"/>
+    </m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='bigl' or @name='bigr' or @name='bigm' or @name='big'][*[1][self::tml:o]]">
+<!-- bigl -->
+    <m:mo stretchy="true" minsize="8.5pt">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="*[1]/@val"/>
+    </m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='Bigl' or @name='Bigr' or @name='Bigm'][*[1][self::tml:o]]">
+<!-- Bigl -->
+    <m:mo stretchy="true" minsize="11.5pt">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="*[1]/@val"/>
+    </m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='biggl' or @name='biggr' or @name='biggm'][*[1][self::tml:o]]">
+<!-- biggl -->
+    <m:mo stretchy="true" minsize="14.5pt">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="*[1]/@val"/>
+    </m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='Biggl' or @name='Biggr' or @name='Biggm'][*[1][self::tml:o]]">
+<!-- biggl -->
+    <m:mo stretchy="true" minsize="17.5pt">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:value-of select="*[1]/@val"/>
+    </m:mo>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='hat']">
+<!-- hat -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0302;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='widehat']">
+<!-- widehat -->
+    <m:mover accent="false">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo stretchy="true">&#x0302;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='check']">
+<!-- check -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x030c;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='tilde']">
+<!-- tilde -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0303;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='widetilde']">
+<!-- widetilde -->
+    <m:mover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo stretchy="true">&#x0303;</m:mo>
+    </m:mover>>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='acute']">
+<!-- acute -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0301;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='grave']">
+<!-- grave -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0300;</m:mo>
+    </m:mover>>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='dot']">
+<!-- dot -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0307;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='ddot']">
+<!-- ddot -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0308;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='breve']">
+<!-- breve -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0306;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='bar']">
+<!-- bar -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x0304;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='vec']">
+<!-- vec -->
+    <m:mover accent="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo>&#x20d7;</m:mo>
+    </m:mover>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='overline']">
+<!-- overline -->
+    <m:mover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo stretchy="true">&#x0305;</m:mo>
+    </m:mover>>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='underline']">
+<!-- underline -->
+    <m:munder>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo stretchy="true">&#x0332;</m:mo>
+    </m:munder>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='sqrt']">
+<!-- sqrt -->
+    <m:msqrt>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*"/>
+    </m:msqrt>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='root']">
+<!-- root -->
+    <m:mroot>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[2]"/>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mroot>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='frac']">
+<!-- frac -->
+    <m:mfrac>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:mfrac>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='over']">
+<!-- over -->
+    <m:mfrac>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:mfrac>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='atop']">
+<!-- atop -->
+    <m:mfrac linethickness="0">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
+    </m:mfrac>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='choose']">
+<!-- choose -->
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo stretchy="true">(</m:mo>
+      <m:mfrac linethickness="0">
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </m:mfrac>
+      <m:mo stretchy="true">)</m:mo>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='brace']">
+<!-- brace -->
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo stretchy="true">{</m:mo>
+      <m:mfrac linethickness="0">
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </m:mfrac>
+      <m:mo stretchy="true">}</m:mo>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='brack']">
+<!-- brack -->
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo stretchy="true">[</m:mo>
+      <m:mfrac linethickness="0">
+        <xsl:apply-templates select="*[1]"/>
+        <xsl:apply-templates select="*[2]"/>
+      </m:mfrac>
+      <m:mo stretchy="true">]</m:mo>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='displaystyle']">
+<!-- displaystyle -->
+    <m:mstyle displaystyle="true">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='textstyle']">
+<!-- textstyle -->
+    <m:mstyle scriptlevel="0">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='scriptstyle']">
+<!-- scriptstyle -->
+    <m:mstyle scriptlevel="1">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='scriptscriptstyle']">
+<!-- scriptscriptstyle -->
+    <m:mstyle scriptlevel="2">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='pmod']">
+<!-- pmod -->
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo>(</m:mo>
+      <m:mrow>
+        <m:mo>mod</m:mo>
+        <xsl:apply-templates select="*[1]"/>
+      </m:mrow>
+      <m:mo>)</m:mo>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='rm']">
+<!-- rm -->
+    <m:mstyle mathvariant="normal">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='bf']">
+<!-- bf -->
+    <m:mstyle mathvariant="bold">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='tt']">
+<!-- tt -->
+    <m:mstyle mathvariant="monospace">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='sl']">
+<!-- sl -->
+    <m:mstyle mathvariant="italic">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='it']">
+<!-- it -->
+    <m:mstyle mathvariant="italic">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+    </m:mstyle>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name=',']">
+<!-- , -->
+    <m:mspace width="thinmathspace">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+    </m:mspace>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='&gt;']">
+<!-- > -->
+    <m:mspace width="mediummathspace">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+    </m:mspace>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name=';']">
+<!-- ; -->
+    <m:mspace width="thickmathspace">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+    </m:mspace>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='!']">
+<!-- ! -->
+    <m:mspace width="-0.166667em">
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+    </m:mspace>
+  </xsl:template>
+
+  <xsl:template name="table-content">
+      <xsl:choose>
+        <xsl:when test="tml:row">
+          <xsl:apply-templates select="tml:row"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <m:mtr>
+            <m:mtd>
+              <xsl:apply-templates select="*"/>
+            </m:mtd>
+          </m:mtr>
+        </xsl:otherwise>
+      </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='matrix']">
+<!-- matrix -->
+    <m:mtable>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:call-template name="table-content"/>
+    </m:mtable>
+  </xsl:template>
+
+  <xsl:template match="tml:row">
+    <m:mtr>
+      <xsl:apply-templates select="tml:cell"/>
+    </m:mtr>
+  </xsl:template>
+
+  <xsl:template match="tml:cell">
+    <m:mtd>
+      <xsl:apply-templates select="*"/>
+    </m:mtd>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='pmatrix']">
+<!-- pmatrix -->
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo stretchy="true">(</m:mo>
+      <m:mtable>
+        <xsl:call-template name="table-content"/>
+      </m:mtable>
+      <m:mo stretchy="true">)</m:mo>
+    </m:mrow>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='bordermatrix']">
+<!-- bordermatrix -->
+    <m:mtable>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mtr>
+        <xsl:apply-templates select="tml:row[1]/tml:cell[1]"/>
+        <m:mtd/>
+        <xsl:apply-templates select="tml:row[1]/tml:cell[position() &gt; 1]"/>
+       <m:mtd/>
+      </m:mtr>
+      <xsl:for-each select="tml:row[position() &gt; 1]">
+        <m:mtr>
+          <xsl:apply-templates select="tml:cell[1]"/>
+          <xsl:if test="position() = 1">
+            <m:mtd rowspan="{count(../tml:row) - 1}">
+              <m:mo stretchy="true">(</m:mo>
+            </m:mtd>
+          </xsl:if>
+          <xsl:apply-templates select="tml:cell[position() &gt; 1]"/>
+          <xsl:if test="position() = 1">
+            <m:mtd rowspan="{count(../tml:row) - 1}">
+              <m:mo stretchy="true">)</m:mo>
+            </m:mtd>
+          </xsl:if>         
+        </m:mtr>
+      </xsl:for-each>      
+    </m:mtable>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='overbrace']">
+<!-- overbrace -->
+    <m:mover>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo stretchy="true">????</m:mo>
+    </m:mover>>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='underbrace']">
+<!-- underbrace -->
+    <m:munder>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="*[1]"/>
+      <m:mo stretchy="true">????</m:mo>
+    </m:munder>
+  </xsl:template>
+
+  <xsl:template match="tml:c[@name='cases']">
+<!-- cases -->
+    <m:mrow>
+      <xsl:if test="@id">
+        <xsl:attribute name="xref">
+          <xsl:value-of select="@id"/>
+        </xsl:attribute>
+      </xsl:if>
+      <m:mo stretchy="true">{</m:mo>
+      <m:mtable>
+        <xsl:call-template name="table-content"/>
+      </m:mtable>
+    </m:mrow>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/helm/DEVEL/mathml_editor/xsl/tml-tex.xsl b/helm/DEVEL/mathml_editor/xsl/tml-tex.xsl
new file mode 100644 (file)
index 0000000..f3ba8d5
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+     xmlns:tml="http://helm.cs.unibo.it/2002/TML"
+     xmlns:m="http://www.w3.org/1998/Math/MathML"
+     version="1.0">
+
+  <xsl:output method="text" indent="yes"/>
+
+  <xsl:param name="id" select="/.."/>
+
+  <xsl:template match="/">
+    <xsl:choose>
+      <xsl:when test="$id">
+        <xsl:apply-templates select="descendant::*[@id=$id]"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates select="*"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:tex">
+    <xsl:apply-templates select="*"/>
+  </xsl:template>
+
+  <xsl:template match="tml:math">
+    <xsl:choose>
+      <xsl:when test="@display='1'">$$<xsl:apply-templates select="*"/>$$</xsl:when>
+      <xsl:otherwise>$<xsl:apply-templates select="*"/>$</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:i">
+    <xsl:choose>
+      <xsl:when test="@name">\<xsl:value-of select="@name"/><xsl:value-of select="' '"/></xsl:when>
+      <xsl:when test="string-length(@val)=1"><xsl:value-of select="@val"/></xsl:when>
+      <xsl:otherwise>{\it <xsl:value-of select="@val"/>}</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:n">
+    <xsl:choose>
+      <xsl:when test="@name">\<xsl:value-of select="@name"/><xsl:value-of select="' '"/></xsl:when>
+      <xsl:when test="string-length(@val)=1"><xsl:value-of select="@val"/></xsl:when>
+      <xsl:otherwise>{\rm <xsl:value-of select="@val"/>}</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:o">
+    <xsl:choose>
+      <xsl:when test="@name">\<xsl:value-of select="@name"/><xsl:value-of select="' '"/></xsl:when>
+      <xsl:when test="string-length(@val)=1"><xsl:value-of select="@val"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="@val"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:sb">
+    <xsl:choose>
+      <xsl:when test="@under='1'">
+        <xsl:apply-templates select="*[1]"/>__<xsl:apply-templates select="*[2]"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates select="*[1]"/>_<xsl:apply-templates select="*[2]"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:sp">
+    <xsl:choose>
+      <xsl:when test="@over='1'">
+        <xsl:apply-templates select="*[1]"/>^^<xsl:apply-templates select="*[2]"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates select="*[1]"/>^<xsl:apply-templates select="*[2]"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tml:g[@id]">{<xsl:apply-templates select="*"/>}</xsl:template>
+
+  <xsl:template match="tml:g">
+    <xsl:apply-templates select="*"/>
+  </xsl:template>
+
+  <xsl:template match="tml:row">
+    <xsl:apply-templates select="cell"/>\cr </xsl:template>
+
+  <xsl:template match="tml:cell">
+    <xsl:apply-templates select="*"/>
+    <xsl:if test="position() &lt; last()">&amp;</xsl:if>
+  </xsl:template>
+
+<!--/// CONTROL SEQUENCES ///-->
+
+  <xsl:template match="tml:c[*[1][self::tml:g[@left-open='1']]]">
+    <xsl:apply-templates select="*[1]"/>\<xsl:value-of select="@name"/>
+    <xsl:if test="*[2][self::tml:i]"><xsl:value-of select="' '"/></xsl:if>
+    <xsl:apply-templates select="*[position()&gt;1]"/>
+  </xsl:template>
+
+  <xsl:template match="tml:c">\<xsl:value-of select="@name"/>
+    <xsl:if test="*[1][self::tml:i]"><xsl:value-of select="' '"/></xsl:if>
+    <xsl:apply-templates select="*"/>
+  </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/helm/uwobo/.cvsignore b/helm/uwobo/.cvsignore
new file mode 100644 (file)
index 0000000..2fd79ea
--- /dev/null
@@ -0,0 +1,5 @@
+build
+docs
+resources
+backup
+dist
diff --git a/helm/uwobo/.cvswrappers b/helm/uwobo/.cvswrappers
new file mode 100644 (file)
index 0000000..0140b55
--- /dev/null
@@ -0,0 +1 @@
+*.jar  -k 'b' -m 'COPY'
diff --git a/helm/uwobo/ant/ant.jar b/helm/uwobo/ant/ant.jar
new file mode 100644 (file)
index 0000000..9a14d89
Binary files /dev/null and b/helm/uwobo/ant/ant.jar differ
diff --git a/helm/uwobo/ant/jaxp.jar b/helm/uwobo/ant/jaxp.jar
new file mode 100644 (file)
index 0000000..9cfa231
Binary files /dev/null and b/helm/uwobo/ant/jaxp.jar differ
diff --git a/helm/uwobo/ant/parser.jar b/helm/uwobo/ant/parser.jar
new file mode 100644 (file)
index 0000000..eb85832
Binary files /dev/null and b/helm/uwobo/ant/parser.jar differ
diff --git a/helm/uwobo/antRun b/helm/uwobo/antRun
new file mode 100755 (executable)
index 0000000..5894f44
--- /dev/null
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+if [ "$JAVA_HOME" != "" ] ; then
+       $JAVA_HOME/bin/java -cp ant/ant.jar:ant/jaxp.jar:ant/parser.jar:$JAVA_HOME/lib/tools.jar -Dant.home=. $ANT_OPTS org.apache.tools.ant.Main $@
+else
+       echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
diff --git a/helm/uwobo/antRun.bat b/helm/uwobo/antRun.bat
new file mode 100644 (file)
index 0000000..e83ce36
--- /dev/null
@@ -0,0 +1,17 @@
+@echo off
+set ANT_CMD_LINE_ARGS=
+
+:setupArgs
+if %1a==a goto checkJavaHome
+set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
+shift
+goto setupArgs
+
+:checkJavaHome
+if not "%JAVA_HOME%" == "" goto runAnt
+echo Warning: JAVA_HOME environment variable is not set.
+
+:runAnt
+java -cp ant\ant.jar;ant\jaxp.jar;ant\parser.jar;%JAVA_HOME%\lib\tools.jar -Dant.home=.\ org.apache.tools.ant.Main %ANT_CMD_LINE_ARGS%
+
+set ANT_CMD_LINE_ARGS=
diff --git a/helm/uwobo/build.xml b/helm/uwobo/build.xml
new file mode 100644 (file)
index 0000000..c021b0b
--- /dev/null
@@ -0,0 +1,176 @@
+<?xml version="1.0"?>
+
+<project name="uwobo" default="build" basedir=".">
+
+       <property name="Name" value="Uwobo"/>
+       <property name="name" value="uwobo"/>
+       <property name="version" value="1.1.12"/>
+
+       <property file=".${name}.properties" />
+       <property file="${user.home}/.${name}.properties" />
+
+       <property name="packages" value="it.unibo.cs.helm.uwobo.*" />
+
+       <property name="helm.home" value="." />
+       <property name="src.dir" value="src" />
+       <property name="docs.dir" value="docs" />
+       <property name="lib.dir" value="lib" />
+       <property name="build.dir" value="build" />
+       <property name="dist.dir" value="dist" />
+       <property name="deploy.dir" value="deploy/webapps/helm"/>
+       <property name="tomcat.dir" value="/projects/helm/shared/libraries/tomcat/"/>
+       <property file=".${name}.properties" />
+       <property file="${user.home}/.${name}.properties" />
+
+       <path id="compile.classpath">
+               <fileset dir="${lib.dir}">
+                       <include name="*.jar"/>
+                       <include name="*.zip"/>
+                       <exclude name="${name}*.jar"/>
+               </fileset>
+               <pathelement location="${build.dir}"/>
+       </path>
+
+       <path id="runtime_server.classpath">
+               <fileset dir="${lib.dir}">
+                       <include name="*.jar"/>
+                       <include name="*.zip"/>
+                       <exclude name="${name}_client.jar"/>
+               </fileset>
+       </path>
+
+       <path id="runtime_client.classpath">
+               <fileset dir="${lib.dir}">
+                       <include name="*.jar"/>
+                       <include name="*.zip"/>
+                       <exclude name="${name}_server.jar"/>
+               </fileset>
+       </path>
+
+       <target name="prepare">
+               <mkdir dir="${build.dir}" />
+               <tstamp />
+       </target>
+
+       <target name="compile" depends="prepare">
+               <javac srcdir="${src.dir}" destdir="${build.dir}" debug="on" deprecation="off" >
+                       <include name="**/*.java" />
+                       <classpath refid="compile.classpath"/>
+               </javac>
+
+               <filter token="PACKAGE" value="${Name}" />
+               <filter token="VERSION" value="${version}" />
+               <filter token="DATE" value="${TODAY}" />
+               <filter token="TIME" value="${TSTAMP}" />
+               <copy todir="${build.dir}" overwrite="true" filtering="on">
+                       <fileset dir="${src.dir}">
+                               <include name="**/properties.txt" />
+                       </fileset>
+               </copy>
+       </target>
+
+       <target name="build" depends="compile">
+               <war warfile="${lib.dir}/helm.war" webxml="web.xml">
+                       <lib dir="${lib.dir}">
+                               <exclude name="servlet.jar"/>
+                               <exclude name="${name}*.jar"/>
+                               <exclude name="*.war"/>
+                       </lib>
+                       <classes dir="${build.dir}"/>
+               </war>
+       </target>
+
+       <target name="install" depends="build">
+               <delete dir="${tomcat.dir}/webapps/helm" />
+               <copy todir="${tomcat.dir}/webapps" file="${lib.dir}/helm.war" />
+       </target>
+
+       <target name="compile_final" depends="clean, prepare">
+               <javac srcdir="${src.dir}" destdir="${build.dir}" debug="off" deprecation="on" optimize="on">
+                       <include name="**/*.java" />
+                       <classpath refid="compile.classpath"/>
+               </javac>
+
+               <filter token="PACKAGE" value="${Name}" />
+               <filter token="VERSION" value="${version}" />
+               <filter token="DATE" value="${TODAY}" />
+               <filter token="TIME" value="${TSTAMP}" />
+               <copy todir="${build.dir}" overwrite="true" filtering="on">
+                       <fileset dir="${src.dir}">
+                               <include name="**/properties.txt" />
+                       </fileset>
+               </copy>
+       </target>
+
+       <target name="build_final" depends="compile_final">
+               <war warfile="${lib.dir}/helm.war" webxml="web.xml">
+                       <lib dir="${lib.dir}">
+                               <exclude name="servlet.jar"/>
+                               <exclude name="${name}*.jar"/>
+                               <exclude name="*.war"/>
+                       </lib>
+                       <classes dir="${build.dir}"/>
+               </war>
+       </target>
+
+       <target name="dist" depends="build_final">
+               <mkdir dir="${dist.dir}" />
+               <mkdir dir="${dist.dir}/ant" />
+               <chmod file="${dist.dir}/ant" perm="ugo+x" type="dir"/>
+               <mkdir dir="${dist.dir}/lib" />
+               <chmod file="${dist.dir}/lib" perm="ugo+x" type="dir"/>
+               <mkdir dir="${dist.dir}/docs" />
+               <chmod file="${dist.dir}/docs" perm="ugo+x" type="dir"/>
+               <mkdir dir="${dist.dir}/resources" />
+               <chmod file="${dist.dir}/resources" perm="ugo+x" type="dir"/>
+               <mkdir dir="${dist.dir}/src" />
+               <chmod file="${dist.dir}/src" perm="ugo+x" type="dir"/>
+
+               <copy todir="${dist.dir}/ant" >
+                       <fileset dir="ant" />
+               </copy>
+               <copy todir="${dist.dir}/lib" >
+                       <fileset dir="${lib.dir}" />
+               </copy>
+               <copy todir="${dist.dir}/docs" >
+                       <fileset dir="${docs.dir}" />
+               </copy>
+               <copy todir="${dist.dir}/resources" >
+                       <fileset dir="resources" />
+               </copy>
+               <copy todir="${dist.dir}/src" >
+                       <fileset dir="${src.dir}" />
+               </copy>
+
+               <copy todir="${dist.dir}" file="antRun" />
+               <chmod file="${dist.dir}/antRun" perm="ugo+rx"/>
+               <copy todir="${dist.dir}" file="antRun.bat" />
+               <copy todir="${dist.dir}" file="build.xml" />
+               <copy todir="${dist.dir}" file="web.xml" />
+       </target>
+
+       <target name="dist-zip" depends="dist">
+               <zip zipfile="backup/${Name}-${version}.zip" basedir="${dist.dir}" includes="**" />
+       </target>
+
+       <target name="dist-unzip">
+               <unzip src="backup/${Name}.zip" dest="."/>
+       </target>
+
+       <target name="dist-tgz" depends="dist">
+               <move todir="${name}">
+                       <fileset dir="${dist.dir}"/>
+               </move>
+               <tar tarfile="backup/${Name}-${version}.tar" basedir="." includes="${name}/**"/>
+               <move todir="${dist.dir}">
+                       <fileset dir="${name}"/>
+               </move>
+               <gzip zipfile="backup/${Name}-${version}.tar.gz" src="backup/${Name}-${version}.tar"/>
+       </target>
+
+       <target name="clean">
+               <delete dir="${build.dir}" />    
+               <delete dir="${dist.dir}" />    
+       </target>
+</project>
diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/Key.java b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Key.java
new file mode 100644 (file)
index 0000000..22df4a4
--- /dev/null
@@ -0,0 +1,9 @@
+package it.unibo.cs.helm.uwobo;
+
+import java.util.*;
+
+public class Key {
+        public String  name;
+        public HashMap params;
+};
+
diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Server.java
new file mode 100644 (file)
index 0000000..da11a07
--- /dev/null
@@ -0,0 +1,301 @@
+package it.unibo.cs.helm.uwobo;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import javax.xml.transform.*;
+import javax.xml.transform.sax.*;
+import javax.xml.transform.stream.*;
+import org.apache.xalan.serialize.*;
+import org.apache.xalan.xslt.*;
+import org.apache.xalan.templates.*;
+import org.apache.xalan.transformer.*;
+import org.apache.xerces.parsers.*;
+import org.xml.sax.*;
+import org.xml.sax.ext.*;
+import org.xml.sax.helpers.*;
+
+/**
+// This file is part of UWOBO, a small and simple XSLT server.
+// 
+// UWOBO is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// UWOBO is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with UWOBO; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// 
+// For details, send a mail to <luca.padovani@cs.unibo.it>
+* @author Luca Padovani, Riccardo Solmi
+*/
+
+public class Server {
+       private static class Style {
+               public String fileName;
+               public long lastModified;
+               public Templates stylesheet;
+       };
+
+       public static final String SERVERNAME = "uwobo-XSLT-server";
+       public static final String PACKAGE;
+       public static final String VERSION;
+       public static final String DATE;
+       public static final String TIME;
+
+       static {
+               Properties props = new Properties();
+               try {
+                       InputStream in = Server.class.getResourceAsStream("properties.txt");
+                       props.load(in);
+                       in.close();
+               } catch (IOException ioe) {
+                       System.err.println("Could not load the version information.");
+               }
+
+               PACKAGE = props.getProperty("PACKAGE");
+               VERSION = props.getProperty("VERSION");
+               DATE = props.getProperty("DATE");
+               TIME = props.getProperty("TIME");
+       }
+
+       private final HashMap hashMap = new HashMap();
+       private static int logCounter = 0;
+       
+       private final Templates compileStylesheet(String xsl_file) throws TransformerConfigurationException, SAXException, IOException {
+               StreamSource streamsource =
+                       new StreamSource(new URL(xsl_file).openStream());
+               streamsource.setSystemId(xsl_file);
+               return ((SAXTransformerFactory)TransformerFactory.newInstance())
+                       .newTemplates(streamsource);
+       }
+
+       private String getContentType(Templates templates) {
+               final Properties oprops = templates.getOutputProperties();
+               final String encoding = oprops.getProperty(OutputKeys.ENCODING);  
+               final String media = oprops.getProperty(OutputKeys.MEDIA_TYPE);
+
+               if (media != null) {
+                       if (encoding != null)
+                               return media + "; charset=" + encoding;
+                       return media;
+               } else {
+                       final String method = oprops.getProperty(OutputKeys.METHOD);
+                       if (method.equals("html"))
+                               return "text/html";
+                       else if (method.equals("text"))
+                               return "text/plain";
+                       else 
+                               return "text/xml";
+               }
+       }
+
+       private final ContentHandler applyStylesheet(Templates stylesheet, HashMap params, ContentHandler saxOutput)
+       throws TransformerConfigurationException, SAXException
+       {
+               TransformerHandler th = ((SAXTransformerFactory)TransformerFactory.newInstance()).newTransformerHandler(stylesheet);
+
+               th.setResult(new SAXResult(saxOutput));
+
+               if (params != null) {
+                       final Transformer transformer = th.getTransformer();
+                       Iterator i = params.keySet().iterator();
+                       while (i.hasNext()) {
+                               final String name = (String) i.next();
+                               final String value = (String) params.get(name);
+                               transformer.setParameter(name, value);
+                       }
+               }
+
+               return th;
+       }
+
+       private final void parseFile(String datasheet, ContentHandler saxOutput) throws SAXException, IOException, Exception {
+               final XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+               reader.setFeature("http://xml.org/sax/features/namespaces", true);
+               reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+               reader.setContentHandler(saxOutput);
+               if (saxOutput instanceof LexicalHandler)
+                       reader.setProperty("http://xml.org/sax/properties/lexical-handler", (LexicalHandler)saxOutput);
+               reader.parse(datasheet);
+       }
+
+       private final ContentHandler saveFile(OutputStream outputStream, Properties props) throws IOException {
+               final Serializer ser = SerializerFactory.getSerializer(props);
+               ser.setOutputStream(outputStream);
+               return ser.asContentHandler();
+       }
+
+       public static void log(String msg) {
+               System.err.println(SERVERNAME + "[" + logCounter++ + "]: " + msg);
+       }
+
+       public void add(String filename, String key) throws TransformerConfigurationException, SAXException, IOException {
+               if (hashMap.containsKey(key)) {
+                       log("there is already a stylesheet with keyword \"" + key + "\" (aborted)");
+                       return;
+               }
+
+               Style style = new Style();
+               style.fileName = filename;
+               style.lastModified = new File(filename).lastModified();
+               log("processing stylesheet \"" + filename + "\"... ");
+               style.stylesheet = compileStylesheet(filename);
+               log("done!");
+
+               hashMap.put(key, style);
+       }
+
+       public void removeAll() throws TransformerConfigurationException, SAXException, IOException {
+               String key;
+               Style style;
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext()) {
+                       key = (String)i.next();
+                       style = (Style)hashMap.get(key);
+                       log("removing \"" + key + " (" + style.fileName + ")");
+               }
+               hashMap.clear();
+       }
+
+       public void remove(String key) {
+               Style style = (Style)hashMap.get(key);
+               if (style != null) {
+                       log("removing \"" + key + " (" + style.fileName + ")");
+                       hashMap.remove(key);
+               } else {
+                       log("error, stylesheet \"" + key + "\" not loaded");
+               }
+       }
+
+       public String getContentType(String key) {
+               Style style = (Style)hashMap.get(key);
+               if (style != null) {
+                       return getContentType(style.stylesheet);
+               } else {
+                       log("error, stylesheet \"" + key + "\" not loaded");
+                       return null;
+               }
+       }
+
+       public List list() {
+               log("listing stylesheets...");
+               ArrayList l = new ArrayList();
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext()) {
+                       String key  = (String)i.next();
+                       Style style = (Style)hashMap.get(key);
+                       l.add("  " + key + " (" + style.fileName + "; " + getContentType(style.stylesheet) + ")");
+                       System.out.println("  " + key + " (" + style.fileName + ")");
+               }
+               log("done!");
+               return l;
+       }
+
+       private ContentHandler applyRec(final Key[] keys, int idx, final ContentHandler saxOutput)
+       throws TransformerConfigurationException, SAXException, IOException
+       {
+               if (idx < 0)
+                       return saxOutput;
+               else {
+                       final Style style = (Style) hashMap.get(keys[idx].name);
+                       if (style == null) {
+                               log("cannot apply unknwon stylesheet \"" + keys[idx].name + "\" (aborted)");
+                               return null;
+                       }
+                       return applyStylesheet(style.stylesheet, keys[idx].params, applyRec(keys, idx - 1, saxOutput));
+               }
+       }
+
+       public void apply(String inFile, OutputStream outputStream, Key[] keys, Properties userProperties)
+       throws FileNotFoundException, IOException, TransformerConfigurationException, SAXException, Exception
+       {
+/*             File outFile = new File(outFilename);
+               if (outFile.exists())
+                       System.out.println("Using cached version\n");
+               else {
+*/                     
+                       final Key[] rkeys = new Key[keys.length];
+                       for (int i = 0; i < keys.length; i++)
+                               rkeys[i] = keys[keys.length - i - 1];
+
+                       Properties outputProperties; 
+                       Properties defaultProperties;
+                       String method;
+
+                       if (keys.length > 0) {
+                               Style style = (Style) hashMap.get(rkeys[0].name);
+                               if (style == null) {
+                                       log("error, stylesheet \"" + rkeys[0].name + "\" not loaded");
+                                       return;
+                               }
+                               outputProperties = style.stylesheet.getOutputProperties();
+                               method = userProperties.getProperty("method");
+                               if (method == null) method = outputProperties.getProperty("method");
+                               if (method == null) method = "xml";
+                               defaultProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
+                       } else {
+                               method = userProperties.getProperty("method");
+                               if (method == null) method = "xml";
+                               outputProperties = org.apache.xalan.templates.OutputProperties.getDefaultMethodProperties(method);
+                               defaultProperties = outputProperties;
+                       }
+
+                       for (Enumeration e = userProperties.propertyNames(); e.hasMoreElements(); ) {
+                               String prop = (String) e.nextElement();
+                               String value = userProperties.getProperty(prop);
+                               if (value.equals("")) {
+                                       String defaultValue = defaultProperties.getProperty(prop);
+                                       if (defaultValue != null)
+                                               outputProperties.setProperty(prop, defaultProperties.getProperty(prop));
+                                       else
+                                               outputProperties.remove(prop);
+                               } else {
+                                       outputProperties.setProperty(prop, value);
+                               }
+                       }
+                       
+                       parseFile(inFile, applyRec(rkeys, rkeys.length - 1, saveFile(outputStream, outputProperties)));
+//             }
+       }
+
+       public void reloadAll() throws TransformerConfigurationException, SAXException, IOException {
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext())
+                       reload((String)i.next());
+       }
+
+       public void reload(String key) throws TransformerConfigurationException, SAXException, IOException {
+               Style style = (Style)hashMap.get(key);
+
+               log("reloading \"" + key + "\"... ");
+               style.stylesheet = compileStylesheet(style.fileName);
+               style.lastModified = new File(style.fileName).lastModified();
+               log("done!");
+       }
+
+       public void updateAll() throws TransformerConfigurationException, SAXException, IOException {
+               Iterator i = hashMap.keySet().iterator();
+               while (i.hasNext())
+                       update((String)i.next());
+       }
+
+       public void update(String key) throws TransformerConfigurationException, SAXException, IOException {
+               Style style = (Style)hashMap.get(key);
+
+               log("updating \"" + key + "\"... ");
+               File styleFile = new File(style.fileName);
+               if (styleFile.lastModified() > style.lastModified) {
+                       style.stylesheet = compileStylesheet(style.fileName);
+                       style.lastModified = styleFile.lastModified();
+                       log("done!");
+               } else
+                       log("\"" + key + "\" is up to date");
+       }
+}
diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/Servlet.java b/helm/uwobo/src/it/unibo/cs/helm/uwobo/Servlet.java
new file mode 100644 (file)
index 0000000..0e28877
--- /dev/null
@@ -0,0 +1,247 @@
+package it.unibo.cs.helm.uwobo;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import javax.xml.transform.*;
+import org.xml.sax.*;
+
+/*
+*
+* usage:
+*   http://aristotele/helm/servlet/uwobo/help
+*   http://aristotele/helm/servlet/uwobo/add?xsluri=&key=
+*   http://aristotele/helm/servlet/uwobo/remove[?key=]
+*   http://aristotele/helm/servlet/uwobo/list
+*   http://aristotele/helm/servlet/uwobo/reload[?key=]
+*   http://aristotele/helm/servlet/uwobo/update[?key=]
+*   http://aristotele/helm/servlet/uwobo/apply?xmluri=&keys=[&param.=]*
+*
+* example:
+*   http://aristotele/helm/servlet/uwobo/add?xsluri=file:///D:/Archivio/Progetti/helm/resources/xsl/foo1.xsl&key=foo1
+*   http://aristotele/helm/servlet/uwobo/add?xsluri=file:///D:/Archivio/Progetti/helm/resources/xsl/foo2.xsl&key=foo2
+*   http://aristotele/helm/servlet/uwobo/apply?xmluri=file:///D:/Archivio/Progetti/helm/resources/xsl/foo.xml&key=foo1&key=foo2
+*
+* installation notes (Tomcat):
+*      replace parser.jar and jaxp.jar from /lib with xerces.jar
+*
+*      add in conf/server.xml
+*              <Context path="/helm" 
+*                      docBase="webapps/helm" 
+*                      crossContext="false"
+*                      debug="0" 
+*                      reloadable="true" > 
+*              </Context>
+*
+*      add in uriworkermap.properties
+*              /helm/*=ajp12
+*
+* bugs:
+*      directory base stylesheet inclusi
+*
+* @author Riccardo Solmi
+*/
+public class Servlet extends HttpServlet {
+       public static final String[] usage = {
+               "http://<i>hostname</i>/helm/servlet/uwobo/help",
+               "http://<i>hostname</i>/helm/servlet/uwobo/add?xsluri=<i>stylesheet</i>&key=<i>name</i>",
+               "http://<i>hostname</i>/helm/servlet/uwobo/remove[?key=<i>name</i>]",
+               "http://<i>hostname</i>/helm/servlet/uwobo/list",
+               "http://<i>hostname</i>/helm/servlet/uwobo/reload[?key=<i>name</i>]",
+               "http://<i>hostname</i>/helm/servlet/uwobo/update[?key=<i>name</i>]",
+               "http://<i>hostname</i>/helm/servlet/uwobo/apply?xmluri=<i>xmldata</i>&keys=<i>key_1,...,key_n</i>[&param.<i>name</i>=<i>value</i>]*"
+       };
+       public static final String help;
+       
+       static {
+               StringBuffer sb = new StringBuffer();
+               sb.append("<ul>");
+               for (int i=0; i<usage.length; i++)
+                       sb.append("<li>").append(usage[i]).append("</li>");
+               sb.append("</ul>");
+               help = sb.toString();
+       }
+
+       private Server server;
+
+       public void init(ServletConfig config) throws ServletException
+       {
+               super.init(config);
+
+               System.out.println("UWOBO init");
+               server = new Server();
+       }
+
+       public static String[] split(final String s, final String delim)
+       {
+               StringTokenizer st = new StringTokenizer(s, delim);
+               String[] res = new String[st.countTokens()];
+               for (int i = 0; i < res.length; i++) res[i] = st.nextToken();
+               return res;
+       }
+       
+       public void doGet(HttpServletRequest request, HttpServletResponse response)
+       throws ServletException, IOException
+       {
+               System.out.println("UWOBO "+request.getPathInfo());
+               ServletOutputStream out;
+
+               try {
+                       final String cmd = request.getPathInfo();
+                       if (cmd == null) {
+                               sendError(response, HttpServletResponse.SC_NOT_FOUND, "unknown command", help);
+                               return;
+                       }
+                       if (cmd.equals("/add")) {
+                               final String filename = request.getParameter("xsluri");
+                               if (filename == null) {
+                                       sendError(response, HttpServletResponse.SC_BAD_REQUEST, "bad parameters", usage[1]);
+                                       return;
+                               }
+                               final String key = request.getParameter("key");
+                               server.add(filename, key);
+                       } else if (cmd.equals("/apply")) {
+                               final String infile = request.getParameter("xmluri");
+                               final String keys = request.getParameter("keys");
+
+                               if (infile == null || keys == null) {
+                                       sendError(response, HttpServletResponse.SC_BAD_REQUEST, "bad parameters", usage[6]);
+                                       return;
+                               }
+
+                               final String[] keyName = split(keys, ",");
+                               final Key[] keySeq = new Key[keyName.length];
+                               for (int i = 0; i < keySeq.length; i++) {
+                                       keySeq[i] = new Key();
+                                       keySeq[i].name = keyName[i];
+                                       keySeq[i].params = new HashMap();
+                               }
+
+                               final Properties props = new Properties();
+                               final Enumeration e = request.getParameterNames();
+                               while (e.hasMoreElements()) {
+                                       String param = (String) e.nextElement();
+                                       if (param.startsWith("param.")) {
+                                               final String name = param.substring(6);
+                                               final String value = request.getParameter(param);
+                                               final String[] keyParam = split(name, ".");
+                                               if (keyParam.length == 1) {
+                                                       // this is a global parameter
+                                                       Server.log("global parameter: " + keyParam[0] + " = " + value);
+                                                       for (int i = 0; i < keySeq.length; i++)
+                                                               // we add the global parameter only if there is no
+                                                               // local parameter with the same name
+                                                               if (!keySeq[i].params.containsKey(keyParam[0]))
+                                                                       keySeq[i].params.put(keyParam[0], value);
+                                               } else if (keyParam.length == 2) {
+                                                       // this is a local parameter
+                                                       Server.log("local parameter: " + keyParam[0] + "." + keyParam[1] + " = " + value);
+                                                       for (int i = 0; i < keySeq.length; i++) {
+                                                               if (keySeq[i].name.equals(keyParam[0]))
+                                                                       keySeq[i].params.put(keyParam[1], value);
+                                                       }
+                                               } else {
+                                                       sendError(response, HttpServletResponse.SC_BAD_REQUEST, "bad parameters", usage[6]);
+                                                       return;
+                                               }
+                                       } else if (param.startsWith("prop.")) {
+                                               final String name = param.substring(5);
+                                               final String value = request.getParameter(param);
+                                               Server.log("property: " + name + " = " + value);
+                                               props.setProperty(name, value);
+                                       }
+                               }
+                                       
+                               String contentType = props.getProperty(OutputKeys.MEDIA_TYPE);
+                               if (contentType == null && keySeq.length > 0) 
+                                       contentType = server.getContentType(keySeq[keySeq.length - 1].name);
+                               else if (contentType == null)
+                                       contentType = "text/xml";
+                               response.setContentType(contentType);
+                               Server.log("content type: " + contentType);
+
+                               out = response.getOutputStream();
+                               server.apply(infile, out, keySeq, props);
+                               out.close();
+                               return;
+                       } else if (cmd.equals("/remove")) {
+                               final String key = request.getParameter("key");
+                               if (key == null)
+                                       server.removeAll();
+                               else
+                                       server.remove(key);
+                       } else if (cmd.equals("/list")) {
+                               Iterator i = server.list().iterator();
+
+                               response.setContentType("text/html");
+                               out = response.getOutputStream();
+                               out.println("<html><body><h1>Uwobo servlet</h1><p>stylesheet list:</p><ul>");
+                               while (i.hasNext())
+                                       out.println("<li>"+i.next()+"</li>");
+                               out.println("</ul></body></html>");
+                               out.close();
+                               return;
+                       } else if (cmd.equals("/reload")) {
+                               final String key = request.getParameter("key");
+                               if (key == null)
+                                       server.reloadAll();
+                               else
+                                       server.reload(key);
+                       } else if (cmd.equals("/update")) {
+                               final String key = request.getParameter("key");
+                               if (key == null)
+                                       server.updateAll();
+                               else
+                                       server.update(key);
+                       } else if (cmd.equals("/help")) {
+                               response.setContentType("text/html");
+                               out = response.getOutputStream();
+                               out.println("<html><body><h1>"+server.PACKAGE+" servlet - version "+server.VERSION+"</h1>");
+                               out.println("<b>compiled "+server.DATE+" at "+server.TIME.substring(0,2)+":"+server.TIME.substring(2)+"</b>");
+                               out.println("<p>usage:</p>"+help+"</body></html>");
+                               out.close();
+                               return;
+                       } else {
+                               sendError(response, HttpServletResponse.SC_NOT_FOUND, "unknown command", help);
+                               return;
+                       }       
+               } catch (TransformerConfigurationException tce) {
+                       sendError(response, HttpServletResponse.SC_BAD_REQUEST, "stylesheet error", tce);
+                       return;
+               } catch (SAXException se) {
+                       sendError(response, HttpServletResponse.SC_BAD_REQUEST, "SAX Exception", se);
+                       return;
+               } catch (Exception e) {
+                       sendError(response, HttpServletResponse.SC_BAD_REQUEST, "exception", e);
+                       return;
+               }
+
+               response.setContentType("text/html");
+               response.setHeader("Cache-Control", "no-cache");
+               response.setHeader("Pragma", "no-cache");
+               response.setHeader("Expires", "0");
+               out = response.getOutputStream();
+               out.println("<html><body><h1>Uwobo servlet</h1><p>done</p></body></html>");
+               out.close();
+       }
+
+       private void sendError(HttpServletResponse response, int code, String msg, Exception e) throws IOException {
+               String err;
+               if (e != null)
+                       err = "<p>"+e.getMessage()+"</P>";
+               else
+                       err = "";
+               response.setContentType("text/html");
+               response.sendError(code, "<html><body><h1>Uwobo servlet</h1><p>"+msg+"</p>"+err+"</body></html>");
+       }
+       
+       private void sendError(HttpServletResponse response, int code, String msg, String usage) throws IOException {
+               response.setContentType("text/html");
+               response.sendError(code, "<html><body><h1>Uwobo servlet</h1><p>"+msg+"</p>usage: "+usage+"</body></html>");
+       }
+       
+       public String getServletInfo() {
+               return "The UWOBO servlet";
+       }
+}
diff --git a/helm/uwobo/src/it/unibo/cs/helm/uwobo/properties.txt b/helm/uwobo/src/it/unibo/cs/helm/uwobo/properties.txt
new file mode 100644 (file)
index 0000000..eb28611
--- /dev/null
@@ -0,0 +1,4 @@
+PACKAGE=@PACKAGE@
+VERSION=@VERSION@
+DATE=@DATE@
+TIME=@TIME@
diff --git a/helm/uwobo/web.xml b/helm/uwobo/web.xml
new file mode 100644 (file)
index 0000000..badb809
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE web-app 
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" 
+    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
+
+<web-app>
+
+    <display-name>Uwobo Application</display-name>
+    <description>
+       This is an xslt web application
+    </description>
+
+    <servlet>
+        <servlet-name>uwobo</servlet-name>
+        <servlet-class>it.unibo.cs.helm.uwobo.Servlet</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>uwobo</servlet-name>
+        <url-pattern>/helm/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>