* the GNU General Public Licence version 2 or later.
*/
+/*
+
+If someone desperately needs partial "structures" (such as a few cells of
+an array inset or similar) (s)he could uses the following hack as starting
+point to write some macros:
+
+ \newif\ifcomment
+ \commentfalse
+ \ifcomment
+ \def\makeamptab{\catcode`\&=4\relax}
+ \def\makeampletter{\catcode`\&=11\relax}
+ \def\b{\makeampletter\expandafter\makeamptab\bi}
+ \long\def\bi#1\e{}
+ \else
+ \def\b{}\def\e{}
+ \fi
+
+ ...
+
+ \[\begin{array}{ccc}
+ 1 & 2\b & 3^2\\
+ 4 & 5\e & 6\\
+ 7 & 8 & 9
+ \end{array}\]
+
+*/
+
+
#include <config.h>
#include <cctype>
#include "array.h"
#include "math_inset.h"
#include "math_arrayinset.h"
+#include "math_braceinset.h"
#include "math_charinset.h"
#include "math_deliminset.h"
#include "math_factory.h"
enum {
- 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_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 // leave the loop at the end
}
if (getToken().cat() != catBegin) {
- lyxerr << "'{' expected\n";
+ lyxerr << "'{' in \\newcommand expected (1)\n";
return name;
}
string arg = getArg('[', ']');
int narg = arg.empty() ? 0 : atoi(arg.c_str());
+
+ if (getToken().cat() != catBegin) {
+ lyxerr << "'{' in \\newcommand expected (2)\n";
+ return name;
+ }
+
MathArray ar;
- parse_into(ar, FLAG_BRACE | FLAG_BRACE_LAST);
+ parse_into(ar, FLAG_BRACE_LAST);
MathMacroTable::create(name, narg, ar);
-
return name;
}
string const name = getArg('{', '}');
- if (name == "equation" || name == "equation*") {
- curr_num_ = !stared(name);
+ if (name == "equation" || name == "equation*" || name == "displaymath") {
+ curr_num_ = (name == "equation");
curr_label_.erase();
matrix = MathAtom(new MathMatrixInset(LM_OT_EQUATION));
MathMatrixInset * p = matrix->asMatrixInset();
void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
{
- stack<MathTextCodes> fontcodes;
- fontcodes.push(LM_TC_MIN);
-
bool panic = false;
int limits = 0;
}
}
- if (flags & FLAG_BRACE) {
- if (t.cat() != catBegin) {
- error("Expected {. Maybe you forgot to enclose an argument in {}");
- panic = true;
- break;
- } else {
- flags &= ~FLAG_BRACE;
- continue;
- }
- }
-
if (flags & FLAG_BLOCK) {
if (t.cat() == catAlign || t.cs() == "\\")
return;
break;
else if (t.cat() == catLetter)
- add(array, t.character(), fontcodes.top());
+ add(array, t.character(), code);
- else if (t.cat() == catSpace &&
- (fontcodes.top() == LM_TC_TEXTRM || code == LM_TC_TEXTRM))
- add(array, ' ', fontcodes.top());
+ else if (t.cat() == catSpace && code == LM_TC_TEXTRM)
+ add(array, t.character(), code);
else if (t.cat() == catParameter) {
Token const & n = getToken();
}
else if (t.cat() == catBegin) {
- add(array, '{', LM_TC_TEX);
- fontcodes.push(LM_TC_MIN);
+ MathArray ar;
+ parse_into(ar, FLAG_BRACE_LAST);
+#ifndef WITH_WARNINGS
+#warning this might be wrong in general!
+#endif
+ // ignore braces around simple items
+ if (ar.size() == 1 || (ar.size() == 2 && ar.back()->asScriptInset())) {
+ array.push_back(ar);
+ } else {
+ array.push_back(MathAtom(new MathBraceInset));
+ array.back()->cell(0).swap(ar);
+ }
}
else if (t.cat() == catEnd) {
if (flags & FLAG_BRACE_LAST)
return;
+ //lyxerr << "found '}' unexpectedly, array: '" << array << "'\n";
+ lyxerr << "found '}' unexpectedly\n";
add(array, '}', LM_TC_TEX);
- fontcodes.pop();
}
else if (t.cat() == catAlign) {
- lyxerr << "found tab unexpectedly, array: '" << array << "'\n";
+ //lyxerr << "found tab unexpectedly, array: '" << array << "'\n";
+ lyxerr << "found tab unexpectedly\n";
add(array, '&', LM_TC_TEX);
}
return;
else if (t.cat() == catOther)
- add(array, t.character(), fontcodes.top());
+ add(array, t.character(), code);
//
- // codesequences
+ // control sequences
//
- else if (t.cs() == "protect")
+ else if (t.cs() == "protect")
+ // ignore \\protect, will be re-added during output
;
else if (t.cs() == "end")
else if (t.cs() == "\\") {
curr_skip_ = getArg('[', ']');
- if (flags & FLAG_NEWLINE)
- return;
- lyxerr[Debug::MATHED]
- << "found newline unexpectedly, array: '" << array << "'\n";
+ //lyxerr << "found newline unexpectedly, array: '" << array << "'\n";
+ lyxerr << "found newline unexpectedly\n";
array.push_back(createMathInset("\\"));
}
else if (t.cs() == "right") {
if (!(flags & FLAG_RIGHT)) {
- lyxerr << "got so far: '" << array << "'\n";
+ //lyxerr << "got so far: '" << array << "'\n";
error("Unmatched right delimiter");
}
return;
}
else if (t.cs() == "label") {
- //MathArray ar;
- //parse_into(ar, FLAG_ITEM);
- //ostringstream os;
- //ar.write(os, true);
- //curr_label_ = os.str();
- // was:
curr_label_ = getArg('{', '}');
}
else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") {
MathAtom p = createMathInset(t.cs());
- // search backward for position of last '{' if any
- int pos;
- for (pos = array.size() - 1; pos >= 0; --pos)
- if (array.at(pos)->getChar() == '{')
- break;
- if (pos >= 0) {
- // found it -> use the part after '{' as "numerator"
- p->cell(0) = MathArray(array, pos + 1, array.size());
- parse_into(p->cell(1), FLAG_BRACE_LAST);
- // delete denominator and the '{'
- array.erase(pos, array.size());
- } else if (flags & FLAG_RIGHT) {
- // we are inside a \left ... \right block
- //lyxerr << "found '" << t.cs() << "' enclosed by \\left .. \\right\n";
- p->cell(0).swap(array);
- parse_into(p->cell(1), FLAG_RIGHT);
- // handle the right delimiter properly
- putback();
- } else {
- // not found -> use everything as "numerator"
- p->cell(0).swap(array);
- parse_into(p->cell(1), FLAG_BLOCK);
- }
- array.push_back(MathAtom(p));
+ array.swap(p->cell(0));
+ parse_into(p->cell(1), flags, code);
+ array.push_back(p);
+ return;
}
/*
// theCatcode[' '] = catLetter;
//}
- MathTextCodes t = static_cast<MathTextCodes>(l->id);
MathArray ar;
- parse_into(ar, FLAG_ITEM, t);
- for (MathArray::iterator it = ar.begin(); it != ar.end(); ++it)
- (*it)->handleFont(t);
+ parse_into(ar, FLAG_ITEM, static_cast<MathTextCodes>(l->id));
array.push_back(ar);
// undo catcode changes
}
else if (l->token == LM_TK_OLDFONT) {
- fontcodes.pop();
- fontcodes.push(static_cast<MathTextCodes>(l->id));
+ code = static_cast<MathTextCodes>(l->id);
}
else {