From 2731c5dc5511fce18cadaec76663d8dfdaa65d10 Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Fri, 26 Apr 2019 15:30:08 +0200 Subject: [PATCH] Correctly protect macros with optionals inserted in an optional argument The trick turns out to be inserting in braces the whole optional argument, rather than the single macro. See #11552 for the long history. --- src/mathed/InsetMathMacro.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp index 4b5242e5fc..5269df005f 100644 --- a/src/mathed/InsetMathMacro.cpp +++ b/src/mathed/InsetMathMacro.cpp @@ -1101,14 +1101,24 @@ void InsetMathMacro::write(WriteStream & os) const // For correctly parsing it when a document is reloaded, we // need to enclose an optional argument in braces if it starts // with a script inset with empty nucleus or ends with a - // delimiter-size-modifier macro (see #10497 and #11346) + // delimiter-size-modifier macro (see #10497 and #11346). + // We also need to do that when the optional argument + // contains macros with optionals. bool braced = false; size_type last = cell(i).size() - 1; - if (cell(i).size() && cell(i)[last].nucleus()->asUnknownInset()) { - latexkeys const * l = in_word_set(cell(i)[last].nucleus()->name()); + if (cell(i).size() && cell(i)[last]->asUnknownInset()) { + latexkeys const * l = in_word_set(cell(i)[last]->name()); braced = (l && l->inset == "big"); - } else if (cell(i).size() && cell(i)[0].nucleus()->asScriptInset()) { - braced = cell(i)[0].nucleus()->asScriptInset()->nuc().empty(); + } else if (cell(i).size() && cell(i)[0]->asScriptInset()) { + braced = cell(i)[0]->asScriptInset()->nuc().empty(); + } else { + for (size_type j = 0; j < cell(i).size(); ++j) { + InsetMathMacro const * ma = cell(i)[j]->asMacro(); + if (ma && ma->optionals()) { + braced = true; + break; + } + } } if (braced) os << "[{" << cell(i) << "}]"; -- 2.39.5