Yet another attempt at properly fixing #11552

This commit supercedes [54147a71/lyxgit] and [acba8476/lyxgit].
This commit is contained in:
Enrico Forestieri 2019-04-24 17:28:53 +02:00
parent ddb51c721c
commit 60ac25a435
2 changed files with 28 additions and 42 deletions

View File

@ -1083,18 +1083,6 @@ void InsetMathMacro::write(WriteStream & os) const
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";
os << "\\" << name();
bool first = true;
// Optional arguments:
// First find last non-empty optional argument
idx_type emptyOptFrom = 0;
@ -1104,6 +1092,18 @@ void InsetMathMacro::write(WriteStream & os) const
emptyOptFrom = i + 1;
}
// 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 && emptyOptFrom)
os << '{';
// Always protect macros in a fragile environment
if (os.fragile())
os << "\\protect";
os << "\\" << name();
bool first = true;
// print out optionals
for (i=0; i < cells_.size() && i < emptyOptFrom; ++i) {
first = false;
@ -1142,7 +1142,7 @@ void InsetMathMacro::write(WriteStream & os) const
}
// Close the opened brace or add space if there was no argument
if (d->optionals_ && inside_macro)
if (d->optionals_ && inside_macro && emptyOptFrom)
os << '}';
else if (first)
os.pendingSpace(true);

View File

@ -942,41 +942,27 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
cell->push_back(MathAtom(new InsetMathSpace(string(1, t.character()), "")));
else if (t.cat() == catBegin) {
bool const inbraces = nextToken().cat() == catBegin ||
(!cell->empty() && cell->back()->asMacro());
MathData ar;
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();
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;
bool has_opts = mc && mc->getChar() == '[';
InsetMathMacro const * ma = !inbraces && ar.size() ? ar[0]->asMacro() : 0;
InsetMathChar const * mc = ma && ar.size() > 1 ? ar[1]->asCharInset(): 0;
bool braced = 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 (!inbraces && !braced && ma && buf) {
if (mode_ & Parse::TRACKMACRO)
has_opts = buf->usermacros_with_opts.count(ma->name());
braced = buf->usermacros_with_opts.count(ma->name());
else {
MacroData const * md = buf->getMacro(ma->name(), false);
has_opts = md && md->optionals();
braced = md && md->optionals();
}
}
if (has_opts) {
// Remove the BraceInset around a macro
// with optional arguments. It will be
// automatically reinserted on write.
MathData md = mb->cell(0);
ar.erase(i);
ar.insert(i,md);
}
}
if (ar.size() == 1 && ar[0]->extraBraces())
if ((ar.size() == 1 && ar[0]->extraBraces()) || braced)
cell->append(ar);
else
cell->push_back(MathAtom(new InsetMathBrace(ar)));