/* * File: math_cursor.C * Purpose: Interaction for mathed * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx> * Created: January 1996 * Description: Math interaction for a WYSIWYG math editor. * * Dependencies: Xlib, XForms * * Copyright: (c) 1996, Alejandro Aguilar Sierra * * Version: 0.8beta, Mathed & Lyx project. * * You are free to use and modify this code under the terms of * the GNU General Public Licence version 2 or later.
*/
// Leave the inset bool MathedCursor::Pop()
{ if (!mathstk.Empty()) {
cursor = mathstk.pop();
cursor->Next(); returntrue;
} returnfalse;
}
// Go to the inset bool MathedCursor::Push()
{ if (cursor->IsActive()) {
MathParInset *p = cursor->GetActiveInset(); if (!p) returnfalse;
mathstk.push(&cursor);
cursor->SetData(p); returntrue;
} returnfalse;
}
bool MathedCursor::Right(bool sel)
{ if (macro_mode) {
MacroModeClose(); returntrue;
}
clearLastCode(); if (sel && !selection) SelStart(); if (!sel && selection) SelClear(); bool result = false;
if (cursor->IsActive()) { if (cursor->IsScript()) {
cursor->Next(); // A script may be followed by another script if (cursor->IsScript())
cursor->Next(); returntrue;
} if (!selection) {
MathParInset *p = cursor->GetActiveInset(); if (!p) {
fprintf(stderr, "Math error: Inset expected.\n"); return cursor->Next();
}
p->setArgumentIdx(0);
mathstk.push(&cursor);
cursor->SetData(p);
result = true;
} else
result = cursor->Next();
} else { if (cursor->GetChar()!=LM_TC_CR)
result = cursor->Next(); if (!result && !mathstk.Empty()) {
cursor = mathstk.pop();
cursor->Next();
cursor->Adjust();
result = true; if (selection) SelClear();
}
} return result;
}
void MathedCursor::SetPos(int x, int y)
{ int xp = 0;
if (macro_mode) MacroModeClose();
lastcode = LM_TC_MIN;
mathstk.Reset();
mathstk.push(&cursor);
cursor->SetData(par);
cursor->fitCoord(x, y); while (cursor->GetX()<x && cursor->OK()) { if (cursor->IsActive()) {
MathParInset *p = cursor->GetActiveInset(); if (p->Inside(x, y)) {
p->SetFocus(x, y);
mathstk.push(&cursor);
cursor->SetData(p);
cursor->fitCoord(x, y); continue;
}
}
xp = cursor->GetX();
cursor->ipush(); if (!cursor->Next() && !Pop()) break;
} if (x-xp < cursor->GetX()-x) cursor->ipop();
cursor->Adjust();
}
if (MathIsActive(t)) {
cursor->Prev();
Push();
}
}
} else
fprintf(stderr, "Math error: Full stack.\n");
}
void MathedCursor::Delete()
{ if (macro_mode) return; if (selection) {
SelDel(); return;
} if (cursor->Empty() && !mathstk.Empty()) {
cursor = mathstk.pop();
} // if (cursor->GetChar()!=LM_TC_TAB)
cursor->Delete();
cursor->checkTabs();
}
void MathedCursor::DelLine()
{ if (macro_mode) MacroModeClose(); if (selection) {
SelDel(); return;
}
MathParInset *p= cursor->p; if (p && (p->GetType()<=LM_OT_MATRIX && p->GetType()>=LM_OT_MPAR)) {
cursor->delRow();
}
}
bool MathedCursor::Up(bool sel)
{ bool result = false;
if (macro_mode) MacroModeClose();
if (sel && !selection) SelStart(); if (!sel && selection) SelClear();
MathParInset *p;
if (cursor->IsScript()) { char cd = cursor->GetChar(); if (MathIsUp(cd)) {
Push(); returntrue;
} else { // A subscript may be followed by a superscript
cursor->ipush();
cursor->Next(); if (MathIsUp(cursor->GetChar())) {
Push(); returntrue;
} else// return to the previous state
cursor->ipop();
}
}
result = cursor->Up(); if (!result && cursor->p) {
p = cursor->p;
bool MathedCursor::Down(bool sel)
{ bool result = false;
if (macro_mode) MacroModeClose();
if (sel && !selection) SelStart(); if (!sel && selection) SelClear(); // if (selection) SelClear();
MathParInset *p;
if (cursor->IsScript()) { char cd = cursor->GetChar(); if (MathIsDown(cd)) {
Push(); returntrue;
} else { // A superscript may be followed by a subscript
cursor->ipush();
cursor->Next(); if (MathIsDown(cursor->GetChar())) {
Push(); returntrue;
} else
cursor->ipop();
}
}
result = cursor->Down(); if (!result && cursor->p) {
p= cursor->p; if (p->GetType()==LM_OT_SCRIPT) {
MathedXIter *cx = mathstk.Item(1); bool is_up = (cx->GetChar()==LM_TC_UP);
cursor = mathstk.pop();
cursor->Next();
result = (is_up) ? true: Down();
} else {
result = (p->getArgumentIdx() < p->getMaxArgumentIdx()); if (result) {
p->setArgumentIdx(p->getArgumentIdx()+1);
cursor->SetData(p);
}
} if (!result && !mathstk.Empty()) {
cursor = mathstk.pop(); return Down(sel);
}
} return result;
}
bool MathedCursor::Limits()
{ if (cursor->IsInset()) {
MathedInset *p = cursor->GetInset(); bool ol = p->GetLimits();
p->SetLimits(!ol); return (ol!=p->GetLimits());
} returnfalse;
}
void MathedCursor::setLabel(charconst* label)
{ // ugly hack and possible bug if (!cursor->setLabel(strnew(label)))
fprintf(stderr, "MathErr: Bad place to set labels.");
}
void MathedCursor::setNumbered()
{ // another ugly hack
MathedRowSt *crow = cursor->crow; if (!crow) return;
crow->setNumbered(!crow->isNumbered());
}
if (s[0]=='^' || s[0]=='_') { char c = cursor->GetChar(); if (MathIsUp(c) && s[0]=='^' || MathIsDown(c) && s[0]=='_') {
Push(); return;
} else// A script may be followed by a script if (MathIsUp(c) || MathIsDown(c)) {
cursor->ipush();
cursor->Next();
c = cursor->GetChar(); if (MathIsUp(c) && s[0]=='^' || MathIsDown(c) && s[0]=='_') {
Push(); return;
} else
cursor->ipop();
}
p = new MathParInset(LM_ST_SCRIPT, "", LM_OT_SCRIPT);
Insert (p, (s[0]=='_') ? LM_TC_DOWN: LM_TC_UP); return;
} else if (s[0]=='!' || s[0]==',' || s[0]==':' || s[0]==';') { int sp = ((s[0]==',') ? 1:((s[0]==':') ? 2:((s[0]==';') ? 3: 0)));
p = new MathSpaceInset(sp);
Insert(p); return;
} else
l = in_word_set (s, strlen(s));
if (!l) {
p = MathMacroTable::mathMTable.getMacro(s); if (!p) {
lyxerr.debug(LString("Macro2 ") + s + ' '
+ (long)tcode, Error::MATHED);
p = new MathFuncInset(s, LM_OT_UNDEF);
} else {
tcode = ((MathMacro*)p)->getTCode();
fprintf(stderr, "Macro2 %s %d ", s, tcode);
}
} else {
MathedInsetTypes fractype = LM_OT_FRAC; switch (l->token) { case LM_TK_BIGSYM:
{
p = new MathBigopInset(l->name, l->id); break;
} case LM_TK_SYM:
{ if (l->id<255) {
Insert((byte)l->id, MathIsBOPS(l->id) ?
LM_TC_BOPS: LM_TC_SYMB);
} else {
p = new MathFuncInset(l->name);
} break;
} case LM_TK_STACK:
fractype = LM_OT_STACKREL;
lyxerr.debug(" i:stackrel ", Error::MATHED); case LM_TK_FRAC:
{
p = new MathFracInset(fractype);
tcode = LM_TC_ACTIVE_INSET; break;
} case LM_TK_SQRT:
{
p = new MathSqrtInset;
tcode = LM_TC_ACTIVE_INSET; break;
} case LM_TK_WIDE:
{
p = new MathDecorationInset(l->id);
tcode = LM_TC_ACTIVE_INSET; break;
} case LM_TK_FUNCLIM:
{
p = new MathFuncInset(l->name, LM_OT_FUNCLIM); break;
} case LM_TK_SPACE:
{
p = new MathSpaceInset(l->id); break;
} case LM_TK_DOTS:
{
p = new MathDotsInset(l->name, l->id); break;
} case LM_TK_ACCENT:
setAccent(l->id); break; case LM_TK_MACRO:
p = MathMacroTable::mathMTable.getMacro(s);
tcode = ((MathMacro*)p)->getTCode();
lyxerr.debug(LString("Macro ") + s + ' '
+ (long)tcode, Error::MATHED); break; default:
{
p = new MathFuncInset(l->name); break;
}
}
} if (p) {
Insert(p, tcode);
par->Metrics();
}
}
bool MathedCursor::pullArg()
{ if (cursor->IsActive()) {
MathParInset *p = cursor->GetActiveInset(); if (!p) { returnfalse;
}
LyxArrayBase *a = p->GetData();
p->SetData(0); Delete(); if (a) {
cursor->Merge(a);
cursor->Adjust();
}
void MathedCursor::MacroModeClose()
{ if (macro_mode) { // fprintf(stderr, "Pos[%d] ", cursor->getPos());
macro_mode = false;
latexkeys *l = in_word_set(macrobf, macroln); if (macroln>0 && (!l || (l && IsMacro(l->token, l->id))) &&
!MathMacroTable::mathMTable.getMacro(macrobf)) { if (!l) {
imacro->SetName(strnew(macrobf)); // This guarantees that the string will be removed by destructor
imacro->SetType(LM_OT_UNDEF);
} else
imacro->SetName(l->name);
} else {
Left();
imacro->SetName(NULL); if (cursor->GetInset()->GetType()==LM_OT_ACCENT) {
setAccent(((MathAccentInset*)cursor->GetInset())->getAccentCode());
}
cursor->Delete(); if (l || MathMacroTable::mathMTable.getMacro(macrobf)) {
Interpret(macrobf);
}
}
imacro = NULL;
}
}
void MathedCursor::MacroModeBack()
{ if (macro_mode) { if (macroln>0) {
macrobf[--macroln] = '\0';
imacro->Metrics();
} else
MacroModeClose();
} else
fprintf(stderr, "Mathed Warning: we are not in macro mode\n");
}
void MathedCursor::MacroModeInsert(char c)
{ if (macro_mode) {
macrobf[macroln+1] = macrobf[macroln];
macrobf[macroln++] = c;
imacro->Metrics();
} else
fprintf(stderr, "Mathed Warning: we are not in macro mode\n");
}
for (int i=accent-1; i>=0; i--) { if (i==accent-1)
ac = new MathAccentInset(c, t, nestaccent[i]); else
ac = new MathAccentInset(ac, nestaccent[i]);
} if (ac)
cursor->Insert(ac);
for (int i=accent-1; i>=0; i--) { if (i==accent-1)
ac = new MathAccentInset(p, nestaccent[i]); else
ac = new MathAccentInset(ac, nestaccent[i]);
} if (ac)
cursor->Insert(ac);
accent = 0; // consumed!
}
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.