commit 61145265fc977aba31b3c029ea19edbbea21e97b
Author: Guillaume Munch <[email protected]>
Date: Sat Aug 1 08:05:33 2015 +0100
Math commands used in text mode now always use the current selection as
contents
(#9762)
* fixes a bug where this was already the expected behaviour of
math-subscript and math-superscript but failed.
* corrects the behaviour where if there is \newcommand in the
selection, then a corresponding macro template is introduced
instead of a math inset.
* fixes a bug where math-display, math-subscript and math-supscript
would also introduce such a macro template in a way unrelated to
their function. Now it only happens with math-mode without
arguments.
* fixes a bug where a text that does not denote a macro definition,
e.g. "aaa\newcommandaaa", would produce \invalidmacro.
diff --git a/src/Text3.cpp b/src/Text3.cpp
index dedfca5..0e51bb0 100644
--- a/src/Text3.cpp
+++ b/src/Text3.cpp
@@ -132,7 +132,7 @@ static void finishChange(Cursor & cur, bool selecting)
}
-static void mathDispatch(Cursor & cur, FuncRequest const & cmd, bool display)
+static void mathDispatch(Cursor & cur, FuncRequest const & cmd)
{
cur.recordUndo();
docstring sel = cur.selectionAsString(false);
@@ -152,45 +152,39 @@ static void mathDispatch(Cursor & cur, FuncRequest const
& cmd, bool display)
LATTEST(old_pos == cur.pos());
#endif
cur.nextInset()->edit(cur, true);
- // don't do that also for LFUN_MATH_MODE
- // unless you want end up with always changing
- // to mathrm when opening an inlined inset --
- // I really hate "LyXfunc overloading"...
- if (display)
- cur.dispatch(FuncRequest(LFUN_MATH_DISPLAY));
- // Avoid an unnecessary undo step if cmd.argument
- // is empty
- if (!cmd.argument().empty())
- cur.dispatch(FuncRequest(LFUN_MATH_INSERT,
- cmd.argument()));
+ if (cmd.action() != LFUN_MATH_MODE)
+ // LFUN_MATH_MODE has a different meaning in math mode
+ cur.dispatch(cmd);
} else {
- // create a macro if we see "\\newcommand"
- // somewhere, and an ordinary formula
- // otherwise
- if (sel.find(from_ascii("\\newcommand")) == string::npos
- && sel.find(from_ascii("\\newlyxcommand")) ==
string::npos
- && sel.find(from_ascii("\\def")) ==
string::npos)
- {
- InsetMathHull * formula = new
InsetMathHull(cur.buffer());
- string const selstr = to_utf8(sel);
- istringstream is(selstr);
- Lexer lex;
+ InsetMathHull * formula = new InsetMathHull(cur.buffer());
+ string const selstr = to_utf8(sel);
+ istringstream is(selstr);
+ Lexer lex;
+ lex.setStream(is);
+ if (!formula->readQuiet(lex)) {
+ // No valid formula, let's try with delims
+ is.str("$" + selstr + "$");
lex.setStream(is);
if (!formula->readQuiet(lex)) {
- // No valid formula, let's try with delims
- is.str("$" + selstr + "$");
- lex.setStream(is);
- if (!formula->readQuiet(lex)) {
- // Still not valid, leave it as is
- valid = false;
- delete formula;
- cur.insert(sel);
- } else
- cur.insert(formula);
- } else
- cur.insert(formula);
- } else {
- cur.insert(new MathMacroTemplate(cur.buffer(), sel));
+ // Still not valid, leave it as is
+ valid = false;
+ delete formula;
+ cur.insert(sel);
+ }
+ }
+ if (valid) {
+ cur.insert(formula);
+ cur.nextInset()->edit(cur, true);
+ LASSERT(cur.inMathed(), return);
+ cur.pos() = 0;
+ cur.resetAnchor();
+ cur.setSelection(true);
+ cur.pos() = cur.lastpos();
+ if (cmd.action() != LFUN_MATH_MODE)
+ // LFUN_MATH_MODE has a different meaning in
math mode
+ cur.dispatch(cmd);
+ cur.clearSelection();
+ cur.pos() = cur.lastpos();
}
}
if (valid)
@@ -2015,22 +2009,38 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
changeDepth(cur, INC_DEPTH);
break;
- case LFUN_MATH_DISPLAY:
- mathDispatch(cur, cmd, true);
- break;
-
case LFUN_REGEXP_MODE:
regexpDispatch(cur, cmd);
break;
- case LFUN_MATH_MODE:
- if (cmd.argument() == "on")
+ case LFUN_MATH_MODE: {
+ if (cmd.argument() == "on" || cmd.argument() == "") {
// don't pass "on" as argument
// (it would appear literally in the first cell)
- mathDispatch(cur, FuncRequest(LFUN_MATH_MODE), false);
- else
- mathDispatch(cur, cmd, false);
+ docstring sel = cur.selectionAsString(false);
+ MathMacroTemplate * macro = new
MathMacroTemplate(cur.buffer());
+ // create a macro template if we see "\\newcommand"
somewhere, and
+ // an ordinary formula otherwise
+ if (!sel.empty()
+ && (sel.find(from_ascii("\\newcommand")) !=
string::npos
+ ||
sel.find(from_ascii("\\newlyxcommand")) != string::npos
+ || sel.find(from_ascii("\\def")) !=
string::npos)
+ && macro->fromString(sel)) {
+ cur.recordUndo();
+ replaceSelection(cur);
+ cur.insert(macro);
+ } else {
+ // no meaningful macro template was found
+ delete macro;
+ mathDispatch(cur,FuncRequest(LFUN_MATH_MODE));
+ }
+ } else
+ // The argument is meaningful
+ // We replace cmd with LFUN_MATH_INSERT because
LFUN_MATH_MODE
+ // has a different meaning in math mode
+ mathDispatch(cur,
FuncRequest(LFUN_MATH_INSERT,cmd.argument()));
break;
+ }
case LFUN_MATH_MACRO:
if (cmd.argument().empty())
@@ -2058,27 +2068,16 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
}
break;
- // passthrough hat and underscore outside mathed:
+ case LFUN_MATH_DISPLAY:
case LFUN_MATH_SUBSCRIPT:
- mathDispatch(cur, FuncRequest(LFUN_SELF_INSERT, "_"), false);
- break;
case LFUN_MATH_SUPERSCRIPT:
- mathDispatch(cur, FuncRequest(LFUN_SELF_INSERT, "^"), false);
- break;
-
case LFUN_MATH_INSERT:
case LFUN_MATH_AMS_MATRIX:
case LFUN_MATH_MATRIX:
case LFUN_MATH_DELIM:
- case LFUN_MATH_BIGDELIM: {
- cur.recordUndo();
- cap::replaceSelection(cur);
- cur.insert(new InsetMathHull(cur.buffer(), hullSimple));
- checkAndActivateInset(cur, true);
- LASSERT(cur.inMathed(), break);
- cur.dispatch(cmd);
+ case LFUN_MATH_BIGDELIM:
+ mathDispatch(cur, cmd);
break;
- }
case LFUN_FONT_EMPH: {
Font font(ignore_font, ignore_language);
diff --git a/src/mathed/MacroTable.cpp b/src/mathed/MacroTable.cpp
index 7a75a4f..919edd4 100644
--- a/src/mathed/MacroTable.cpp
+++ b/src/mathed/MacroTable.cpp
@@ -243,7 +243,8 @@ MacroTable::iterator
MacroTable::insert(Buffer * buf, docstring const & def)
{
//lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl;
- MathMacroTemplate mac(buf, def);
+ MathMacroTemplate mac(buf);
+ mac.fromString(def);
MacroData data(buf, mac);
return insert(mac.name(), data);
}
diff --git a/src/mathed/MathMacroTemplate.cpp b/src/mathed/MathMacroTemplate.cpp
index 485a060..d2d3cba 100644
--- a/src/mathed/MathMacroTemplate.cpp
+++ b/src/mathed/MathMacroTemplate.cpp
@@ -425,26 +425,20 @@ MathMacroTemplate::MathMacroTemplate(Buffer * buf,
docstring const & name, int n
}
-MathMacroTemplate::MathMacroTemplate(Buffer * buf, docstring const & str)
- : InsetMathNest(buf, 3), numargs_(0), optionals_(0),
- type_(MacroTypeNewcommand), lookOutdated_(true)
+bool MathMacroTemplate::fromString(docstring const & str)
{
- buffer_ = buf;
- initMath();
-
- MathData ar(buf);
+ MathData ar(buffer_);
mathed_parse_cell(ar, str, Parse::NORMAL);
if (ar.size() != 1 || !ar[0]->asMacroTemplate()) {
lyxerr << "Cannot read macro from '" << ar << "'" << endl;
asArray(from_ascii("invalidmacro"), cell(0));
- // FIXME: The macro template does not make sense after this.
- // The whole parsing should not be in a constructor which
- // has no chance to report failure.
- return;
+ // The macro template does not make sense after this.
+ return false;
}
operator=( *(ar[0]->asMacroTemplate()) );
updateLook();
+ return true;
}
diff --git a/src/mathed/MathMacroTemplate.h b/src/mathed/MathMacroTemplate.h
index 0bb3d4d..366c654 100644
--- a/src/mathed/MathMacroTemplate.h
+++ b/src/mathed/MathMacroTemplate.h
@@ -34,8 +34,8 @@ public:
std::vector<MathData> const & optionalValues =
std::vector<MathData>(),
MathData const & def = MathData(),
MathData const & display = MathData());
- ///
- MathMacroTemplate(Buffer * buf, const docstring & str);
+ /// parses from string, returns false if failed
+ bool fromString (const docstring & str);
///
bool editable() const { return true; }
///