]> matita.cs.unibo.it Git - helm.git/commitdiff
* this is a large commit
authorLuca Padovani <luca.padovani@unito.it>
Sat, 8 Feb 2003 22:13:29 +0000 (22:13 +0000)
committerLuca Padovani <luca.padovani@unito.it>
Sat, 8 Feb 2003 22:13:29 +0000 (22:13 +0000)
* added freeze/thaw methods to parser
* added XSLT + Diff class
* added <include> method for including dictionaries
* added preliminary ocaml binding (C+ML)
* code cleanup

47 files changed:
helm/DEVEL/mathml_editor/AUTHORS
helm/DEVEL/mathml_editor/BUGS-GDOME2
helm/DEVEL/mathml_editor/Makefile.am
helm/DEVEL/mathml_editor/Makefile.in
helm/DEVEL/mathml_editor/configure.ac
helm/DEVEL/mathml_editor/dictionary-basic.xml [new file with mode: 0644]
helm/DEVEL/mathml_editor/dictionary-test.xml [new file with mode: 0644]
helm/DEVEL/mathml_editor/dictionary-tex.xml [new file with mode: 0644]
helm/DEVEL/mathml_editor/dictionary.dtd
helm/DEVEL/mathml_editor/dictionary.xml [deleted file]
helm/DEVEL/mathml_editor/ocaml/Makefile.am [new file with mode: 0644]
helm/DEVEL/mathml_editor/ocaml/c_mathml_editor.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/ocaml/c_mathml_editor.h [new file with mode: 0644]
helm/DEVEL/mathml_editor/ocaml/i_mathml_editor.ml [new file with mode: 0644]
helm/DEVEL/mathml_editor/ocaml/mathml_editor.ml [new file with mode: 0644]
helm/DEVEL/mathml_editor/ocaml/ml_mathml_editor.c [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/AMathMLFactory.hh
helm/DEVEL/mathml_editor/src/APushLexer.hh
helm/DEVEL/mathml_editor/src/APushParser.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/APushParser.hh
helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLT.cc
helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLT.hh
helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLTDiff.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLTDiff.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/Diff.cc [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/Diff.hh [new file with mode: 0644]
helm/DEVEL/mathml_editor/src/Makefile.am
helm/DEVEL/mathml_editor/src/Makefile.in
helm/DEVEL/mathml_editor/src/TDictionary.cc
helm/DEVEL/mathml_editor/src/TDictionary.hh
helm/DEVEL/mathml_editor/src/TDocument.cc
helm/DEVEL/mathml_editor/src/TDocument.hh
helm/DEVEL/mathml_editor/src/TNode.hh
helm/DEVEL/mathml_editor/src/TPushLexer.cc
helm/DEVEL/mathml_editor/src/TPushLexer.hh
helm/DEVEL/mathml_editor/src/TPushParser.cc
helm/DEVEL/mathml_editor/src/TPushParser.hh
helm/DEVEL/mathml_editor/src/TToken.hh
helm/DEVEL/mathml_editor/src/TTokenizer.cc
helm/DEVEL/mathml_editor/src/TTokenizer.hh
helm/DEVEL/mathml_editor/src/dom.hh
helm/DEVEL/mathml_editor/src/globals.hh
helm/DEVEL/mathml_editor/test/Makefile.in
helm/DEVEL/mathml_editor/test/aux.cc
helm/DEVEL/mathml_editor/test/editor.cc
helm/DEVEL/mathml_editor/test/guiGTK.c
helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl

index 2ba63d6cc72aea9a2119297c4a5af8891c119ef0..7cec8397e6249fd63020fb3cde9bb88f72736a38 100644 (file)
@@ -1 +1,2 @@
 Luca Padovani <lpadovan@cs.unibo.it>
+Paolo Marinelli <pmarinel@cs.unibo.it>
index 2b89215f0cb3742375a8d6795cc623891ecdfb4b..5f756359fa33cddb0cbe426635c255409a4eb5a2 100644 (file)
@@ -1,15 +1,4 @@
 
-* 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
index edd3988bb0b309f507ad2890bc43739b7a9d314c..8f4639ebf4c1698c1be23202292e62ab03888352 100644 (file)
@@ -1,5 +1,5 @@
 #EXTRA_DIST = BUGS HISTORY LICENSE aclocal.m4 debian/
-SUBDIRS = src test
+SUBDIRS = src test ocaml
 CLEANFILES = core
 
 bin_SCRIPTS = editex-config
index f68e1f659d8ec8c20f8f2c2dd9f5fa0e5f90f092..fdf08ab3e71ee626f82b0525479cf4ea16804fdf 100644 (file)
@@ -76,18 +76,32 @@ GMETADOM_CFLAGS = @GMETADOM_CFLAGS@
 GMETADOM_LIBS = @GMETADOM_LIBS@
 GTKMATHVIEW_CFLAGS = @GTKMATHVIEW_CFLAGS@
 GTKMATHVIEW_LIBS = @GTKMATHVIEW_LIBS@
+HAVE_OCAMLC = @HAVE_OCAMLC@
+HAVE_OCAMLDEP = @HAVE_OCAMLDEP@
+HAVE_OCAMLFIND = @HAVE_OCAMLFIND@
+HAVE_OCAMLMKLIB = @HAVE_OCAMLMKLIB@
+HAVE_OCAMLOPT = @HAVE_OCAMLOPT@
 LDFLAGS = @LDFLAGS@
 LIBTOOL = @LIBTOOL@
 LN_S = @LN_S@
 MAKEINFO = @MAKEINFO@
+MLGDOME_CFLAGS = @MLGDOME_CFLAGS@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
+OCAMLC = @OCAMLC@
+OCAMLDEP = @OCAMLDEP@
+OCAMLFIND = @OCAMLFIND@
+OCAMLMKLIB = @OCAMLMKLIB@
+OCAMLOPT = @OCAMLOPT@
+OCAMLSTDLIBDIR = @OCAMLSTDLIBDIR@
+OCAMLSTUBDIR = @OCAMLSTUBDIR@
+OCAML_INCLUDE_DIR = @OCAML_INCLUDE_DIR@
 PACKAGE = @PACKAGE@
 RANLIB = @RANLIB@
 STRIP = @STRIP@
 VERSION = @VERSION@
 
-SUBDIRS = src test
+SUBDIRS = src test ocaml
 CLEANFILES = core
 
 bin_SCRIPTS = editex-config
index 0dca72c8cb5fec57e629218c746226b52332e5ec..dd7b07b7b58df414ad4444bee1e8d4d4c26d3099 100644 (file)
@@ -72,6 +72,11 @@ AC_PROG_CXX
 AC_PROG_INSTALL
 AC_HEADER_STDC([])
 
+AC_LANG_PUSH(C++)
+AC_CHECK_HEADERS(hash_map)
+AC_CHECK_HEADERS(ext/hash_map)
+AC_LANG_POP(C++)
+
 AC_SUBST(CFLAGS)
 AC_SUBST(CPPFLAGS)
 AC_SUBST(LDFLAGS)
@@ -110,7 +115,7 @@ AC_SUBST(GMETADOM_CFLAGS)
 AC_SUBST(GMETADOM_LIBS)
 
 GDOMEXSLT_CONFIG="gdome_xslt_cpp_smart-config"
-GDOMEXSLT_MIN_VERSION=0.0.1
+GDOMEXSLT_MIN_VERSION=0.0.4
 AC_MSG_CHECKING([for gdome_xslt C++ library] >= $GDOMEXSLT_MIN_VERSION) 
 if test "x$GDOMEXSLT_PREFIX" != "x"
 then
@@ -171,10 +176,71 @@ fi
 AC_SUBST(GTKMATHVIEW_CFLAGS)
 AC_SUBST(GTKMATHVIEW_LIBS)
 
+AC_CHECK_PROG(HAVE_OCAMLC, ocamlc, yes, no)
+if test $HAVE_OCAMLC = "no"; then
+  AC_MSG_ERROR([could not find ocamlc in PATH, please make sure ocaml is installed])
+else
+  OCAMLC=ocamlc
+  OCAMLSTDLIBDIR="`ocamlc -where`"
+  OCAMLSTUBDIR="`ocamlc -where`/stublibs"
+  AC_SUBST(OCAMLC)
+  AC_SUBST(OCAMLSTDLIBDIR)
+  AC_SUBST(OCAMLSTUBDIR)
+fi
+
+AC_CHECK_PROG(HAVE_OCAMLOPT, ocamlopt, yes, no)
+if test $HAVE_OCAMLOPT = "no"; then
+       AC_MSG_WARN([ocaml native libraries won't be compiled since ocamlopt was not found])
+else
+  OCAMLOPT=ocamlopt
+  AC_SUBST(OCAMLOPT)
+fi
+AM_CONDITIONAL(HAVE_OCAMLOPT_COND, test x$HAVE_OCAMLOPT = xyes)
+
+AC_CHECK_PROG(HAVE_OCAMLFIND, ocamlfind, yes, no)
+if test $HAVE_OCAMLFIND = "no"; then
+  AC_MSG_ERROR([could not find ocamlfind in PATH, please make sure findlib is installed])
+else
+  OCAMLFIND=ocamlfind
+  AC_SUBST(OCAMLFIND)
+fi
+
+AC_CHECK_PROG(HAVE_OCAMLDEP, ocamldep, yes, no)
+if test $HAVE_OCAMLDEP = "yes"; then
+  OCAMLDEP=ocamldep
+  AC_SUBST(OCAMLDEP)
+fi
+
+AC_CHECK_PROG(HAVE_OCAMLMKLIB, ocamlmklib, yes, no)
+if test $HAVE_OCAMLMKLIB = "no"; then
+  AC_MSG_ERROR([could not find ocamlmklib in PATH, please make sure ocamlmklib is installed])
+else
+  OCAMLMKLIB=ocamlmklib
+  AC_SUBST(OCAMLMKLIB)
+fi
+
+AC_MSG_CHECKING(for gdome2 ocaml binding)
+ocamlfind query gdome2 ||
+  AC_MSG_ERROR(gdome2 not installed (according to findlib))
+MLGDOME_CFLAGS="`$OCAMLFIND query -i-format gdome2`"
+AC_SUBST(MLGDOME_CFLAGS)
+
+AC_MSG_CHECKING(for the ocaml library dir)
+OCAML_LIB_DIR=`ocamlc -where`
+AC_MSG_RESULT($OCAML_LIB_DIR)
+
+AC_CHECK_FILE(/usr/include/caml/mlvalues.h,
+       OCAML_INCLUDE_DIR=/usr/include/caml,
+       OCAML_INCLUDE_DIR=$OCAML_LIB_DIR/caml
+)
+
+AC_SUBST(OCAML_INCLUDE_DIR)
+
 AC_CONFIG_FILES([
  Makefile 
  src/Makefile
  test/Makefile
+ ocaml/Makefile
  editex-config
 ])
 AC_CONFIG_COMMANDS([default],[[chmod +x editex-config]],[[]])
diff --git a/helm/DEVEL/mathml_editor/dictionary-basic.xml b/helm/DEVEL/mathml_editor/dictionary-basic.xml
new file mode 100644 (file)
index 0000000..ed2e264
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+
+<dictionary name="TeX">
+
+  <!-- MACRO for testing  -->
+  <entry name="cursor"     pattern=""/>
+  <entry name="error"      pattern="#1"/>
+
+</dictionary>
diff --git a/helm/DEVEL/mathml_editor/dictionary-test.xml b/helm/DEVEL/mathml_editor/dictionary-test.xml
new file mode 100644 (file)
index 0000000..a9f3c0c
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+
+<dictionary name="TeX">
+
+  <include href="dictionary-tex.xml"/>
+
+  <!-- MACRO for testing  -->
+  <entry name="red"        pattern="{"/>
+  <entry name="green"      pattern="#1\over"/>
+  <entry name="duedelim"   pattern="#1\over\over#2"/>
+
+</dictionary>
diff --git a/helm/DEVEL/mathml_editor/dictionary-tex.xml b/helm/DEVEL/mathml_editor/dictionary-tex.xml
new file mode 100644 (file)
index 0000000..6bb3c5e
--- /dev/null
@@ -0,0 +1,357 @@
+<?xml version="1.0"?>
+
+<dictionary name="TeX">
+
+  <include href="dictionary-basic.xml"/>
+
+  <!-- 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"/>
+
+  <!-- MACRO for testing  -->
+  <entry name="red"        pattern="{"/>
+  <entry name="green"      pattern="#1\over"/>
+  <entry name="duedelim"   pattern="#1\over\over#2"/>
+
+</dictionary>
index 4d092af2b62213eddc7199acaace7a613430ed19..3fefc71fee6dc465b861a72efb0f0662ac9c1bc0 100644 (file)
@@ -1,9 +1,12 @@
 
-<!ELEMENT dictionary (entry)*>
+<!ELEMENT dictionary ((include)*,(entry*))>
 <!ATTLIST dictionary
   name      CDATA   #REQUIRED
 >
 
+<!ELEMENT include EMPTY>
+<!ATTLIST include href CDATA>
+
 <!ELEMENT entry EMPTY>
 <!ATTLIST entry
   name      ID        #REQUIRED
diff --git a/helm/DEVEL/mathml_editor/dictionary.xml b/helm/DEVEL/mathml_editor/dictionary.xml
deleted file mode 100644 (file)
index 4c7045d..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-<?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"/>
-
-  <!-- MACRO for testing  -->
-  <entry name="red"        pattern="{"/>
-  <entry name="green"      pattern="#1\over"/>
-  <entry name="duedelim"   pattern="#1\over\over#2"/>
-
-</dictionary>
diff --git a/helm/DEVEL/mathml_editor/ocaml/Makefile.am b/helm/DEVEL/mathml_editor/ocaml/Makefile.am
new file mode 100644 (file)
index 0000000..9c1cc70
--- /dev/null
@@ -0,0 +1,86 @@
+PKGNAME = mathml-editor
+ARCHIVE = mlmathml-editor
+REQUIRES = gdome2 gdome2-xslt
+OCAMLFIND = @OCAMLFIND@
+OCAMLC = $(OCAMLFIND) @OCAMLC@ -package "$(REQUIRES)"
+OCAMLOPT = $(OCAMLFIND) @OCAMLOPT@ -package "$(REQUIRES)"
+OCAMLDEP = $(OCAMLFIND) @OCAMLDEP@ -package "$(REQUIRES)"
+OCAMLMKLIB = @OCAMLMKLIB@
+DLL = dll$(ARCHIVE).so
+OCAMLSTDLIBDIR = $(DESTDIR)/@OCAMLSTDLIBDIR@
+OCAMLSTUBDIR = $(DESTDIR)/@OCAMLSTUBDIR@
+OCAMLINSTALLDIR = $(OCAMLSTDLIBDIR)/$(PKGNAME)
+MODULES = i_mathml_editor mathml_editor
+INIT =
+CMI_S = $(MODULES:%=%.cmi)
+CMO_S = $(MODULES:%=%.cmo)
+CMX_S = $(MODULES:%=%.cmx)
+O_S = ml_mathml_editor.o
+SHARED_LIBS = $(GMETADOM_LIBS) $(GDOMEXSLT_LIBS)
+BYTE_STUFF = $(ARCHIVE).cma
+NATIVE_STUFF = $(ARCHIVE).cmxa $(ARCHIVE).a
+BYTE_INSTALL_STUFF =   \
+       i_mathml_editor.cmi mathml_editor.cmi $(ARCHIVE).cma $(DLL) META
+NATIVE_INSTALL_STUFF = $(ARCHIVE).a $(ARCHIVE).cmxa
+
+EXTRA_DIST =   \
+       META.in mathml_editor.ml i_mathml_editor.ml     \
+       ml_mathml_editor.h c_mathml_editor.h .depend
+
+if HAVE_OCAMLOPT_COND
+noinst_DATA = $(BYTE_STUFF) $(NATIVE_STUFF)
+else
+noinst_DATA = $(BYTE_STUFF)
+endif
+
+noinst_LTLIBRARIES = libmlmathml_editor.la
+libmlmathml_editor_la_SOURCES = \
+  c_mathml_editor.cc \
+  ml_mathml_editor.c
+
+#test: test.ml $(ARCHIVE).cma
+#      $(OCAMLC) -o $@ -linkpkg $(INCLUDES) $<
+
+#test.opt: test.ml $(ARCHIVE).cmxa
+#      $(OCAMLOPT) -o $@ -linkpkg $(INCLUDES) $<
+
+if HAVE_OCAMLOPT_COND
+install-data-local:    $(BYTE_INSTALL_STUFF) $(NATIVE_INSTALL_STUFF)
+else
+install-data-local:    $(BYTE_INSTALL_STUFF)
+endif
+       $(mkinstalldirs) $(OCAMLSTDLIBDIR) $(OCAMLSTUBDIR)
+       chmod -x $(DLL)
+       $(OCAMLFIND) install -destdir $(OCAMLSTDLIBDIR) $(PKGNAME) $^
+       ln -fs $(DLL) $(OCAMLSTUBDIR)/lib$(ARCHIVE).so
+
+CLEANFILES =   \
+       $(ARCHIVE).{cma,cmxa,a} $(CMI_S) $(CMO_S) $(CMX_S) ml_mathml_editor.o   \
+       $(DLL) $(INIT).cm[iox] libmlmathml_editor.a
+
+INCLUDES =     \
+       $(GDOME_CFLAGS) $(MLGDOME_CFLAGS) \
+       $(GMETADOM_CFLAGS) $(GDOMEXSLT_CFLAGS) \
+       -I$(top_srcdir)/src
+
+$(ARCHIVE).cma $(DLL): $(CMO_S)
+       $(OCAMLMKLIB) -o $(ARCHIVE) -L@OCAMLSTUBDIR@ $(CMO_S) $(O_S) $(SHARED_LIBS)
+$(ARCHIVE).cmxa $(ARCHIVE).a: $(CMX_S)
+       $(OCAMLMKLIB) -o $(ARCHIVE) -L@OCAMLSTUBDIR@ $(CMX_S) $(O_S) $(SHARED_LIBS)
+
+%.cmi: %.mli
+       $(OCAMLC) -c $<
+%.cmo %.cmi: %.ml
+       $(OCAMLC) -c $<
+%.cmx: %.ml %.cmi
+       $(OCAMLOPT) -c $<
+
+i_mathml_editor.cmo: i_mathml_editor.ml
+       $(OCAMLC) -c $<
+i_mathml_editor.cmx: i_mathml_editor.ml
+       $(OCAMLOPT) -c $<
+
+depend: *.ml *.mli
+       $(OCAMLDEP) *.ml *.mli >.depend
+include .depend
+
diff --git a/helm/DEVEL/mathml_editor/ocaml/c_mathml_editor.cc b/helm/DEVEL/mathml_editor/ocaml/c_mathml_editor.cc
new file mode 100644 (file)
index 0000000..284f1ed
--- /dev/null
@@ -0,0 +1,157 @@
+
+#include <GdomeSmartDOMXSLT.hh>
+
+#include "ALogger.hh"
+#include "TDictionary.hh"
+#include "CMathMLFactoryXSLT.hh"
+#include "TPushLexer.hh"
+#include "TPushParser.hh"
+
+class CCallbackLogger : public ALogger
+{
+public:
+  CCallbackLogger(void (*)(int, const char*, void*), void*);
+  virtual ~CCallbackLogger() { };
+
+protected:
+  virtual void message(Level, const std::string&);
+
+private:
+  void (*callback)(int, const char*, void*);
+  void* user_data;
+};
+
+CCallbackLogger::CCallbackLogger(void (*cb)(int, const char*, void*), void* data) : callback(cb), user_data(data)
+{
+  assert(callback);
+}
+
+void
+CCallbackLogger::message(Level l, const std::string& s)
+{
+  assert(callback);
+  callback(l, s.c_str(), user_data);
+}
+
+struct Editor
+{
+  Editor(const DOM::Document&, const DOM::Document&, const DOM::Document&, void (*)(int, const char*, void*), void*);
+  ~Editor();
+
+  ALogger*        logger;
+  TDictionary*    dictionary;
+  DOMX::XSLTStylesheet* tml_mml;
+  DOMX::XSLTStylesheet* tml_tex;
+  AMathMLFactory* factory;
+  TPushParser*    parser;
+  APushLexer*     lexer;
+};
+
+Editor::Editor(const DOM::Document& dict, const DOM::Document& mml, const DOM::Document& tex,
+              void (*cb)(int, const char*, void*), void* data)
+{
+  assert(cb);
+  logger = new CCallbackLogger(cb, data);
+  dictionary = new TDictionary(*logger);
+  dictionary->load(DOM::Document(dict));
+  tml_mml = new DOMX::XSLTStylesheet(mml);
+  tml_tex = new DOMX::XSLTStylesheet(tex);
+  factory = new CMathMLFactoryXSLT(*logger, *tml_mml);
+  parser = new TPushParser(*logger, *factory, *dictionary);
+  lexer = new TPushLexer(*logger, *parser);
+}
+
+Editor::~Editor()
+{
+  delete lexer;
+  delete parser;
+  delete factory;
+  delete tml_tex;
+  delete tml_mml;
+  delete dictionary;
+  delete logger;
+}
+
+extern "C" Editor*
+c_mathml_editor_new(GdomeDocument* dictionary,
+                   GdomeDocument* tml_mml,
+                   GdomeDocument* tml_tex,
+                   void (*log_message_cb)(int, const char*, void*),
+                   void* user_data)
+{
+  return new Editor(DOM::Document(dictionary),
+                   DOM::Document(tml_mml),
+                   DOM::Document(tml_tex), log_message_cb, user_data);
+}
+
+extern "C" void
+c_mathml_editor_destroy(Editor* editor)
+{
+  assert(editor);
+  delete editor;
+}
+
+extern "C" int
+c_mathml_editor_freeze(Editor* editor)
+{
+  assert(editor);
+  return editor->parser->freeze();
+}
+
+extern "C" int
+c_mathml_editor_thaw(Editor* editor)
+{
+  assert(editor);
+  return editor->parser->thaw();
+}
+
+extern "C" void
+c_mathml_editor_push(Editor* editor, char ch)
+{
+  assert(editor);
+  editor->lexer->push(ch);
+}
+
+extern "C" void
+c_mathml_editor_drop(Editor* editor, int alt)
+{
+  assert(editor);
+  editor->lexer->drop(alt != 0);
+}
+
+extern "C" char*
+c_mathml_editor_get_tex(const Editor* editor)
+{
+  assert(editor);
+  DOM::Document res = editor->tml_tex->apply(editor->parser->document());
+  DOM::Element root = res.get_documentElement();
+  return strdup(std::string(root.get_nodeValue()).c_str());
+}
+
+extern "C" void
+c_mathml_editor_reset(Editor* editor)
+{
+  assert(editor);
+  editor->parser->reset();
+}
+
+extern "C" GdomeDocument*
+c_mathml_editor_get_tml(const Editor* editor)
+{
+  assert(editor);
+  GdomeNode* n = editor->parser->document().cloneNode(true).gdome_object();
+  GdomeDocument* doc = gdome_cast_doc(n);
+  assert(n && doc);
+  return doc;
+}
+
+extern "C" GdomeDocument*
+c_mathml_editor_get_mml(const Editor* editor)
+{
+  assert(editor);
+  GdomeNode* n = editor->factory->document().gdome_object();
+  GdomeDocument* doc = gdome_cast_doc(n);
+  assert(n && doc);
+  return doc;
+}
+
diff --git a/helm/DEVEL/mathml_editor/ocaml/c_mathml_editor.h b/helm/DEVEL/mathml_editor/ocaml/c_mathml_editor.h
new file mode 100644 (file)
index 0000000..7e7c0e3
--- /dev/null
@@ -0,0 +1,20 @@
+
+#ifndef __c_mathml_editor_h__
+#define __c_mathml_editor_h__
+
+#include <gdome.h>
+
+typedef struct Editor Editor;
+
+Editor*        c_mathml_editor_new(GdomeDocument*, GdomeDocument*, GdomeDocument*, void (*)(int, const char*, void*), void*);
+void           c_mathml_editor_destroy(Editor*);
+int            c_mathml_editor_freeze(Editor*);
+int            c_mathml_editor_thaw(Editor*);
+void           c_mathml_editor_reset(Editor*);
+void           c_mathml_editor_push(Editor*, char);
+void           c_mathml_editor_drop(Editor*, int);
+char*          c_mathml_editor_get_tex(const Editor*);
+GdomeDocument* c_mathml_editor_get_tml(const Editor*);
+GdomeDocument* c_mathml_editor_get_mml(const Editor*);
+
+#endif /* __c_mathml_editor_h__ */
diff --git a/helm/DEVEL/mathml_editor/ocaml/i_mathml_editor.ml b/helm/DEVEL/mathml_editor/ocaml/i_mathml_editor.ml
new file mode 100644 (file)
index 0000000..5019fbe
--- /dev/null
@@ -0,0 +1,35 @@
+
+type t
+
+external create : 
+  dictionary:[> `Document] GdomeT.t ->
+  mml: [> `Document] GdomeT.t -> 
+  tex: [> `Document] GdomeT.t ->
+  log:(string -> unit) ->
+  t
+  = "ml_mathml_editor_new"
+
+external freeze : editor:t -> bool
+  = "ml_mathml_editor_freeze"
+
+external thaw : editor:t -> bool
+  = "ml_mathml_editor_thaw"
+
+external reset : editor:t -> unit
+  = "ml_mathml_editor_reset"
+
+external push : editor:t -> ch:char -> unit
+  = "ml_mathml_editor_push"
+
+external drop : editor:t -> alt:bool -> unit
+  = "ml_mathml_editor_drop"
+
+external get_tex : editor:t -> string
+  = "ml_mathml_editor_get_tex"
+
+external get_tml : editor:t -> TDocument.t
+  = "ml_mathml_editor_get_tml"
+
+external get_mml : editor:t -> TDocument.t
+  = "ml_mathml_editor_get_mml"
+
diff --git a/helm/DEVEL/mathml_editor/ocaml/mathml_editor.ml b/helm/DEVEL/mathml_editor/ocaml/mathml_editor.ml
new file mode 100644 (file)
index 0000000..58ca8f7
--- /dev/null
@@ -0,0 +1,31 @@
+
+let create ~dictionary ~mml ~tml ~log =
+  I_mathml_editor.create dictionary#as_Document mml#as_Document tml#as_Document log
+;;
+
+let freeze = I_mathml_editor.freeze
+;;
+
+let thaw = I_mathml_editor.thaw
+;;
+
+let reset = I_mathml_editor.reset
+;;
+
+let push = I_mathml_editor.push
+;;
+
+let drop = I_mathml_editor.drop
+;;
+
+let get_tex = I_mathml_editor.get_tex
+;;
+
+let get_tml ~editor =
+  new Gdome.document (I_mathml_editor.get_tml ~editor)
+;;
+
+let get_mml ~editor =
+  new Gdome.document (I_mathml_editor.get_mml ~editor)
+;;
+
diff --git a/helm/DEVEL/mathml_editor/ocaml/ml_mathml_editor.c b/helm/DEVEL/mathml_editor/ocaml/ml_mathml_editor.c
new file mode 100644 (file)
index 0000000..79594c2
--- /dev/null
@@ -0,0 +1,143 @@
+
+#include <caml/memory.h>
+#include <caml/custom.h>
+#include <caml/callback.h>
+
+#include "mlgdomevalue.h"
+
+#include "c_mathml_editor.h"
+
+typedef struct
+{
+  Editor* c_editor;
+  value   callback;
+} ml_Editor;
+
+ml_Editor*
+Editor_val(value v)
+{
+  ml_Editor* editor = (ml_Editor*) Data_custom_val(v);
+  assert(editor != NULL);
+  return editor;
+}
+
+static void
+ml_mathml_editor_finalize(value v)
+{
+  ml_Editor* editor = Editor_val(v);
+  assert(editor);
+
+  remove_global_root(&editor->callback);
+  c_mathml_editor_destroy(editor->c_editor);
+}
+
+void
+ml_mathml_editor_log_callback(int level, const char* msg, void* user_data)
+{
+  ml_Editor* ml_editor = (ml_Editor*) user_data;
+  assert(ml_editor);
+  callback2(ml_editor->callback, Val_int(level), copy_string(msg));
+}
+
+value
+ml_mathml_editor_new(value dictionary,
+                    value tml_mml,
+                    value tml_tex,
+                    value log_message_cb)
+{
+  static struct custom_operations ops =
+  {
+    "HELM/MathML Editor",
+    ml_mathml_editor_finalize,
+    custom_compare_default,
+    custom_hash_default,
+    custom_serialize_default,
+    custom_deserialize_default
+  };
+  
+  value v = alloc_custom(&ops, sizeof(ml_Editor), 0, 1);
+  ml_Editor* ml_editor = (ml_Editor*) Data_custom_val(v);
+  ml_editor->c_editor = c_mathml_editor_new(Document_val(dictionary),
+                                           Document_val(tml_mml),
+                                           Document_val(tml_tex),
+                                           ml_mathml_editor_log_callback,
+                                           (void*) ml_editor);
+  ml_editor->callback = log_message_cb;
+  register_global_root(&ml_editor->callback);
+
+  return v;
+}
+
+value
+ml_mathml_editor_freeze(value v)
+{
+  CAMLparam1(v);
+  ml_Editor* editor = Editor_val(v);
+  CAMLreturn(Val_bool(c_mathml_editor_freeze(editor->c_editor)));
+}
+
+value
+ml_mathml_editor_thaw(value v)
+{
+  CAMLparam1(v);
+  ml_Editor* editor = Editor_val(v);
+  CAMLreturn(Val_bool(c_mathml_editor_thaw(editor->c_editor)));
+}
+
+value
+ml_mathml_editor_push(value v, value ch)
+{
+  CAMLparam2(v, ch);
+  ml_Editor* editor = Editor_val(v);
+  c_mathml_editor_push(editor->c_editor, Int_val(ch));
+  CAMLreturn(Val_unit);
+}
+
+value
+ml_mathml_editor_drop(value v, value alt)
+{
+  CAMLparam2(v, alt);
+  ml_Editor* editor = Editor_val(v);
+  c_mathml_editor_drop(editor->c_editor, Bool_val(alt));
+  CAMLreturn(Val_unit);
+}
+
+value
+ml_mathml_editor_get_tex(value v)
+{
+  CAMLparam1(v);
+  ml_Editor* editor = Editor_val(v);
+  char* res = c_mathml_editor_get_tex(editor->c_editor);
+  CAMLlocal1(ml_res);
+  ml_res = copy_string(res);
+  free(res);
+  CAMLreturn(ml_res);
+}
+
+value
+ml_mathml_editor_reset(value v, value s)
+{
+  CAMLparam1(v);
+  ml_Editor* editor = Editor_val(v);
+  c_mathml_editor_reset(editor->c_editor);
+  CAMLreturn(Val_unit);
+}
+
+value
+ml_mathml_editor_get_tml(value v)
+{
+  CAMLparam1(v);
+  ml_Editor* editor = Editor_val(v);
+  GdomeDocument* doc = c_mathml_editor_get_tml(editor->c_editor);
+  CAMLreturn(Val_Document(doc));
+}
+
+value
+ml_mathml_editor_get_mml(value v)
+{
+  CAMLparam1(v);
+  ml_Editor* editor = Editor_val(v);
+  GdomeDocument* doc = c_mathml_editor_get_mml(editor->c_editor);
+  CAMLreturn(Val_Document(doc));
+}
+
index a514e9453b349faec9a9399831a215b0cab3e43b..5186c63bbdcae4b850ec1ec541e344f45ba90e90 100644 (file)
 class AMathMLFactory
 {
 public:
-  AMathMLFactory(class ALogger& l) : logger(l), consumer(0) { };
-  AMathMLFactory(class ALogger& l, class AMathMLConsumer& c) : logger(l), consumer(&c) { };
+  AMathMLFactory(class ALogger& l) : logger(l) { };
   virtual ~AMathMLFactory() { };
 
+  virtual void reset(void) = 0;
   virtual void documentModified(class TDocument&) = 0;
   virtual DOM::Document document(void) const = 0;
 
 protected:
   class ALogger& logger;
-  class AMathMLConsumer* consumer;
 };
 
 #endif // __AMathMLFactory_hh__
index 4fca8cf7651ba467d70766fa913b8d8147b4aa82..342d18fe919dd4241408f68fc79f00bbbfc8059e 100644 (file)
@@ -9,6 +9,7 @@ public:
   virtual ~APushLexer() { };
 
   virtual void push(char) = 0;
+  virtual void drop(bool = false) = 0;
   virtual void reset(void) = 0;
   virtual bool error(void) const = 0;
 
diff --git a/helm/DEVEL/mathml_editor/src/APushParser.cc b/helm/DEVEL/mathml_editor/src/APushParser.cc
new file mode 100644 (file)
index 0000000..9ff5eff
--- /dev/null
@@ -0,0 +1,24 @@
+
+#include "APushParser.hh"
+#include "AMathMLFactory.hh"
+
+void
+APushParser::reset()
+{
+  if (factory) factory->reset();
+}
+
+bool
+APushParser::freeze()
+{
+  return freeze_level++ == 0;
+}
+
+bool
+APushParser::thaw()
+{
+  if (freeze_level > 0)
+    return --freeze_level == 0;
+  else
+    return true;
+}
index c7989614eaf4cf2feecb7043fb300dbda5c7206e..3a3aa8842c350092c0aecd84577537b4f5724c93 100644 (file)
 #ifndef __APushParser_hh__
 #define __APushParser_hh__
 
+#include <string>
+
 class APushParser
 {
 public:
-  APushParser(class ALogger& l) : logger(l), factory(0) { };
-  APushParser(class ALogger& l, class AMathMLFactory& f) : logger(l), factory(&f) { };
-
+  APushParser(class ALogger& l) : logger(l), factory(0), freeze_level(0) { };
+  APushParser(class ALogger& l, class AMathMLFactory& f) : logger(l), factory(&f), freeze_level(0) { };
   virtual ~APushParser() { };
-  virtual void push(const TToken&) = 0;
+
+  virtual void reset(void);
+  virtual void push(const class TToken&) = 0;
+  virtual std::string drop(void) = 0;
   virtual void setCursorHint(const std::string&) = 0;
 
+  virtual bool freeze(void);
+  virtual bool thaw(void);
+  bool frozen(void) const { return freeze_level > 0; };
+
 protected:
   class ALogger& logger;
   class AMathMLFactory* factory;
+
+private:
+  unsigned freeze_level;
 };
 
 #endif // __APushParser_hh__
index 244d3640b0f60fec1dc11d14cfa200d630b58366..2b714cb91f83d175f1757fb0c627a8f097d49c41 100644 (file)
@@ -5,42 +5,48 @@
 #include "CMathMLFactoryXSLT.hh"
 #include "AMathMLConsumer.hh"
 
+CMathMLFactoryXSLT::CMathMLFactoryXSLT(ALogger& l, const DOMX::XSLTStylesheet& s)
+  : AMathMLFactory(l), style(s)
+{
+  reset();
+}
+
+void
+CMathMLFactoryXSLT::reset()
+{
+  DOM::DOMImplementation di;
+  DOM::DocumentType dt;
+  result = di.createDocument(MATHML_NS_URI, "m:math", dt);
+}
+
 void
 CMathMLFactoryXSLT::documentModified(TDocument& doc)
 {
   if (TNode dirty = doc.dirtyNode()) 
     {
       std::vector< std::pair<DOM::GdomeString, DOM::GdomeString> > dirtyId;
-      if (result)
+      if (result.get_documentElement().hasAttribute("xref"))
        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)
-       {
-         DOM::Element root = res.get_documentElement();
-         assert(root);
-         assert(root.hasAttribute("xref"));
+      style.save(doc.document(), stdout);
+
+      DOM::Element root = res.get_documentElement();
+      assert(root);
+      assert(root.hasAttribute("xref"));
 
-         try
-           {
-             bool ok = subst(result.get_documentElement(), root.getAttribute("xref"), result.importNode(root, true));
-             assert(ok);
-           }
-         catch (DOM::DOMException& e)
-           {
-             cout << "!!!!!!!!!!!!!!!! EXCEPTION " << e.code << " " << e.msg << endl;
-             assert(0);
-           }
+      if (result.get_documentElement().hasAttribute("xref"))
+       {
+         bool ok = subst(result.get_documentElement(), root.getAttribute("xref"), result.importNode(root, true));
+         assert(ok);
        }
       else
-       result = res;
+       result.replaceChild(result.importNode(root, true), result.get_documentElement());
+       
+      style.save(result, stdout);
 
       doc.clearDirty();
-
-      if (consumer) consumer->documentModified(result);
     }
 }
 
index 70998e092ba92b246dfbe45f8347cb826f61d1c1..9d129a3782b9389574c4c1026800afa8eff9aa00 100644 (file)
@@ -2,22 +2,23 @@
 #ifndef __CMathMLFactoryXSLT_hh__
 #define __CMathMLFactoryXSLT_hh__
 
+#include <GdomeSmartDOM.hh>
 #include "AMathMLFactory.hh"
 
 class CMathMLFactoryXSLT : public AMathMLFactory
 {
 public:
-  CMathMLFactoryXSLT(class ALogger& l, const DOM::XSLTStylesheet& s) : AMathMLFactory(l), style(s) { };
-  CMathMLFactoryXSLT(class ALogger& l, class AMathMLConsumer& c, const DOM::XSLTStylesheet& s) : AMathMLFactory(l, c), style(s) { };
+  CMathMLFactoryXSLT(class ALogger&, const class GdomeSmartDOMExt::XSLTStylesheet&);
 
+  virtual void reset(void);
   virtual void documentModified(class TDocument&);
-  virtual DOM::Document document(void) const { return result; };
+  virtual GdomeSmartDOM::Document document(void) const { return result; };
 
 private:
-  static bool subst(const DOM::Element& e1, const DOM::GdomeString& id, const DOM::Element& e2);
+  static bool subst(const GdomeSmartDOM::Element&, const GdomeSmartDOM::GdomeString&, const GdomeSmartDOM::Element&);
 
-  const DOM::XSLTStylesheet& style;
-  DOM::Document result;
+  const class GdomeSmartDOMExt::XSLTStylesheet& style;
+  GdomeSmartDOM::Document result;
 };
 
 #endif // __CMathMLFactoryXSLT_hh__
diff --git a/helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLTDiff.cc b/helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLTDiff.cc
new file mode 100644 (file)
index 0000000..53fa5aa
--- /dev/null
@@ -0,0 +1,87 @@
+
+#include "dom.hh"
+#include "Diff.hh"
+#include "TNode.hh"
+#include "TDocument.hh"
+#include "CMathMLFactoryXSLTDiff.hh"
+#include "AMathMLConsumer.hh"
+
+CMathMLFactoryXSLTDiff::CMathMLFactoryXSLTDiff(ALogger& l, const DOMX::XSLTStylesheet& s)
+  : AMathMLFactory(l), style(s)
+{
+  reset();
+}
+
+void
+CMathMLFactoryXSLTDiff::reset()
+{
+  DOM::DOMImplementation di;
+  DOM::DocumentType dt;
+  result = di.createDocument(MATHML_NS_URI, "m:math", dt);
+}
+
+void
+CMathMLFactoryXSLTDiff::documentModified(TDocument& doc)
+{
+  if (TNode dirty = doc.dirtyNode()) 
+    {
+      std::vector< std::pair<DOM::GdomeString, DOM::GdomeString> > dirtyId;
+      if (false && result.get_documentElement().hasAttribute("xref"))
+       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);
+      //cout << "*** THE DIRTY FRAGMENT HAS ID = " << std::string(dirty["id"]) << endl;
+      //style.save(doc.document(), stdout);
+      cout << "*** THE CURRENT DOCUMENT:" << endl;
+      if (result) style.save(result, stdout);
+      cout << "*** THE NEW DOCUMENT:" << endl;
+      style.save(res, stdout);
+      cout << "*** THE DIFF:" << endl;
+      DOMX::Diff diff = DOMX::Diff::diff(result, res);
+      style.save(diff.document(), stdout);
+      diff.patch();
+#if 0
+      DOM::Element root = res.get_documentElement();
+      assert(root);
+      assert(root.hasAttribute("xref"));
+      if (result.get_documentElement().hasAttribute("xref"))
+       {
+         bool ok = subst(result.get_documentElement(), root.getAttribute("xref"), result.importNode(root, true));
+         assert(ok);
+       }
+      else
+       result = res;
+#endif
+      //style.save(result, stdout);
+
+      doc.clearDirty();
+    }
+}
+
+bool
+CMathMLFactoryXSLTDiff::subst(const DOM::Element& e1, const DOM::GdomeString& id, const DOM::Element& e2)
+{
+  assert(e1);
+  assert(e2);
+  if (e1.getAttribute("xref") == id)
+    {
+      DOMX::Diff diff = DOMX::Diff::diff(e1, e2);
+      style.save(diff.document(), stdout);
+      diff.patch();
+      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;
+    }
+}
+
diff --git a/helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLTDiff.hh b/helm/DEVEL/mathml_editor/src/CMathMLFactoryXSLTDiff.hh
new file mode 100644 (file)
index 0000000..ac933b5
--- /dev/null
@@ -0,0 +1,23 @@
+
+#ifndef __CMathMLFactoryXSLTDiff_hh__
+#define __CMathMLFactoryXSLTDiff_hh__
+
+#include "AMathMLFactory.hh"
+
+class CMathMLFactoryXSLTDiff : public AMathMLFactory
+{
+public:
+  CMathMLFactoryXSLTDiff(class ALogger&, const DOMX::XSLTStylesheet&);
+
+  virtual void reset(void);
+  virtual void documentModified(class TDocument&);
+  virtual DOM::Document document(void) const { return result; };
+
+private:
+  bool subst(const DOM::Element& e1, const DOM::GdomeString& id, const DOM::Element& e2);
+
+  const DOMX::XSLTStylesheet& style;
+  DOM::Document result;
+};
+
+#endif // __CMathMLFactoryXSLT_hh__
diff --git a/helm/DEVEL/mathml_editor/src/Diff.cc b/helm/DEVEL/mathml_editor/src/Diff.cc
new file mode 100644 (file)
index 0000000..948baa6
--- /dev/null
@@ -0,0 +1,368 @@
+
+#include <sstream>
+#include <functional>
+#include <vector>
+#include <algorithm>
+
+#include "Diff.hh"
+
+namespace GdomeSmartDOMExt
+{
+
+  Diff
+  Diff::diff(const Document& dest, const Document& source, flatNodeEq flatEq)
+  {
+    assert(dest);
+    assert(source);
+    assert(flatEq);
+
+    return diff(dest.get_documentElement(), source.get_documentElement(), flatEq);
+  }
+  
+  Diff
+  Diff::diff(const Element& dest, const Element& source, flatNodeEq flatEq)
+  {
+    assert(dest);
+    assert(source);
+    assert(flatEq);
+
+    DOMImplementation di;
+    Document doc = di.createDocument(DDIFF_NS_URI, "diff:doc", DocumentType());
+    Element root = doc.get_documentElement();
+    root.setAttributeNS(XMLNS_NS_URI, "xmlns:diff", DDIFF_NS_URI);
+
+    Diff diff(dest, doc, flatEq);
+    if (Node d = diff.diffNodes(dest, source)) root.appendChild(d);
+    else root.appendChild(doc.createElementNS(DDIFF_NS_URI, "diff:same"));
+
+    return diff;
+  }
+
+  struct NodeEqPredicate : std::binary_function<Node,Node,bool>
+  {
+    NodeEqPredicate(Diff::flatNodeEq e) : eq(e) { };
+    bool operator()(const Node& n1, const Node& n2) const { return eq(n1, n2); };
+
+  private:
+    Diff::flatNodeEq eq;
+  };
+    
+  std::vector<Node>
+  collectProperAttributes(const Node& n)
+  {
+    assert(n);
+    NamedNodeMap map = n.get_attributes();
+    unsigned len = map.get_length();
+
+    std::vector<Node> res;
+    res.reserve(len);
+    for (unsigned i = 0; i < len; i++)
+      {
+       Node attr = map.item(i);
+       assert(attr);
+       if (attr.get_nodeName() != "xmlns" && attr.get_prefix() != "xmlns") res.push_back(attr);
+      }
+
+    return res;
+  }
+
+  bool
+  Diff::defaultFlatNodeEq(const Node& n1, const Node& n2)
+  {
+    assert(n1);
+    assert(n2);
+
+    unsigned nodeType = n1.get_nodeType();
+    if (nodeType != n2.get_nodeType()) return false;
+
+    GdomeString ns1 = n1.get_namespaceURI();
+    GdomeString ns2 = n2.get_namespaceURI();
+    if (ns1 != ns2) return false;
+
+    switch (nodeType)
+      {
+      case Node::ATTRIBUTE_NODE:
+       if (!ns1.null())
+         {
+           assert(!ns2.null());
+           if (n1.get_localName() != n2.get_localName()) return false;
+         }
+       else
+         {
+           assert(ns2.null());
+           if (n1.get_nodeName() != n2.get_nodeName()) return false;
+         }
+       // WARNING: fallback for checking node value
+      case Node::TEXT_NODE:
+      case Node::CDATA_SECTION_NODE:
+       if (n1.get_nodeValue() != n2.get_nodeValue()) return false;
+       return true;
+      case Node::ELEMENT_NODE:
+       {
+         //cout << "comparing: " << n1.get_nodeName() << " ? " << n2.get_nodeName() << endl;
+         if (!ns1.null())
+           {
+             assert(!ns2.null());
+             if (n1.get_localName() != n2.get_localName()) return false;
+           }
+         else
+           {
+             assert(ns2.null());
+             if (n1.get_nodeName() != n2.get_nodeName()) return false;
+           }
+#if 1
+         std::vector<Node> m1 = collectProperAttributes(n1);
+         std::vector<Node> m2 = collectProperAttributes(n2);
+         if (m1.size() != m2.size()) return false;
+
+         for (unsigned i = 0; i < m1.size(); i++)
+           {
+             std::vector<Node>::iterator p2 = std::find_if(m2.begin(), m2.end(), std::bind2nd(NodeEqPredicate(defaultFlatNodeEq), m1[i]));
+             if (p2 == m2.end()) return false;
+           }
+#endif
+       }
+       return true;
+      default:
+       return true;
+      }
+
+  }
+
+  void
+  Diff::sameChunk(const Node& res, unsigned long n) const
+  {
+    assert(n > 0);
+    Element s = doc.createElementNS(DDIFF_NS_URI, "diff:same");
+    if (n != 1)
+      {
+       std::ostringstream os;
+       os << n;
+       s.setAttribute("count", os.str());
+      }
+    res.appendChild(s);
+  }
+
+  Node
+  Diff::diffNodes(const Node& p1, const Node& p2) const
+  {
+    if (eq(p1, p2))
+      {
+       Element m = doc.createElementNS(DDIFF_NS_URI, "diff:merge");
+       if (diffChildren(p1, p2, m)) return m;
+       else return Node();
+      }
+    else
+      {
+       Element r = doc.createElementNS(DDIFF_NS_URI, "diff:replace");
+       r.appendChild(doc.importNode(p2, true));
+       return r;
+      }
+  }
+
+  bool
+  Diff::diffChildren(const Node& n1, const Node& n2, const Node& res) const
+  {
+    assert(n1);
+    assert(n2);
+    assert(res);
+
+    Node p1 = n1.get_firstChild();
+    Node p2 = n2.get_firstChild();
+    bool same = true;
+    unsigned nSame = 0;
+    while (p1 && p2)
+      {
+       if (Node d = diffNodes(p1, p2))
+         {
+           same = false;
+           if (nSame > 0)
+             {
+               sameChunk(res, nSame);
+               nSame = 0;
+             }
+           res.appendChild(d);
+         }
+       else
+         nSame++;
+
+       p1 = p1.get_nextSibling();
+       p2 = p2.get_nextSibling();
+      }
+
+    if (p1)
+      {
+       same = false;
+       if (nSame > 0)
+         {
+           sameChunk(res, nSame);
+           nSame = 0;
+         }
+
+       unsigned nRemoved = 0;
+       while (p1)
+         {
+           nRemoved++;
+           p1 = p1.get_nextSibling();
+         }
+
+       if (nRemoved > 0)
+         {
+           Element r = doc.createElementNS(DDIFF_NS_URI, "diff:remove");
+           if (nRemoved > 1)
+             {
+               std::ostringstream os;
+               os << nRemoved;
+               r.setAttribute("count", os.str());
+             }
+           res.appendChild(r);
+         }
+      }
+
+    if (p2)
+      {
+       same = false;
+       if (nSame > 0)
+         {
+           sameChunk(res, nSame);
+           nSame = 0;
+         }
+
+       Element i = doc.createElementNS(DDIFF_NS_URI, "diff:insert");
+       while (p2)
+         {
+           i.appendChild(doc.importNode(p2, true));
+           p2 = p2.get_nextSibling();
+         }
+       res.appendChild(i);
+      }
+
+    return !same;
+  }
+
+  static Node
+  getFirstElement(const Node& n)
+  {
+    Node p = n.get_firstChild();
+    while (p && p.get_nodeType() != Node::ELEMENT_NODE)
+      p = p.get_nextSibling();
+    return p;
+  }
+
+  static Node
+  getNextElement(const Node& n)
+  {
+    Node p = n.get_nextSibling();
+    while (p && p.get_nodeType() != Node::ELEMENT_NODE)
+      p = p.get_nextSibling();
+    return p;
+  }
+
+  void
+  Diff::patchRootNode(const Node& node, const Element& elem) const
+  {
+    GdomeString name = elem.get_localName();
+    if (name == "same")
+      {
+       if (elem.hasAttribute("count"))
+         {
+           unsigned count;
+           istringstream is(elem.getAttribute("count"));
+           is >> count;
+           assert(count == 1);
+         }
+      }
+    else if (name == "replace")
+      {
+       Document d1 = node.get_ownerDocument();
+       Node parent = node.get_parentNode();
+       assert(parent);
+#if 0
+       /* the following patch is because of gdome2 bug that prevents from
+        * replacing the root element of a document.
+        */
+       assert(!node.get_previousSibling());
+       assert(!node.get_nextSibling());
+       parent.removeChild(node);
+       parent.appendChild(d1.importNode(getFirstElement(elem), true));
+#endif
+       parent.replaceChild(d1.importNode(getFirstElement(elem), true), node);
+      }
+    else if (name == "merge")
+      patchChildren(node, elem);
+    else
+      assert(0);
+  }
+
+  void
+  Diff::patchChildren(const Node& n1, const Element& e2) const
+  {
+    Node p1 = n1.get_firstChild();
+    Element p2 = getFirstElement(e2);
+    while (p2)
+      {
+       GdomeString name = p2.get_localName();
+       if (name == "same")
+         {
+           unsigned count = 1;
+           if (p2.hasAttribute("count"))
+             {
+               istringstream is(p2.getAttribute("count"));
+               is >> count;
+             }
+           while (count-- > 0)
+             {
+               if (!p1) throw BADDiff("too few nodes in original document (same)");
+               p1 = p1.get_nextSibling();
+             }
+         }
+       else if (name == "replace")
+         {
+           Document d1 = n1.get_ownerDocument();
+           if (!p1) throw BADDiff("no node to replace in original document");
+           Node next = p1.get_nextSibling();
+           n1.replaceChild(d1.importNode(p2.get_firstChild(), true), p1);
+           p1 = next;
+         }
+       else if (name == "insert")
+         {
+           Document d1 = n1.get_ownerDocument();
+           for (Node i = p2.get_firstChild(); i; i = i.get_nextSibling())
+             n1.insertBefore(d1.importNode(i, true), p1);
+         }
+       else if (name == "merge")
+         {
+           if (!p1) throw BADDiff("no node to merge in original document");
+           patchChildren(p1, p2);
+           p1 = p1.get_nextSibling();
+         }
+       else if (name == "remove")
+         {
+           unsigned count = 1;
+           if (p2.hasAttribute("count"))
+             {
+               istringstream is(p2.getAttribute("count"));
+               is >> count;
+             }
+           while (count-- > 0)
+             {
+               if (!p1) throw BADDiff("too few nodes in original document (remove)");
+               Node next = p1.get_nextSibling();
+               n1.removeChild(p1);
+               p1 = next;
+             }
+         }
+       else
+         assert(0);
+
+       p2 = getNextElement(p2);
+      }
+  }
+
+  void
+  Diff::patch() const
+  {
+    patchRootNode(dest, getFirstElement(doc.get_documentElement()));
+  }
+
+}
diff --git a/helm/DEVEL/mathml_editor/src/Diff.hh b/helm/DEVEL/mathml_editor/src/Diff.hh
new file mode 100644 (file)
index 0000000..099314b
--- /dev/null
@@ -0,0 +1,53 @@
+
+#ifndef __Diff_hh__
+#define __Diff_hh__
+
+#include <GdomeSmartDOM.hh>
+
+#define XMLNS_NS_URI "http://www.w3.org/2000/xmlns/"
+#define DDIFF_NS_URI "http://helm.cs.unibo.it/2002/DDIFF"
+
+namespace GdomeSmartDOMExt
+{
+  using namespace GdomeSmartDOM;
+
+  class Diff
+  {
+  public:
+    typedef bool (*flatNodeEq)(const Node&, const Node&);
+    static bool defaultFlatNodeEq(const Node&, const Node&);
+
+  private:
+    Diff(const Node& n, const Document& d, flatNodeEq e) : dest(n), doc(d), eq(e) { };
+
+  public:
+    static Diff diff(const Document&, const Document&, flatNodeEq = defaultFlatNodeEq);
+    static Diff diff(const Element&, const Element&, flatNodeEq = defaultFlatNodeEq);
+
+    Document document(void) const { return doc; };
+    Node     node(void) const { return dest; };
+
+    void patch(void) const;
+
+    struct BADDiff
+    {
+      BADDiff(const std::string& s) : msg(s) { };
+      const std::string msg;
+    };
+
+  private:
+    Node diffNodes(const Node&, const Node&) const;
+    bool diffChildren(const Node&, const Node&, const Node&) const;
+    void sameChunk(const Node&, unsigned long) const;
+    void patchRootNode(const Node&, const Element&) const;
+    void patchChildren(const Node&, const Element&) const;
+
+    Document   doc;
+    Node       dest;
+    flatNodeEq eq;
+  };
+
+}
+
+#endif // __ddiff_hh__
index c0afe28ee379ed79082c1ffa72dd29e6dd19a5b0..bfb6b97b6408fccb755b12aa60babc900273b02a 100644 (file)
@@ -4,22 +4,27 @@ lib_LTLIBRARIES = libeditex.la
 libeditex_la_LDFLAGS = -version-info @EDITEX_VERSION_INFO@
 
 libeditex_la_SOURCES = \
+  Diff.cc \
   CLoggerConsole.cc \
   TPushLexer.cc \
+  APushParser.cc \
   TPushParser.cc \
   CMathMLFactoryXSLT.cc \
+  CMathMLFactoryXSLTDiff.cc \
   TDictionary.cc \
   TDocument.cc \
   TNode.cc \
   TTokenizer.cc
 
 pkginclude_HEADERS = \
+  Diff.hh \
   ALogger.hh \
   CLoggerConsole.hh \
   APushLexer.hh \
   APushParser.hh \
   AMathMLFactory.hh \
   CMathMLFactoryXSLT.hh \
+  CMathMLFactoryXSLTDiff.hh \
   TPushLexer.hh \
   TPushParser.hh \
   TTokenizer.hh \
index 0592ae444bdfcfc41f3ac742a7463e2e4888baff..4cd204308851354a976fc8c3a5f995212adfa3bd 100644 (file)
@@ -74,12 +74,26 @@ GMETADOM_CFLAGS = @GMETADOM_CFLAGS@
 GMETADOM_LIBS = @GMETADOM_LIBS@
 GTKMATHVIEW_CFLAGS = @GTKMATHVIEW_CFLAGS@
 GTKMATHVIEW_LIBS = @GTKMATHVIEW_LIBS@
+HAVE_OCAMLC = @HAVE_OCAMLC@
+HAVE_OCAMLDEP = @HAVE_OCAMLDEP@
+HAVE_OCAMLFIND = @HAVE_OCAMLFIND@
+HAVE_OCAMLMKLIB = @HAVE_OCAMLMKLIB@
+HAVE_OCAMLOPT = @HAVE_OCAMLOPT@
 LDFLAGS = @LDFLAGS@
 LIBTOOL = @LIBTOOL@
 LN_S = @LN_S@
 MAKEINFO = @MAKEINFO@
+MLGDOME_CFLAGS = @MLGDOME_CFLAGS@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
+OCAMLC = @OCAMLC@
+OCAMLDEP = @OCAMLDEP@
+OCAMLFIND = @OCAMLFIND@
+OCAMLMKLIB = @OCAMLMKLIB@
+OCAMLOPT = @OCAMLOPT@
+OCAMLSTDLIBDIR = @OCAMLSTDLIBDIR@
+OCAMLSTUBDIR = @OCAMLSTUBDIR@
+OCAML_INCLUDE_DIR = @OCAML_INCLUDE_DIR@
 PACKAGE = @PACKAGE@
 RANLIB = @RANLIB@
 STRIP = @STRIP@
@@ -89,10 +103,10 @@ lib_LTLIBRARIES = libeditex.la
 
 libeditex_la_LDFLAGS = -version-info @EDITEX_VERSION_INFO@
 
-libeditex_la_SOURCES =    CLoggerConsole.cc   TPushLexer.cc   TPushParser.cc   CMathMLFactoryXSLT.cc   TDictionary.cc   TDocument.cc   TNode.cc   TTokenizer.cc
+libeditex_la_SOURCES =    Diff.cc   CLoggerConsole.cc   TPushLexer.cc   APushParser.cc   TPushParser.cc   CMathMLFactoryXSLT.cc   CMathMLFactoryXSLTDiff.cc   TDictionary.cc   TDocument.cc   TNode.cc   TTokenizer.cc
 
 
-pkginclude_HEADERS =    ALogger.hh   CLoggerConsole.hh   APushLexer.hh   APushParser.hh   AMathMLFactory.hh   CMathMLFactoryXSLT.hh   TPushLexer.hh   TPushParser.hh   TTokenizer.hh   TDictionary.hh   TDocument.hh   TNode.hh   TListener.hh   dom.hh
+pkginclude_HEADERS =    Diff.hh   ALogger.hh   CLoggerConsole.hh   APushLexer.hh   APushParser.hh   AMathMLFactory.hh   CMathMLFactoryXSLT.hh   CMathMLFactoryXSLTDiff.hh   TPushLexer.hh   TPushParser.hh   TTokenizer.hh   TDictionary.hh   TDocument.hh   TNode.hh   TListener.hh   dom.hh
 
 
 INCLUDES = $(GMETADOM_CFLAGS) $(GDOMEXSLT_CFLAGS)
@@ -105,8 +119,9 @@ LTLIBRARIES =  $(lib_LTLIBRARIES)
 DEFS = @DEFS@ -I. -I$(srcdir) -I..
 LIBS = @LIBS@
 libeditex_la_LIBADD = 
-libeditex_la_OBJECTS =  CLoggerConsole.lo TPushLexer.lo TPushParser.lo \
-CMathMLFactoryXSLT.lo TDictionary.lo TDocument.lo TNode.lo \
+libeditex_la_OBJECTS =  Diff.lo CLoggerConsole.lo TPushLexer.lo \
+APushParser.lo TPushParser.lo CMathMLFactoryXSLT.lo \
+CMathMLFactoryXSLTDiff.lo TDictionary.lo TDocument.lo TNode.lo \
 TTokenizer.lo
 CXXFLAGS = @CXXFLAGS@
 CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -122,7 +137,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
 GZIP_ENV = --best
-DEP_FILES =  .deps/CLoggerConsole.P .deps/CMathMLFactoryXSLT.P \
+DEP_FILES =  .deps/APushParser.P .deps/CLoggerConsole.P \
+.deps/CMathMLFactoryXSLT.P .deps/CMathMLFactoryXSLTDiff.P .deps/Diff.P \
 .deps/TDictionary.P .deps/TDocument.P .deps/TNode.P .deps/TPushLexer.P \
 .deps/TPushParser.P .deps/TTokenizer.P
 SOURCES = $(libeditex_la_SOURCES)
index 8c16d2ba91327bf0dba38ed1ecc3cb554a905276..3cf2334876ded1f66367a302c558675c6c017f51 100644 (file)
@@ -9,11 +9,19 @@
 static TDictionary::Entry undefinedEntry;
 
 void
-TDictionary::load(const char* uri)
+TDictionary::load(const std::string& uri)
 {
+  logger.debug("Dictionary: loading `" + uri + "'");
+
   DOM::DOMImplementation di;
+  DOM::Document doc = di.createDocumentFromURI(uri.c_str());
+  assert(doc);
+  load(doc);
+}
 
-  DOM::Document doc = di.createDocumentFromURI(uri);
+void
+TDictionary::load(const DOM::Document& doc)
+{
   assert(doc);
 
   DOM::Element root = doc.get_documentElement();
@@ -23,7 +31,17 @@ TDictionary::load(const char* uri)
   TTokenizer tokenizer(logger);
 
   for (DOM::Node p = root.get_firstChild(); p; p = p.get_nextSibling())
-    if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "entry")
+    if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "include")
+      {
+       DOM::Element el = p;
+       assert(el);
+       if (el.hasAttribute("href"))
+         // WARNING: this may result into an infinite loop!
+         load(std::string(el.getAttribute("href")));
+       else
+         logger.warning("Dictionary: include statement with no href attribute (ignored)");
+      }
+    else if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "entry")
       {
        DOM::Element el = p;
        assert(el);
@@ -31,7 +49,7 @@ TDictionary::load(const char* uri)
 
        std::string name = el.getAttribute("name");
        if (entries.find(name) != entries.end())
-         cerr << "WARNING: entry `" << name << "' is being redefined" << endl;
+         logger.info("Dictionary: `" + name + "' is being redefined");
 
        Entry entry;
 
@@ -50,13 +68,13 @@ TDictionary::load(const char* uri)
          {
            entry.value = el.getAttribute("val");
            if (entry.cls == MACRO)
-             cerr << "WARNING: `" << name << "' has a specified value, but is classified as macro" << endl;
+             logger.warning("Dictionary: `" + name + "' has a specified value, but is classified as macro");
          }
 
        if (el.hasAttribute("pattern"))
          {
            if (entry.cls != MACRO)
-             cerr << "WARNING: `" << name << "' has a specified pattern, but is not classified as macro" << endl;
+             logger.warning("Dictionary: `" + name + "' has a specified pattern, but is not classified as macro");
 
            std::string pattern = el.getAttribute("pattern");
            if (pattern == "{}")
@@ -69,6 +87,7 @@ TDictionary::load(const char* uri)
              entry.pattern = tokenizer.tokenize(pattern);
          }
 
+#if 0
        if (el.hasAttribute("infix"))
          {
            std::istringstream is(el.getAttribute("infix"));
@@ -104,6 +123,7 @@ TDictionary::load(const char* uri)
                if (!el.hasAttribute("prefix")) entry.prefix = postfix;
              }
          }
+#endif
 
        if (el.hasAttribute("limits"))
          {
@@ -124,7 +144,7 @@ TDictionary::load(const char* uri)
        if (el.hasAttribute("delimiter"))
          {
            if (entry.cls != OPERATOR && !entry.embellishment)
-             cerr << "WARNING: `" << name << "' delimiter ignored for non-operator" << endl;
+             logger.warning("Dictionary: `" + name + "' delimiter ignored for non-operator");
 
            std::istringstream is(el.getAttribute("delimiter"));
            unsigned delimiter;
@@ -135,7 +155,7 @@ TDictionary::load(const char* uri)
        if (el.hasAttribute("table"))
          {
            if (entry.cls != MACRO)
-             cerr << "WARNING: `" << name << "' table ignored for non-macro" << endl;
+             logger.warning("Dictionary: `" + name + "' table ignored for non-macro");
 
            std::istringstream is(el.getAttribute("table"));
            unsigned table;
index b769aaa4ed32e18d205bbc6e05d5791c6990809f..5349cf00475d5b9debee02353f1bfe2f80a24064 100644 (file)
@@ -2,16 +2,19 @@
 #ifndef __TDictionary_hh__
 #define __TDictionary_hh__
 
+#include <config.h>
+
 #include <string>
 #include <vector>
 #include <hash_map>
 
+#include "dom.hh"
 #include "TToken.hh"
 
 class TDictionary
 {
 public:
-  TDictionary(void) { };
+  TDictionary(class ALogger& l) : logger(l) { };
   ~TDictionary() { };
 
   enum Form
@@ -35,7 +38,6 @@ public:
     Entry(void)
     { 
       cls = UNDEFINED;
-      infix = prefix = postfix = 0;
       table = delimiter = limits = embellishment = leftOpen = rightOpen = 0;
     };
 
@@ -49,9 +51,6 @@ public:
     unsigned previousParam(unsigned) const;
 
     EntryClass cls;
-    unsigned infix : 8;
-    unsigned prefix : 8;
-    unsigned postfix : 8;
     unsigned delimiter : 1;
     unsigned limits : 1;
     unsigned embellishment : 1;
@@ -60,7 +59,8 @@ public:
     unsigned table : 1;
   };
 
-  void load(const char* uri);
+  void load(const std::string& uri);
+  void load(const DOM::Document& doc);
   const Entry& find(const std::string&) const;
 
 private:
@@ -72,7 +72,14 @@ private:
   { bool operator()(const std::string&, const class String*) const; };
 #endif
 
+  class ALogger& logger;
+#if defined(HAVE_EXT_HASH_MAP)
+  typedef __gnu_cxx::hash_map< std::string, Entry, StringHash > Dictionary;
+#elif defined(HAVE_HASH_MAP)
   typedef std::hash_map< std::string, Entry, StringHash > Dictionary;
+#else
+#error "no hash_map could be found"
+#endif
   Dictionary entries;
 };
 
index a7b5c8d3a5d2cb57fcd5adc11f79eb6e61ad91ab..e578b79f46ae9d8411f3d00931c8c5dcbacac2e1 100644 (file)
@@ -34,16 +34,19 @@ TDocument::serialize(const char* filename) const
   di.saveDocumentToFile(doc, filename, GDOME_SAVE_LIBXML_INDENT);
 }
 
+std::string
+TDocument::makeId(unsigned id)
+{
+  ostringstream os;
+  os << "I" << id;
+  return os.str();
+}
+
 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());
-    }
+  if (id > 0) elem.setAttribute("id", makeId(id));
   return elem;
 }
 
@@ -130,6 +133,24 @@ TDocument::findIdNode(const DOM::Node& node)
   return DOM::Node(0);
 }
 
+TNode
+TDocument::getNodeByIdAux(const TNode& node, const std::string& id)
+{
+  if (node.hasId(id)) return node;
+  else
+    for (TNode p = node.first(); p; p = p.next())
+      if (TNode res = getNodeByIdAux(p, id)) return res;
+  return TNode();
+}
+
+TNode
+TDocument::getNodeById(unsigned id) const
+{
+  DOM::Element root = doc.get_documentElement();
+  assert(root);
+  return getNodeByIdAux(root, makeId(id));
+}
+
 void
 TDocument::handleEvent(const DOM::Event& ev)
 {
index cf4b7c391b2c7e60a491b8abd169a0f4293ce009..b1ca562c63431125a7f54a7b0919e8709a0f6afd 100644 (file)
@@ -21,6 +21,7 @@ public:
 
   DOM::Document document(void) const { return doc; };
 
+  TNode getNodeById(unsigned) const;
   TNode root(void) { return doc.get_documentElement(); };
   TNode dirtyNode(void) const { return dirty; };
   void  clearDirty(void) { dirty = DOM::Element(0); };
@@ -32,6 +33,8 @@ private:
   DOM::Element dirty;
 
   virtual void handleEvent(const DOM::Event&);
+  static std::string makeId(unsigned);
+  static TNode getNodeByIdAux(const TNode&, const std::string&);
   static unsigned nodeDepth(const DOM::Node&);
   static DOM::Node findCommonAncestor(const DOM::Node&, const DOM::Node&);
   static DOM::Node findIdNode(const DOM::Node&);
index b2c68fa6973a76e7a6d48f8c2eb57b6f9a067425..c9f85b8f8d34c84a5da5bb1cbfc55885caf74d44 100644 (file)
@@ -64,6 +64,7 @@ public:
   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  hasId(const std::string& id) const { return node.getAttribute("id") == 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"); };
index 1d25abbe98edff1fa8299e0eb82fc7585b6397d7..c8d04f1bd4354401a4de38b2b83c18c101d231fb 100644 (file)
@@ -55,7 +55,6 @@ TPushLexer::push(char ch)
     case ACCEPT:
       if (ch == '\\') state = ESCAPE;
       else if (ch == '#') state = PARAMETER;
-      else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
       else if (ch == -1) ;
       else transaction(ch, ACCEPT);
       break;
@@ -65,10 +64,6 @@ TPushLexer::push(char ch)
          buffer.push_back(ch);
          state = MACRO;
        }
-      else if (ch == '\b')
-        {
-         state = ACCEPT;
-       }
       else if (ch == -1) error();
       else
        {
@@ -89,11 +84,6 @@ TPushLexer::push(char ch)
          buffer.erase();
          state = PARAMETER;
        }
-      else if (ch == '\b')
-       {
-         buffer.erase(buffer.length() - 1, 1);
-         if (buffer.length() == 0) state = ESCAPE;
-       }
       else if (isalpha(ch))
        buffer.push_back(ch);
       else if (ch == -1)
@@ -114,7 +104,6 @@ TPushLexer::push(char ch)
       if (ch == '\\') state = ESCAPE;
       else if (ch == '#') state = PARAMETER;
       else if (isspace(ch)) ;
-      else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
       else if (ch == -1) state = ACCEPT;
       else transaction(ch, ACCEPT);
       break;
@@ -140,6 +129,45 @@ TPushLexer::push(char ch)
     }
 }
 
+void
+TPushLexer::drop(bool alt)
+{
+  std::string restore = "";
+
+  switch (state)
+    {
+    case ACCEPT:
+    case IGNORE_SPACE:
+      restore = parser.drop();
+      if (restore.length() > 0 && restore[0] == '\\')
+       {
+         buffer = std::string(restore, 1, restore.length() - 1);
+         state = (buffer.length() > 0) ? MACRO : ESCAPE;
+       }
+      break;
+    case ESCAPE:
+      state = ACCEPT;
+      break;
+    case MACRO:
+      if (alt) buffer.erase();
+      else buffer.erase(buffer.length() - 1, 1);
+      if (buffer.length() == 0) state = ESCAPE;
+      break;
+    case PARAMETER:
+    default:
+      assert(0);
+      break;
+    }
+
+  switch (state)
+    {
+    case ESCAPE: parser.setCursorHint("\\"); break;
+    case MACRO: parser.setCursorHint("\\" + buffer); break;
+    case PARAMETER: parser.setCursorHint("#"); break;
+    default: parser.setCursorHint(""); break;
+    }
+}
+
 bool
 TPushLexer::error() const
 {
index a12a9bf63112bbdf6a7a80a6f4f82e1684ee5f29..f2f409158b0a71388efc1d8f18bdf4f803eae803 100644 (file)
@@ -13,6 +13,7 @@ public:
   virtual ~TPushLexer() { };
 
   virtual void push(char);
+  virtual void drop(bool = false);
   virtual void reset(void);
   virtual void flush(void);
   virtual bool error(void) const;
index 62a9208e66ac095920411ff0821e0c1ea2206446..906e8f414497e54254bd6ebc3dd4b0a9a596d05f 100644 (file)
@@ -5,27 +5,27 @@
 
 TPushParser::TPushParser(ALogger& l, const TDictionary& d) : APushParser(l), dictionary(d)
 {
-  init();
+  reset();
 }
 
 TPushParser::TPushParser(ALogger& l, AMathMLFactory& f, const TDictionary& d) : APushParser(l, f), dictionary(d)
 {
-  init();
+  reset();
+}
+
+TPushParser::~TPushParser()
+{
 }
 
 void
-TPushParser::init()
+TPushParser::reset()
 {
+  APushParser::reset();
   nextId = 1;
   cursor = doc.create("cursor");
   cursor["id"] = "I0";
   doc.clearDirty();
   doc.root().append(cursor);
-  logger.verbosity(ALogger::Debug);
-}
-
-TPushParser::~TPushParser()
-{
 }
 
 std::string
@@ -1233,159 +1233,156 @@ TPushParser::process(const TToken& token)
     case TToken::ACTIVE: do_active(token.value); break;
     case TToken::COMMENT: do_comment(); break;
     case TToken::CONTROL: do_control(token.value); break;
-    case TToken::GDELETE: do_gdelete(); break;
     }
 }
 
 void
 TPushParser::push(const TToken& token)
 {
-  if (token.category == TToken::GDELETE)
-    {
-      process(token);
-    }
-  else
-    {
-
-      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())
+  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 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 a delimiter of the argument, 
-                   // so we increment the frame.pos
+               // The token matches with a delimiter of the argument, 
+               // so we increment the frame.pos
+               frame.pos++;
+
+               if (frame.entry.lastDelimiter(frame.pos))
+                 {
+                   // this delimiter is the last one for the argumet, 
+                   // so the argument is completed
+                   cursor.remove();
                    frame.pos++;
 
-                   if (frame.entry.lastDelimiter(frame.pos))
+                   if (frame.pos == frame.entry.pattern.size())
                      {
-                       // this delimiter is the last one for the argumet, 
-                       // so the argument is completed
-                       cursor.remove();
-                       frame.pos++;
-
-                       if (frame.pos == frame.entry.pattern.size())
-                         {
-                           // This token has completed the entry
-                           advance(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);
+                       // This token has completed the entry
+                       advance(parent);
                      }
-                 }
-               else
-                 {
-                   // Delimiter mismatch.
-                   if (frame.entry.pattern[frame.pos].category != TToken::PARAMETER)
+                   else if (frame.entry.paramDelimited(frame.pos))
                      {
-                       // in this case, there is a sequence of delimiters that delimitates
-                       // the argument, and the user correctly inserted a portion of this 
-                       // sequence, but now has inserted a wrong delimiter.
-                       // Here, there are some possibilities:
-                       //   - ignore the token, and wait for the correct delimiter
-                       //   - ignore the token, wait for the correct delimiter and emit an error
-                       // At the moment, we implement the second possibily
-                       logger.error("parser: it's not the correct delimiter...you have to type " + frame.entry.pattern[frame.pos + 1].value);
+                       // 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
-                     {
-                       // in this case, the sequence of delimiters is composed of one 
-                       // delimiter. It means that we have to process the token
-                       process(token);
-                     }
-                 }
+                     parent.parent().append(cursor);
+                 }
              }
            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++;
+               // Delimiter mismatch.
+               if (frame.entry.pattern[frame.pos].category != TToken::PARAMETER)
+                 {
+                   // in this case, there is a sequence of delimiters that delimitates
+                   // the argument, and the user correctly inserted a portion of this 
+                   // sequence, but now has inserted a wrong delimiter.
+                   // Here, there are some possibilities:
+                   //   - ignore the token, and wait for the correct delimiter
+                   //   - ignore the token, wait for the correct delimiter and emit an error
+                   // At the moment, we implement the second possibily
+                   logger.error("parser: it's not the correct delimiter...you have to type " + frame.entry.pattern[frame.pos + 1].value);
+                 }
+               else
+                 {
+                   // in this case, the sequence of delimiters is composed of one 
+                   // delimiter. It means that we have to process the token
                    process(token);
-                 }
+                 }
              }
-           else if (frame.entry.pattern[frame.pos] == 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)
              {
-               // 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);
+               // 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
+         }
+       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))
              {
-               // There is a mismatch. Emit an error and ignore the token?
-               logger.debug("parser: token ignored: " + token.value);
+               // 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?
+           logger.debug("parser: token ignored: " + token.value);
+         }
 
-          }
-        else
-          process(token);
-      else
-        {
-          logger.warning("ignored token");
-        }
-
-    } // this end corresponds to the else of the if (token.category == TToken::GDELETE)
+      }
+    else
+      process(token);
+  else
+    {
+      logger.warning("ignored token");
+    }
 
-  if (factory) factory->documentModified(doc);
+  if (factory && doc.dirtyNode() && !frozen()) factory->documentModified(doc);
+}
 
+std::string
+TPushParser::drop()
+{
+  do_gdelete();
+  if (factory && doc.dirtyNode() && !frozen()) factory->documentModified(doc);
+  return "";
 }
 
 void
@@ -1426,6 +1423,21 @@ TPushParser::advance(const TNode& node)
 void
 TPushParser::setCursorHint(const std::string& c)
 {
-  cursor["val"] = c;
-  if (factory) factory->documentModified(doc);
+  if (cursor["val"] != c)
+    {
+      cursor["val"] = c;
+      if (factory && doc.dirtyNode() && !frozen()) factory->documentModified(doc);
+    }
+}
+
+bool
+TPushParser::thaw()
+{
+  if (APushParser::thaw() && factory && doc.dirtyNode())
+    {
+      factory->documentModified(doc);
+      return true;
+    }
+  else
+    return false;
 }
index e852bc6072e189a5e995c3346683fac04f0437ad..b01524be4dcfd06b44b5c3432e1f2a968c6a1fd0 100644 (file)
@@ -17,15 +17,16 @@ public:
   TPushParser(class ALogger&, class AMathMLFactory&, const class TDictionary&);
   virtual ~TPushParser();
 
+  virtual void reset(void);
   virtual void push(const TToken&);
+  virtual std::string drop(void);
   virtual void setCursorHint(const std::string&);
 
-protected:
-  TDocument document(void) const { return doc; }
+  virtual bool thaw(void);
 
-private:
-  void init(void);
+  DOM::Document document(void) const { return doc.document().cloneNode(true); }
 
+private:
   std::string PRIME(void) const;
   bool isPrimes(const TNode&) const;
   
index bf19fb187a12897fdfd32eab6175dea2adb195c4..1cb6ca15e5848a8f9827d1fde8e52e9ab51910c4 100644 (file)
@@ -22,8 +22,7 @@ struct TToken
       OTHER,
       ACTIVE,
       COMMENT,
-      CONTROL,
-      GDELETE
+      CONTROL
     };
 
   TToken(TCat c) : category(c) { };
index cfa10ec71cb1618fa4f7d88755624049d0d927b8..1002733a7a0ea1f4ea39adeb0154232b877995cd 100644 (file)
@@ -30,3 +30,9 @@ TTokenizer::push(const TToken& token)
   tokens.push_back(token);
 }
 
+std::string
+TTokenizer::drop()
+{
+  assert(0);
+  return "";
+}
index 54618c88b1e4c10120f31fc4cc159afacc47dd30..62d08241c13d6af833440a7c97d203dc3240e0d7 100644 (file)
@@ -18,6 +18,7 @@ public:
 
 private:
   virtual void push(const TToken&);
+  virtual std::string drop(void);
   virtual void setCursorHint(const std::string&) { };
 
   std::list<TToken> tokens;
index a2058302efdca768eb464e33eab22cfa6994995c..f31ecffb20cc1a569279f863125df7be6a4db93b 100644 (file)
@@ -6,6 +6,7 @@
 #include <GdomeSmartDOMXSLT.hh>
 
 namespace DOM = GdomeSmartDOM;
+namespace DOMX = GdomeSmartDOMExt;
 
 typedef DOM::Char32     TChar;
 typedef DOM::UCS4String TString;
index 2f26a91595f588f0667c7417f9ac894071295a7c..25755a8a8248a304e1b238a1d5b651701849d355 100644 (file)
@@ -2,7 +2,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/"
+#define TML_NS_URI    "http://helm.cs.unibo.it/2002/TML"
+#define XMLNS_NS_URI  "http://www.w3.org/2000/xmlns/"
+#define MATHML_NS_URI "http://www.w3.org/1998/Math/MathML"
 
 #endif // __globals_hh__
index 2bf438dc59736b397e75a7e898db5040d1d86559..dae4241b2119293e7d599355a930c4de112619b0 100644 (file)
@@ -74,12 +74,26 @@ GMETADOM_CFLAGS = @GMETADOM_CFLAGS@
 GMETADOM_LIBS = @GMETADOM_LIBS@
 GTKMATHVIEW_CFLAGS = @GTKMATHVIEW_CFLAGS@
 GTKMATHVIEW_LIBS = @GTKMATHVIEW_LIBS@
+HAVE_OCAMLC = @HAVE_OCAMLC@
+HAVE_OCAMLDEP = @HAVE_OCAMLDEP@
+HAVE_OCAMLFIND = @HAVE_OCAMLFIND@
+HAVE_OCAMLMKLIB = @HAVE_OCAMLMKLIB@
+HAVE_OCAMLOPT = @HAVE_OCAMLOPT@
 LDFLAGS = @LDFLAGS@
 LIBTOOL = @LIBTOOL@
 LN_S = @LN_S@
 MAKEINFO = @MAKEINFO@
+MLGDOME_CFLAGS = @MLGDOME_CFLAGS@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
+OCAMLC = @OCAMLC@
+OCAMLDEP = @OCAMLDEP@
+OCAMLFIND = @OCAMLFIND@
+OCAMLMKLIB = @OCAMLMKLIB@
+OCAMLOPT = @OCAMLOPT@
+OCAMLSTDLIBDIR = @OCAMLSTDLIBDIR@
+OCAMLSTUBDIR = @OCAMLSTUBDIR@
+OCAML_INCLUDE_DIR = @OCAML_INCLUDE_DIR@
 PACKAGE = @PACKAGE@
 RANLIB = @RANLIB@
 STRIP = @STRIP@
index 61f9e5d795e32372c9fa0016c600faa6acf97d08..4b4404af4e41370e26c8a5cff9e525a440ef18fc 100644 (file)
@@ -124,6 +124,14 @@ findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
   lastS = q;
 }
 
+static DOM::Element
+findElementWithRef(const DOM::Element& el)
+{
+  DOM::Element p = el;
+  while (p && !p.hasAttribute("xref")) p = p.get_parentNode();
+  return p;
+}
+
 static DOM::Node
 leftmostChild(const DOM::Node& node)
 {
@@ -188,17 +196,14 @@ rightSibling(const DOM::Node& node)
 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()))
+  if (GdomeNode* n = findCommonAncestor(DOM::Element(first), DOM::Element(last)).gdome_object())
     {
-      GdomeException exc = 0;
-      gdome_el_ref(res, &exc);
-      assert(exc == 0);
+      GdomeElement* res = gdome_cast_el(n);
+      g_assert(res != NULL);
       return res;
     }
   else
-    return 0;
+    return NULL;
 }
 
 extern "C" void
@@ -214,6 +219,32 @@ find_common_siblings(GdomeElement* first, GdomeElement* last,
   if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
 }
 
+extern "C" GdomeElement*
+find_element_with_ref(GdomeElement* elem)
+{
+  if (GdomeNode* n = findElementWithRef(DOM::Element(elem)).gdome_object())
+    {
+      GdomeElement* res = gdome_cast_el(n);
+      g_assert(res != NULL);
+      return res;
+    }
+  else
+    return NULL;
+}
+
+extern "C" GdomeElement*
+find_common_ancestor_with_ref(GdomeElement* first, GdomeElement* last)
+{
+  if (GdomeNode* n = findElementWithRef(findCommonAncestor(DOM::Element(first), DOM::Element(last))).gdome_object())
+    {
+      GdomeElement* res = gdome_cast_el(n);
+      g_assert(res != NULL);
+      return res;
+    }
+  else
+    return NULL;
+}
+
 extern "C" void
 delete_element(GdomeElement* elem)
 {
index 9d548289c6a2625491060ef5b83ae543a492c369..62435ca788e95322d9ca128f88231a17960039da 100644 (file)
@@ -5,36 +5,16 @@
 #include "TDictionary.hh"
 #include "CLoggerConsole.hh"
 #include "CMathMLFactoryXSLT.hh"
+#include "CMathMLFactoryXSLTDiff.hh"
 #include "AMathMLConsumer.hh"
 
 #include "guiGTK.h"
 
-TDictionary dictionary;
-
 extern void *parseMathMLFile(char *);
 
-class CMathMLConsumer : public AMathMLConsumer
-{
-public:
-  CMathMLConsumer(void) { firstTime = true; };
-
-  virtual void documentModified(const DOM::Document& result)
-  {
-    if (firstTime)
-      {
-       if (GUI_load_document(gdome_cast_doc(static_cast<GdomeNode*>(result))) < 0)
-         cerr << "c'e' stato un errore" << endl;
-       firstTime = false;
-      }
-  }
-
-private:
-  bool firstTime;
-};
-
 struct Context
 {
-  Context(const std::string& s, TPushLexer& l) : buffer(s), i(0), lexer(l) { };
+  Context(const std::string& s, TPushLexer& l, TPushParser& p) : buffer(s), i(0), lexer(l), parser(p) { };
 
   void send(void)
   {
@@ -45,6 +25,7 @@ struct Context
   std::string buffer;
   unsigned i;
   TPushLexer& lexer;
+  TPushParser& parser;
 };
 
 extern "C" int
@@ -58,27 +39,52 @@ edit_timeout(Context* data)
 }
 
 extern "C" void
-push_char(Context* context, gchar ch)
+edit_push_char(Context* context, gchar ch)
 {
+  assert(context != NULL);
   GUI_freeze();
   cout << "*** SENDING " << ch << endl;
   context->lexer.push(ch);
   GUI_thaw();
 }
 
+extern "C" void
+edit_push_string(Context* context, const gchar* s)
+{
+  assert(context != NULL);
+  assert(s != NULL);
+  GUI_freeze();
+  context->parser.freeze();
+  for (unsigned i = 0; s[i]; i++) context->lexer.push(s[i]);
+  context->parser.thaw();
+  GUI_thaw();
+}
+
+extern "C" void
+edit_drop(Context* context, gboolean alt)
+{
+  assert(context != NULL);
+  GUI_freeze();
+  context->lexer.drop(alt);
+  GUI_thaw();
+}
+
+void
 main(int argc, char* argv[])
 {
   CLoggerConsole logger;
+  logger.verbosity(ALogger::Debug);
+
+  TDictionary dictionary(logger);
   logger.info("loading the dictionary...");
-  dictionary.load("dictionary.xml");
+  dictionary.load("dictionary-test.xml");
 
   logger.info("loading the stylesheet...");
   DOM::DOMImplementation di;
   DOM::Document docStyle = di.createDocumentFromURI("./xsl/tml-mmlp.xsl");
-  DOM::XSLTStylesheet style(docStyle);
+  DOMX::XSLTStylesheet style(docStyle);
 
-  CMathMLConsumer consumer;
-  CMathMLFactoryXSLT factory(logger, consumer, style);
+  CMathMLFactoryXSLTDiff factory(logger, style);
   TPushParser parser(logger, factory, dictionary);
   TPushLexer lexer(logger, parser);
 
@@ -95,9 +101,10 @@ main(int argc, char* argv[])
   style.save(result, stdout);
 #endif
 
-  Context context("", lexer);
+  Context context("", lexer, parser);
 
   GUI_init(&argc, &argv, "mathmleditor", 500, 600, &context);
+  GUI_load_document(gdome_cast_doc(static_cast<GdomeNode*>(factory.document())));
   GUI_run();
   GUI_uninit();
   GUI_unload_document();
index cd1c7c878c4f8b117d68aefcde16695dd6534c8f..7426e3f5db0da0ed6b629e8820fe46b0e192e9e3 100644 (file)
 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 GdkCursor* normal_cursor;
-static GdkCursor* link_cursor;  
 
+static gpointer context = NULL;
 static gchar* doc_name = NULL;
+static GdomeElement* first_selected = NULL;
 static GdomeElement* root_selected = NULL;
 
-static guint statusbar_context;
-
 static void create_widget_set(gpointer);
 static GtkWidget* get_main_menu(void);
 static void file_open(GtkWidget*, gpointer);
@@ -57,9 +54,10 @@ static void options_change_font_size(GtkWidget*, gboolean);
 static void options_verbosity(GtkWidget*, guint);
 static void options_anti_aliasing(GtkWidget*, gpointer);
 static void options_transparency(GtkWidget*, gpointer);
-static void selection_delete(GtkWidget*, gpointer);
-static void selection_parent(GtkWidget*, gpointer);
-static void selection_reset(GtkWidget*, gpointer);
+static void edit_delete_selection(GtkWidget*, gpointer);
+static void edit_select_parent(GtkWidget*, gpointer);
+static void edit_reset_selection(GtkWidget*, gpointer);
+static void edit_insert(GtkWidget*, gpointer);
 static void help_about(GtkWidget*, gpointer);
 
 static GtkItemFactoryEntry menu_items[] = {
@@ -70,10 +68,12 @@ static GtkItemFactoryEntry menu_items[] = {
   { "/File/sep1",                      NULL,         NULL,          0, "<Separator>" },
   { "/File/_Quit",                     "<control>Q", gtk_main_quit, 0, NULL },
 
-  { "/_Selection",                     NULL, NULL,                  0,  "<Branch>" },
-  { "/Selection/Reset",                NULL, selection_reset,       0, NULL },
-  { "/Selection/Delete",               NULL, selection_delete,      0, NULL },
-  { "/Selection/Select Parent",        NULL, selection_parent,      0, NULL },
+  { "/_Edit",                          NULL, NULL,                  0,  "<Branch>" },
+  { "/Edit/Reset Selection",           NULL, edit_reset_selection,  0, NULL },
+  { "/Edit/Delete Selection",          NULL, edit_delete_selection, 0, NULL },
+  { "/Edit/Select Parent",             NULL, edit_select_parent,    0, NULL },
+  { "/Edit/sep1",                      NULL,         NULL,          0, "<Separator>" },
+  { "/Edit/Insert...",                 "<control>I", edit_insert,   0, NULL },
 
   { "/_Options",                       NULL, NULL,                  0,  "<Branch>" },
   { "/Options/Default _Font Size",     NULL, NULL,                  0,  "<Branch>" },
@@ -134,7 +134,7 @@ load_error_msg(const char* name)
 }
 
 void
-GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpointer context)
+GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpointer c)
 {
   gtk_init(argc, argv);
 
@@ -146,15 +146,30 @@ GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpoint
 
   gtk_widget_show(window);
 
-  normal_cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
-  link_cursor = gdk_cursor_new(GDK_HAND2);
-
+  context = c;
   /*edit_timeout_id = gtk_timeout_add(400, edit_timeout, context);*/
 }
 
 void
 GUI_uninit()
 {
+  GdomeException exc = 0;
+
+  if (first_selected != NULL)
+    {
+      gdome_el_unref(first_selected, &exc);
+      g_assert(exc == 0);
+      first_selected = NULL;
+    }
+
+  if (root_selected != NULL)
+    {
+      gdome_el_unref(root_selected, &exc);
+      g_assert(exc == 0);
+      root_selected = NULL;
+    }
+
+  context = NULL;
 }
 
 int
@@ -199,9 +214,6 @@ GUI_unload_document()
 
   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
@@ -314,7 +326,7 @@ options_verbosity(GtkWidget* widget, guint level)
 }
 
 static void
-selection_delete(GtkWidget* widget, gpointer data)
+edit_delete_selection(GtkWidget* widget, gpointer data)
 {
   if (root_selected != NULL)
     {
@@ -330,7 +342,7 @@ selection_delete(GtkWidget* widget, gpointer data)
 }
 
 static void
-selection_parent(GtkWidget* widget, gpointer data)
+edit_select_parent(GtkWidget* widget, gpointer data)
 {
   if (root_selected != NULL)
     {
@@ -345,7 +357,7 @@ selection_parent(GtkWidget* widget, gpointer data)
 }
 
 static void
-selection_reset(GtkWidget* widget, gpointer data)
+edit_reset_selection(GtkWidget* widget, gpointer data)
 {
   if (root_selected != NULL)
     {
@@ -357,6 +369,51 @@ selection_reset(GtkWidget* widget, gpointer data)
     }
 }
 
+static void
+insert_tex(GtkWidget* widget, GtkEntry* entry)
+{
+  gchar* text;
+  g_return_if_fail(entry != NULL);
+
+  text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
+  edit_push_string(context, text);
+  g_free(text);
+}
+
+static void
+edit_insert(GtkWidget* widget, gpointer data)
+{
+  GtkWidget* dialog;
+  GtkWidget* entry;
+  GtkWidget* ok;
+  GtkWidget* cancel;
+
+  dialog = gtk_dialog_new();
+  entry = gtk_entry_new();
+  ok = gtk_button_new_with_label("OK");
+  cancel = gtk_button_new_with_label("Cancel");
+
+  gtk_signal_connect (GTK_OBJECT (ok), "clicked",
+                     GTK_SIGNAL_FUNC (insert_tex), (gpointer) entry);
+
+  gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+  gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+  gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+  gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 5);
+
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), entry);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), ok);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), cancel);
+
+  gtk_widget_show_all (dialog);
+}
+
 static void
 help_about(GtkWidget* widget, gpointer data)
 {
@@ -365,7 +422,7 @@ help_about(GtkWidget* widget, gpointer data)
   GtkWidget* ok;
 
   dialog = gtk_dialog_new();
-  label = gtk_label_new("\n    MathML Viewer    \n    Copyright (C) 2000-2003 Luca Padovani    \n");
+  label = gtk_label_new("\n    MathML Editor    \n    Copyright (C) 2003 Luca Padovani    \n");
   ok = gtk_button_new_with_label("Close");
 
   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
@@ -379,7 +436,7 @@ help_about(GtkWidget* widget, gpointer data)
 }
 
 static void
-change_default_font_size(GtkSpinButton* widget, GtkSpinButton* spin)
+change_default_font_size(GtkWidget* widget, GtkSpinButton* spin)
 {
   g_return_if_fail(spin != NULL);
   gtk_math_view_set_font_size( GTK_MATH_VIEW(main_area), gtk_spin_button_get_value_as_int(spin));
@@ -436,97 +493,75 @@ options_set_font_size(GtkWidget* widget, gpointer data)
   gtk_widget_show_all (dialog);
 }
 
-#if 0
-#if defined(HAVE_GMETADOM)
 static void
-element_changed(GtkMathView* math_view, GdomeElement* elem)
+select_begin(GtkMathView* math_view, GdomeElement* first, gint state)
 {
-  GdomeDOMString* link = NULL;
-
-  g_return_if_fail(math_view != NULL);
-  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
-
-/*   printf("pointer is on %p\n", elem); */
+  GdomeException exc = 0;
 
-  link = find_hyperlink(elem, XLINK_NS_URI, "href");
-  if (link != NULL)
-    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, link_cursor);
-  else
-    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, normal_cursor);
-
-  if (link != NULL)
-    gdome_str_unref(link);
-}
-#endif
-#endif
-
-static void
-selection_changed(GtkMathView* math_view, GdomeElement* first, GdomeElement* last)
-{
   g_return_if_fail(math_view != NULL);
   g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
   g_return_if_fail(first != NULL);
 
-/*   printf("selection changed %p %p\n", first, last); */
+  gtk_math_view_freeze(math_view);
 
-  if (last != NULL)
+  if (root_selected != NULL)
     {
-      GdomeException exc = 0;
+      gtk_math_view_unselect(math_view, root_selected);
+      gdome_el_unref(root_selected, &exc);
+      g_assert(exc == 0);
+    }
 
-      if (root_selected != NULL)
-       {
-         gdome_el_unref(root_selected, &exc);
-         g_assert(exc == 0);
-       }
+  root_selected = first_selected = find_element_with_ref(first);
 
-      root_selected = find_common_ancestor(first, last);
-/*       printf("selecting root %p\n", first, last, root_selected); */
-      /* gtk_math_view_set_selection(math_view, root_selected); */
+  if (root_selected != NULL)
+    {
+      gtk_math_view_select(math_view, root_selected);
+      gdome_el_ref(root_selected, &exc);
       g_assert(exc == 0);
     }
+
+  gtk_math_view_thaw(math_view);
 }
 
-#if 0
-#if defined(HAVE_GMETADOM)
 static void
-clicked(GtkMathView* math_view, GdomeElement* elem)
+select_over(GtkMathView* math_view, GdomeElement* elem, gint state)
 {
-  GdomeException exc;
-  GdomeDOMString* name;
-  GdomeDOMString* ns_uri;
-  GdomeElement* p;
+  GdomeElement* new_selected = NULL;
+  GdomeException exc = 0;
 
   g_return_if_fail(math_view != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+  g_return_if_fail(elem != NULL);
 
-  /* printf("clicked on %p\n", elem); */
+  if (first_selected == NULL || elem == NULL)
+    new_selected = NULL;
+  else
+    new_selected = find_common_ancestor_with_ref(first_selected, elem);
 
-  if (elem != NULL)
+  if (new_selected != root_selected)
     {
-      GdomeElement* action;
-      GdomeDOMString* href = find_hyperlink(elem, XLINK_NS_URI, "href");
-      if (href != NULL)
-       {
-/*       printf("hyperlink %s\n", href->str); */
-         gdome_str_unref(href);
-       }
-
-      action = find_self_or_ancestor(elem, MATHML_NS_URI, "maction");
-/*       printf("action? %p\n", action); */
-      if (action != NULL)
+      gtk_math_view_freeze(math_view);
+      if (root_selected != NULL)
        {
-         gtk_math_view_freeze(math_view);
-         action_toggle(action);
-         gtk_math_view_thaw(math_view);
-         gdome_el_unref(action, &exc);
+         gtk_math_view_unselect(math_view, root_selected);
+         gdome_el_unref(root_selected, &exc);
          g_assert(exc == 0);
        }
+      root_selected = new_selected;
+      if (root_selected != NULL)
+       gtk_math_view_select(math_view, root_selected);
+      gtk_math_view_thaw(math_view);
+    }
+  else if (new_selected != NULL)
+    {
+      gdome_el_unref(new_selected, &exc);
+      g_assert(exc == 0);
     }
+
 }
-#endif
-#endif
 
 static gboolean
-key_press_event(gpointer context,
+key_press_event(gpointer c,
                GdkEventKey* event,
                GtkWidget* widget)
 {
@@ -536,36 +571,16 @@ key_press_event(gpointer context,
 
   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;
-  case GDK_BackSpace: push_char(context, event->keyval); break;
-  default:
-    if (event->keyval < 0x80) push_char(context, event->keyval);
-    return FALSE;
-  }
+  switch (event->keyval)
+    {
+    case GDK_BackSpace:
+      edit_drop(context, event->state & GDK_MOD1_MASK);
+      break;
+    default:
+      if ((event->state & (~GDK_SHIFT_MASK)) == 0 && event->keyval < 0x80)
+       edit_push_char(context, event->keyval);
+      return FALSE;
+    }
 
   return TRUE;
 }
@@ -590,33 +605,19 @@ create_widget_set(gpointer context)
 
   //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),
+                            "select_begin", GTK_SIGNAL_FUNC (select_begin),
                             (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),
+                            "select_over", GTK_SIGNAL_FUNC (select_over),
                             (gpointer) main_area);
-#endif
 
   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);
+  gtk_widget_add_events(GTK_WIDGET(main_area), GDK_KEY_PRESS_MASK);
 
   scrolled_area = gtk_scrolled_window_new(NULL, NULL);
   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area),
@@ -626,71 +627,11 @@ create_widget_set(gpointer context)
   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);
-}
-
-#if 0
-static void
-create_widget_set()
-{
-  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_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), 
-                            "clicked", GTK_SIGNAL_FUNC(clicked),
-                            (gpointer) main_area);
-
-  gtk_widget_add_events(GTK_WIDGET(main_area),
-                       GDK_BUTTON_PRESS_MASK
-                       | GDK_BUTTON_RELEASE_MASK
-                       | GDK_POINTER_MOTION_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);
 }
-#endif
 
 GtkWidget*
 get_main_menu()
index 9054b9c997ffbaf020b6378f819c373384ed3fbd..8736053872db15bd8c9b00518b0d4cd910786493 100644 (file)
@@ -88,9 +88,7 @@
            <xsl:attribute name="xref">
              <xsl:value-of select="@id"/>
            </xsl:attribute>
-         </xsl:if>
-        I
-        </m:mtext>
+         </xsl:if>I</m:mtext>
       </xsl:otherwise>
     </xsl:choose>
   </xsl:template>
           <xsl:value-of select="@id"/>
         </xsl:attribute>
       </xsl:if>
-      <xsl:apply-templates select="*[2]"/>
-      <xsl:apply-templates select="*[1]"/>
+      <xsl:choose>
+        <xsl:when test="count(*) &lt; 2">
+         <m:mrow/>
+         <xsl:apply-templates select="*[1]"/>
+       </xsl:when>
+       <xsl:otherwise>
+          <xsl:apply-templates select="*[2]"/>
+          <xsl:apply-templates select="*[1]"/>
+       </xsl:otherwise>
+      </xsl:choose>
     </m:mroot>
   </xsl:template>