commit aad2bc0bab33639ed2790b7bd4ac98cef50ea696
Author: Enrico Forestieri <[email protected]>
Date: Fri Jul 4 12:21:05 2025 -0400
Fix bug #8934
Patch by Georg adapted to current master, and amended, by Enrico.
---
src/Buffer.cpp | 1 -
src/Buffer.h | 3 +-
src/insets/InsetInclude.cpp | 8 +---
src/mathed/MathParser.cpp | 91 ++++++++++++++++++++++++++++++++++++---------
status.24x | 2 +
5 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 43dd4a69da..46db015569 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -1131,7 +1131,6 @@ bool Buffer::readDocument(Lexer & lex)
for (auto const & m : usermacros)
pbuf->usermacros.insert(m);
}
- usermacros.clear();
updateMacros();
updateMacroInstances(InternalUpdate);
return res;
diff --git a/src/Buffer.h b/src/Buffer.h
index dc2583629d..7b78281e3b 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -629,7 +629,8 @@ public:
MacroData const * getMacro(docstring const & name, Buffer const &
child, bool global = true) const;
/// Collect user macro names at loading time
- typedef std::set<docstring> UserMacroSet;
+ /// Map maps from macro name to number of optional arguments
+ typedef std::map<docstring, size_t> UserMacroSet;
mutable UserMacroSet usermacros;
/// Replace the inset contents for insets which InsetCode is equal
diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp
index f4ecaae8a0..5e23280096 100644
--- a/src/insets/InsetInclude.cpp
+++ b/src/insets/InsetInclude.cpp
@@ -512,12 +512,8 @@ Buffer * InsetInclude::loadIfNeeded() const
// inform parent buffer about local macros.
Buffer const * parent = &buffer();
child->setParent(parent);
- MacroNameSet macros;
- child->listMacroNames(macros);
- MacroNameSet::const_iterator cit = macros.begin();
- MacroNameSet::const_iterator end = macros.end();
- for (; cit != end; ++cit)
- parent->usermacros.insert(*cit);
+ for (auto const & m : child->usermacros)
+ parent->usermacros.insert(m);
}
// Cache the child buffer.
diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp
index 8a324818ed..382b14b71e 100644
--- a/src/mathed/MathParser.cpp
+++ b/src/mathed/MathParser.cpp
@@ -1079,12 +1079,13 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned
flags,
if (nextToken().cat() == catBegin)
parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
+ size_t const optionals = 0;
cell->push_back(MathAtom(new InsetMathMacroTemplate(buf,
- name, nargs, 0, MacroTypeDef,
+ name, nargs, optionals, MacroTypeDef,
vector<MathData>(), def, display)));
if (buf && (mode_ & Parse::TRACKMACRO))
- buf->usermacros.insert(name);
+ buf->usermacros[name] = optionals;
}
else if (t.cs() == "newcommand" ||
@@ -1132,7 +1133,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
optionalValues, def, display)));
if (buf && (mode_ & Parse::TRACKMACRO))
- buf->usermacros.insert(name);
+ buf->usermacros[name] = optionals;
}
else if (t.cs() == "newcommandx" ||
@@ -1253,7 +1254,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
optionalValues, def, display)));
if (buf && (mode_ & Parse::TRACKMACRO))
- buf->usermacros.insert(name);
+ buf->usermacros[name] = optionals;
}
else if (t.cs() == "(") {
@@ -1989,10 +1990,28 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned
flags,
if (l && !is_user_macro) {
if (l->inset == "big") {
skipSpaces();
+ // If we are parsing for an optional
argument,
+ // we must not handle ']' as a
delimiter (bug 8934).
+ // In standard LaTeX \foo[\Big] will
give an error
+ // "Missing delimiter (. inserted)",
however in
+ // combination with
\DeclarePairedDelimiterX from
+ // the mathtools package \Big on its
own inside an
+ // optional argument is valid:
+ // \documentclass{article}
+ // \usepackage{mathtools}
+ //
\DeclarePairedDelimiterX{\COM}[2]{[}{]}{#1,#2}
+ //
\newcommand{\Com}[3][]{\COM[#1]{#2}{#3}}
+ // \begin{document}
+ // $\Com[\Big]AB$
+ // \end{document}
+ // Therefore, if we are looking for
FLAG_BRACK_LAST,
+ // and if the delimiter is ']', let
FLAG_BRACK_LAST
+ // take precedence.
docstring const delim =
getToken().asInput();
- if
(InsetMathBig::isBigInsetDelim(delim))
+ if
(InsetMathBig::isBigInsetDelim(delim) &&
+ (delim != "]" || !(flags &
FLAG_BRACK_LAST)))
cell->push_back(MathAtom(
-
new InsetMathBig(buf, t.cs(), delim)));
+ new InsetMathBig(buf,
t.cs(), delim)));
else {
cell->push_back(createInsetMath(t.cs(), buf));
// For some reason delim.empty()
@@ -2109,19 +2128,57 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned
flags,
m = at->currentMode();
//lyxerr << "default creation: m2: " <<
m << endl;
idx_type start = 0;
- // this fails on \bigg[...\bigg]
- //MathData opt;
- //parse(opt, FLAG_OPTION,
InsetMath::VERBATIM_MODE);
- //if (!opt.empty()) {
- // start = 1;
- // at.nucleus()->cell(0) = opt;
- //}
- for (idx_type i = start; i <
at->nargs(); ++i) {
- parse(at.nucleus()->cell(i),
FLAG_ITEM, m);
- if (mode ==
InsetMath::MATH_MODE)
+ // The code for handling arguments of
at does not work
+ // together with the optional argument
handling, therefore
+ // we must not use the latter if
at->nargs() > 0.
+ size_t optionals = 0;
+ if (is_user_macro && at->nargs() == 0
&& buf) {
+ if (mode_ & Parse::TRACKMACRO) {
+
Buffer::UserMacroSet::const_iterator it =
+
buf->usermacros.find(t.cs());
+ if (it !=
buf->usermacros.end())
+ optionals =
it->second;
+ } else {
+ MacroData const * const
user_macro =
+
buf->getMacro(t.cs(), false);
+ if (user_macro)
+ optionals =
user_macro->optionals();
+
+ }
+ }
+ if (optionals > 0)
+ {
+ cell->push_back(at);
+ // Try to parse the optional
arguments with FLAG_OPTION.
+ // Without this the end of the
optional arg will not
+ // be handled correctly (bug
8934).
+ // We must know the number of
allowed optional arguments
+ // of the macro template.
Otherwise user defined macros
+ // similar to big operators
like \mybigg[...\mybigg]
+ // would not be parsed
correctly.
+ for (size_t i = 0; i <
optionals; ++i) {
+ // We need to
distinguish empty arguments []
+ // and missing
arguments, since this makes a
+ // difference for some
macros.
+ MathData opt(buf);
skipSpaces();
+ if (good() &&
nextToken().asInput() == "[") {
+ parse(opt,
FLAG_OPTION, m);
+ // the optional
arg will later be attached to the
+ // macro by
MathData::collectOptionalParameters()
+ opt.insert(0,
MathAtom(new InsetMathChar(buf, '[')));
+
opt.push_back(MathAtom(new InsetMathChar(buf, ']')));
+
cell->append(opt);
+ }
+ }
+ } else {
+ for (idx_type i = start; i <
at->nargs(); ++i) {
+
parse(at.nucleus()->cell(i), FLAG_ITEM, m);
+ if (mode ==
InsetMath::MATH_MODE)
+ skipSpaces();
+ }
+ cell->push_back(at);
}
- cell->push_back(at);
}
}
}
diff --git a/status.24x b/status.24x
index 86896eaa8b..95fb1874af 100644
--- a/status.24x
+++ b/status.24x
@@ -50,6 +50,8 @@ What's new
- Fix LaTeX output of formulas with a prime, a superscript and a subscripi
(bug 13004).
+- Fix problem when using DeclarePairedDelimiterX (bug 8934).
+
* USER INTERFACE
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs