]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/MathParser.cpp
tex2lyx: support for \item with opt arg in itemize environment
[lyx.git] / src / mathed / MathParser.cpp
index 1982af3c86c47b2b2e85f59fb367d4a1c9a654c0..21621a3e25c4088953c06dbb11b418d980cd8252 100644 (file)
@@ -56,9 +56,11 @@ following hack as starting point to write some macros:
 #include "InsetMathRef.h"
 #include "InsetMathRoot.h"
 #include "InsetMathScript.h"
+#include "InsetMathSideset.h"
 #include "InsetMathSpace.h"
 #include "InsetMathSplit.h"
 #include "InsetMathSqrt.h"
+#include "InsetMathStackrel.h"
 #include "InsetMathString.h"
 #include "InsetMathTabular.h"
 #include "MathMacroTemplate.h"
@@ -859,7 +861,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                        } else {
                                                // This is not an outer hull and display math is
                                                // not allowed inside text mode environments.
-                                               error("bad math environment");
+                                               error("bad math environment $$");
                                                break;
                                        }
                                } else {
@@ -1238,13 +1240,19 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                }
 
                else if (t.cs() == "(") {
-                       cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
-                       parse(cell->back().nucleus()->cell(0), FLAG_SIMPLE2, InsetMath::MATH_MODE);
+                       if (mode == InsetMath::UNDECIDED_MODE) {
+                               cell->push_back(MathAtom(new InsetMathHull(buf, hullSimple)));
+                               parse2(cell->back(), FLAG_SIMPLE2, InsetMath::MATH_MODE, false);
+                       } else {
+                               // Don't create nested math hulls (bug #5392)
+                               cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
+                               parse(cell->back().nucleus()->cell(0), FLAG_SIMPLE2, InsetMath::MATH_MODE);
+                       }
                }
 
                else if (t.cs() == "[") {
                        if (mode != InsetMath::UNDECIDED_MODE) {
-                               error("bad math environment");
+                               error("bad math environment [");
                                break;
                        }
                        cell->push_back(MathAtom(new InsetMathHull(buf, hullEquation)));
@@ -1360,15 +1368,13 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        }
                }
 
-               else if (t.cs() == "nonumber") {
-                       if (grid.asHullInset())
-                               grid.asHullInset()->numbered(cellrow, false);
-               }
+               // \notag is the same as \nonumber if amsmath is used
+               else if ((t.cs() == "nonumber" || t.cs() == "notag") &&
+                        grid.asHullInset())
+                       grid.asHullInset()->numbered(cellrow, false);
 
-               else if (t.cs() == "number") {
-                       if (grid.asHullInset())
-                               grid.asHullInset()->numbered(cellrow, true);
-               }
+               else if (t.cs() == "number" && grid.asHullInset())
+                       grid.asHullInset()->numbered(cellrow, true);
 
                else if (t.cs() == "hline") {
                        grid.rowinfo(cellrow).lines_ ++;
@@ -1441,12 +1447,63 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
                }
 
+               else if (t.cs() == "sideset") {
+                       // Here allowed formats are \sideset{_{bl}^{tl}}{_{br}^{tr}}{operator}
+                       MathData ar[2];
+                       InsetMathScript * script[2] = {0, 0};
+                       for (int i = 0; i < 2; ++i) {
+                               parse(ar[i], FLAG_ITEM, mode);
+                               if (ar[i].size() == 1)
+                                       script[i] = ar[i][0].nucleus()->asScriptInset();
+                       }
+                       bool const hasscript[2] = {script[0] ? true : false, script[1] ? true : false};
+                       cell->push_back(MathAtom(new InsetMathSideset(buf, hasscript[0], hasscript[1])));
+                       if (hasscript[0]) {
+                               if (script[0]->hasDown())
+                                       cell->back().nucleus()->cell(1) = script[0]->down();
+                               if (script[0]->hasUp())
+                                       cell->back().nucleus()->cell(2) = script[0]->up();
+                       } else
+                               cell->back().nucleus()->cell(1) = ar[0];
+                       if (hasscript[1]) {
+                               if (script[1]->hasDown())
+                                       cell->back().nucleus()->cell(2 + hasscript[0]) = script[1]->down();
+                               if (script[1]->hasUp())
+                                       cell->back().nucleus()->cell(3 + hasscript[0]) = script[1]->up();
+                       } else
+                               cell->back().nucleus()->cell(2 + hasscript[0]) = ar[1];
+                       parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
+               }
+
+               else if (t.cs() == "stackrel") {
+                       // Here allowed formats are \stackrel[subscript]{superscript}{operator}
+                       MathData ar;
+                       parse(ar, FLAG_OPTION, mode);
+                       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);
+               }
+
                else if (t.cs() == "xrightarrow" || t.cs() == "xleftarrow") {
                        cell->push_back(createInsetMath(t.cs(), buf));
                        parse(cell->back().nucleus()->cell(1), FLAG_OPTION, mode);
                        parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
                }
 
+               else if (t.cs() == "xhookrightarrow" || t.cs() == "xhookleftarrow" ||
+                            t.cs() == "xRightarrow" || t.cs() == "xLeftarrow" ||
+                                t.cs() == "xleftrightarrow" || t.cs() == "xLeftrightarrow" ||
+                                t.cs() == "xrightharpoondown" || t.cs() == "xrightharpoonup" ||
+                                t.cs() == "xleftharpoondown" || t.cs() == "xleftharpoonup" ||
+                                t.cs() == "xleftrightharpoons" || t.cs() == "xrightleftharpoons" ||
+                                t.cs() == "xmapsto") {
+                       cell->push_back(createInsetMath(t.cs(), buf));
+                       parse(cell->back().nucleus()->cell(1), FLAG_OPTION, mode);
+                       parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
+               }
+
                else if (t.cs() == "ref" || t.cs() == "eqref" || t.cs() == "prettyref"
                          || t.cs() == "pageref" || t.cs() == "vpageref" || t.cs() == "vref") {
                        cell->push_back(MathAtom(new InsetMathRef(buf, t.cs())));
@@ -1487,6 +1544,13 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                else if (t.cs() == "begin") {
                        docstring const name = getArg('{', '}');
+                       
+                       if (name.empty()) {
+                               success_ = false;
+                               error("found invalid environment");
+                               return success_;
+                       }
+                       
                        environments_.push_back(name);
 
                        if (name == "array" || name == "subarray") {
@@ -1519,14 +1583,20 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        }
 
                        else if (name == "math") {
-                               cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
-                               parse(cell->back().nucleus()->cell(0), FLAG_END, InsetMath::MATH_MODE);
+                               if (mode == InsetMath::UNDECIDED_MODE) {
+                                       cell->push_back(MathAtom(new InsetMathHull(buf, hullSimple)));
+                                       parse2(cell->back(), FLAG_END, InsetMath::MATH_MODE, false);
+                               } else {
+                                       // Don't create nested math hulls (bug #5392)
+                                       cell->push_back(MathAtom(new InsetMathEnsureMath(buf)));
+                                       parse(cell->back().nucleus()->cell(0), FLAG_END, InsetMath::MATH_MODE);
+                               }
                        }
 
                        else if (name == "equation" || name == "equation*"
                                        || name == "displaymath") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                cell->push_back(MathAtom(new InsetMathHull(buf, hullEquation)));
@@ -1535,7 +1605,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                        else if (name == "eqnarray" || name == "eqnarray*") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                cell->push_back(MathAtom(new InsetMathHull(buf, hullEqnArray)));
@@ -1543,17 +1613,19 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        }
 
                        else if (name == "align" || name == "align*") {
-                               if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
-                                       break;
+                               if (mode == InsetMath::UNDECIDED_MODE) {
+                                       cell->push_back(MathAtom(new InsetMathHull(buf, hullAlign)));
+                                       parse2(cell->back(), FLAG_END, InsetMath::MATH_MODE, !stared(name));
+                               } else {
+                                       cell->push_back(MathAtom(new InsetMathSplit(buf, name,
+                                                       'c', !stared(name))));
+                                       parse2(cell->back(), FLAG_END, mode, !stared(name));
                                }
-                               cell->push_back(MathAtom(new InsetMathHull(buf, hullAlign)));
-                               parse2(cell->back(), FLAG_END, InsetMath::MATH_MODE, !stared(name));
                        }
 
                        else if (name == "flalign" || name == "flalign*") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                cell->push_back(MathAtom(new InsetMathHull(buf, hullFlAlign)));
@@ -1562,7 +1634,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                        else if (name == "alignat" || name == "alignat*") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                // ignore this for a while
@@ -1573,7 +1645,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                        else if (name == "xalignat" || name == "xalignat*") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                // ignore this for a while
@@ -1584,7 +1656,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                        else if (name == "xxalignat") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                // ignore this for a while
@@ -1595,7 +1667,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                        else if (name == "multline" || name == "multline*") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                cell->push_back(MathAtom(new InsetMathHull(buf, hullMultline)));
@@ -1604,7 +1676,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                        else if (name == "gather" || name == "gather*") {
                                if (mode != InsetMath::UNDECIDED_MODE) {
-                                       error("bad math environment");
+                                       error("bad math environment " + name);
                                        break;
                                }
                                cell->push_back(MathAtom(new InsetMathHull(buf, hullGather)));
@@ -1783,6 +1855,33 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        }
                }
 
+               else if (t.cs() == "smash") {
+                       skipSpaces();
+                       if (nextToken().asInput() == "[") {
+                               // Since the phantom inset cannot handle optional arguments
+                               // other than b and t, we must not create an InsetMathPhantom
+                               // if opt is different from b and t (bug 8967).
+                               docstring const opt = parse_verbatim_option();
+                               if (opt == "t" || opt == "b") {
+                                       cell->push_back(createInsetMath(t.cs() + opt, buf));
+                                       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())));
+                                       MathData ar;
+                                       mathed_parse_cell(ar, '[' + opt + ']', mode_);
+                                       cell->append(ar);
+                                       ar = MathData();
+                                       mathed_parse_cell(ar, '{' + arg + '}', mode_);
+                                       cell->append(ar);
+                               }
+                       }
+                       else {
+                               cell->push_back(createInsetMath(t.cs(), buf));
+                               parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
+                       }
+               }
+
 #if 0
                else if (t.cs() == "infer") {
                        MathData ar;
@@ -1985,7 +2084,8 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                        //}
                                        for (InsetMath::idx_type i = start; i < at->nargs(); ++i) {
                                                parse(at.nucleus()->cell(i), FLAG_ITEM, m);
-                                               skipSpaces();
+                                               if (mode == InsetMath::MATH_MODE)
+                                                       skipSpaces();
                                        }
                                        cell->push_back(at);
                                }