]> git.lyx.org Git - features.git/commitdiff
Amend [54147a71/lyxgit]
authorEnrico Forestieri <forenr@lyx.org>
Tue, 23 Apr 2019 19:06:12 +0000 (21:06 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 18 Jun 2020 13:48:27 +0000 (15:48 +0200)
If none of the optional arguments of a macro is used, there is no
following '[' after the macro name. Unfortunately, at loading time
the macro machinery is still not initialized, so the optionals()
member of InsetMathMacro is unusable. Hence, we have to track the
creation of macros with optionals as already we do for all macros.
The collected information is only used at loading time, because
the macros are dynamic and they may loose or acquire optional args.

Fixes the particular case reported at #11552.

src/Buffer.h
src/mathed/MathParser.cpp

index f1bd1f5e795ee7d85513c1217fda43971d8f875a..7fc9e4808c386324c88b9bd16aecfe73501f9fa7 100644 (file)
@@ -621,6 +621,9 @@ public:
        typedef std::set<docstring> UserMacroSet;
        mutable UserMacroSet usermacros;
 
+       /// Collect user macro names with optional parameters at loading time
+       mutable UserMacroSet usermacros_with_opts;
+
        /// Replace the inset contents for insets which InsetCode is equal
        /// to the passed \p inset_code.
        void changeRefsIfUnique(docstring const & from, docstring const & to);
index c41a6cfbd7b9ceab923d0b59badf7a868d755fe1..470731fc8ee77e76f85225695b12a9212c8fdb48 100644 (file)
@@ -946,13 +946,28 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        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();
-                               mc = mb && mb->cell(0).size() > 1 && mb->cell(0)[0]->asMacro()
+                               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;
-                               if (mc && mc->getChar() == '[') {
+                               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.
@@ -1149,8 +1164,11 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                name, nargs, optionals, MacroTypeNewcommand,
                                optionalValues, def, display)));
 
-                       if (buf && (mode_ & Parse::TRACKMACRO))
+                       if (buf && (mode_ & Parse::TRACKMACRO)) {
                                buf->usermacros.insert(name);
+                               if (optionals)
+                                       buf->usermacros_with_opts.insert(name);
+                       }
                }
 
                else if (t.cs() == "newcommandx" ||
@@ -1270,8 +1288,11 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                name, nargs, optionals, MacroTypeNewcommandx,
                                optionalValues, def, display)));
 
-                       if (buf && (mode_ & Parse::TRACKMACRO))
+                       if (buf && (mode_ & Parse::TRACKMACRO)) {
                                buf->usermacros.insert(name);
+                               if (optionals)
+                                       buf->usermacros_with_opts.insert(name);
+                       }
                }
 
                else if (t.cs() == "(") {