commit 60ac25a435a7dfbbee62530e793be65c62c44b0d
Author: Enrico Forestieri <[email protected]>
Date:   Wed Apr 24 17:28:53 2019 +0200

    Yet another attempt at properly fixing #11552
    
    This commit supercedes [54147a71/lyxgit] and [acba8476/lyxgit].
---
 src/mathed/InsetMathMacro.cpp |   22 ++++++++++----------
 src/mathed/MathParser.cpp     |   44 ++++++++++++++---------------------------
 2 files changed, 26 insertions(+), 40 deletions(-)

diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp
index d1bb67d..4d20d93 100644
--- a/src/mathed/InsetMathMacro.cpp
+++ b/src/mathed/InsetMathMacro.cpp
@@ -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);
diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp
index 470731f..8539ab6 100644
--- a/src/mathed/MathParser.cpp
+++ b/src/mathed/MathParser.cpp
@@ -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)));

Reply via email to