-/** The math parser
- \author André Pönitz (2001)
+/**
+ * \file math_parser.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author André Pönitz
+ *
+ * Full author contact details are available in file CREDITS.
*/
/*
#include <config.h>
-
#include "math_parser.h"
-#include "math_inset.h"
#include "math_arrayinset.h"
#include "math_braceinset.h"
-#include "math_boxinset.h"
#include "math_charinset.h"
#include "math_commentinset.h"
#include "math_deliminset.h"
#include "math_envinset.h"
-#include "math_extern.h"
#include "math_factory.h"
#include "math_kerninset.h"
#include "math_macro.h"
#include "math_macrotemplate.h"
-#include "math_hullinset.h"
#include "math_parboxinset.h"
#include "math_parinset.h"
#include "math_rootinset.h"
#include "math_scriptinset.h"
-#include "math_sizeinset.h"
#include "math_sqrtinset.h"
-#include "math_stringinset.h"
#include "math_support.h"
#include "math_tabularinset.h"
-#include "math_xyarrowinset.h"
//#include "insets/insetref.h"
#include "ref_inset.h"
#include "lyxlex.h"
+#include "support/std_sstream.h"
#include "debug.h"
-#include "support/LAssert.h"
-#include "support/lstrings.h"
-#include <cctype>
-#include <algorithm>
using std::istream;
using std::ostream;
MathInset::mode_type asMode(MathInset::mode_type oldmode, string const & str)
{
+ //lyxerr << "handling mode: '" << str << "'" << endl;
if (str == "mathmode")
return MathInset::MATH_MODE;
if (str == "textmode" || str == "forcetext")
fill(theCatcode + 'a', theCatcode + 'z' + 1, catLetter);
fill(theCatcode + 'A', theCatcode + 'Z' + 1, catLetter);
- theCatcode['\\'] = catEscape;
- theCatcode['{'] = catBegin;
- theCatcode['}'] = catEnd;
- theCatcode['$'] = catMath;
- theCatcode['&'] = catAlign;
- theCatcode['\n'] = catNewline;
- theCatcode['#'] = catParameter;
- theCatcode['^'] = catSuper;
- theCatcode['_'] = catSub;
- theCatcode['\7f'] = catIgnore;
- theCatcode[' '] = catSpace;
- theCatcode['\t'] = catSpace;
- theCatcode['\r'] = catNewline;
- theCatcode['~'] = catActive;
- theCatcode['%'] = catComment;
+ theCatcode[int('\\')] = catEscape;
+ theCatcode[int('{')] = catBegin;
+ theCatcode[int('}')] = catEnd;
+ theCatcode[int('$')] = catMath;
+ theCatcode[int('&')] = catAlign;
+ theCatcode[int('\n')] = catNewline;
+ theCatcode[int('#')] = catParameter;
+ theCatcode[int('^')] = catSuper;
+ theCatcode[int('_')] = catSub;
+ theCatcode[int(0x7f)] = catIgnore;
+ theCatcode[int(' ')] = catSpace;
+ theCatcode[int('\t')] = catSpace;
+ theCatcode[int('\r')] = catNewline;
+ theCatcode[int('~')] = catActive;
+ theCatcode[int('%')] = catComment;
}
Token const & Parser::getToken()
{
static const Token dummy;
- //lyxerr << "looking at token " << tokens_[pos_] << " pos: " << pos_ << '\n';
+ //lyxerr << "looking at token " << tokens_[pos_] << " pos: " << pos_ << endl;
return good() ? tokens_[pos_++] : dummy;
}
while (catcode(c) == catSpace || catcode(c) == catNewline)
if (!is.get(c))
break;
- //lyxerr << "putting back: " << c << "\n";
+ //lyxerr << "putting back: " << c << endl;
is.putback(c);
}
char c;
while (is.get(c)) {
- //lyxerr << "reading c: " << c << "\n";
+ //lyxerr << "reading c: " << c << endl;
switch (catcode(c)) {
case catNewline: {
}
case catIgnore: {
- lyxerr << "ignoring a char: " << int(c) << "\n";
+ lyxerr << "ignoring a char: " << int(c) << endl;
break;
}
lyxerr << " <#> ";
lyxerr << tokens_[i];
}
- lyxerr << " pos: " << pos_ << "\n";
+ lyxerr << " pos: " << pos_ << endl;
}
grid.asHullInset()->numbered(cellrow, numbered);
//dump();
+ //lyxerr << " flags: " << flags << endl;
+ //lyxerr << " mode: " << mode << endl;
//lyxerr << "grid: " << grid << endl;
while (good()) {
Token const & t = getToken();
#ifdef FILEDEBUG
- lyxerr << "t: " << t << " flags: " << flags << "\n";
+ lyxerr << "t: " << t << " flags: " << flags << endl;
+ lyxerr << "mode: " << mode << endl;
cell->dump();
- lyxerr << "\n";
+ lyxerr << endl;
#endif
if (flags & FLAG_ITEM) {
- skipSpaces();
- flags &= ~FLAG_ITEM;
- if (t.cat() == catBegin) {
+ if (t.cat() == catBegin) {
// skip the brace and collect everything to the next matching
// closing brace
- flags |= FLAG_BRACE_LAST;
- continue;
+ parse1(grid, FLAG_BRACE_LAST, mode, numbered);
+ return;
}
// handle only this single token, leave the loop if done
- flags |= FLAG_LEAVE;
+ flags = FLAG_LEAVE;
}
}
else {
- error("something strange in the parser\n");
+ error("something strange in the parser");
break;
}
}
else if (t.cat() == catAlign) {
++cellcol;
- //lyxerr << " column now " << cellcol << " max: " << grid.ncols() << "\n";
+ //lyxerr << " column now " << cellcol << " max: " << grid.ncols() << endl;
if (cellcol == grid.ncols()) {
- //lyxerr << "adding column " << cellcol << "\n";
+ //lyxerr << "adding column " << cellcol << endl;
grid.addCol(cellcol - 1);
}
cell = &grid.cell(grid.index(cellrow, cellcol));
}
else if (t.character() == ']' && (flags & FLAG_BRACK_LAST)) {
- //lyxerr << "finished reading option\n";
+ //lyxerr << "finished reading option" << endl;
return;
}
cell->back().nucleus()->lock(true);
}
- else if (t.cs() == "def" || t.cs() == "newcommand") {
+ else if (t.cs() == "def" ||
+ t.cs() == "newcommand" ||
+ t.cs() == "renewcommand")
+ {
+ string const type = t.cs();
string name;
int nargs = 0;
if (t.cs() == "def") {
++nargs;
}
nargs /= 2;
- //lyxerr << "read \\def parameter list '" << pars << "'\n";
+ //lyxerr << "read \\def parameter list '" << pars << "'" << endl;
- } else { // t.cs() == "newcommand"
+ } else { // t.cs() == "newcommand" || t.cs() == "renewcommand"
if (getToken().cat() != catBegin) {
- error("'{' in \\newcommand expected (1) \n");
+ error("'{' in \\newcommand expected (1) ");
return;
}
name = getToken().cs();
if (getToken().cat() != catEnd) {
- error("'}' in \\newcommand expected\n");
+ error("'}' in \\newcommand expected");
return;
}
//MathArray test;
//test.push_back(createMathInset(name));
//if (ar1.contains(test)) {
- // error("we cannot handle recursive macros at all.\n");
+ // error("we cannot handle recursive macros at all.");
// return;
//}
// is a version for display attached?
skipSpaces();
MathArray ar2;
- if (nextToken().cat() == catBegin) {
+ if (nextToken().cat() == catBegin)
parse(ar2, FLAG_ITEM, MathInset::MATH_MODE);
- }
- cell->push_back(MathAtom(new MathMacroTemplate(name, nargs, ar1, ar2)));
+ cell->push_back(MathAtom(new MathMacroTemplate(name, nargs, type,
+ ar1, ar2)));
}
else if (t.cs() == "(") {
parse(count, FLAG_ITEM, mode);
int cols = 1;
if (!extractNumber(count, cols)) {
- lyxerr << " can't extract number of cells from " << count << "\n";
+ lyxerr << " can't extract number of cells from " << count << endl;
}
// resize the table if necessary
for (int i = 0; i < cols; ++i) {
++cellcol;
if (cellcol == grid.ncols()) {
- //lyxerr << "adding column " << cellcol << "\n";
+ //lyxerr << "adding column " << cellcol << endl;
grid.addCol(cellcol - 1);
}
cell = &grid.cell(grid.index(cellrow, cellcol));
else if (t.cs() == "right") {
if (flags & FLAG_RIGHT)
return;
- //lyxerr << "got so far: '" << cell << "'\n";
+ //lyxerr << "got so far: '" << cell << "'" << endl;
error("Unmatched right delimiter");
return;
}
else {
dump();
- lyxerr << "found unknown math environment '" << name << "'\n";
+ lyxerr << "found unknown math environment '" << name << "'" << endl;
// create generic environment inset
cell->push_back(MathAtom(new MathEnvInset(name)));
parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
else if (t.cs() == "label") {
string label = parse_verbatim_item();
+ MathArray ar;
+ asArray(label, ar);
if (grid.asHullInset()) {
grid.asHullInset()->label(cellrow, label);
} else {
cell->push_back(createMathInset(t.cs()));
- cell->push_back(MathAtom(new MathBraceInset(asArray(label))));
+ cell->push_back(MathAtom(new MathBraceInset(ar)));
}
}
parse2(cell->back(), FLAG_ITEM, mode, false);
}
- else if (t.cs() == "xymatrix") {
- cell->push_back(createMathInset(t.cs()));
- parse2(cell->back(), FLAG_ITEM, mode, false);
- }
-
- else if (t.cs() == "framebox") {
+ else if (t.cs() == "framebox" || t.cs() == "makebox") {
cell->push_back(createMathInset(t.cs()));
parse(cell->back().nucleus()->cell(0), FLAG_OPTION, MathInset::TEXT_MODE);
parse(cell->back().nucleus()->cell(1), FLAG_OPTION, MathInset::TEXT_MODE);
p->up_ = nextToken().cat() == catSuper;
getToken();
parse(p->cell(1), FLAG_ITEM, mode);
- //lyxerr << "read label: " << p->cell(1) << "\n";
+ //lyxerr << "read label: " << p->cell(1) << endl;
}
cell->push_back(MathAtom(p));
- //lyxerr << "read cell: " << cell << "\n";
+ //lyxerr << "read cell: " << cell << endl;
}
#endif
MathAtom at = createMathInset(t.cs());
MathInset::mode_type m = mode;
//if (m == MathInset::UNDECIDED_MODE)
+ //lyxerr << "default creation: m1: " << m << endl;
if (at->currentMode() != MathInset::UNDECIDED_MODE)
m = at->currentMode();
+ //lyxerr << "default creation: m2: " << m << endl;
MathInset::idx_type start = 0;
// this fails on \bigg[...\bigg]
//MathArray opt;