/*!
- * Check wether the last row is empty and remove it if yes.
+ * Check whether the last row is empty and remove it if yes.
* Otherwise the following code
* \verbatim
\begin{array}{|c|c|}
* \endverbatim
* will result in a grid with 3 rows (+ the dummy row that is always present),
* because the last '\\' opens a new row.
+ * Note that this is only needed for inner-hull grid types, such as array
+ * or aligned, but not for outer-hull grid types, such as eqnarray or align.
*/
void delEmptyLastRow(InsetMathGrid & grid)
{
}
+/*!
+ * Tell whether the environment name corresponds to an inner-hull grid type.
+ */
+bool innerHull(docstring const & name)
+{
+ // For [bB]matrix, [vV]matrix, and pmatrix we can check the suffix only
+ return name == "array" || name == "cases" || name == "aligned"
+ || name == "alignedat" || name == "gathered" || name == "split"
+ || name == "subarray" || name == "tabular" || name == "matrix"
+ || name.substr(1) == "matrix";
+}
+
+
// These are TeX's catcodes
enum CatCode {
catEscape, // 0 backslash
if (!is) {
error("unexpected end of input");
} else {
+ if (c == '\n')
+ c = ' ';
docstring s(1, c);
if (catcode(c) == catLetter) {
// collect letters
Token const & n = getToken();
if (n.cat() == catMath) {
// TeX's $$...$$ syntax for displayed math
- cell->push_back(MathAtom(new InsetMathHull(buf, hullEquation)));
- parse2(cell->back(), FLAG_SIMPLE, InsetMath::MATH_MODE, false);
- getToken(); // skip the second '$' token
+ if (mode == InsetMath::UNDECIDED_MODE) {
+ cell->push_back(MathAtom(new InsetMathHull(buf, hullEquation)));
+ parse2(cell->back(), FLAG_SIMPLE, InsetMath::MATH_MODE, false);
+ getToken(); // skip the second '$' token
+ } else {
+ // This is not an outer hull and display math is
+ // not allowed inside text mode environments.
+ error("bad math environment");
+ break;
+ }
} else {
// simple $...$ stuff
putback();
}
else {
- error("something strange in the parser");
- break;
+ Token const & n = getToken();
+ if (n.cat() == catMath) {
+ error("something strange in the parser");
+ break;
+ } else {
+ // This is inline math ($...$), but the parser thinks we are
+ // already in math mode and latex would issue an error, unless we
+ // are inside a text mode user macro. We have no way to tell, so
+ // let's play safe by using \ensuremath, as it will work in any case.
+ putback();
+ cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
+ parse(cell->back().nucleus()->cell(0), FLAG_SIMPLE, InsetMath::MATH_MODE);
+ }
}
}
}
else if (t.cs() == "(") {
- if (mode == InsetMath::MATH_MODE) {
- error("bad math environment");
- break;
- }
- cell->push_back(MathAtom(new InsetMathHull(buf, hullSimple)));
- parse2(cell->back(), FLAG_SIMPLE2, InsetMath::MATH_MODE, false);
+ cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
+ parse(cell->back().nucleus()->cell(0), FLAG_SIMPLE2, InsetMath::MATH_MODE);
}
else if (t.cs() == "[") {
// probably need to refine this test.
// Right now we only have to test for
// single line hull insets.
- if (grid.nrows() > 1)
+ if (grid.nrows() > 1 && innerHull(name))
delEmptyLastRow(grid);
return success_;
}
#endif
else if (t.cs() == "limits" || t.cs() == "nolimits") {
- CatCode cat = nextToken().cat();
+ CatCode const cat = nextToken().cat();
if (cat == catSuper || cat == catSub)
limits = t.cs() == "limits" ? 1 : -1;
else {
}
else if (name == "math") {
- if (mode == InsetMath::MATH_MODE) {
- error("bad math environment");
- break;
- }
- cell->push_back(MathAtom(new InsetMathHull(buf, hullSimple)));
- parse2(cell->back(), FLAG_END, InsetMath::MATH_MODE, true);
+ cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
+ parse(cell->back().nucleus()->cell(0), FLAG_END, InsetMath::MATH_MODE);
}
else if (name == "equation" || name == "equation*"
else if (t.cs() == "substack") {
cell->push_back(createInsetMath(t.cs(), buf));
parse2(cell->back(), FLAG_ITEM, mode, false);
+ // Delete empty last row if present
+ InsetMathGrid & subgrid =
+ *(cell->back().nucleus()->asGridInset());
+ if (subgrid.nrows() > 1)
+ delEmptyLastRow(subgrid);
}
else if (t.cs() == "xymatrix") {
os << getToken().asInput();
cell->push_back(createInsetMath(t.cs() + os.str(), buf));
parse2(cell->back(), FLAG_ITEM, mode, false);
+ // Delete empty last row if present
+ InsetMathGrid & subgrid =
+ *(cell->back().nucleus()->asGridInset());
+ if (subgrid.nrows() > 1)
+ delEmptyLastRow(subgrid);
+ }
+
+ else if (t.cs() == "Diagram") {
+ odocstringstream os;
+ while (good() && nextToken().cat() != catBegin)
+ os << getToken().asInput();
+ cell->push_back(createInsetMath(t.cs() + os.str(), buf));
+ parse2(cell->back(), FLAG_ITEM, mode, false);
}
else if (t.cs() == "framebox" || t.cs() == "makebox") {
else if (t.cs().size()) {
bool const no_mhchem =
- (t.cs() == "ce" || t.cs() == "cf") && buf
- && buf->params().use_mhchem == BufferParams::package_off;
+ (t.cs() == "ce" || t.cs() == "cf")
+ && buf && buf->params().use_mhchem ==
+ BufferParams::package_off;
+
bool const is_user_macro = no_mhchem ||
(buf && (mode_ & Parse::TRACKMACRO
- ? buf->usermacros.count(t.cs()) != 0
- : buf->getMacro(t.cs(), false) != 0));
+ ? buf->usermacros.count(t.cs()) != 0
+ : buf->getMacro(t.cs(), false) != 0));
+
latexkeys const * l = in_word_set(t.cs());
if (l && !is_user_macro) {
if (l->inset == "big") {