From ba5f02ca07e7a1a9b3aa3306a0ca73ef22a6c57f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Mon, 13 Aug 2001 14:02:37 +0000 Subject: [PATCH] small step to a unified parser for file & interactive input git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2501 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/ChangeLog | 8 + src/mathed/Makefile.am | 2 + src/mathed/formulabase.C | 216 ++++--------------- src/mathed/math_cursor.C | 398 +++++++++++++++++++---------------- src/mathed/math_cursor.h | 6 +- src/mathed/math_defs.h | 8 +- src/mathed/math_hash.C | 5 +- src/mathed/math_macrotable.C | 4 +- src/mathed/math_parser.C | 182 ++++++---------- src/mathed/math_parser.h | 8 +- 10 files changed, 345 insertions(+), 492 deletions(-) diff --git a/src/mathed/ChangeLog b/src/mathed/ChangeLog index a2784e6cb4..02a744d5b9 100644 --- a/src/mathed/ChangeLog +++ b/src/mathed/ChangeLog @@ -1,4 +1,12 @@ +2001-08-13 André Pönitz + + * math_factory.[Ch]: new files for the creation of math insets + + * math_parser.C: + math_cursor.C: + math_hash.C: simplifications + 2001-08-10 André Pönitz * math_scopeinset.[Ch]: new inset for {} blocks diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index dd26fecdac..7ba7b4df3e 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -37,6 +37,8 @@ libmathed_la_SOURCES = \ math_diminset.h \ math_dotsinset.C \ math_dotsinset.h \ + math_factory.C \ + math_factory.h \ math_fracinset.C \ math_fracinset.h \ math_fracbase.C \ diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index b68844fa55..aaba69af14 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -344,6 +344,7 @@ void InsetFormulaBase::insetKeyPress(XKeyEvent *) } +int greek_kb_flag = 0; UpdatableInset::RESULT InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, @@ -352,22 +353,17 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, //lyxerr << "InsetFormulaBase::LocalDispatch: act: " << action // << " arg: '" << arg << "' cursor: " << mathcursor << "\n"; - static int greek_kb_flag = 0; if (!mathcursor) return UNDISPATCHED; - MathTextCodes varcode = LM_TC_MIN; - bool was_macro = mathcursor->inMacroMode(); - bool sel = false; + RESULT result = DISPATCHED; + bool sel = false; + bool was_macro = mathcursor->inMacroMode(); bool was_selection = mathcursor->selection(); - RESULT result = DISPATCHED; hideInsetCursor(bv); - if (mathcursor->getLastCode() == LM_TC_TEX) - varcode = LM_TC_TEX; - mathcursor->normalize(); switch (action) { @@ -457,8 +453,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, // sprintf(dispatch_buffer, "%d %d",); // dispatch_result = dispatch_buffer; // break; - case LFUN_SETXY: - { + case LFUN_SETXY: { lyxerr << "LFUN_SETXY broken!\n"; int x; int y; @@ -469,9 +464,8 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, par()->getXY(x1, y1); mathcursor->setPos(x1 + x, y1 + y); updateLocal(bv, false); + break; } - break; - case LFUN_PASTE: if (was_macro) @@ -499,42 +493,26 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, // --- accented characters ------------------------------ - case LFUN_UMLAUT: handleAccent(bv, "ddot"); break; - case LFUN_CIRCUMFLEX: handleAccent(bv, "hat"); break; - case LFUN_GRAVE: handleAccent(bv, "grave"); break; - case LFUN_ACUTE: handleAccent(bv, "acute"); break; - case LFUN_TILDE: handleAccent(bv, "tilde"); break; - case LFUN_MACRON: handleAccent(bv, "bar"); break; - case LFUN_DOT: handleAccent(bv, "dot"); break; - case LFUN_CARON: handleAccent(bv, "check"); break; - case LFUN_BREVE: handleAccent(bv, "breve"); break; - case LFUN_VECTOR: handleAccent(bv, "vec"); break; - - // Greek mode - case LFUN_GREEK: - if (!greek_kb_flag) { - greek_kb_flag = 1; - bv->owner()->message(_("Math greek mode on")); - } else - greek_kb_flag = 0; - break; - - // Greek keyboard - case LFUN_GREEK_TOGGLE: - greek_kb_flag = greek_kb_flag ? 0 : 2; - if (greek_kb_flag) - bv->owner()->message(_("Math greek keyboard on")); - else - bv->owner()->message(_("Math greek keyboard off")); - break; - - // Math fonts - case LFUN_BOLD: handleFont(bv, LM_TC_BF); break; - case LFUN_SANS: handleFont(bv, LM_TC_SF); break; - case LFUN_EMPH: handleFont(bv, LM_TC_CAL); break; - case LFUN_ROMAN: handleFont(bv, LM_TC_RM); break; - case LFUN_CODE: handleFont(bv, LM_TC_TT); break; - case LFUN_DEFAULT: handleFont(bv, LM_TC_VAR); break; + case LFUN_UMLAUT: handleAccent(bv, "ddot"); break; + case LFUN_CIRCUMFLEX: handleAccent(bv, "hat"); break; + case LFUN_GRAVE: handleAccent(bv, "grave"); break; + case LFUN_ACUTE: handleAccent(bv, "acute"); break; + case LFUN_TILDE: handleAccent(bv, "tilde"); break; + case LFUN_MACRON: handleAccent(bv, "bar"); break; + case LFUN_DOT: handleAccent(bv, "dot"); break; + case LFUN_CARON: handleAccent(bv, "check"); break; + case LFUN_BREVE: handleAccent(bv, "breve"); break; + case LFUN_VECTOR: handleAccent(bv, "vec"); break; + + // Math fonts + case LFUN_GREEK: handleFont(bv, LM_TC_GREEK1); break; + case LFUN_GREEK_TOGGLE: handleFont(bv, LM_TC_GREEK); break; + case LFUN_BOLD: handleFont(bv, LM_TC_BF); break; + case LFUN_SANS: handleFont(bv, LM_TC_SF); break; + case LFUN_EMPH: handleFont(bv, LM_TC_CAL); break; + case LFUN_ROMAN: handleFont(bv, LM_TC_RM); break; + case LFUN_CODE: handleFont(bv, LM_TC_TT); break; + case LFUN_DEFAULT: handleFont(bv, LM_TC_VAR); break; case LFUN_MATH_MODE: handleFont(bv, LM_TC_TEXTRM); @@ -564,14 +542,6 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, } break; - case LFUN_INSERT_MATH: - if (!arg.empty()) { - bv->lockedInsetStoreUndo(Undo::INSERT); - mathcursor->interpret(arg); - updateLocal(bv, true); - } - break; - case LFUN_MATH_SPACE: { bv->lockedInsetStoreUndo(Undo::EDIT); @@ -696,129 +666,23 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, result = UNDISPATCHED; break; - default: - if ((action == -1 || action == LFUN_SELFINSERT) && !arg.empty()) { - unsigned char c = arg[0]; - - lyxerr << "Action: " << action << endl; - - lyxerr << "char: '" << c << "' int: " << int(c) << endl; - //owner_->getIntl()->getTrans().TranslateAndInsert(c, lt); - //lyxerr << "trans: '" << c << "' int: " << int(c) << endl; + case -1: + case LFUN_INSERT_MATH: + case LFUN_SELFINSERT: + if (!arg.empty()) { bv->lockedInsetStoreUndo(Undo::INSERT); - - if (c == 0) { // Dead key, do nothing - //lyxerr << "deadkey" << endl; - break; - } - - if (isalpha(c)) { - if (mathcursor->getLastCode() == LM_TC_TEX) { - mathcursor->macroModeOpen(); - mathcursor->clearLastCode(); - varcode = LM_TC_MIN; - } else if (!varcode) { - MathTextCodes f = mathcursor->getLastCode() ? - mathcursor->getLastCode() : - mathcursor->nextCode(); - varcode = MathIsAlphaFont(f) ? - static_cast(f) : - LM_TC_VAR; - } - - // lyxerr << "Varcode << vardoce; - MathTextCodes char_code = varcode; - if (greek_kb_flag) { - char greek[26] = - {'A', 'B', 'X', 0 , 'E', 0 , 0 , 'H', 'I', 0 , - 'K', 0 , 'M', 'N', 'O', 0 , 0 , 'P', 0 , 'T', - 0, 0, 0, 0, 0 , 'Z' }; - - if ('A' <= c && c <= 'Z' && greek[c - 'A']) { - char_code = LM_TC_RM; - c = greek[c - 'A']; - } else - char_code = LM_TC_SYMB; - } - - mathcursor->insert(c, char_code); - - if (greek_kb_flag && char_code == LM_TC_RM) - mathcursor->setLastCode(LM_TC_VAR); - - varcode = LM_TC_MIN; - - if (greek_kb_flag < 2) - greek_kb_flag = 0; - - } else if (c == '{') { - mathcursor->insert(new MathScopeInset); - mathcursor->left(); - mathcursor->clearLastCode(); - } else if (strchr("!,:;", c) && (varcode == LM_TC_TEX||was_macro)) { - mathcursor->insert(c, LM_TC_TEX); - mathcursor->clearLastCode(); - } else if (c == '_' && varcode == LM_TC_TEX) { - mathcursor->insert(c, LM_TC_SPECIAL); - mathcursor->clearLastCode(); - } else if ('0' <= c && c <= '9' && (varcode == LM_TC_TEX||was_macro)) { - mathcursor->macroModeOpen(); - mathcursor->clearLastCode(); - mathcursor->insert(c, LM_TC_MIN); - } else if (('0' <= c && c <= '9') || strchr(";:!|[]().,?", c)) { - MathTextCodes code = mathcursor->getLastCode(); - if (code != LM_TC_TEXTRM) - code = LM_TC_CONST; - mathcursor->insert(c, code); - } else if (strchr("+/-*<>=", c)) { - MathTextCodes code = mathcursor->getLastCode(); - if (code != LM_TC_TEXTRM) - code = LM_TC_BOP; - mathcursor->insert(c, code); - } else if (strchr("#$%{|}", c)) { - MathTextCodes code = mathcursor->getLastCode(); - if (code != LM_TC_TEXTRM) - code = LM_TC_SPECIAL; - mathcursor->insert(c, code); - } else if (c == '_' || c == '^') { - char s[2]; - s[0] = c; - s[1] = 0; - mathcursor->interpret(s); - } else if (c == ' ') { - if (!varcode) { - MathTextCodes f = (mathcursor->getLastCode()) ? - mathcursor->getLastCode() : - mathcursor->nextCode(); - varcode = MathIsAlphaFont(f) ? f : LM_TC_VAR; - } - - if (varcode == LM_TC_TEXTRM) - mathcursor->insert(c, LM_TC_TEXTRM); - else if (was_macro) - mathcursor->macroModeClose(); - else if (mathcursor->popRight()) - ; - else { - // this would not work if the inset is in an table! - //bv->text->cursorRight(bv, true); - result = FINISHED; - } - } else if (c == '\'' || c == '@') { - mathcursor->insert(c, LM_TC_VAR); - } else if (c == '\\') { - if (was_macro) - mathcursor->macroModeClose(); - bv->owner()->message(_("TeX mode")); - mathcursor->setLastCode(LM_TC_TEX); - } + mathcursor->interpret(arg); updateLocal(bv, true); - } else if (action == LFUN_MATH_PANEL) { - result = UNDISPATCHED; - } else { - lyxerr << "Closed by action " << action << endl; - result = FINISHED; } + break; + + case LFUN_MATH_PANEL: + result = UNDISPATCHED; + break; + + default: + lyxerr << "Closed by action " << action << endl; + result = FINISHED; } mathcursor->normalize(); diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 0fa40b8ee7..6279fdfaeb 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -23,35 +23,25 @@ #include #include +#include "support/lstrings.h" #include "debug.h" #include "LColor.h" #include "Painter.h" -#include "mathed/support.h" +#include "support.h" #include "formulabase.h" #include "math_cursor.h" +#include "math_factory.h" #include "math_arrayinset.h" -#include "math_bigopinset.h" #include "math_charinset.h" -#include "math_symbolinset.h" #include "math_decorationinset.h" #include "math_deliminset.h" -#include "math_dotsinset.h" -#include "math_fracinset.h" #include "math_funcinset.h" -#include "math_funcliminset.h" -#include "math_gridinset.h" #include "math_macro.h" -#include "math_macroarg.h" #include "math_macrotable.h" -#include "math_macrotemplate.h" #include "math_matrixinset.h" -#include "math_noglyphinset.h" -#include "math_rootinset.h" -#include "math_spaceinset.h" -#include "math_sqrtinset.h" -#include "math_stackrelinset.h" -#include "support/lstrings.h" +#include "math_scopeinset.h" #include "math_scriptinset.h" +#include "math_spaceinset.h" #include "math_parser.h" using std::endl; @@ -131,7 +121,7 @@ std::ostream & operator<<(std::ostream & os, MathCursorPos const & p) MathCursor::MathCursor(InsetFormulaBase * formula) - : formula_(formula), lastcode_(LM_TC_MIN), imacro_(0), selection_(false) + : formula_(formula), lastcode_(LM_TC_VAR), imacro_(0), selection_(false) { first(); } @@ -142,6 +132,7 @@ MathCursor::~MathCursor() delete imacro_; } + void MathCursor::pushLeft(MathInset * par) { MathCursorPos p; @@ -279,7 +270,7 @@ bool MathCursor::left(bool sel) return true; } selHandle(sel); - clearLastCode(); + lastcode_ = LM_TC_VAR; MathInset * p = prevInset(); if (openable(p, sel, false)) { @@ -299,7 +290,7 @@ bool MathCursor::right(bool sel) return true; } selHandle(sel); - clearLastCode(); + lastcode_ = LM_TC_VAR; MathInset * p = nextInset(); if (openable(p, sel, false)) { @@ -331,7 +322,7 @@ void MathCursor::setPos(int x, int y) //lyxerr << "MathCursor::setPos x: " << x << " y: " << y << "\n"; macroModeClose(); - lastcode_ = LM_TC_MIN; + lastcode_ = LM_TC_VAR; first(); cursor().par_ = outerPar(); @@ -375,7 +366,7 @@ void MathCursor::home() { dump("home 1"); macroModeClose(); - clearLastCode(); + lastcode_ = LM_TC_VAR; if (!par()->idxHome(idx(), pos())) popLeft(); dump("home 2"); @@ -386,7 +377,7 @@ void MathCursor::end() { dump("end 1"); macroModeClose(); - clearLastCode(); + lastcode_ = LM_TC_VAR; if (!par()->idxEnd(idx(), pos())) popRight(); dump("end 2"); @@ -405,14 +396,14 @@ void MathCursor::insert(char c, MathTextCodes t) if (selection_) selDel(); - if (t != LM_TC_MIN) + if (t != LM_TC_VAR) lastcode_ = t; - if (imacro_ && !(MathIsAlphaFont(t) || t == LM_TC_MIN)) + if (imacro_ && !(MathIsAlphaFont(t) || t == LM_TC_VAR)) macroModeClose(); if (imacro_) { - if (MathIsAlphaFont(t) || t == LM_TC_MIN) { + if (MathIsAlphaFont(t) || t == LM_TC_VAR) { // was MacroModeinsert(c); imacro_->setName(imacro_->name() + c); return; @@ -440,6 +431,23 @@ void MathCursor::insert(MathInset * p) } +void MathCursor::niceInsert(MathInset * p) +{ + if (!p) { + lyxerr << "should not happen\n"; + return; + } + selCut(); + insert(p); + if (p->nargs()) { + posLeft(); + right(); // do not push for e.g. MathSymbolInset + selPaste(); + } + p->metrics(p->size()); +} + + void MathCursor::insert(MathArray const & ar) { macroModeClose(); @@ -609,141 +617,6 @@ void MathCursor::setSize(MathStyles size) } -void MathCursor::interpret(string const & t) -{ - //lyxerr << "interpret: '" << s << "'\n"; - //lyxerr << "in: " << in_word_set(s) << " \n"; - - if (t.empty()) - return; - - // temporary glue code - string s = t; - if (s[0] == '\\') - s = s.substr(1); - - if (s[0] == '^' || s[0] == '_') { - bool const up = (s[0] == '^'); - selCut(); - MathScriptInset * p = prevScriptInset(); - if (!p) { - MathInset * b = prevInset(); - if (b && b->isScriptable()) { - p = new MathScriptInset(up, !up, b->clone()); - posLeft(); - plainErase(); - } else { - p = new MathScriptInset(up, !up); - } - insert(p); - } - pushRight(p); - if (up) - p->up(true); - else - p->down(true); - idx() = up ? 0 : 1; - pos() = 0; - selPaste(); - return; - } - - if (s[0] == '!' || s[0] == ',' || s[0] == ':' || s[0] == ';') { - int sp = (s[0] == ',') ? 1:((s[0] == ':') ? 2:((s[0] == ';') ? 3: 0)); - insert(new MathSpaceInset(sp)); - return; - } - - MathInset * p = 0; - latexkeys const * l = in_word_set(s); - - if (l == 0) { - if (s == "root") - p = new MathRootInset; - else if (MathMacroTable::hasTemplate(s)) - p = new MathMacro(MathMacroTable::provideTemplate(s)); - else if (s.size() > 7 && s.substr(0, 7) == "matrix ") { - int m = 1; - int n = 1; - string v_align; - string h_align; - istringstream is(s.substr(7).c_str()); - is >> m >> n >> v_align >> h_align; - m = std::max(1, m); - n = std::max(1, n); - v_align += 'c'; - MathArrayInset * pp = new MathArrayInset(m, n); - pp->valign(v_align[0]); - pp->halign(h_align); - p = pp; - } - else - p = new MathFuncInset(s); - } else { - switch (l->token) { - case LM_TK_NOGLYPH: - case LM_TK_NOGLYPHB: - p = new MathNoglyphInset(l); - break; - - case LM_TK_BIGSYM: - p = new MathBigopInset(l); - break; - - case LM_TK_FUNCLIM: - p = new MathFuncLimInset(l); - break; - - case LM_TK_SYM: - p = new MathSymbolInset(l); - break; - - case LM_TK_STACK: - p = new MathStackrelInset; - break; - - case LM_TK_FRAC: - p = new MathFracInset; - break; - - case LM_TK_SQRT: - p = new MathSqrtInset; - break; - - case LM_TK_DECORATION: - p = new MathDecorationInset(l); - break; - - case LM_TK_SPACE: - p = new MathSpaceInset(l->id); - break; - - case LM_TK_DOTS: - p = new MathDotsInset(l); - break; - - case LM_TK_MACRO: - p = new MathMacro(MathMacroTable::provideTemplate(s)); - break; - - default: - p = new MathFuncInset(l->name); - break; - } - } - - if (p) { - selCut(); - insert(p); - if (p->nargs()) { - posLeft(); - right(); // do not push for e.g. MathSymbolInset - selPaste(); - } - p->metrics(p->size()); - } -} - void MathCursor::macroModeOpen() { @@ -764,7 +637,7 @@ void MathCursor::macroModeClose() posLeft(); plainErase(); imacro_ = 0; - interpret(name); + interpret("\\" + name); } } @@ -859,7 +732,6 @@ void MathCursor::drawSelection(Painter & pain) const int y2 = c.yo() + c.descent(); pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection); } else { - std::vector indices = i1.par_->idxBetween(i1.idx_, i2.idx_); for (unsigned i = 0; i < indices.size(); ++i) { MathXArray & c = i1.xcell(indices[i]); @@ -875,13 +747,14 @@ void MathCursor::drawSelection(Painter & pain) const MathTextCodes MathCursor::nextCode() const { - //return (pos() == size()) ? LM_TC_MIN : nextInset()->code(); - return LM_TC_MIN; + //return (pos() == size()) ? LM_TC_VAR : nextInset()->code(); + return LM_TC_VAR; } void MathCursor::handleFont(MathTextCodes t) { + macroModeClose(); if (selection_) { MathCursorPos i1; MathCursorPos i2; @@ -979,24 +852,6 @@ bool MathCursor::selection() const } -void MathCursor::clearLastCode() -{ - lastcode_ = LM_TC_MIN; -} - - -void MathCursor::setLastCode(MathTextCodes t) -{ - lastcode_ = t; -} - - -MathTextCodes MathCursor::getLastCode() const -{ - return lastcode_; -} - - MathArrayInset * MathCursor::enclosingArray(int & idx) const { for (int i = Cursor_.size() - 1; i >= 0; --i) { @@ -1365,6 +1220,7 @@ MathArray & MathCursorPos::cell(int idx) const return par_->cell(idx); } + MathArray & MathCursorPos::cell() const { return par_->cell(idx_); @@ -1393,3 +1249,183 @@ MathCursorPos MathCursor::normalAnchor() const } return normal; } + + +void MathCursor::interpret(string const & s) +{ + //lyxerr << "interpret: '" << s << "'\n"; + //lyxerr << "in: " << in_word_set(s) << " \n"; + + if (s.empty()) + return; + + char c = s[0]; + + lyxerr << "char: '" << c << "' int: " << int(c) << endl; + //owner_->getIntl()->getTrans().TranslateAndInsert(c, lt); + //lyxerr << "trans: '" << c << "' int: " << int(c) << endl; + + latexkeys const * l = in_word_set(s.substr(1)); + if (l) { + lastcode_ = LM_TC_VAR; + niceInsert(createMathInset(l)); + return; + } + + if (MathMacroTable::hasTemplate(s.substr(1))) { + niceInsert(new MathMacro(MathMacroTable::provideTemplate(s.substr(1)))); + return; + } + + if (s.size() > 8 && s.substr(0, 8) == "\\matrix ") { + int m = 1; + int n = 1; + string v_align; + string h_align; + istringstream is(s.substr(8).c_str()); + is >> m >> n >> v_align >> h_align; + m = std::max(1, m); + n = std::max(1, n); + v_align += 'c'; + MathArrayInset * pp = new MathArrayInset(m, n); + pp->valign(v_align[0]); + pp->halign(h_align); + niceInsert(pp); + return; + } + + if (s.size() > 1) + return niceInsert(new MathFuncInset(s.substr(1))); + + + // we got just a single char now + + if (c == '^' || c == '_') { + bool const up = (s[0] == '^'); + selCut(); + MathScriptInset * p = prevScriptInset(); + if (!p) { + MathInset * b = prevInset(); + if (b && b->isScriptable()) { + p = new MathScriptInset(up, !up, b->clone()); + posLeft(); + plainErase(); + } else + p = new MathScriptInset(up, !up); + insert(p); + } + pushRight(p); + if (up) + p->up(true); + else + p->down(true); + idx() = up ? 0 : 1; + pos() = 0; + selPaste(); + return; + } + + if (c == '{') { + niceInsert(new MathScopeInset); + return; + } + + if (isalpha(c) && (lastcode_ == LM_TC_GREEK || lastcode_ == LM_TC_GREEK1)) { + static char const greek[26] = + {'A', 'B', 'X', 0 , 'E', 0 , 0 , 'H', 'I', 0 , + 'K', 0 , 'M', 'N', 'O', 0 , 0 , 'P', 0 , 'T', + 0, 0, 0, 0, 0 , 'Z' }; + + MathTextCodes code = LM_TC_SYMB; + if ('A' <= c && c <= 'Z' && greek[c - 'A']) { + code = LM_TC_RM; + c = greek[c - 'A']; + } + insert(c, code); + +#warning greek insert problem? look here! + //if (lastcode_ == LM_TC_GREEK1) + lastcode_ = LM_TC_VAR; + return; + } + + if (c == '_' && lastcode_ == LM_TC_TEX) { + lastcode_ = LM_TC_VAR; + insert(c, LM_TC_SPECIAL); + return; + } + + if ('0' <= c && c <= '9' && (lastcode_ == LM_TC_TEX || imacro_)) { + macroModeOpen(); + lastcode_ = LM_TC_VAR; + insert(c, lastcode_); + return; + } + + if (('0' <= c && c <= '9') || strchr(";:!|[]().,?", c)) { + if (lastcode_ != LM_TC_TEXTRM) + lastcode_ = LM_TC_CONST; + insert(c, lastcode_); + return; + } + + if (strchr("+/-*<>=", c)) { + if (lastcode_ != LM_TC_TEXTRM) + lastcode_ = LM_TC_BOP; + insert(c, lastcode_); + return; + } + + if (strchr("#$%{|}", c)) { + if (lastcode_ != LM_TC_TEXTRM) + lastcode_ = LM_TC_SPECIAL; + insert(c, lastcode_); + return; + } + + if (c == ' ') { + if (imacro_) { + lastcode_ = LM_TC_VAR; + macroModeClose(); + return; + } + + if (lastcode_ == LM_TC_TEXTRM) { + insert(c, LM_TC_TEXTRM); + return; + } + + if (mathcursor->popRight()) + return; + +#warning look here + // this would not work if the inset is in an table! + //bv->text->cursorRight(bv, true); + //result = FINISHED; + return; + } + + if (c == '\'' || c == '@') { + insert(c, LM_TC_VAR); + return; + } + + if (c == '\\') { + if (imacro_) + macroModeClose(); + //bv->owner()->message(_("TeX mode")); + lastcode_ = LM_TC_TEX; + return; + } + + if (isalpha(c)) { + if (lastcode_ == LM_TC_TEX) { + macroModeOpen(); + lastcode_ = LM_TC_VAR; + } + insert(c, lastcode_); + return; + } + +} + diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index 836c43ee00..389ce3dc20 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -113,6 +113,8 @@ public: /// void plainInsert(MathInset * p); /// + void niceInsert(MathInset * p); + /// void delLine(); /// This is in pixels from (maybe?) the top of inset void setPos(int, int); @@ -164,10 +166,6 @@ public: /// void drawSelection(Painter & pain) const; /// - void clearLastCode(); - /// - void setLastCode(MathTextCodes t); - /// void handleFont(MathTextCodes t); /// void handleAccent(string const & name); diff --git a/src/mathed/math_defs.h b/src/mathed/math_defs.h index 4dc01bf78f..c38323a2e7 100644 --- a/src/mathed/math_defs.h +++ b/src/mathed/math_defs.h @@ -73,11 +73,15 @@ enum MathTextCodes { LM_TC_IT, /// LM_TC_TEXTRM, - /// Math mode TeX characters ",;:{}" 20 + /// Math mode TeX characters ",;:{}" LM_TC_TEX, /// Special characters "{}&#_%" LM_TC_SPECIAL, - /// Internal code for operators 22 + /// Internal code when typing greek + LM_TC_GREEK, + /// Internal code when typing a single greek character + LM_TC_GREEK1, + /// Internal code for operators LM_TC_BOP, /// Internal code for symbols LM_TC_SYMB, diff --git a/src/mathed/math_hash.C b/src/mathed/math_hash.C index 45f9161516..3fe70743b3 100644 --- a/src/mathed/math_hash.C +++ b/src/mathed/math_hash.C @@ -121,7 +121,6 @@ latexkeys wordlist[] = {"doteq", LM_TK_NOGLYPH, 0, LMB_RELATION}, {"downarrow", LM_TK_SYM, LM_downarrow, LMB_NONE}, {"ell", LM_TK_NOGLYPH, 0, LMB_NONE}, - {"emptyset", LM_TK_MACRO, LM_emptyset, LMB_NONE}, {"end", LM_TK_END, 0, LMB_NONE}, {"epsilon", LM_TK_NOGLYPH, 0, LMB_NONE}, {"equiv", LM_TK_SYM, LM_equiv, LMB_RELATION}, @@ -200,7 +199,6 @@ latexkeys wordlist[] = {"nolimits", LM_TK_LIMIT, static_cast(-1), LMB_NONE}, {"nonumber", LM_TK_NONUM, 0, LMB_NONE}, {"not", LM_TK_DECORATION, LM_not, LMB_NONE}, - {"notin", LM_TK_MACRO, LM_notin, LMB_RELATION}, {"nu", LM_TK_SYM, LM_nu, LMB_NONE}, {"nwarrow", LM_TK_NOGLYPH, 0, LMB_NONE}, {"odot", LM_TK_NOGLYPH, 0, LMB_OPERATOR}, @@ -209,13 +207,13 @@ latexkeys wordlist[] = {"oplus", LM_TK_SYM, LM_oplus, LMB_OPERATOR}, {"oslash", LM_TK_SYM, LM_oslash, LMB_OPERATOR}, {"otimes", LM_TK_SYM, LM_otimes, LMB_OPERATOR}, + {"over", LM_TK_OVER, 0, LMB_NONE}, {"overbrace", LM_TK_DECORATION, LM_overbrace, LMB_NONE}, {"overleftarrow", LM_TK_DECORATION, LM_overleftarrow, LMB_NONE}, {"overline", LM_TK_DECORATION, LM_overline, LMB_NONE}, {"overrightarrow", LM_TK_DECORATION, LM_overightarrow, LMB_NONE}, {"parallel", LM_TK_NOGLYPH, 0, LMB_RELATION}, {"partial", LM_TK_SYM, LM_partial, LMB_NONE}, - {"perp", LM_TK_MACRO, LM_perp, LMB_RELATION}, {"phi", LM_TK_SYM, LM_phi, LMB_NONE}, {"pi", LM_TK_SYM, LM_pi, LMB_NONE}, {"pm", LM_TK_SYM, LM_pm, LMB_OPERATOR}, @@ -237,6 +235,7 @@ latexkeys wordlist[] = {"rightharpoondown", LM_TK_NOGLYPH, 0, LMB_NONE}, {"rightharpoonup", LM_TK_NOGLYPH, 0, LMB_NONE}, {"rightleftharpoons", LM_TK_NOGLYPH, 0, LMB_NONE}, + {"root", LM_TK_ROOT, 0, LMB_NONE}, //{"scriptscriptstyle", LM_TK_STY, LM_ST_SCRIPTSCRIPT, LMB_NONE}, //{"scriptstyle", LM_TK_STY, LM_ST_SCRIPT, LMB_NONE}, {"searrow", LM_TK_NOGLYPH, 0, LMB_NONE}, diff --git a/src/mathed/math_macrotable.C b/src/mathed/math_macrotable.C index c50033d581..4706c764a0 100644 --- a/src/mathed/math_macrotable.C +++ b/src/mathed/math_macrotable.C @@ -95,7 +95,7 @@ void MathMacroTable::builtinMacros() createTemplate("notin", 0, "\\not\\in"); createTemplate("perp", 0, "\\bot"); createTemplate("to", 0, "\\rightarrow"); - //createTemplate("lint", 4, "\\int_{#1}^{#2}#3 d#4"); + //createTemplate("lint", 4, "\\int_#1^#2#3 d#4"); //createTemplate("silentmult", 0, "\\cdot"); - createTemplate("binom", 2, "\\left(\\frac{#1}{#2}\\right)"); + createTemplate("binom", 2, "\\left(\\frac#1#2\\right)"); } diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index 5697ad3144..cb7188d962 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -27,30 +27,21 @@ #include "array.h" #include "math_inset.h" #include "math_arrayinset.h" -#include "math_bigopinset.h" #include "math_charinset.h" -#include "math_dotsinset.h" -#include "math_decorationinset.h" #include "math_deliminset.h" -#include "math_fracinset.h" +#include "math_factory.h" #include "math_funcinset.h" -#include "math_funcliminset.h" #include "math_macro.h" #include "math_macrotable.h" #include "math_macrotemplate.h" #include "math_matrixinset.h" -#include "math_noglyphinset.h" #include "math_rootinset.h" #include "math_scopeinset.h" #include "math_sqrtinset.h" #include "math_scriptinset.h" -#include "math_sizeinset.h" -#include "math_spaceinset.h" #include "math_sqrtinset.h" -#include "math_stackrelinset.h" -#include "math_symbolinset.h" #include "debug.h" -#include "mathed/support.h" +#include "support.h" #include "lyxlex.h" #include "support/lstrings.h" @@ -92,12 +83,9 @@ MathInset * lastScriptInset(MathArray & array, bool up, bool down, int limits) // These are lexical codes, not semantic enum lexcode_enum { - LexNone, LexESC, LexAlpha, LexBOP, // Binary operators or relations - LexOpen, - LexClose, LexComment, LexArgument, LexSpace, @@ -111,19 +99,18 @@ lexcode_enum lexcode[256]; const unsigned char LM_TK_OPEN = '{'; -const unsigned char LM_TK_CLOSE = '}'; enum { - FLAG_BRACE = 1 << 0, // A { needed //} - FLAG_BRACE_LAST = 1 << 1, // // { Last } ends the parsing process - FLAG_RIGHT = 1 << 2, // Next right ends the parsing process - FLAG_END = 1 << 3, // Next end ends the parsing process - FLAG_BRACK_END = 1 << 5, // // [ Next ] ends the parsing process - FLAG_AMPERSAND = 1 << 6, // Next & ends the parsing process - FLAG_NEWLINE = 1 << 7, // Next \\ ends the parsing process - FLAG_ITEM = 1 << 8, // read a (possibly braced token) + FLAG_BRACE = 1 << 0, // an opening brace needed + FLAG_BRACE_LAST = 1 << 1, // last closing brace ends the parsing process + FLAG_RIGHT = 1 << 2, // next right ends the parsing process + FLAG_END = 1 << 3, // next end ends the parsing process + FLAG_BRACK_END = 1 << 4, // next closing bracket ends the parsing process + FLAG_AMPERSAND = 1 << 5, // next & ends the parsing process + FLAG_NEWLINE = 1 << 6, // next \\ ends the parsing process + FLAG_ITEM = 1 << 7, // read a (possibly braced token) + FLAG_BLOCK = 1 << 8, // next block ends the parsing process FLAG_LEAVE = 1 << 9, // marker for leaving the - FLAG_OPTARG = 1 << 10 // reads an argument in [] }; @@ -181,9 +168,10 @@ void lexInit() lexcode['['] = lexcode[']'] = lexcode['^'] = lexcode['_'] = lexcode['&'] = LexSelf; + lexcode['{'] = LexSelf; + lexcode['}'] = LexSelf; + lexcode['\\'] = LexESC; - lexcode['{'] = LexOpen; - lexcode['}'] = LexClose; } @@ -333,10 +321,6 @@ int Parser::yylex() c = getuchar(); ival_ = c - '0'; return LM_TK_ARGUMENT; - } else if (lexcode[c] == LexOpen) { - return LM_TK_OPEN; - } else if (lexcode[c] == LexClose) { - return LM_TK_CLOSE; } else if (lexcode[c] == LexESC) { c = getuchar(); //lyxerr << "reading second byte: '" << c << "' code: " << lexcode[c] << endl; @@ -364,21 +348,18 @@ int Parser::yylex() //lyxerr[Debug::MATHED] << "reading: text '" << sval_ << "'\n"; //lyxerr << "reading: text '" << sval_ << "'\n"; - latexkeys const * l = in_word_set(sval_); - if (!l) + lval_ = in_word_set(sval_); + if (!lval_) return LM_TK_UNDEF; - if (l->token == LM_TK_BEGIN || l->token == LM_TK_END) { + if (lval_->token == LM_TK_BEGIN || lval_->token == LM_TK_END) { string name = lexArg('{'); int i = 0; while (i < latex_mathenv_num && name != latex_mathenv[i].name) ++i; ival_ = i; - } else if (l->token == LM_TK_SPACE) - ival_ = l->id; - else - lval_ = l; - return l->token; + } + return lval_->token; } } } @@ -574,22 +555,32 @@ void Parser::parse_into(MathArray & array, unsigned flags) if (t == LM_TK_OPEN) { // skip the brace and collect everything to the next matching // closing brace - t = yylex(); flags |= FLAG_BRACE_LAST; + t = yylex(); } else { // take only this single token flags |= FLAG_LEAVE; } } - if ((flags & FLAG_BRACE) && t != LM_TK_OPEN) { - error("Expected {. Maybe you forgot to enclose an argument in {}"); - panic = true; - break; + if (flags & FLAG_BRACE) { + if (t != LM_TK_OPEN) { + error("Expected {. Maybe you forgot to enclose an argument in {}"); + panic = true; + break; + } else { + flags &= ~FLAG_BRACE; + t = yylex(); + continue; + } } switch (t) { + case LM_TK_MATH: + case LM_TK_END: + return; + case LM_TK_ALPHA: if (!isspace(ival_) || yyvarcode == LM_TC_TEXTRM) array.push_back(new MathCharInset(ival_, yyvarcode)); @@ -610,15 +601,15 @@ void Parser::parse_into(MathArray & array, unsigned flags) array.push_back(new MathCharInset(ival_, LM_TC_CONST)); break; - case LM_TK_OPEN: + case '{': + //lyxerr << " creating ScopeInset\n"; array.push_back(new MathScopeInset); parse_into(array.back()->cell(0), FLAG_BRACE_LAST); break; - case LM_TK_CLOSE: - if (flags & FLAG_BRACE_LAST) { + case '}': + if (flags & FLAG_BRACE_LAST) flags |= FLAG_LEAVE; - } break; case '[': @@ -671,58 +662,10 @@ void Parser::parse_into(MathArray & array, unsigned flags) case LM_TK_PROTECT: break; - case LM_TK_NOGLYPH: - case LM_TK_NOGLYPHB: - limits = 0; - array.push_back(new MathNoglyphInset(lval_)); - break; - - case LM_TK_BIGSYM: - limits = 0; - array.push_back(new MathBigopInset(lval_)); - break; - - case LM_TK_FUNCLIM: - limits = 0; - array.push_back(new MathFuncLimInset(lval_)); - break; - - case LM_TK_SYM: - limits = 0; - array.push_back(new MathSymbolInset(lval_)); - break; - case LM_TK_BOP: array.push_back(new MathCharInset(ival_, LM_TC_BOP)); break; - case LM_TK_SPACE: - if (ival_ >= 0) - array.push_back(new MathSpaceInset(ival_)); - break; - - case LM_TK_DOTS: - array.push_back(new MathDotsInset(lval_)); - break; - - case LM_TK_STACK: - { - MathStackrelInset * p = new MathStackrelInset; - parse_into(p->cell(0), FLAG_ITEM); - parse_into(p->cell(1), FLAG_ITEM); - array.push_back(p); - break; - } - - case LM_TK_FRAC: - { - MathFracInset * p = new MathFracInset; - parse_into(p->cell(0), FLAG_ITEM); - parse_into(p->cell(1), FLAG_ITEM); - array.push_back(p); - break; - } - case LM_TK_SQRT: { unsigned char c = getuchar(); @@ -782,22 +725,10 @@ void Parser::parse_into(MathArray & array, unsigned flags) break; } - case LM_TK_DECORATION: - { - MathDecorationInset * p = new MathDecorationInset(lval_); - parse_into(p->cell(0), FLAG_ITEM); - array.push_back(p); - break; - } - case LM_TK_NONUM: curr_num_ = false; break; - case LM_TK_FUNC: - array.push_back(new MathSymbolInset(lval_)); - break; - case LM_TK_UNDEF: if (MathMacroTable::hasTemplate(sval_)) { MathMacro * m = MathMacroTable::cloneTemplate(sval_); @@ -809,10 +740,6 @@ void Parser::parse_into(MathArray & array, unsigned flags) array.push_back(new MathFuncInset(sval_)); break; - case LM_TK_MATH: - case LM_TK_END: - return; - case LM_TK_BEGIN: { int i = ival_; @@ -836,18 +763,29 @@ void Parser::parse_into(MathArray & array, unsigned flags) break; } - case LM_TK_MACRO: - array.push_back(MathMacroTable::cloneTemplate(lval_->name)); - break; - case LM_TK_LABEL: curr_label_ = lexArg('{', true); break; + + case LM_TK_OVER: + { + MathArray ar; + parse_into(ar, FLAG_BLOCK); + break; + } default: - error("Unrecognized token"); - lyxerr[Debug::MATHED] << "[" << t << " " << sval_ << "]" << endl; - break; + limits = 0; + MathInset * p = createMathInset(lval_); + if (p) { + for (int i = 0; i < p->nargs(); ++i) + parse_into(p->cell(i), FLAG_ITEM); + array.push_back(p); + } else { + error("Unrecognized token"); + //lyxerr[Debug::MATHED] << "[" << t << " " << sval_ << "]\n"; + lyxerr << "[" << t << " " << sval_ << "]\n"; + } } // end of big switch @@ -857,7 +795,7 @@ void Parser::parse_into(MathArray & array, unsigned flags) } if (panic) { - lyxerr << " Math Panic, expect problems!" << endl; + lyxerr << " Math Panic, expect problems!\n"; // Search for the end command. do { t = yylex(); @@ -879,8 +817,9 @@ void parse_end(LyXLex & lex, int lineno) lex.nextToken(); if (lex.getString() == "\\end_inset") break; - lyxerr[Debug::MATHED] << "InsetFormula::Read: Garbage before \\end_inset," - " or missing \\end_inset!" << endl; + //lyxerr[Debug::MATHED] << "InsetFormula::Read: Garbage before \\end_inset," + lyxerr << "InsetFormula::Read: Garbage before \\end_inset," + " or missing \\end_inset!\n"; } } @@ -942,4 +881,3 @@ MathMatrixInset * mathed_parse_normal(LyXLex & lex) parse_end(lex, parser.lineno()); return p; } - diff --git a/src/mathed/math_parser.h b/src/mathed/math_parser.h index b8a2494379..5a34b89e72 100644 --- a/src/mathed/math_parser.h +++ b/src/mathed/math_parser.h @@ -45,10 +45,16 @@ enum MathTokenEnum /// LM_TK_SYM, /// + LM_TK_OVER, + /// + LM_TK_CHOOSE, + /// LM_TK_FRAC, /// LM_TK_SQRT, /// + LM_TK_ROOT, + /// LM_TK_BEGIN, /// LM_TK_END, @@ -91,8 +97,6 @@ enum MathTokenEnum /// LM_TK_STY, /// - LM_TK_MACRO, - /// LM_TK_SPECIAL, /// LM_TK_ARGUMENT, -- 2.39.2