On Thu, Dec 01, 2016 at 11:47:19AM +0100, Kornel Benko wrote:
> Am Donnerstag, 1. Dezember 2016 um 01:01:44, schrieb Enrico Forestieri 
> <for...@lyx.org>
> > 
> > Or we can add the braces on output, as done in the attached patch (also
> > including the previous one). The braces will be added anytime a macro
> > has optional arguments (not only when it is nested), but, given that this
> > avoids a latex error, I think it is acceptable.
> > 
> > The test case now displays and compiles fine for me.
> > 
> 
> Confirmed, works very nice. Please commit.

I found a small glitch with the previous patch. As the braces are always
added and lyx removes only the ones appearing in a macro argument, if you
copy/paste a macro with optional arguments you always get the outer braces,
which tend to accumulate. Instead, the attached patch only adds the braces
if the macro is actually in the argument of a math macro, thus avoiding
this issue. Please, also test this one.

-- 
Enrico
diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index f2100af..2a36e55 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -659,12 +659,15 @@ void MathData::collectOptionalParameters(Cursor * cur,
                if (operator[](pos)->getChar() != '[')
                        break;
 
-               // found possible optional argument, look for "]"
+               // found possible optional argument, look for pairing "]"
+               int count = 1;
                size_t right = pos + 1;
                for (; right < size(); ++right) {
                        MathAtom & cell = operator[](right);
 
-                       if (cell->getChar() == ']')
+                       if (cell->getChar() == '[')
+                               ++count;
+                       else if (cell->getChar() == ']' && --count == 0)
                                // found right end
                                break;
 
diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp
index 34b5160..afc40a4 100644
--- a/src/mathed/MathMacro.cpp
+++ b/src/mathed/MathMacro.cpp
@@ -1068,6 +1068,15 @@ void MathMacro::write(WriteStream & os) const
        // we should be ok to continue even if this fails.
        LATTEST(d->macro_);
 
+       // We may already be in the argument of a macro
+       bool const inside_macro = os.insideMacro();
+       os.insideMacro(true);
+
+       // 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)
+               os << '{';
+
        // Always protect macros in a fragile environment
        if (os.fragile())
                os << "\\protect";
@@ -1106,9 +1115,13 @@ void MathMacro::write(WriteStream & os) const
                first = false;
        }
 
-       // add space if there was no argument
-       if (first)
+       // Close the opened brace or add space if there was no argument
+       if (d->optionals_ && inside_macro)
+               os << '}';
+       else if (first)
                os.pendingSpace(true);
+
+       os.insideMacro(inside_macro);
 }
 
 
diff --git a/src/mathed/MathStream.cpp b/src/mathed/MathStream.cpp
index ee65835..cf3fb51 100644
--- a/src/mathed/MathStream.cpp
+++ b/src/mathed/MathStream.cpp
@@ -128,10 +128,10 @@ WriteStream & operator<<(WriteStream & ws, docstring 
const & s)
 WriteStream::WriteStream(otexrowstream & os, bool fragile, bool latex,
                                                 OutputType output, Encoding 
const * encoding)
        : os_(os), fragile_(fragile), firstitem_(false), latex_(latex),
-         output_(output), pendingspace_(false), pendingbrace_(false),
-         textmode_(false), locked_(0), ascii_(0), canbreakline_(true),
-         mathsout_(false), ulemcmd_(NONE), line_(0), encoding_(encoding),
-         row_entry_(TexRow::row_none)
+         output_(output), insidemacro_(false), pendingspace_(false),
+         pendingbrace_(false), textmode_(false), locked_(0), ascii_(0),
+         canbreakline_(true), mathsout_(false), ulemcmd_(NONE), line_(0),
+         encoding_(encoding), row_entry_(TexRow::row_none)
 {}
 
 
diff --git a/src/mathed/MathStream.h b/src/mathed/MathStream.h
index 2a4d4d7..271330e 100644
--- a/src/mathed/MathStream.h
+++ b/src/mathed/MathStream.h
@@ -81,6 +81,10 @@ public:
        void ulemCmd(UlemCmdType ulemcmd) { ulemcmd_ = ulemcmd; }
        /// tell which ulem command type we are inside
        UlemCmdType ulemCmd() const { return ulemcmd_; }
+       /// record whether we are in the argument of a math macro
+       void insideMacro(bool insidemacro) { insidemacro_ = insidemacro; }
+       /// tell whether we are in the argument of a math macro
+       bool insideMacro() const { return insidemacro_; }
        /// writes space if next thing is isalpha()
        void pendingSpace(bool how);
        /// writes space if next thing is isalpha()
@@ -120,6 +124,8 @@ private:
        int latex_;
        /// output type (default, source preview, instant preview)?
        OutputType output_;
+       /// are we in the argument of a math macro?
+       bool insidemacro_;
        /// do we have a space pending?
        bool pendingspace_;
        /// do we have a brace pending?

Reply via email to