On Thu, Dec 01, 2016 at 04:31:44PM -0500, Richard Heck wrote:
> 
> I'm no expert on this part of the code, but this doesn't look too
> dangerous. Since 2.2.3 is still a little ways away, is it worth
> committing to stable?

I think it is not risky and I am attaching the version for stable here.
However, it behaves a bit differently than in trunk, as the braces that
are added when the macro appears in the argument of another macro are
preserved on copy/paste. I don't know why, but if this is deemed a minor
glitch, it could go as is. Frankly, I don't want to spend more time
trying to understand why that is so...

-- 
Enrico
diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 7e302c8..0701244 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -713,12 +713,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 9fe6e15..06d5a2c 100644
--- a/src/mathed/MathMacro.cpp
+++ b/src/mathed/MathMacro.cpp
@@ -938,6 +938,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";
@@ -976,9 +985,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 7ea6ab7..a4b723b 100644
--- a/src/mathed/MathStream.cpp
+++ b/src/mathed/MathStream.cpp
@@ -125,9 +125,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)
+	  output_(output), insidemacro_(false), pendingspace_(false),
+	  pendingbrace_(false), textmode_(false), locked_(0), ascii_(0),
+	  canbreakline_(true), mathsout_(false), ulemcmd_(NONE), line_(0),
+	  encoding_(encoding)
 {}
 
 
diff --git a/src/mathed/MathStream.h b/src/mathed/MathStream.h
index b2a7992..977947b 100644
--- a/src/mathed/MathStream.h
+++ b/src/mathed/MathStream.h
@@ -80,6 +80,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()
@@ -122,6 +126,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