]> git.lyx.org Git - features.git/commitdiff
Yet another attempt at properly fixing #11552
authorEnrico Forestieri <forenr@lyx.org>
Wed, 24 Apr 2019 15:28:53 +0000 (17:28 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 18 Jun 2020 13:48:27 +0000 (15:48 +0200)
This commit supercedes [54147a71/lyxgit] and [acba8476/lyxgit].

src/mathed/InsetMathMacro.cpp
src/mathed/MathParser.cpp

index d1bb67d59652e2c5376474807230892b9768ca9e..4d20d9302e8b4416090d4666822a3a134ff2e127 100644 (file)
@@ -1083,9 +1083,18 @@ void InsetMathMacro::write(WriteStream & os) const
        bool const inside_macro = os.insideMacro();
        os.insideMacro(true);
 
+       // Optional arguments:
+       // First find last non-empty optional argument
+       idx_type emptyOptFrom = 0;
+       idx_type i = 0;
+       for (; i < cells_.size() && i < d->optionals_; ++i) {
+               if (!cell(i).empty())
+                       emptyOptFrom = i + 1;
+       }
+
        // Enclose in braces to avoid latex errors with xargs if we have
        // optional arguments and are in the optional argument of a macro
-       if (d->optionals_ && inside_macro)
+       if (d->optionals_ && inside_macro && emptyOptFrom)
                os << '{';
 
        // Always protect macros in a fragile environment
@@ -1095,15 +1104,6 @@ void InsetMathMacro::write(WriteStream & os) const
        os << "\\" << name();
        bool first = true;
 
-       // Optional arguments:
-       // First find last non-empty optional argument
-       idx_type emptyOptFrom = 0;
-       idx_type i = 0;
-       for (; i < cells_.size() && i < d->optionals_; ++i) {
-               if (!cell(i).empty())
-                       emptyOptFrom = i + 1;
-       }
-
        // print out optionals
        for (i=0; i < cells_.size() && i < emptyOptFrom; ++i) {
                first = false;
@@ -1142,7 +1142,7 @@ void InsetMathMacro::write(WriteStream & os) const
        }
 
        // Close the opened brace or add space if there was no argument
-       if (d->optionals_ && inside_macro)
+       if (d->optionals_ && inside_macro && emptyOptFrom)
                os << '}';
        else if (first)
                os.pendingSpace(true);
index 470731fc8ee77e76f85225695b12a9212c8fdb48..8539ab66194dd9121d983c642ef207dfd664defa 100644 (file)
@@ -942,41 +942,27 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        cell->push_back(MathAtom(new InsetMathSpace(string(1, t.character()), "")));
 
                else if (t.cat() == catBegin) {
+                       bool const inbraces = nextToken().cat() == catBegin ||
+                               (!cell->empty() && cell->back()->asMacro());
                        MathData ar;
                        parse(ar, FLAG_BRACE_LAST, mode);
                        // do not create a BraceInset if they were written by LyX
                        // this helps to keep the annoyance of  "a choose b"  to a minimum
-                       InsetMathMacro const * ma;
-                       InsetMathBrace const * mb;
-                       InsetMathChar const * mc;
-                       for (size_type i = 0; i < ar.size(); ++i) {
-                               mb = ar[i]->asBraceInset();
-                               ma = mb && mb->cell(0).size()
-                                       ? mb->cell(0)[0]->asMacro() : 0;
-                               mc = ma && mb && mb->cell(0).size() > 1
-                                       ? mb->cell(0)[1]->asCharInset(): 0;
-                               bool has_opts = mc && mc->getChar() == '[';
-                               // If this is a macro, it may have optional
-                               // arguments, even if only defaults are used.
-                               // In this case, there is no following '['.
-                               if (!has_opts && ma && buf) {
-                                       if (mode_ & Parse::TRACKMACRO)
-                                               has_opts = buf->usermacros_with_opts.count(ma->name());
-                                       else {
-                                               MacroData const * md = buf->getMacro(ma->name(), false);
-                                               has_opts = md && md->optionals();
-                                       }
-                               }
-                               if (has_opts) {
-                                       // Remove the BraceInset around a macro
-                                       // with optional arguments. It will be
-                                       // automatically reinserted on write.
-                                       MathData md = mb->cell(0);
-                                       ar.erase(i);
-                                       ar.insert(i,md);
+                       InsetMathMacro const * ma = !inbraces && ar.size() ? ar[0]->asMacro() : 0;
+                       InsetMathChar const * mc = ma && ar.size() > 1 ? ar[1]->asCharInset(): 0;
+                       bool braced = mc && mc->getChar() == '[';
+                       // If this is a macro, it may have optional
+                       // arguments, even if only defaults are used.
+                       // In this case, there is no following '['.
+                       if (!inbraces && !braced && ma && buf) {
+                               if (mode_ & Parse::TRACKMACRO)
+                                       braced = buf->usermacros_with_opts.count(ma->name());
+                               else {
+                                       MacroData const * md = buf->getMacro(ma->name(), false);
+                                       braced = md && md->optionals();
                                }
                        }
-                       if (ar.size() == 1 && ar[0]->extraBraces())
+                       if ((ar.size() == 1 && ar[0]->extraBraces()) || braced)
                                cell->append(ar);
                        else
                                cell->push_back(MathAtom(new InsetMathBrace(ar)));