6047: Lyx 1.6.3 unable to typeset the third chemical equation of the
      file mhchem.lyx (package mhchem)
4043: mhchem support
5394: support for the mhchems's \ce command
The \ce and \cf insets are text mode environments that allow entering
spaces and mathmode commands. LyX leaves them alone and doesn't try to
be smart, i.e., the behaviour is exactly the same we had in the old days
with text-in-math mode environments, before the introduction of the
\ensuremath and \lyxmathsym macros. This means that in those environments
one has to know what he is doing, as LyX will not offer any protection.
The hack of enclosing \ce and \cf in a \text{} environment in order to
be able to enter spaces is no longer necessary.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30338 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Enrico Forestieri 2009-07-03 00:05:58 +00:00
parent 7e2391c64c
commit 0a90c42b86
13 changed files with 88 additions and 29 deletions

View File

@ -99,6 +99,9 @@ texttt font textmode
textup font textmode textup font textmode
emph font textmode emph font textmode
noun font textmode noun font textmode
# ce and cf are provided by the mhchem package
ce font forcetext
cf font forcetext
# old-style font commands # old-style font commands
bf oldfont none bf oldfont none

View File

@ -405,7 +405,10 @@ int Cursor::currentMode()
LASSERT(!empty(), /**/); LASSERT(!empty(), /**/);
for (int i = depth() - 1; i >= 0; --i) { for (int i = depth() - 1; i >= 0; --i) {
int res = operator[](i).inset().currentMode(); int res = operator[](i).inset().currentMode();
if (res != Inset::UNDECIDED_MODE) bool locked_mode = operator[](i).inset().lockedMode();
// Also return UNDECIDED_MODE when the mode is locked,
// as in this case it is treated the same as TEXT_MODE
if (res != Inset::UNDECIDED_MODE || locked_mode)
return res; return res;
} }
return Inset::TEXT_MODE; return Inset::TEXT_MODE;

View File

@ -744,6 +744,10 @@ string const LaTeXFeatures::getPackages() const
packages << "\\PassOptionsToPackage{normalem}{ulem}\n" packages << "\\PassOptionsToPackage{normalem}{ulem}\n"
"\\usepackage{ulem}\n"; "\\usepackage{ulem}\n";
if (mustProvide("mhchem"))
packages << "\\PassOptionsToPackage{version=3}{mhchem}\n"
"\\usepackage{mhchem}\n";
if (mustProvide("nomencl")) { if (mustProvide("nomencl")) {
// Make it work with the new and old version of the package, // Make it work with the new and old version of the package,
// but don't use the compatibility option since it is // but don't use the compatibility option since it is

View File

@ -470,6 +470,8 @@ public:
enum mode_type {UNDECIDED_MODE, TEXT_MODE, MATH_MODE}; enum mode_type {UNDECIDED_MODE, TEXT_MODE, MATH_MODE};
/// return text or mathmode if that is possible to determine /// return text or mathmode if that is possible to determine
virtual mode_type currentMode() const { return UNDECIDED_MODE; } virtual mode_type currentMode() const { return UNDECIDED_MODE; }
/// returns whether changing mode during latex export is forbidden
virtual bool lockedMode() const { return false; }
/// returns whether this inset is allowed in other insets of given mode /// returns whether this inset is allowed in other insets of given mode
virtual bool allowedIn(mode_type) const { return true; } virtual bool allowedIn(mode_type) const { return true; }
/** /**

View File

@ -44,6 +44,14 @@ InsetMath::mode_type InsetMathFont::currentMode() const
} }
bool InsetMathFont::lockedMode() const
{
if (key_->extra == "forcetext")
return true;
return false;
}
void InsetMathFont::metrics(MetricsInfo & mi, Dimension & dim) const void InsetMathFont::metrics(MetricsInfo & mi, Dimension & dim) const
{ {
FontSetChanger dummy(mi.base, key_->name); FontSetChanger dummy(mi.base, key_->name);
@ -93,6 +101,8 @@ void InsetMathFont::validate(LaTeXFeatures & features) const
features.require("amstext"); features.require("amstext");
if (key_->name == "textipa") if (key_->name == "textipa")
features.require("tipa"); features.require("tipa");
if (key_->name == "ce" || key_->name == "cf")
features.require("mhchem");
} }

View File

@ -31,6 +31,8 @@ public:
InsetMathFont const * asFontInset() const { return this; } InsetMathFont const * asFontInset() const { return this; }
/// are we in math mode, text mode, or unsure? /// are we in math mode, text mode, or unsure?
mode_type currentMode() const; mode_type currentMode() const;
/// do we allow changing mode during latex export?
bool lockedMode() const;
/// ///
docstring name() const; docstring name() const;
/// ///

View File

@ -1259,7 +1259,7 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd)
parseflg |= Parse::VERBATIM; parseflg |= Parse::VERBATIM;
// fall through // fall through
case LFUN_PASTE: { case LFUN_PASTE: {
if (cur.currentMode() == TEXT_MODE) if (cur.currentMode() <= TEXT_MODE)
parseflg |= Parse::TEXTMODE; parseflg |= Parse::TEXTMODE;
cur.message(_("Paste")); cur.message(_("Paste"));
cap::replaceSelection(cur); cap::replaceSelection(cur);

View File

@ -340,7 +340,7 @@ MathData InsetMathNest::glue() const
void InsetMathNest::write(WriteStream & os) const void InsetMathNest::write(WriteStream & os) const
{ {
ModeSpecifier specifier(os, currentMode()); ModeSpecifier specifier(os, currentMode(), lockedMode());
docstring const latex_name = name(); docstring const latex_name = name();
os << '\\' << latex_name; os << '\\' << latex_name;
for (size_t i = 0; i < nargs(); ++i) for (size_t i = 0; i < nargs(); ++i)
@ -525,7 +525,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
parseflg |= Parse::VERBATIM; parseflg |= Parse::VERBATIM;
// fall through // fall through
case LFUN_PASTE: { case LFUN_PASTE: {
if (cur.currentMode() == TEXT_MODE) if (cur.currentMode() <= TEXT_MODE)
parseflg |= Parse::TEXTMODE; parseflg |= Parse::TEXTMODE;
cur.recordUndoSelection(); cur.recordUndoSelection();
cur.message(_("Paste")); cur.message(_("Paste"));
@ -890,37 +890,37 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
break; break;
case LFUN_FONT_BOLD: case LFUN_FONT_BOLD:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "textbf"); handleFont(cur, cmd.argument(), "textbf");
else else
handleFont(cur, cmd.argument(), "mathbf"); handleFont(cur, cmd.argument(), "mathbf");
break; break;
case LFUN_FONT_BOLDSYMBOL: case LFUN_FONT_BOLDSYMBOL:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "textbf"); handleFont(cur, cmd.argument(), "textbf");
else else
handleFont(cur, cmd.argument(), "boldsymbol"); handleFont(cur, cmd.argument(), "boldsymbol");
break; break;
case LFUN_FONT_SANS: case LFUN_FONT_SANS:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "textsf"); handleFont(cur, cmd.argument(), "textsf");
else else
handleFont(cur, cmd.argument(), "mathsf"); handleFont(cur, cmd.argument(), "mathsf");
break; break;
case LFUN_FONT_EMPH: case LFUN_FONT_EMPH:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "emph"); handleFont(cur, cmd.argument(), "emph");
else else
handleFont(cur, cmd.argument(), "mathcal"); handleFont(cur, cmd.argument(), "mathcal");
break; break;
case LFUN_FONT_ROMAN: case LFUN_FONT_ROMAN:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "textrm"); handleFont(cur, cmd.argument(), "textrm");
else else
handleFont(cur, cmd.argument(), "mathrm"); handleFont(cur, cmd.argument(), "mathrm");
break; break;
case LFUN_FONT_TYPEWRITER: case LFUN_FONT_TYPEWRITER:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "texttt"); handleFont(cur, cmd.argument(), "texttt");
else else
handleFont(cur, cmd.argument(), "mathtt"); handleFont(cur, cmd.argument(), "mathtt");
@ -929,13 +929,13 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
handleFont(cur, cmd.argument(), "mathfrak"); handleFont(cur, cmd.argument(), "mathfrak");
break; break;
case LFUN_FONT_ITAL: case LFUN_FONT_ITAL:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
handleFont(cur, cmd.argument(), "textit"); handleFont(cur, cmd.argument(), "textit");
else else
handleFont(cur, cmd.argument(), "mathit"); handleFont(cur, cmd.argument(), "mathit");
break; break;
case LFUN_FONT_NOUN: case LFUN_FONT_NOUN:
if (currentMode() == TEXT_MODE) if (currentMode() <= TEXT_MODE)
// FIXME: should be "noun" // FIXME: should be "noun"
handleFont(cur, cmd.argument(), "textsc"); handleFont(cur, cmd.argument(), "textsc");
else else
@ -955,7 +955,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
docstring const save_selection = grabAndEraseSelection(cur); docstring const save_selection = grabAndEraseSelection(cur);
selClearOrDel(cur); selClearOrDel(cur);
//cur.plainInsert(MathAtom(new InsetMathMBox(cur.bv()))); //cur.plainInsert(MathAtom(new InsetMathMBox(cur.bv())));
if (currentMode() == Inset::TEXT_MODE) if (currentMode() <= Inset::TEXT_MODE)
cur.plainInsert(MathAtom(new InsetMathEnsureMath)); cur.plainInsert(MathAtom(new InsetMathEnsureMath));
else else
cur.plainInsert(MathAtom(new InsetMathBox(from_ascii("mbox")))); cur.plainInsert(MathAtom(new InsetMathBox(from_ascii("mbox"))));
@ -1472,7 +1472,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
// remove the '\\' // remove the '\\'
if (c == '\\') { if (c == '\\') {
cur.backspace(); cur.backspace();
if (currentMode() == InsetMath::TEXT_MODE) if (currentMode() <= InsetMath::TEXT_MODE)
cur.niceInsert(createInsetMath("textbackslash")); cur.niceInsert(createInsetMath("textbackslash"));
else else
cur.niceInsert(createInsetMath("backslash")); cur.niceInsert(createInsetMath("backslash"));
@ -1585,14 +1585,14 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
selClearOrDel(cur); selClearOrDel(cur);
if (c == '\n') { if (c == '\n') {
if (currentMode() == InsetMath::TEXT_MODE) if (currentMode() <= InsetMath::TEXT_MODE)
cur.insert(c); cur.insert(c);
return true; return true;
} }
if (c == ' ') { if (c == ' ') {
if (currentMode() == InsetMath::TEXT_MODE) { if (currentMode() <= InsetMath::TEXT_MODE) {
// insert spaces in text mode, // insert spaces in text or undecided mode,
// but suppress direct insertion of two spaces in a row // but suppress direct insertion of two spaces in a row
// the still allows typing '<space>a<space>' and deleting the 'a', but // the still allows typing '<space>a<space>' and deleting the 'a', but
// it is better than nothing... // it is better than nothing...
@ -1643,7 +1643,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
cur.niceInsert(createInsetMath("sim")); cur.niceInsert(createInsetMath("sim"));
return true; return true;
} }
if (!isAsciiOrMathAlpha(c)) { if (currentMode() == InsetMath::MATH_MODE && !isAsciiOrMathAlpha(c)) {
MathAtom at = createInsetMath("text"); MathAtom at = createInsetMath("text");
at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c))); at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
cur.niceInsert(at); cur.niceInsert(at);

View File

@ -103,7 +103,7 @@ void InsetMathString::mathmlize(MathStream & os) const
void InsetMathString::write(WriteStream & os) const void InsetMathString::write(WriteStream & os) const
{ {
if (!os.latex()) { if (!os.latex() || os.lockedMode()) {
os << str_; os << str_;
return; return;
} }

View File

@ -276,7 +276,7 @@ bool ensureMath(WriteStream & os, bool needs_math_mode, bool macro)
} }
bool ensureMode(WriteStream & os, InsetMath::mode_type mode) int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked)
{ {
bool textmode = mode == InsetMath::TEXT_MODE; bool textmode = mode == InsetMath::TEXT_MODE;
if (os.latex() && textmode && os.pendingBrace()) { if (os.latex() && textmode && os.pendingBrace()) {
@ -285,9 +285,11 @@ bool ensureMode(WriteStream & os, InsetMath::mode_type mode)
os.pendingSpace(false); os.pendingSpace(false);
os.textMode(true); os.textMode(true);
} }
bool oldmode = os.textMode(); int oldmodes = os.textMode() ? 1 : 0;
os.textMode(textmode); os.textMode(textmode);
return oldmode; oldmodes |= os.lockedMode() ? 2 : 0;
os.lockedMode(locked);
return oldmodes;
} }

View File

@ -155,6 +155,12 @@ void WriteStream::textMode(bool textmode)
} }
void WriteStream::lockedMode(bool locked)
{
locked_ = locked;
}
WriteStream & operator<<(WriteStream & ws, MathAtom const & at) WriteStream & operator<<(WriteStream & ws, MathAtom const & at)
{ {
at->write(ws); at->write(ws);

View File

@ -65,6 +65,10 @@ public:
void textMode(bool textmode); void textMode(bool textmode);
/// tell whether we are in text mode or not when producing latex code /// tell whether we are in text mode or not when producing latex code
bool textMode() const { return textmode_; } bool textMode() const { return textmode_; }
/// tell whether we are allowed to switch mode when producing latex code
void lockedMode(bool locked);
/// tell whether we are allowed to switch mode when producing latex code
bool lockedMode() const { return locked_; }
/// LaTeX encoding /// LaTeX encoding
Encoding const * encoding() const { return encoding_; } Encoding const * encoding() const { return encoding_; }
private: private:
@ -84,6 +88,8 @@ private:
bool pendingbrace_; bool pendingbrace_;
/// are we in text mode when producing latex code? /// are we in text mode when producing latex code?
bool textmode_; bool textmode_;
/// are we allowed to switch mode when producing latex code?
bool locked_;
/// ///
int line_; int line_;
/// ///
@ -109,7 +115,7 @@ WriteStream & operator<<(WriteStream &, unsigned int);
bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false); bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
/// ensure the requested mode, possibly by closing \ensuremath /// ensure the requested mode, possibly by closing \ensuremath
bool ensureMode(WriteStream & os, InsetMath::mode_type mode); int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked);
/** /**
@ -169,12 +175,22 @@ private:
* environment works in a given mode. For example, \mbox works in text * environment works in a given mode. For example, \mbox works in text
* mode, but \boxed works in math mode. Note that no mode changing commands * mode, but \boxed works in math mode. Note that no mode changing commands
* are needed, but we have to track the current mode, hence this class. * are needed, but we have to track the current mode, hence this class.
* This is only used when exporting to latex and helps determining whether
* the mode needs being temporarily switched when a command would not work
* in the current mode. As there are cases where this switching is to be
* avoided, the optional third parameter can be used to lock the mode.
* *
* Example: * Example 1:
* *
* ModeSpecifier specifier(os, TEXT_MODE); * ModeSpecifier specifier(os, TEXT_MODE);
* *
* Sets the current mode to text mode. * Sets the current mode to text mode and allows mode switching.
*
* Example 2:
*
* ModeSpecifier specifier(os, TEXT_MODE, true);
*
* Sets the current mode to text mode and disallows mode switching.
* *
* At the end of specifier's scope the mode is reset to its previous value. * At the end of specifier's scope the mode is reset to its previous value.
*/ */
@ -182,15 +198,20 @@ class ModeSpecifier
{ {
public: public:
/// ///
explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode) explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
: os_(os), textmode_(ensureMode(os, mode)) {} bool locked = false)
: os_(os), oldmodes_(ensureMode(os, mode, locked)) {}
/// ///
~ModeSpecifier() { os_.textMode(textmode_); } ~ModeSpecifier()
{
os_.textMode(oldmodes_ & 1);
os_.lockedMode(oldmodes_ & 2);
}
private: private:
/// ///
WriteStream & os_; WriteStream & os_;
/// ///
bool textmode_; int oldmodes_;
}; };

View File

@ -591,6 +591,12 @@ fontinfo fontinfos[] = {
{"textipa", inh_family, inh_series, {"textipa", inh_family, inh_series,
inh_shape, Color_foreground}, inh_shape, Color_foreground},
// mhchem support
{"ce", inh_family, inh_series,
inh_shape, Color_foreground},
{"cf", inh_family, inh_series,
inh_shape, Color_foreground},
// LyX internal usage // LyX internal usage
{"lyxtex", inh_family, inh_series, {"lyxtex", inh_family, inh_series,
UP_SHAPE, Color_latex}, UP_SHAPE, Color_latex},