Amend [54147a71/lyxgit]

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.
This commit is contained in:
Enrico Forestieri 2019-04-23 21:06:12 +02:00
parent 93bfd1d8f8
commit acba847649
2 changed files with 28 additions and 4 deletions

View 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);

View 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() == "(") {