]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/InsetMathMacro.cpp
Preserve \inputencoding value when switching to non-TeX fonts.
[lyx.git] / src / mathed / InsetMathMacro.cpp
index 4b5242e5fc93f23e66584bdcc7c8e91fc06cea23..5e72eecdc27850b4737e833593b420df9f9f4bdb 100644 (file)
@@ -661,17 +661,20 @@ void InsetMathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc,
                values[i].insert(0, MathAtom(proxy));
        }
        // expanding macro with the values
-       // Only update the argument macros if anything was expanded, otherwise
-       // we would get an endless loop (bug 9140). UpdateLocker does not work
-       // in this case, since MacroData::expand() creates new InsetMathMacro
-       // objects, so this would be a different recursion path than the one
-       // protected by UpdateLocker.
-       if (d->macro_->expand(values, d->expanded_)) {
+       // Only update the argument macros if anything was expanded or the LyX
+       // representation part does not contain the macro itself, otherwise we
+       // would get an endless loop (bugs 9140 and 11595). UpdateLocker does
+       // not work in this case, since MacroData::expand() creates new
+       // InsetMathMacro objects, so this would be a different recursion path
+       // than the one protected by UpdateLocker.
+       docstring const & display = d->macro_->display();
+       docstring const latexname = from_ascii("\\") + macroName();
+       if (d->macro_->expand(values, d->expanded_)
+           && !support::contains(display, latexname)) {
                if (utype == OutputUpdate && !d->expanded_.empty())
                        d->expanded_.updateMacros(cur, mc, utype, nesting);
        }
        // get definition for list edit mode
-       docstring const & display = d->macro_->display();
        asArray(display.empty() ? d->macro_->definition() : display,
                d->definition_, Parse::QUIET | Parse::MACRODEF);
 }
@@ -1101,14 +1104,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) << "}]";