#include "math_arrayinset.h"
#include "math_braceinset.h"
#include "math_charinset.h"
+#include "math_colorinset.h"
#include "math_commentinset.h"
#include "math_deliminset.h"
#include "math_envinset.h"
}
+/*!
+ * Check wether the last row is empty and remove it if yes.
+ * Otherwise the following code
+ * \verbatim
+\begin{array}{|c|c|}
+\hline
+1 & 2 \\ \hline
+3 & 4 \\ \hline
+\end{array}
+ * \endverbatim
+ * will result in a grid with 3 rows (+ the dummy row that is always present),
+ * because the last '\\' opens a new row.
+ */
+void delEmptyLastRow(MathGridInset & grid)
+{
+ MathGridInset::row_type const row = grid.nrows() - 1;
+ for (MathGridInset::col_type col = 0; col < grid.ncols(); ++col) {
+ if (!grid.cell(grid.index(row, col)).empty())
+ return;
+ }
+ // Copy the row information of the empty row (which would contain the
+ // last hline in the example above) to the dummy row and delete the
+ // empty row.
+ grid.rowinfo(row + 1) = grid.rowinfo(row);
+ grid.delRow(row);
+}
+
+
// These are TeX's catcodes
enum CatCode {
catEscape, // 0 backslash
vector<Token> tokens_;
///
unsigned pos_;
+ /// Stack of active environments
+ vector<string> environments_;
};
else if (t.cs() == "end") {
if (flags & FLAG_END) {
// eat environment name
- //string const name =
- getArg('{', '}');
- // FIXME: check that we ended the correct environment
- return;
- }
- error("found 'end' unexpectedly");
+ string const name = getArg('{', '}');
+ if (environments_.empty())
+ error("'found \\end{" + name +
+ "}' without matching '\\begin{" +
+ name + "}'");
+ else if (name != environments_.back())
+ error("'\\end{" + name +
+ "}' does not match '\\begin{" +
+ environments_.back() + "}'");
+ else {
+ environments_.pop_back();
+ // Delete empty last row in matrix
+ // like insets.
+ // If you abuse MathGridInset for
+ // non-matrix like structures you
+ // probably need to refine this test.
+ // Right now we only have to test for
+ // single line hull insets.
+ if (grid.nrows() > 1)
+ delEmptyLastRow(grid);
+ return;
+ }
+ } else
+ error("found 'end' unexpectedly");
}
else if (t.cs() == ")") {
else if (t.cs() == "left") {
skipSpaces();
- string l = getToken().asString();
+ Token const & tl = getToken();
+ // \| and \Vert are equivalent, and MathDelimInset
+ // can't handle \|
+ // FIXME: fix this in MathDelimInset itself!
+ string const l = tl.cs() == "|" ? "Vert" : tl.asString();
MathArray ar;
parse(ar, FLAG_RIGHT, mode);
skipSpaces();
- string r = getToken().asString();
+ Token const & tr = getToken();
+ string const r = tr.cs() == "|" ? "Vert" : tr.asString();
cell->push_back(MathAtom(new MathDelimInset(l, r, ar)));
}
else if (t.cs() == "begin") {
string const name = getArg('{', '}');
+ environments_.push_back(name);
if (name == "array" || name == "subarray") {
string const valign = parse_verbatim_option() + 'c';
}
else if (name == "split" || name == "cases" ||
- name == "gathered" || name == "aligned" ||
- name == "alignedat") {
+ name == "gathered" || name == "aligned") {
+ cell->push_back(createMathInset(name));
+ parse2(cell->back(), FLAG_END, mode, false);
+ }
+
+ else if (name == "alignedat") {
+ // ignore this for a while
+ getArg('{', '}');
cell->push_back(createMathInset(name));
parse2(cell->back(), FLAG_END, mode, false);
}
}
else if (t.cs() == "label") {
+ // FIXME: This is swallowed in inline formulas
string label = parse_verbatim_item();
MathArray ar;
asArray(label, ar);
}
else if (t.cs() == "color") {
- MathAtom at = createMathInset(t.cs());
- parse(at.nucleus()->cell(0), FLAG_ITEM, MathInset::TEXT_MODE);
- parse(at.nucleus()->cell(1), flags, mode);
- cell->push_back(at);
+ string const color = parse_verbatim_item();
+ cell->push_back(MathAtom(new MathColorInset(true, color)));
+ parse(cell->back().nucleus()->cell(0), flags, mode);
+ return;
+ }
+
+ else if (t.cs() == "textcolor") {
+ string const color = parse_verbatim_item();
+ cell->push_back(MathAtom(new MathColorInset(false, color)));
+ parse(cell->back().nucleus()->cell(0), FLAG_ITEM, MathInset::TEXT_MODE);
+ }
+
+ else if (t.cs() == "normalcolor") {
+ cell->push_back(createMathInset(t.cs()));
+ parse(cell->back().nucleus()->cell(0), flags, mode);
return;
}
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" || t.cs() == "makebox") {
cell->push_back(createMathInset(t.cs()));
parse(cell->back().nucleus()->cell(0), FLAG_OPTION, MathInset::TEXT_MODE);