From 02ebfa000b9d41cf085cc633985ffe8235ede64f Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Fri, 17 Oct 2008 21:40:11 +0000 Subject: [PATCH] Fix bug 3397 http://bugzilla.lyx.org/show_bug.cgi?id=3397 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26934 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Cursor.cpp | 4 +- src/Cursor.h | 4 +- src/Text3.cpp | 6 +- src/mathed/InsetMathGrid.cpp | 24 ++++- src/mathed/InsetMathHull.cpp | 8 ++ src/mathed/InsetMathHull.h | 2 + src/mathed/InsetMathNest.cpp | 7 +- src/mathed/MathParser.cpp | 187 ++++++++++++++++++++-------------- src/mathed/MathParser.h | 15 ++- src/mathed/MathSupport.cpp | 6 +- src/mathed/MathSupport.h | 3 +- src/mathed/mathparser_flags.h | 51 ++++++++++ 12 files changed, 221 insertions(+), 96 deletions(-) create mode 100644 src/mathed/mathparser_flags.h diff --git a/src/Cursor.cpp b/src/Cursor.cpp index a51c98b8b4..38ce314f68 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -1242,10 +1242,10 @@ void Cursor::insert(Inset * inset0) } -void Cursor::niceInsert(docstring const & t) +void Cursor::niceInsert(docstring const & t, Parse::flags f) { MathData ar; - asArray(t, ar); + asArray(t, ar, f); if (ar.size() == 1) niceInsert(ar[0]); else diff --git a/src/Cursor.h b/src/Cursor.h index a3efffed1a..a849759ac9 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -17,6 +17,8 @@ #include "Font.h" #include "Undo.h" +#include "mathed/mathparser_flags.h" + #include @@ -371,7 +373,7 @@ public: /// void niceInsert(MathAtom const & at); /// - void niceInsert(docstring const & str); + void niceInsert(docstring const & str, Parse::flags f = Parse::NORMAL); /// in pixels from top of screen void setScreenPos(int x, int y); diff --git a/src/Text3.cpp b/src/Text3.cpp index 22408657cb..6693e6297b 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -164,13 +164,12 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd, bool display) istringstream is(selstr); Lexer lex; lex.setStream(is); - mathed_parser_warn_contents(false); - formula->read(lex); + formula->readQuiet(lex); if (formula->getType() == hullNone) { // No valid formula, let's try with delims is.str("$" + selstr + "$"); lex.setStream(is); - formula->read(lex); + formula->readQuiet(lex); if (formula->getType() == hullNone) { // Still not valid, leave it as is valid = false; @@ -180,7 +179,6 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd, bool display) cur.insert(formula); } else cur.insert(formula); - mathed_parser_warn_contents(true); } else { cur.insert(new MathMacroTemplate(sel)); } diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp index 03e66d6a8c..aa79ed0f78 100644 --- a/src/mathed/InsetMathGrid.cpp +++ b/src/mathed/InsetMathGrid.cpp @@ -62,6 +62,17 @@ static int extractInt(istream & is) } +static void resetGrid(InsetMathGrid & grid) +{ + while (grid.ncols() > 1) + grid.delCol(grid.ncols()); + while (grid.nrows() > 1) + grid.delRow(grid.nrows()); + grid.cell(0).erase(0, grid.cell(0).size()); + grid.setDefaults(); +} + + ////////////////////////////////////////////////////////////// @@ -1053,6 +1064,9 @@ void InsetMathGrid::splitCell(Cursor & cur) void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) { //lyxerr << "*** InsetMathGrid: request: " << cmd << endl; + + Parse::flags parseflg = Parse::QUIET; + switch (cmd.action) { // insert file functions @@ -1233,6 +1247,9 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) break; } + case LFUN_CLIPBOARD_PASTE: + parseflg |= Parse::VERBATIM; + // fall through case LFUN_PASTE: { cur.message(_("Paste")); cap::replaceSelection(cur); @@ -1247,7 +1264,12 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) } InsetMathGrid grid(1, 1); if (!topaste.empty()) - mathed_parse_normal(grid, topaste); + if (topaste.size() == 1 + || !mathed_parse_normal(grid, topaste, parseflg)) { + resetGrid(grid); + mathed_parse_normal(grid, topaste, + parseflg | Parse::VERBATIM); + } if (grid.nargs() == 1) { // single cell/part of cell diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 8a9a7c36ed..001cdd01ae 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -1584,6 +1584,14 @@ void InsetMathHull::read(Lexer & lex) } +void InsetMathHull::readQuiet(Lexer & lex) +{ + MathAtom at; + mathed_parse_normal(at, lex, Parse::QUIET); + operator=(*at->asHullInset()); +} + + int InsetMathHull::plaintext(odocstream & os, OutputParams const & runparams) const { if (0 && display()) { diff --git a/src/mathed/InsetMathHull.h b/src/mathed/InsetMathHull.h index e43313a9f6..e020e96ae7 100644 --- a/src/mathed/InsetMathHull.h +++ b/src/mathed/InsetMathHull.h @@ -109,6 +109,8 @@ public: /// void read(Lexer & lex); /// + void readQuiet(Lexer & lex); + /// int plaintext(odocstream &, OutputParams const &) const; /// int docbook(odocstream &, OutputParams const &) const; diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index f2d8d2ac76..a1f739afb9 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -513,8 +513,13 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) { //lyxerr << "InsetMathNest: request: " << cmd << endl; + Parse::flags parseflg = Parse::QUIET; + switch (cmd.action) { + case LFUN_CLIPBOARD_PASTE: + parseflg |= Parse::VERBATIM; + // fall through case LFUN_PASTE: { cur.recordUndoSelection(); cur.message(_("Paste")); @@ -528,7 +533,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) is >> n; topaste = cap::selection(n); } - cur.niceInsert(topaste); + cur.niceInsert(topaste, parseflg); cur.clearSelection(); // bug 393 cur.finishUndo(); break; diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp index becc9c89b3..56fdf23c81 100644 --- a/src/mathed/MathParser.cpp +++ b/src/mathed/MathParser.cpp @@ -68,6 +68,7 @@ following hack as starting point to write some macros: #include "support/debug.h" #include "support/convert.h" #include "support/docstream.h" +#include "support/lstrings.h" #include @@ -77,11 +78,10 @@ using namespace std; namespace lyx { +using support::subst; + namespace { -bool warn_unusual_contents = true; - - InsetMath::mode_type asMode(InsetMath::mode_type oldmode, docstring const & str) { //lyxerr << "handling mode: '" << str << "'" << endl; @@ -100,6 +100,21 @@ bool stared(docstring const & s) } +docstring escapeSpecialChars(docstring const & str) +{ + return subst(subst(subst(subst(subst(subst(subst(subst(subst(str, + from_ascii("\\"), from_ascii("\\backslash ")), + from_ascii("^"), from_ascii("\\mathcircumflex ")), + from_ascii("_"), from_ascii("\\_")), + from_ascii("$"), from_ascii("\\$")), + from_ascii("#"), from_ascii("\\#")), + from_ascii("&"), from_ascii("\\&")), + from_ascii("%"), from_ascii("\\%")), + from_ascii("{"), from_ascii("\\{")), + from_ascii("}"), from_ascii("\\}")); +} + + /*! * Add the row \p cellrow to \p grid. * \returns wether the row could be added. Adding a row can fail for @@ -307,21 +322,23 @@ class Parser { public: /// typedef InsetMath::mode_type mode_type; + /// + typedef Parse::flags parse_mode; /// - Parser(Lexer & lex); + Parser(Lexer & lex, parse_mode mode); /// Only use this for reading from .lyx file format, for the reason /// see Parser::tokenize(istream &). - Parser(istream & is); + Parser(istream & is, parse_mode mode); /// - Parser(docstring const & str); + Parser(docstring const & str, parse_mode mode); /// bool parse(MathAtom & at); /// - void parse(MathData & array, unsigned flags, mode_type mode); + bool parse(MathData & array, unsigned flags, mode_type mode); /// - void parse1(InsetMathGrid & grid, unsigned flags, mode_type mode, + bool parse1(InsetMathGrid & grid, unsigned flags, mode_type mode, bool numbered); /// MathData parse(unsigned flags, mode_type mode); @@ -378,26 +395,30 @@ private: unsigned pos_; /// Stack of active environments vector environments_; + /// + parse_mode mode_; + /// + bool success_; }; -Parser::Parser(Lexer & lexer) - : lineno_(lexer.lineNumber()), pos_(0) +Parser::Parser(Lexer & lexer, parse_mode mode) + : lineno_(lexer.lineNumber()), pos_(0), mode_(mode), success_(true) { tokenize(lexer.getStream()); lexer.eatLine(); } -Parser::Parser(istream & is) - : lineno_(0), pos_(0) +Parser::Parser(istream & is, parse_mode mode) + : lineno_(0), pos_(0), mode_(mode), success_(true) { tokenize(is); } -Parser::Parser(docstring const & str) - : lineno_(0), pos_(0) +Parser::Parser(docstring const & str, parse_mode mode) + : lineno_(0), pos_(0), mode_(mode), success_(true) { tokenize(str); } @@ -519,7 +540,8 @@ void Parser::tokenize(istream & is) void Parser::tokenize(docstring const & buffer) { - idocstringstream is(buffer, ios::in | ios::binary); + idocstringstream is(mode_ & Parse::VERBATIM ? + escapeSpecialChars(buffer) : buffer, ios::in | ios::binary); char_type c; while (is.get(c)) { @@ -573,7 +595,8 @@ void Parser::tokenize(docstring const & buffer) } case catIgnore: { - lyxerr << "ignoring a char: " << int(c) << endl; + if (!(mode_ & Parse::QUIET)) + lyxerr << "ignoring a char: " << int(c) << endl; break; } @@ -602,9 +625,12 @@ void Parser::dump() const void Parser::error(string const & msg) { - lyxerr << "Line ~" << lineno_ << ": Math parse error: " << msg << endl; - dump(); - //exit(1); + success_ = false; + if (!(mode_ & Parse::QUIET)) { + lyxerr << "Line ~" << lineno_ << ": Math parse error: " + << msg << endl; + dump(); + } } @@ -614,14 +640,14 @@ bool Parser::parse(MathAtom & at) MathData ar; parse(ar, false, InsetMath::UNDECIDED_MODE); if (ar.size() != 1 || ar.front()->getType() == hullNone) { - if (warn_unusual_contents) + if (!(mode_ & Parse::QUIET)) lyxerr << "unusual contents found: " << ar << endl; at = MathAtom(new InsetMathPar(ar)); //if (at->nargs() > 0) // at.nucleus()->cell(0) = ar; //else // lyxerr << "unusual contents found: " << ar << endl; - return true; + return false; } at = ar[0]; return true; @@ -673,11 +699,12 @@ MathData Parser::parse(unsigned flags, mode_type mode) } -void Parser::parse(MathData & array, unsigned flags, mode_type mode) +bool Parser::parse(MathData & array, unsigned flags, mode_type mode) { InsetMathGrid grid(1, 1); parse1(grid, flags, mode, false); array = grid.cell(0); + return success_; } @@ -688,7 +715,7 @@ void Parser::parse2(MathAtom & at, const unsigned flags, const mode_type mode, } -void Parser::parse1(InsetMathGrid & grid, unsigned flags, +bool Parser::parse1(InsetMathGrid & grid, unsigned flags, const mode_type mode, const bool numbered) { int limits = 0; @@ -720,7 +747,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, // skip the brace and collect everything to the next matching // closing brace parse1(grid, FLAG_BRACE_LAST, mode, numbered); - return; + return success_; } // handle only this single token, leave the loop if done @@ -734,7 +761,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, if (t.cat() != catBegin) { error("opening brace expected"); - return; + return success_; } // skip the brace and collect everything to the next matching @@ -752,7 +779,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, // no option found, put back token and we are done putback(); } - return; + return success_; } // @@ -777,7 +804,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (flags & FLAG_SIMPLE) { // this is the end of the formula - return; + return success_; } else { @@ -820,7 +847,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (t.cat() == catEnd) { if (flags & FLAG_BRACE_LAST) - return; + return success_; error("found '}' unexpectedly"); //LASSERT(false, /**/); //add(cell, '}', LM_TC_TEX); @@ -830,7 +857,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, //lyxerr << " column now " << (cellcol + 1) // << " max: " << grid.ncols() << endl; if (flags & FLAG_ALIGN) - return; + return success_; if (addCol(grid, cellcol)) cell = &grid.cell(grid.index(cellrow, cellcol)); } @@ -870,7 +897,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (t.character() == ']' && (flags & FLAG_BRACK_LAST)) { //lyxerr << "finished reading option" << endl; - return; + return success_; } else if (t.cat() == catOther) @@ -934,12 +961,12 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, // get name if (getToken().cat() != catBegin) { error("'{' in \\newcommand expected (1) "); - return; + return success_; } docstring name = getToken().cs(); if (getToken().cat() != catEnd) { error("'}' in \\newcommand expected"); - return; + return success_; } // get arity @@ -983,7 +1010,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, name = getToken().cs(); if (getToken().cat() != catEnd) { error("'}' in \\newcommandx expected"); - return; + return success_; } } else name = getToken().cs(); @@ -992,7 +1019,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, docstring const arg = getArg('[', ']'); if (arg.empty()) { error("[num] in \\newcommandx expected"); - return; + return success_; } int nargs = convert(arg); @@ -1013,14 +1040,14 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, if (n > nargs) { error("Arity of \\newcommandx too low " "for given optional parameter."); - return; + return success_; } // skip '=' if (getToken().character() != '=') { error("'=' and optional parameter value " "expected for \\newcommandx"); - return; + return success_; } // get value @@ -1055,7 +1082,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, } } else { error("option for \\newcommandx expected"); - return; + return success_; } // skip komma @@ -1066,13 +1093,13 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, } else if (nextToken().character() != ']') { error("Expecting ',' or ']' in options " "of \\newcommandx"); - return; + return success_; } } // skip ']' if (!good()) - return; + return success_; getToken(); } @@ -1128,7 +1155,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, // single line hull insets. if (grid.nrows() > 1) delEmptyLastRow(grid); - return; + return success_; } } else error("found 'end' unexpectedly"); @@ -1136,19 +1163,19 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (t.cs() == ")") { if (flags & FLAG_SIMPLE2) - return; + return success_; error("found '\\)' unexpectedly"); } else if (t.cs() == "]") { if (flags & FLAG_EQUATION) - return; + return success_; error("found '\\]' unexpectedly"); } else if (t.cs() == "\\") { if (flags & FLAG_ALIGN) - return; + return success_; bool added = false; if (nextToken().asInput() == "*") { getToken(); @@ -1174,6 +1201,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, 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 @@ -1291,10 +1319,10 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (t.cs() == "right") { if (flags & FLAG_RIGHT) - return; + return success_; //lyxerr << "got so far: '" << cell << "'" << endl; error("Unmatched right delimiter"); - return; + return success_; } else if (t.cs() == "begin") { @@ -1396,10 +1424,15 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, cell->push_back(MathAtom(new InsetMathSplit(name, (char)valign[0]))); parse2(cell->back(), FLAG_END, mode, false); } else { - dump(); - lyxerr << "found math environment `" << to_utf8(name) - << "' in symbols file with unsupported inset `" - << to_utf8(l->inset) << "'." << endl; + success_ = false; + if (!(mode_ & Parse::QUIET)) { + dump(); + lyxerr << "found math environment `" + << to_utf8(name) + << "' in symbols file with unsupported inset `" + << to_utf8(l->inset) + << "'." << endl; + } // create generic environment inset cell->push_back(MathAtom(new InsetMathEnv(name))); parse(cell->back().nucleus()->cell(0), FLAG_END, mode); @@ -1407,9 +1440,12 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, } else { - dump(); - lyxerr << "found unknown math environment '" << to_utf8(name) - << "'" << endl; + success_ = false; + if (!(mode_ & Parse::QUIET)) { + dump(); + lyxerr << "found unknown math environment '" + << to_utf8(name) << "'" << endl; + } // create generic environment inset cell->push_back(MathAtom(new InsetMathEnv(name))); parse(cell->back().nucleus()->cell(0), FLAG_END, mode); @@ -1453,14 +1489,14 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, cell->clear(); parse(at.nucleus()->cell(1), flags, mode); cell->push_back(at); - return; + return success_; } else if (t.cs() == "color") { docstring const color = parse_verbatim_item(); cell->push_back(MathAtom(new InsetMathColor(true, color))); parse(cell->back().nucleus()->cell(0), flags, mode); - return; + return success_; } else if (t.cs() == "textcolor") { @@ -1472,7 +1508,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, else if (t.cs() == "normalcolor") { cell->push_back(createInsetMath(t.cs())); parse(cell->back().nucleus()->cell(0), flags, mode); - return; + return success_; } else if (t.cs() == "substack") { @@ -1534,7 +1570,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, skipSpaces(); if (getToken().cat() != catBegin) { error("'{' expected in \\" + t.cs()); - return; + return success_; } int count = 0; docstring cmd; @@ -1549,7 +1585,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, } if (getToken().cat() != catEnd) { error("'}' expected in \\" + t.cs()); - return; + return success_; } docstring rem; cmd = Encodings::fromLaTeXCommand(cmd, rem); @@ -1559,7 +1595,8 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, MathAtom at = createInsetMath(t.cs()); cell->push_back(at); MathData ar; - mathed_parse_cell(ar, '{' + rem + '}'); + if (!mathed_parse_cell(ar, '{' + rem + '}', mode_)) + success_ = false;; cell->append(ar); } } @@ -1591,7 +1628,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, flags | FLAG_ALIGN, asMode(mode, l->extra)); if (prevToken().cat() != catAlign && prevToken().cs() != "\\") - return; + return success_; putback(); } @@ -1601,7 +1638,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, flags | FLAG_ALIGN, mode); if (prevToken().cat() != catAlign && prevToken().cs() != "\\") - return; + return success_; putback(); } @@ -1684,6 +1721,7 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, break; } } + return success_; } @@ -1691,39 +1729,36 @@ void Parser::parse1(InsetMathGrid & grid, unsigned flags, } // anonymous namespace -void mathed_parser_warn_contents(bool warn) +bool mathed_parse_cell(MathData & ar, docstring const & str, Parse::flags f) { - warn_unusual_contents = warn; + return Parser(str, f).parse(ar, 0, f & Parse::TEXTMODE ? + InsetMath::TEXT_MODE : InsetMath::MATH_MODE); } -void mathed_parse_cell(MathData & ar, docstring const & str) +bool mathed_parse_cell(MathData & ar, istream & is, Parse::flags f) { - Parser(str).parse(ar, 0, InsetMath::MATH_MODE); + return Parser(is, f).parse(ar, 0, f & Parse::TEXTMODE ? + InsetMath::TEXT_MODE : InsetMath::MATH_MODE); } -void mathed_parse_cell(MathData & ar, istream & is) +bool mathed_parse_normal(MathAtom & t, docstring const & str, Parse::flags f) { - Parser(is).parse(ar, 0, InsetMath::MATH_MODE); + return Parser(str, f).parse(t); } -bool mathed_parse_normal(MathAtom & t, docstring const & str) +bool mathed_parse_normal(MathAtom & t, Lexer & lex, Parse::flags f) { - return Parser(str).parse(t); + return Parser(lex, f).parse(t); } -bool mathed_parse_normal(MathAtom & t, Lexer & lex) +bool mathed_parse_normal(InsetMathGrid & grid, docstring const & str, Parse::flags f) { - return Parser(lex).parse(t); -} - - -void mathed_parse_normal(InsetMathGrid & grid, docstring const & str) -{ - Parser(str).parse1(grid, 0, InsetMath::MATH_MODE, false); + return Parser(str, f).parse1(grid, 0, f & Parse::TEXTMODE ? + InsetMath::TEXT_MODE : InsetMath::MATH_MODE, false); } diff --git a/src/mathed/MathParser.h b/src/mathed/MathParser.h index 43b6f92090..aa798e7cca 100644 --- a/src/mathed/MathParser.h +++ b/src/mathed/MathParser.h @@ -13,6 +13,8 @@ #ifndef MATH_PARSER_H #define MATH_PARSER_H +#include "mathparser_flags.h" + #include "support/types.h" #include "support/docstring.h" @@ -58,21 +60,18 @@ public: /// check whether this is a well-known (La)TeX macro or primitive latexkeys const * in_word_set(docstring const & str); -/// tell the parser whether it should warn about unusual contents -void mathed_parser_warn_contents(bool); - /// parse formula from a string -bool mathed_parse_normal(MathAtom &, docstring const &); +bool mathed_parse_normal(MathAtom &, docstring const &, Parse::flags f = Parse::NORMAL); /// ... the LyX lexxer -bool mathed_parse_normal(MathAtom &, Lexer &); +bool mathed_parse_normal(MathAtom &, Lexer &, Parse::flags f = Parse::NORMAL); /// parse formula from a string into a grid -void mathed_parse_normal(InsetMathGrid &, docstring const &); +bool mathed_parse_normal(InsetMathGrid &, docstring const &, Parse::flags f = Parse::NORMAL); /// parse a single cell from a string -void mathed_parse_cell(MathData & ar, docstring const &); +bool mathed_parse_cell(MathData & ar, docstring const &, Parse::flags f = Parse::NORMAL); /// parse a single cell from a stream. Only use this for reading from .lyx /// file format, for the reason see Parser::tokenize(std::istream &). -void mathed_parse_cell(MathData & ar, std::istream &); +bool mathed_parse_cell(MathData & ar, std::istream &, Parse::flags f = Parse::NORMAL); void initParser(); diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index d1831d4432..948571fdd0 100644 --- a/src/mathed/MathSupport.cpp +++ b/src/mathed/MathSupport.cpp @@ -685,9 +685,11 @@ docstring asString(MathData const & ar) } -void asArray(docstring const & str, MathData & ar) +void asArray(docstring const & str, MathData & ar, Parse::flags pf) { - mathed_parse_cell(ar, str); + bool quiet = pf & Parse::QUIET; + if ((str.size() == 1 || !mathed_parse_cell(ar, str, pf)) && quiet) + mathed_parse_cell(ar, str, pf | Parse::VERBATIM); } diff --git a/src/mathed/MathSupport.h b/src/mathed/MathSupport.h index ead1e095aa..8bda8ac80a 100644 --- a/src/mathed/MathSupport.h +++ b/src/mathed/MathSupport.h @@ -13,6 +13,7 @@ #ifndef MATH_SUPPORT_H #define MATH_SUPPORT_H +#include "mathparser_flags.h" #include "support/strfwd.h" #include @@ -54,7 +55,7 @@ docstring asString(MathData const & ar); docstring asString(InsetMath const &); docstring asString(MathAtom const &); // converts string to single cell -void asArray(docstring const & str, MathData & ar); +void asArray(docstring const &, MathData &, Parse::flags f = Parse::NORMAL); } // namespace lyx diff --git a/src/mathed/mathparser_flags.h b/src/mathed/mathparser_flags.h new file mode 100644 index 0000000000..41d5cd7982 --- /dev/null +++ b/src/mathed/mathparser_flags.h @@ -0,0 +1,51 @@ +// -*- C++ -*- +/** + * \file mathparser_flags.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Enrico Forestieri + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MATHPARSER_FLAGS_H +#define MATHPARSER_FLAGS_H + +namespace lyx { + +namespace Parse { + +enum flags { + /// Parse normally. + NORMAL = 0x00, + /// Start parsing in text mode. + TEXTMODE = 0x01, + /// Parse verbatim. + VERBATIM = 0x02, + /// Quiet operation (no warnigs or errors). + QUIET = 0x04 +}; + + +inline flags operator|(flags const f, flags const g) +{ + return static_cast(int(f) | int(g)); +} + + +inline flags & operator|=(flags & f, flags g) +{ + return f = static_cast(int(f) | int(g)); +} + + +inline flags operator&(flags const f, flags const g) +{ + return static_cast(int(f) & int(g)); +} + +} // namespace Parse + +} // namespace lyx +#endif