See attached patch.
-> gives \rightarrow -<space> > gives - > (what ever that should mean) I think I'll change the format of lib/autocorrect at some point of time, so this is not finished there. Andre' -- Those who desire to give up Freedom in order to gain Security, will not have, nor do they deserve, either one. (T. Jefferson)
Index: lib/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/ChangeLog,v retrieving revision 1.212 diff -u -p -r1.212 ChangeLog --- lib/ChangeLog 3 May 2002 18:34:48 -0000 1.212 +++ lib/ChangeLog 23 May 2002 17:39:31 -0000 @@ -1,3 +1,8 @@ + +2002-05-23 André Pönitz <[EMAIL PROTECTED]> + + * lib/autocorrect: new file + 2002-05-03 Claus Hindsgaul <[EMAIL PROTECTED]> * examples/da_splash.lyx: revised Index: lib/autocorrect =================================================================== RCS file: lib/autocorrect diff -N lib/autocorrect --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/autocorrect 23 May 2002 17:39:31 -0000 @@ -0,0 +1,352 @@ + +# +# Idea of "autocorrection" and parts of this file are shamelessly stolen +# from TeXMacs (they give [EMAIL PROTECTED] as contact) +# +# We do it a bit differently and allow corrections only to combine a symbol +# and a char to a new symbol. +# +# + +| , \lfloor +\lfloor * |, +| ' \lceil +\lceil * |' +, | \rfloor +\rfloor * ,| +' | \rceil +\rceil * '| +\llbracket * [[* +\rrbracket * ]]* + +\cap * \sqcap +\cup * \sqcup +\vee * \curlyvee +\curlyvee * \curlyveeuparrow +\curlyveeuparrow * \curlyveedownarrow + +< / \nless +> / \ngtr +< = \leqslant +> = \geqslant +\leqslant / \nleqslant +\geqslant / \ngeqslant +\leqslant * \leq +\geslant * \geq +\leq / \nleq +\geq / \ngeq +< < \ll +\ll < \lll +> > \gg +\gg > \ggg +\ll = \lleq +\lll = \llleq +\gg = \ggeq +\ggg = \gggeq +\ll / \nll +\lll / \nlll +\gg / \ngg +\ggg / \nggg +\lleq / \nlleq +\llleq / \nllleq +\ggeq / \nggeq +\gggeq / \ngggeq +< . \lessdot +. > \gtrdot +\leqslant . \lesseqdot +\gtrdot = \gtreqdot + +< * \prec +> * \succ +\prec / \nprec +\succ / \nsucc +\prec = \preccurlyeq +\succ = \succcurlyeq +\preccurlyeq / \npreccurlyeq +\succcurlyeq / \nsucccurlyeq +\preccurlyeq * \preceq +\succcurlyeq * \succeq +\preceq / \npreceq +\succeq / \nsucceq +\npreceq * \precneqq +\nsucceq * \succneqq +\ll * \precprec +\precprec * \precprecprec +\gg * \succsucc +\succsucc * \succsuccsucc +\precprec = \precpreceq +\lll * \precprecprec +\precprecprec = \precprecpreceq +\succsucc = \succsucceq +\ggg = \succsuccsucc +\succsuccsucc = \succsuccsucceq +\precprec / \nprecprec +\precprecprec / \nprecprecprec +\succsucc / \nsuccsucc +\succsuccsucc / \nsuccsuccsucc +\precpreceq / \nprecpreceq +\precprecpreceq / \nprecprecpreceq +\succsucceq / \nsuccsucceq +\succsuccsucceq / \nsuccsuccsucceq + +\prec . \precdot +\succ . \dotsucc +\precdot . \preceqdot +\dotsucc . \dotsucceq +\precprec * \llangle +\succsucc * \rrangle + +< > \lessgtr +> < \gtrless +< ~ \lesssim +\lesssim ~ \lessapprox +\prec ~ \precsim +\precsim ~ \precapprox +> ~ \gtrsim +\gtrsim ~ \gtrapprox +\succ ~ \gtrsim +\gtrsim ~ \gtrapprox +\leq * \leqq +\geq * \geqq +\leq > \lesseqgtr +\geq < \gtrqless + +- > \rightarrow +< - \leftarrow +\leftarrow > \leftrightarrow +\rightarrow - \longrightarrow +\leftarrow - \longleftarrow +\longleftarrow > \longleftrightarrow += > \Rightarrow + + +@ * \circ +\circ / \varnothing +\circ + \oplus +\circ - \ominus +@ x \otimes +\circ : \oover +\circ . \odot +@ R \circledR +@ S \circledS +\varnothing * \oslash +@ \ \obslash +@ @ \infty +\circ < \olessthan +\circ > \ogreaterthan +\circ & \owedge +\circ | \obar +\obar * \ovee +\circ v \ovee +\circ @ \infty +@@ * \varocircle +-@ @ \infty +\circ * \box +\box + \boxplus +\box - \boxminus +\box x \boxtimes +\box . \boxdot +\box / \boxslash +\box \ \boxbslash +\box @ \boxcircle +\boxcircle * \boxbox +\box | \boxbar +\box * \bullet +\bullet * \blacksquare + += * \asymp +\asymp * \equiv +\equiv * \asympasymp +\asympasymp * \simsim +~ * \sim +\sim ~ \approx +\approx - \approxeq +\sim - \simeq +\sim = \cong += / \neq +\asymp / \nasymp +\equiv / \nequiv +\asympasymp / \nasympasymp +\simsim / \nsimsim +\sim / \nsim +\approx / \napprox +\simeq / \nsimeq +\cong / \ncong + +#| \| +| * \shortmid +\shortmid * \varshortmid +| | \|| +\|| | \interleave +\|| * \shortparallel +| - \vdash +\vdash - \longvdash +\|| - \Vdash +\Vdash - \longVdash +\interleave - \Vvdash +\Vvdash - \longVvdash +- | \dashv + +< | \vartriangleleft +\vartriangleleft * \blacktriangleleft +\vartriangleleft / \ntriangleleft +\vartriangleleft = \trianglelefteqslant +\trianglelefteqslant / \ntrianglelefteqslant +\trianglelefteqslant * \trianglelefteq +\trianglelefteq / \ntriangleqleft +| > \vartriangleright +\vartriangleright * \blacktriangleright +\vartriangleright / \ntriangleright +\vartriangleright = \trianglerighteq +\trianglerighteq / \ntriangleqright +\trianglerighteq * \trianglerighteqslant +\trianglerighteqslant / \ntrianglerighteqslant + +- * \um ++ - \pm +\pm * \upm +- + \mp +\mp * \ump +@ = \circeq += @ \eqcirc +- @ \multimap +. = \doteq +. . \ldots +\ldots * \cdots +\cdots * \hdots +\hdots * \vdots +\ddots * \ddots +\udots * \udots +: = \assign ++ = \plusassign +- = \minusassign +/ * \div +* * \ast +\ast * \times +\times * \cdot + +< * \subset +\subset * \in +\ / \nsubset +\in * \sqsubset +\subset = \subseteq +\subseteq / \nsubseteq +\subseteq * \subseteqq +\sqsubset * \langle +\langle * \leftslice +\leftslice * \subset + +\subseteq / \nsubseteq +\subseteqq / \nsubseteqq +\nsubseteqq * \subsetneq +\subsetneq * \varsubsetneq +\varsubsetneq * \subsetneqq +\subsetneqq * \varsubsetneqq +\subset + \subsetplus +\subsetplus = \subsetpluseq +\subseteq + \subsetpluseq +\in / \nin +> * \supset +\supset / \nsupset +\supset = \supseteq +\supseteq / \nsupseteq +\supseteq * \supseteqq +\supseteq / \nsupseteq + + +\supseteqq / \nsupseteqq +\supseteq / \supsetneq +\supset + \supsetplus +\supsetplus = \supsetpluseq +\supseteq + \supsetpluseq +\supset * \ni +\ni / \nni + +# +# The following is available in TeXMacs, but not (yet) in LyX +# + +#--| \longdashv +#| = \vDash +#\vDash = \longvDash +#||= \VDash +#||== \longVDash +#| / \nmid +#||/ \nparallel +#|*/ \nshortmid +#||*/ \nshortparallel +#|-/ \nvdash +#||-/ \nVdash +#-|/ \ndashv +#-||/ \ndashV +#|=/ \nvDash +#||=/ \nVDash +#=|/ \nDashv +#=||/ \nDashV +# +#<=**> \lesseqqgtr +#>=**< \gtreqqless +#<>/ \nlessgtr +#></ \ngtrless +#<~/ \nlesssim +#<~/* \lnsim +#<~~/ \nlessapprox +#<~~/* \lnapprox +#<*~/ \nprecsim +#<*~/* \precnsim +#<*~~/ \nprecapprox +#<*~~/* \precnapprox +#>~/ \ngtrsim +#>~/* \gnsim +#>~~/ \ngtrapprox +#>~~/* \gnapprox +#>*~/ \nsuccsim +#>*~/* \succnsim +#>*~~/ \nsuccapprox +#>*~~/* \succnapprox +#<=**/ \nleqq +#>=**/ \ngeqq +#<=*>/ \nlesseqgtr +#>=*</ \ngtreqless +#<=**>/ \nlesseqqgtr +#>=**</ \ngtreqqless +#<=*/* \lneq +#<=**/* \lneqq +#<=**/** \lvertneqq +#>=*/* \gneq +#>=**/* \gneqq +#>=**/** \gvertneqq +#[[ * \llbracket +#]] * \rrbracket +#EE a \amalg +#EE d \partial +#EE p \wp +#EE n \cap +#EE u \cup +#EE w \wedge +#\wedge * \curlywedge +#\curlywedge * \curlywedgeuparrow +#\curlywedgeuparrow * \curlywedgedownarrow +#\curlywedgedownarrow * \wedges +#EE v \vee +#EE x \times + +# <***/ \nsqsubset +# <***= \sqsubseteq +# <***=/ \nsqsubseteq +# >*=/** \varsupsetneq +# >*=*/* \supsetneqq +# >*=*/** \varsupsetneqq +# >*** \sqsupset +# >***/ \nsqsupset +# >***= \sqsupseteq +# >***=/ \nsqsupseteq + +# >**** \rangle +# \rangle * \rightslice + +# EE l \bigl +# EE m \bigm +# EE r \bigr +# EE @ \bigop +# EE L \int Index: src/mathed/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/ChangeLog,v retrieving revision 1.231 diff -u -p -r1.231 ChangeLog --- src/mathed/ChangeLog 23 May 2002 12:08:47 -0000 1.231 +++ src/mathed/ChangeLog 23 May 2002 17:39:32 -0000 @@ -1,3 +1,11 @@ + +2002-05-23 André Pönitz <[EMAIL PROTECTED]> + + * math_autocorrect.[Ch]: new "auto correction" feature + * math_cursor.[Ch]: subsequent changes + * math_parser.C: somewhat better error reporting + + 2002-05-23 John Levon <[EMAIL PROTECTED]> * formula.C: Index: src/mathed/Makefile.am =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/Makefile.am,v retrieving revision 1.88 diff -u -p -r1.88 Makefile.am --- src/mathed/Makefile.am 25 Mar 2002 13:24:28 -0000 1.88 +++ src/mathed/Makefile.am 23 May 2002 17:39:32 -0000 @@ -19,6 +19,8 @@ libmathed_la_SOURCES = \ math_arrayinset.h \ math_atom.C \ math_atom.h \ + math_autocorrect.C \ + math_autocorrect.h \ math_biginset.C \ math_biginset.h \ math_binominset.C \ Index: src/mathed/math_autocorrect.C =================================================================== RCS file: src/mathed/math_autocorrect.C diff -N src/mathed/math_autocorrect.C --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/mathed/math_autocorrect.C 23 May 2002 17:39:32 -0000 @@ -0,0 +1,168 @@ +#include <config.h> + +#include "LString.h" +#include "Lsstream.h" +#include "debug.h" +#include "support/filetools.h" // LibFileSearch +#include "math_data.h" +#include "math_inset.h" +#include "math_parser.h" + +#include <iostream> +#include <fstream> + +using std::ifstream; +using std::istream; +using std::ostream; +using std::endl; + + +namespace { + +class Correction { +public: + /// + Correction() {} + /// + bool correct(MathAtom & at, char c) const; + /// + bool read(istream & is); + /// + void write(ostream & os) const; +private: + /// + MathAtom from1_; + /// + char from2_; + /// + MathAtom to_; +}; + + +bool Correction::read(istream & is) +{ + string s1, s2, s3; + is >> s1 >> s2 >> s3; + if (!is) + return false; + MathArray ar1, ar3; + mathed_parse_cell(ar1, s1); + mathed_parse_cell(ar3, s3); + if (ar1.size() != 1 || s2.size() != 1 || ar3.size() !=1) + return false; + from1_ = ar1.front(); + from2_ = s2[0]; + to_ = ar3.front(); + return true; +} + + +void Correction::write(ostream & os) const +{ + os << "from: '" << from1_ << "' and '" << from2_ + << "' to '" << to_ << "'" << endl; +} + + +bool Correction::correct(MathAtom & at, char c) const +{ + //lyxerr[Debug::MATHED] + // << "trying to correct ar: " << at << " from: '" << from1_ << "'" << +endl; + if (from2_ != c) + return false; + if (!at->match(from1_.nucleus())) + return false; + lyxerr[Debug::MATHED] + << "match found! subst in " << at + << " from: '" << from1_ << "' to '" << to_ << "'" << endl; + at = to_; + return true; +} + + +istream & operator>>(istream & is, Correction & corr) +{ + corr.read(is); + return is; +} + + +ostream & operator<<(ostream & os, Correction & corr) +{ + corr.write(os); + return os; +} + + + + +class Corrections { +public: + /// + typedef vector<Correction>::const_iterator const_iterator; + /// + Corrections() {} + /// + void insert(const Correction & corr) { data_.push_back(corr); } + /// + bool correct(MathAtom & at, char c) const; +private: + /// + vector<Correction> data_; +}; + + +bool Corrections::correct(MathAtom & at, char c) const +{ + for (const_iterator it = data_.begin(); it != data_.end(); ++it) + if (it->correct(at, c)) + return true; + return false; +} + + +Corrections theCorrections; + +void initAutoCorrect() +{ + lyxerr[Debug::MATHED] << "reading autocorrect file" << endl; + string const file = LibFileSearch(string(), "autocorrect"); + if (file.empty()) { + lyxerr << "Could not find autocorrect file" << endl; + return; + } + + string line; + ifstream is(file.c_str()); + while (getline(is, line)) { + if (line.size() == 0 || line[0] == '#') { + //lyxerr[Debug::MATHED] << "ignoring line '" << line << "'" << +endl; + continue; + } + istringstream il(line); + //lyxerr[Debug::MATHED] << "line '" << line << "'" << endl; + Correction corr; + if (corr.read(il)) { + //lyxerr[Debug::MATHED] << "parsed: '" << corr << "'" << endl; + theCorrections.insert(corr); + } + } + + lyxerr[Debug::MATHED] << "done reading autocorrections." << endl; +} + + +} // namespace anon + + +bool math_autocorrect(MathAtom & at, char c) +{ + static bool initialized = false; + + if (!initialized) { + initAutoCorrect(); + initialized = true; + } + + return theCorrections.correct(at, c); +} Index: src/mathed/math_autocorrect.h =================================================================== RCS file: src/mathed/math_autocorrect.h diff -N src/mathed/math_autocorrect.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/mathed/math_autocorrect.h 23 May 2002 17:39:32 -0000 @@ -0,0 +1,9 @@ +#ifndef MATHAUTOCORRECT_H +#define MATHAUTOCORRECT_H + +class MathAtom; + +// make "corrections" according to file lib/autocorrect +bool math_autocorrect(MathAtom & at, char c); + +#endif Index: src/mathed/math_cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_cursor.C,v retrieving revision 1.262 diff -u -p -r1.262 math_cursor.C --- src/mathed/math_cursor.C 23 May 2002 09:21:30 -0000 1.262 +++ src/mathed/math_cursor.C 23 May 2002 17:39:32 -0000 @@ -29,6 +29,7 @@ #include "frontends/Painter.h" #include "math_cursor.h" #include "formulabase.h" +#include "math_autocorrect.h" #include "math_arrayinset.h" #include "math_braceinset.h" #include "math_boxinset.h" @@ -182,7 +183,8 @@ Selection theSelection; MathCursor::MathCursor(InsetFormulaBase * formula, bool left) - : formula_(formula), lastcode_(LM_TC_MIN), selection_(false) + : formula_(formula), lastcode_(LM_TC_MIN), + autocorrect_(false), selection_(false) { left ? first() : last(); } @@ -299,6 +301,7 @@ bool MathCursor::posRight() bool MathCursor::left(bool sel) { dump("Left 1"); + autocorrect_ = false; if (inMacroMode()) { macroModeClose(); lastcode_ = LM_TC_MIN; @@ -319,6 +322,7 @@ bool MathCursor::left(bool sel) bool MathCursor::right(bool sel) { dump("Right 1"); + autocorrect_ = false; if (inMacroMode()) { macroModeClose(); lastcode_ = LM_TC_MIN; @@ -351,7 +355,7 @@ void MathCursor::last() bool positionable(MathCursor::cursor_type const & cursor, - MathCursor::cursor_type const & anchor) + MathCursor::cursor_type const & anchor) { // avoid deeper nested insets when selecting if (cursor.size() > anchor.size()) @@ -386,6 +390,7 @@ void MathCursor::setPos(int x, int y) void MathCursor::home(bool sel) { dump("home 1"); + autocorrect_ = false; selHandle(sel); macroModeClose(); lastcode_ = LM_TC_MIN; @@ -398,6 +403,7 @@ void MathCursor::home(bool sel) void MathCursor::end(bool sel) { dump("end 1"); + autocorrect_ = false; selHandle(sel); macroModeClose(); lastcode_ = LM_TC_MIN; @@ -498,6 +504,7 @@ void MathCursor::paste(MathArray const & void MathCursor::backspace() { + autocorrect_ = false; if (pos() == 0) { pullArg(false); return; @@ -523,6 +530,7 @@ void MathCursor::backspace() void MathCursor::erase() { + autocorrect_ = false; if (inMacroMode()) return; @@ -556,6 +564,7 @@ void MathCursor::erase() void MathCursor::delLine() { + autocorrect_ = false; macroModeClose(); if (selection_) { @@ -586,6 +595,7 @@ bool MathCursor::up(bool sel) if (goUpDown(true)) return true; Cursor_ = save; + autocorrect_ = false; return selection_; } @@ -599,6 +609,7 @@ bool MathCursor::down(bool sel) if (goUpDown(false)) return true; Cursor_ = save; + autocorrect_ = false; return selection_; } @@ -1490,6 +1501,12 @@ bool MathCursor::interpret(char c) return true; } + // leave autocorrect mode if necessary + if (autocorrect_ && c == ' ') { + autocorrect_ = false; + return true; + } + // just clear selection on pressing the space par if (selection_ && c == ' ') { selClear(); @@ -1563,9 +1580,14 @@ bool MathCursor::interpret(char c) return true; } + // try auto-correction + if (autocorrect_ && hasPrevAtom() && math_autocorrect(prevAtom(), c)) + return true; + // no special circumstances, so insert the character without any fuss insert(c, lastcode_ == LM_TC_MIN ? MathCharInset::nativeCode(c) : lastcode_); lastcode_ = LM_TC_MIN; + autocorrect_ = true; return true; } Index: src/mathed/math_cursor.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_cursor.h,v retrieving revision 1.105 diff -u -p -r1.105 math_cursor.h --- src/mathed/math_cursor.h 14 May 2002 09:15:40 -0000 1.105 +++ src/mathed/math_cursor.h 23 May 2002 17:39:32 -0000 @@ -287,7 +287,8 @@ private: InsetFormulaBase * formula_; /// text code of last char entered MathTextCodes lastcode_; - // Selection stuff + /// do we allow autocorrection + bool autocorrect_; /// do we currently select bool selection_; }; Index: src/mathed/math_inset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_inset.C,v retrieving revision 1.81 diff -u -p -r1.81 math_inset.C --- src/mathed/math_inset.C 8 Apr 2002 08:12:09 -0000 1.81 +++ src/mathed/math_inset.C 23 May 2002 17:39:32 -0000 @@ -38,13 +38,22 @@ int MathInset::height() const } +ostream & operator<<(ostream & os, MathAtom const & at) +{ + if (at.nucleus()) + os << *(at.nucleus()); + else + os << "(nil)"; + return os; +} + + ostream & operator<<(ostream & os, MathInset const & inset) { WriteStream wi(os, false, false); inset.write(wi); return os; } - MathInset::size_type MathInset::nargs() const { Index: src/mathed/math_inset.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_inset.h,v retrieving revision 1.111 diff -u -p -r1.111 math_inset.h --- src/mathed/math_inset.h 24 Apr 2002 17:07:42 -0000 1.111 +++ src/mathed/math_inset.h 23 May 2002 17:39:32 -0000 @@ -255,5 +255,6 @@ public: }; std::ostream & operator<<(std::ostream &, MathInset const &); +std::ostream & operator<<(std::ostream &, MathAtom const &); #endif Index: src/mathed/math_parser.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_parser.C,v retrieving revision 1.197 diff -u -p -r1.197 math_parser.C --- src/mathed/math_parser.C 22 Apr 2002 16:31:14 -0000 1.197 +++ src/mathed/math_parser.C 23 May 2002 17:39:32 -0000 @@ -420,8 +420,10 @@ bool Parser::good() const char Parser::getChar() { - if (!good()) + if (!good()) { lyxerr << "The input stream is not well..." << endl; + dump(); + } return tokens_[pos_++].character(); } @@ -486,7 +488,7 @@ void Parser::tokenize(string const & buf char c; while (is.get(c)) { - //lyxerr << "reading c: " << c << "\n"; + lyxerr << "reading c: " << c << "\n"; switch (catcode(c)) { case catNewline: { @@ -1030,8 +1032,8 @@ void Parser::parse_into1(MathArray & arr else if (t.cat() == catEnd) { if (flags & FLAG_BRACE_LAST) return; - dump(); lyxerr << "found '}' unexpectedly, array: '" << array << "'\n"; + dump(); //lyxerr << "found '}' unexpectedly\n"; //lyx::Assert(0); //add(array, '}', LM_TC_TEX); @@ -1039,6 +1041,7 @@ void Parser::parse_into1(MathArray & arr else if (t.cat() == catAlign) { lyxerr << "found tab unexpectedly, array: '" << array << "'\n"; + dump(); //lyxerr << "found tab unexpectedly\n"; add(array, '&', LM_TC_TEX); }