#include "InsetMathEnv.h"
#include "InsetMathFrac.h"
#include "InsetMathKern.h"
-#include "MathMacro.h"
+#include "InsetMathMacro.h"
#include "InsetMathPar.h"
#include "InsetMathRef.h"
#include "InsetMathRoot.h"
#include "InsetMathStackrel.h"
#include "InsetMathString.h"
#include "InsetMathTabular.h"
-#include "MathMacroTemplate.h"
+#include "InsetMathMacroTemplate.h"
+#include "MathExtern.h"
#include "MathFactory.h"
-#include "MathMacroArgument.h"
+#include "InsetMathMacroArgument.h"
#include "MathSupport.h"
#include "Buffer.h"
#include "Encoding.h"
#include "Lexer.h"
-#include "support/debug.h"
#include "support/convert.h"
+#include "support/debug.h"
#include "support/docstream.h"
+#include "support/unique_ptr.h"
#include <sstream>
* \endverbatim
* will result in a grid with 3 rows (+ the dummy row that is always present),
* because the last '\\' opens a new row.
+ * Do never delete a row that contains a multicolumn, even if all cells empty,
+ * since the multicolumn information would get lost otherwise.
* 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.
*/
{
InsetMathGrid::row_type const row = grid.nrows() - 1;
for (InsetMathGrid::col_type col = 0; col < grid.ncols(); ++col) {
- if (!grid.cell(grid.index(row, col)).empty())
+ InsetMathGrid::idx_type const idx = grid.index(row, col);
+ if (!grid.cell(idx).empty() ||
+ grid.cellinfo(idx).multi_ != InsetMathGrid::CELL_NORMAL)
return;
}
// Copy the row information of the empty row (which would contain the
bool parse1(InsetMathGrid & grid, unsigned flags, mode_type mode,
bool numbered);
///
- MathData parse(unsigned flags, mode_type mode);
- ///
int lineno() const { return lineno_; }
///
void putback();
///
void push_back(Token const & t);
///
- void pop_back();
- ///
Token const & prevToken() const;
///
Token const & nextToken() const;
}
-void Parser::pop_back()
-{
- tokens_.pop_back();
-}
-
-
Token const & Parser::prevToken() const
{
static const Token dummy;
docstring res;
if (nextToken().character() == '[') {
Token t = getToken();
- for (Token t = getToken(); t.character() != ']' && good(); t = getToken()) {
+ for (t = getToken(); t.character() != ']' && good(); t = getToken()) {
if (t.cat() == catBegin) {
putback();
res += '{' + parse_verbatim_item() + '}';
docstring res;
if (nextToken().cat() == catBegin) {
Token t = getToken();
- for (Token t = getToken(); t.cat() != catEnd && good(); t = getToken()) {
+ for (t = getToken(); t.cat() != catEnd && good(); t = getToken()) {
if (t.cat() == catBegin) {
putback();
res += '{' + parse_verbatim_item() + '}';
}
-MathData Parser::parse(unsigned flags, mode_type mode)
-{
- MathData ar(buffer_);
- parse(ar, flags, mode);
- return ar;
-}
-
-
bool Parser::parse(MathData & array, unsigned flags, mode_type mode)
{
InsetMathGrid grid(buffer_, 1, 1);
}
else if (t.cat() == catParameter) {
- Token const & n = getToken();
- cell->push_back(MathAtom(new MathMacroArgument(n.character()-'0')));
+ Token const & n = nextToken();
+ char_type c = n.character();
+ if (c && '0' < c && c <= '9') {
+ cell->push_back(MathAtom(new InsetMathMacroArgument(c - '0')));
+ getToken();
+ } else
+ cell->push_back(MathAtom(new InsetMathHash()));
}
else if (t.cat() == catActive)
else if (t.cat() == catOther) {
char_type c = t.character();
- if (isAsciiOrMathAlpha(c)
+ if (!Encodings::isUnicodeTextOnly(c)
|| mode_ & Parse::VERBATIM
|| !(mode_ & Parse::USETEXT)
|| mode == InsetMath::TEXT_MODE) {
MathAtom at = createInsetMath("text", buf);
at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
while (nextToken().cat() == catOther
- && !isAsciiOrMathAlpha(nextToken().character())) {
+ && Encodings::isUnicodeTextOnly(nextToken().character())) {
c = getToken().character();
at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
}
else if (t.cat() == catComment) {
docstring s;
while (good()) {
- Token const & t = getToken();
- if (t.cat() == catNewline)
+ Token const & tt = getToken();
+ if (tt.cat() == catNewline)
break;
- s += t.asInput();
+ s += tt.asInput();
}
cell->push_back(MathAtom(new InsetMathComment(buf, s)));
skipSpaces();
if (nextToken().cat() == catBegin)
parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
- cell->push_back(MathAtom(new MathMacroTemplate(buf,
+ cell->push_back(MathAtom(new InsetMathMacroTemplate(buf,
name, nargs, 0, MacroTypeDef,
vector<MathData>(), def, display)));
if (nextToken().cat() == catBegin)
parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
- cell->push_back(MathAtom(new MathMacroTemplate(buf,
+ cell->push_back(MathAtom(new InsetMathMacroTemplate(buf,
name, nargs, optionals, MacroTypeNewcommand,
optionalValues, def, display)));
if (nextToken().cat() == catBegin)
parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
- cell->push_back(MathAtom(new MathMacroTemplate(buf,
+ cell->push_back(MathAtom(new InsetMathMacroTemplate(buf,
name, nargs, optionals, MacroTypeNewcommandx,
optionalValues, def, display)));
}
}
-#if 0
- else if (t.cs() == "multicolumn") {
- // extract column count and insert dummy cells
+ else if (t.cs() == "multicolumn" && grid.handlesMulticolumn()) {
+ // if the columns are specified numerically,
+ // extract column count and insert dummy cells,
+ // otherwise parse it as an user macro
MathData count;
parse(count, FLAG_ITEM, mode);
- int cols = 1;
- if (!extractNumber(count, cols)) {
- success_ = false;
- lyxerr << " can't extract number of cells from " << count << endl;
- }
- // resize the table if necessary
- for (int i = 0; i < cols; ++i) {
- if (addCol(grid, cellcol)) {
- cell = &grid.cell(grid.index(
- cellrow, cellcol));
- // mark this as dummy
- grid.cellinfo(grid.index(
- cellrow, cellcol)).dummy_ = true;
+ int cols;
+ // limit arbitrarily to 100 columns
+ if (extractNumber(count, cols) && cols > 0 && cols < 100) {
+ // resize the table if necessary
+ size_t first = grid.index(cellrow, cellcol);
+ for (int i = 1; i < cols; ++i) {
+ if (addCol(grid, cellcol)) {
+ size_t const idx = grid.index(cellrow, cellcol);
+ grid.cellinfo(idx).multi_ =
+ InsetMathGrid::CELL_PART_OF_MULTICOLUMN;
+ }
}
- }
- // the last cell is the real thing, not a dummy
- grid.cellinfo(grid.index(cellrow, cellcol)).dummy_ = false;
- // read special alignment
- MathData align;
- parse(align, FLAG_ITEM, mode);
- //grid.cellinfo(grid.index(cellrow, cellcol)).align_ = extractString(align);
+ // the first cell is the real thing, not a dummy
+ cell = &grid.cell(first);
+ grid.cellinfo(first).multi_ =
+ InsetMathGrid::CELL_BEGIN_OF_MULTICOLUMN;
+
+ // read special alignment
+ MathData align;
+ parse(align, FLAG_ITEM, mode);
+ grid.cellinfo(first).align_ = asString(align);
- // parse the remaining contents into the "real" cell
- parse(*cell, FLAG_ITEM, mode);
+ // parse the remaining contents into the "real" cell
+ parse(*cell, FLAG_ITEM, mode);
+ } else {
+ MathAtom at = MathAtom(new InsetMathMacro(buf, t.cs()));
+ cell->push_back(at);
+ cell->push_back(MathAtom(new InsetMathBrace(count)));
+ }
}
-#endif
else if (t.cs() == "limits" || t.cs() == "nolimits") {
CatCode const cat = nextToken().cat();
parse(ar, FLAG_OPTION, mode);
if (!ar.empty()) {
cell->push_back(MathAtom(new InsetMathRoot(buf)));
- cell->back().nucleus()->cell(0) = ar;
- parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
- } else {
+ cell->back().nucleus()->cell(1) = ar;
+ } else
cell->push_back(MathAtom(new InsetMathSqrt(buf)));
- parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
- }
+ parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
}
else if (t.cs() == "cancelto") {
cell->push_back(MathAtom(new InsetMathStackrel(buf, !ar.empty())));
if (!ar.empty())
cell->back().nucleus()->cell(2) = ar;
- parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
+ parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
}
else if (t.cs() == "xrightarrow" || t.cs() == "xleftarrow") {
}
else if (t.cs() == "ref" || t.cs() == "eqref" || t.cs() == "prettyref"
- || t.cs() == "pageref" || t.cs() == "vpageref" || t.cs() == "vref") {
+ || t.cs() == "nameref" || t.cs() == "pageref"
+ || t.cs() == "vpageref" || t.cs() == "vref") {
cell->push_back(MathAtom(new InsetMathRef(buf, t.cs())));
docstring const opt = parse_verbatim_option();
docstring const ref = parse_verbatim_item();
docstring const halign = parse_verbatim_item();
cell->push_back(MathAtom(new InsetMathArray(buf, name,
InsetMathGrid::guessColumns(halign), 1, (char)valign[0], halign)));
- parse2(cell->back(), FLAG_END, mode, false);
+ parse2(cell->back(), FLAG_END, InsetMath::MATH_MODE, false);
}
else if (name == "tabular") {
lyxerr << "found math environment `"
<< to_utf8(name)
<< "' in symbols file with unsupported inset `"
- << to_utf8(l->inset)
+ << l->inset
<< "'." << endl;
}
// create generic environment inset
else {
success_ = false;
- if (!(mode_ & Parse::QUIET)) {
+ if (!(mode_ & Parse::QUIET) &&
+ !(mode_ & Parse::TRACKMACRO)) {
dump();
lyxerr << "found unknown math environment '"
<< to_utf8(name) << "'" << endl;
}
}
- else if (t.cs() == "kern") {
+ else if (t.cs() == "kern" || t.cs() == "mkern") {
// FIXME: A hack...
docstring s;
int num_tokens = 0;
while (true) {
- Token const & t = getToken();
+ Token const & tt = getToken();
++num_tokens;
if (!good()) {
s.clear();
putback();
break;
}
- s += t.character();
+ s += tt.character();
if (isValidLength(to_utf8(s)))
break;
}
if (s.empty())
- cell->push_back(MathAtom(new InsetMathKern));
+ cell->push_back(MathAtom(new InsetMathMacro(buf, t.cs())));
else
cell->push_back(MathAtom(new InsetMathKern(s)));
}
asArray(label, ar);
if (grid.asHullInset()) {
grid.asHullInset()->label(cellrow, label);
+ grid.asHullInset()->numbered(cellrow, true);
} else {
cell->push_back(createInsetMath(t.cs(), buf));
cell->push_back(MathAtom(new InsetMathBrace(ar)));
else {
// Since the Length class cannot use length variables
// we must not create an InsetMathSpace.
- cell->push_back(MathAtom(new MathMacro(buf, name)));
+ cell->push_back(MathAtom(new InsetMathMacro(buf, name)));
MathData ar;
mathed_parse_cell(ar, '{' + arg + '}', mode_);
cell->append(ar);
parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
} else {
docstring const arg = parse_verbatim_item();
- cell->push_back(MathAtom(new MathMacro(buf, t.cs())));
+ cell->push_back(MathAtom(new InsetMathMacro(buf, t.cs())));
MathData ar;
mathed_parse_cell(ar, '[' + opt + ']', mode_);
cell->append(ar);
cell->push_back(createInsetMath(t.cs(), buf));
parse2(cell->back(), FLAG_ITEM, mode, false);
}
-
- // Disabled
- else if (1 && t.cs() == "ar") {
- auto_ptr<InsetMathXYArrow> p(new InsetMathXYArrow);
- // try to read target
- parse(p->cell(0), FLAG_OTPTION, mode);
- // try to read label
- if (nextToken().cat() == catSuper || nextToken().cat() == catSub) {
- p->up_ = nextToken().cat() == catSuper;
- getToken();
- parse(p->cell(1), FLAG_ITEM, mode);
- //lyxerr << "read label: " << p->cell(1) << endl;
- }
-
- cell->push_back(MathAtom(p.release()));
- //lyxerr << "read cell: " << cell << endl;
- }
#endif
else if (t.cs() == "lyxmathsym") {
new InsetMathBig(t.cs(), delim)));
else {
cell->push_back(createInsetMath(t.cs(), buf));
- putback();
+ // For some reason delim.empty()
+ // is always false here
+ if (delim.at(0))
+ putback();
}
}
putback();
}
+ else if (l->inset == "underset" || l->inset == "overset") {
+ cell->push_back(createInsetMath(t.cs(), buf));
+ parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
+ parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
+ }
+
else {
MathAtom at = createInsetMath(t.cs(), buf);
for (InsetMath::idx_type i = 0; i < at->nargs(); ++i)
Encodings::MATH_CMD | Encodings::TEXT_CMD,
is_combining, termination);
}
- if (c) {
+ if (c && buf->params().encoding().encodable(c)) {
if (termination) {
if (nextToken().cat() == catBegin) {
getToken();
}
if (!is_unicode_symbol) {
MathAtom at = is_user_macro ?
- MathAtom(new MathMacro(buf, t.cs()))
+ MathAtom(new InsetMathMacro(buf, t.cs()))
: createInsetMath(t.cs(), buf);
InsetMath::mode_type m = mode;
//if (m == InsetMath::UNDECIDED_MODE)