Fix bug #5029: Support \smash, \mathclap, \mathllap and \mathrlap.

Also improve lyx2lyx roundtrip for automatically loaded packages.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40589 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2012-01-08 12:34:12 +00:00
parent 4d62be3568
commit 187790135b
14 changed files with 250 additions and 19 deletions

View File

@ -734,6 +734,9 @@ dist_imagesmath_DATA = \
images/math/mathcal_L.png \ images/math/mathcal_L.png \
images/math/mathcal_O.png \ images/math/mathcal_O.png \
images/math/mathcircumflex.png \ images/math/mathcircumflex.png \
images/math/mathclap.png \
images/math/mathllap.png \
images/math/mathrlap.png \
images/math/mathrm_T.png \ images/math/mathrm_T.png \
images/math/matrix.png \ images/math/matrix.png \
images/math/measuredangle.png \ images/math/measuredangle.png \
@ -866,6 +869,7 @@ dist_imagesmath_DATA = \
images/math/smallfrown.png \ images/math/smallfrown.png \
images/math/smallsetminus.png \ images/math/smallsetminus.png \
images/math/smallsmile.png \ images/math/smallsmile.png \
images/math/smash.png \
images/math/smile.png \ images/math/smile.png \
images/math/space.png \ images/math/space.png \
images/math/spadesuit.png \ images/math/spadesuit.png \

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

BIN
lib/images/math/smash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

View File

@ -1817,9 +1817,16 @@ def convert_mathdots(document):
" Load mathdots automatically " " Load mathdots automatically "
i = find_token(document.header, "\\use_mhchem" , 0) i = find_token(document.header, "\\use_mhchem" , 0)
if i == -1: if i == -1:
i = find_token(document.header, "\\use_esint" , 0) i = find_token(document.header, "\\use_esint" , 0)
if i != -1: if i == -1:
document.header.insert(i + 1, "\\use_mathdots 1") document.warning("Malformed LyX document: Can't find \\use_mhchem.")
return;
j = find_token(document.preamble, "\\usepackage{mathdots}", 0)
if j == -1:
document.header.insert(i + 1, "\\use_mathdots 0")
else:
document.header.insert(i + 1, "\\use_mathdots 2")
del document.preamble[j]
def revert_mathdots(document): def revert_mathdots(document):

View File

@ -73,8 +73,19 @@ def revert_visible_space(document):
def convert_undertilde(document): def convert_undertilde(document):
" Load undertilde automatically " " Load undertilde automatically "
i = find_token(document.header, "\\use_mathdots" , 0) i = find_token(document.header, "\\use_mathdots" , 0)
if i != -1: if i == -1:
document.header.insert(i + 1, "\\use_undertilde 1") i = find_token(document.header, "\\use_mhchem" , 0)
if i == -1:
i = find_token(document.header, "\\use_esint" , 0)
if i == -1:
document.warning("Malformed LyX document: Can't find \\use_mathdots.")
return;
j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
if j == -1:
document.header.insert(i + 1, "\\use_undertilde 0")
else:
document.header.insert(i + 1, "\\use_undertilde 2")
del document.preamble[j]
def revert_undertilde(document): def revert_undertilde(document):
@ -366,7 +377,12 @@ def convert_use_mathtools(document):
if i == -1: if i == -1:
document.warning("Malformed LyX document: Can't find \\use_package.") document.warning("Malformed LyX document: Can't find \\use_package.")
return; return;
document.header.insert(i + 1, "\\use_package mathtools 0") j = find_token(document.preamble, "\\usepackage{mathtools}", 0)
if j == -1:
document.header.insert(i + 1, "\\use_package mathtools 0")
else:
document.header.insert(i + 1, "\\use_package mathtools 2")
del document.preamble[j]
def revert_use_mathtools(document): def revert_use_mathtools(document):
@ -380,7 +396,8 @@ def revert_use_mathtools(document):
if value == "2": # on if value == "2": # on
add_to_preamble(document, ["\\usepackage{mathtools}"]) add_to_preamble(document, ["\\usepackage{mathtools}"])
elif value == "1": # auto elif value == "1": # auto
commands = ["lgathered", "rgathered", "vcentcolon", "dblcolon", \ commands = ["mathclap", "mathllap", "mathrlap", \
"lgathered", "rgathered", "vcentcolon", "dblcolon", \
"coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \ "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
"Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \ "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
"Colonapprox", "colonsim", "Colonsim"] "Colonapprox", "colonsim", "Colonsim"]

View File

@ -336,6 +336,10 @@ ToolbarSet
Item "Phantom \\phantom" "math-insert \phantom" Item "Phantom \\phantom" "math-insert \phantom"
Item "Horizontal phantom \\hphantom" "math-insert \hphantom" Item "Horizontal phantom \\hphantom" "math-insert \hphantom"
Item "Vertical phantom \\vphantom" "math-insert \vphantom" Item "Vertical phantom \\vphantom" "math-insert \vphantom"
Item "Smash \\smash" "math-insert \smash"
Item "Left overlap \\mathllap" "math-insert \mathllap"
Item "Center overlap \\mathclap" "math-insert \mathclap"
Item "Right overlap \\mathrlap" "math-insert \mathrlap"
End End
Toolbar "sqrt-square" "Roots" Toolbar "sqrt-square" "Roots"

View File

@ -799,9 +799,8 @@ string const LaTeXFeatures::getPackages() const
packages << "\\PassOptionsToPackage{normalem}{ulem}\n" packages << "\\PassOptionsToPackage{normalem}{ulem}\n"
"\\usepackage{ulem}\n"; "\\usepackage{ulem}\n";
if (params_.use_package("mhchem") == BufferParams::package_on || if (mustProvide("mhchem") &&
(mustProvide("mhchem") && params_.use_package("mhchem") != BufferParams::package_off)
params_.use_package("mhchem") != BufferParams::package_off))
packages << "\\PassOptionsToPackage{version=3}{mhchem}\n" packages << "\\PassOptionsToPackage{version=3}{mhchem}\n"
"\\usepackage{mhchem}\n"; "\\usepackage{mhchem}\n";

View File

@ -218,7 +218,7 @@ namespace {
LexerKeyword textClassTags[] = { LexerKeyword textClassTags[] = {
{ "addtohtmlpreamble", TC_ADDTOHTMLPREAMBLE }, { "addtohtmlpreamble", TC_ADDTOHTMLPREAMBLE },
{ "addtohtmlstyles", TC_ADDTOHTMLSTYLES }, { "addtohtmlstyles", TC_ADDTOHTMLSTYLES },
{ "addtopreamble", TC_ADDTOPREAMBLE }, { "addtopreamble", TC_ADDTOPREAMBLE },
{ "citeformat", TC_CITEFORMAT }, { "citeformat", TC_CITEFORMAT },
{ "classoptions", TC_CLASSOPTIONS }, { "classoptions", TC_CLASSOPTIONS },
@ -231,7 +231,7 @@ namespace {
{ "float", TC_FLOAT }, { "float", TC_FLOAT },
{ "format", TC_FORMAT }, { "format", TC_FORMAT },
{ "htmlpreamble", TC_HTMLPREAMBLE }, { "htmlpreamble", TC_HTMLPREAMBLE },
{ "htmlstyles", TC_HTMLSTYLES }, { "htmlstyles", TC_HTMLSTYLES },
{ "htmltocsection", TC_HTMLTOCSECTION }, { "htmltocsection", TC_HTMLTOCSECTION },
{ "ifcounter", TC_IFCOUNTER }, { "ifcounter", TC_IFCOUNTER },
{ "ifstyle", TC_IFSTYLE }, { "ifstyle", TC_IFSTYLE },

View File

@ -2128,6 +2128,10 @@ MathCompletionList::MathCompletionList(Cursor const & cur)
globals.push_back(from_ascii("\\hphantom")); globals.push_back(from_ascii("\\hphantom"));
globals.push_back(from_ascii("\\phantom")); globals.push_back(from_ascii("\\phantom"));
globals.push_back(from_ascii("\\vphantom")); globals.push_back(from_ascii("\\vphantom"));
globals.push_back(from_ascii("\\smash"));
globals.push_back(from_ascii("\\mathclap"));
globals.push_back(from_ascii("\\mathllap"));
globals.push_back(from_ascii("\\mathrlap"));
MathWordList const & words = mathedWordList(); MathWordList const & words = mathedWordList();
MathWordList::const_iterator it2; MathWordList::const_iterator it2;
//lyxerr << "Globals completion commands: "; //lyxerr << "Globals completion commands: ";

View File

@ -12,6 +12,7 @@
#include "InsetMathPhantom.h" #include "InsetMathPhantom.h"
#include "LaTeXFeatures.h"
#include "MathStream.h" #include "MathStream.h"
#include "frontends/Painter.h" #include "frontends/Painter.h"
@ -44,9 +45,11 @@ void InsetMathPhantom::draw(PainterInfo & pi, int x, int y) const
// We first draw the text and then an arrow // We first draw the text and then an arrow
ColorCode const origcol = pi.base.font.color(); ColorCode const origcol = pi.base.font.color();
pi.base.font.setColor(Color_special); if (visibleContents())
pi.base.font.setColor(Color_special);
cell(0).draw(pi, x + 1, y); cell(0).draw(pi, x + 1, y);
pi.base.font.setColor(origcol); if (visibleContents())
pi.base.font.setColor(origcol);
Dimension const dim = dimension(*pi.base.bv); Dimension const dim = dimension(*pi.base.bv);
if (kind_ == phantom || kind_ == vphantom) { if (kind_ == phantom || kind_ == vphantom) {
@ -84,13 +87,13 @@ void InsetMathPhantom::draw(PainterInfo & pi, int x, int y) const
} }
if (kind_ == phantom || kind_ == hphantom) { if (kind_ == phantom || kind_ == hphantom) {
// y1---- / \. // y1---- / \.
// / \. // / \.
// y2--- <----------------> // y2--- <---------------->
// \ / // \ /
// y3---- \ / // y3---- \ /
// | | | | // | | | |
// x1 x2 x3 x4 // x1 x2 x3 x4
int const x1 = x; int const x1 = x;
int const x2 = x + arrow_size; int const x2 = x + arrow_size;
@ -113,6 +116,123 @@ void InsetMathPhantom::draw(PainterInfo & pi, int x, int y) const
pi.pain.line(x1, y2, x4, y2, Color_added_space); pi.pain.line(x1, y2, x4, y2, Color_added_space);
} }
else if (kind_ == mathclap) {
// y1---- \ /
// \ /
// y2--- -------->-<--------
// / \.
// y3---- / \.
// | | | | |
// x1 x2 x3 x4 x5
int const x1 = x;
int const x5 = x + dim.wid;
int const x3 = x + dim.wid / 2;
int const x2 = std::max(x1, x3 - arrow_size);
int const x4 = std::min(x5, x3 + arrow_size);
int const y2 = y + (dim.des - dim.asc) / 2;
int const y1 = y2 - arrow_size;
int const y3 = y2 + arrow_size;
// left arrow
pi.pain.line(x2, y3, x3, y2, Color_added_space);
pi.pain.line(x2, y1, x3, y2, Color_added_space);
// right arrow
pi.pain.line(x4, y3, x3, y2, Color_added_space);
pi.pain.line(x4, y1, x3, y2, Color_added_space);
// joining line
pi.pain.line(x1, y2, x5, y2, Color_added_space);
}
else if (kind_ == mathllap) {
// y1---- \.
// \.
// y2--- ------------------>
// /
// y3---- /
// | | |
// x1 x2 x3
int const x1 = x;
int const x3 = x + dim.wid;
int const x2 = std::max(x1, x3 - arrow_size);
int const y2 = y + (dim.des - dim.asc) / 2;
int const y1 = y2 - arrow_size;
int const y3 = y2 + arrow_size;
// right arrow
pi.pain.line(x3, y2, x2, y3, Color_added_space);
pi.pain.line(x3, y2, x2, y1, Color_added_space);
// joining line
pi.pain.line(x1, y2, x3, y2, Color_added_space);
}
else if (kind_ == mathrlap) {
// y1---- /
// /
// y2--- <------------------
// \.
// y3---- \.
// | | |
// x1 x2 x3
int const x1 = x;
int const x3 = x + dim.wid;
int const x2 = std::min(x3, x + arrow_size);
int const y2 = y + (dim.des - dim.asc) / 2;
int const y1 = y2 - arrow_size;
int const y3 = y2 + arrow_size;
// left arrow
pi.pain.line(x1, y2, x2, y3, Color_added_space);
pi.pain.line(x1, y2, x2, y1, Color_added_space);
// joining line
pi.pain.line(x1, y2, x3, y2, Color_added_space);
}
else if (kind_ == smash) {
// y1---------
// |
// y2----- \ | /
// \ /
// y3-------- |
// / \.
// y4----- / | \.
// |
// y5---------
// | | |
// / | \.
// x1 x2 x3
int const x2 = x + dim.wid / 2;
int const x1 = x2 - arrow_size;
int const x3 = x2 + arrow_size;
int const y1 = y - dim.asc;
int const y5 = y + dim.des;
int const y3 = y;
int const y2 = std::max(y1, y3 - arrow_size);
int const y4 = std::min(y5, y3 + arrow_size);
// top arrow
pi.pain.line(x1, y2, x2, y3, Color_added_space);
pi.pain.line(x3, y2, x2, y3, Color_added_space);
// bottom arrow
pi.pain.line(x1, y4, x2, y3, Color_added_space);
pi.pain.line(x3, y4, x2, y3, Color_added_space);
// joining line
pi.pain.line(x2, y1, x2, y5, Color_added_space);
}
drawMarkers(pi, x, y); drawMarkers(pi, x, y);
} }
@ -130,6 +250,18 @@ void InsetMathPhantom::write(WriteStream & os) const
case hphantom: case hphantom:
os << "\\hphantom{"; os << "\\hphantom{";
break; break;
case smash:
os << "\\smash{";
break;
case mathclap:
os << "\\mathclap{";
break;
case mathllap:
os << "\\mathllap{";
break;
case mathrlap:
os << "\\mathrlap{";
break;
} }
os << cell(0) << '}'; os << cell(0) << '}';
} }
@ -147,6 +279,18 @@ void InsetMathPhantom::normalize(NormalStream & os) const
case hphantom: case hphantom:
os << "[hphantom "; os << "[hphantom ";
break; break;
case smash:
os << "[smash ";
break;
case mathclap:
os << "[mathclap ";
break;
case mathllap:
os << "[mathllap ";
break;
case mathrlap:
os << "[mathrlap ";
break;
} }
os << cell(0) << ']'; os << cell(0) << ']';
} }
@ -164,8 +308,44 @@ void InsetMathPhantom::infoize(odocstream & os) const
case hphantom: case hphantom:
os << "Hphantom"; os << "Hphantom";
break; break;
case smash:
os << "Smash";
break;
case mathllap:
os << "Mathllap";
break;
case mathclap:
os << "Mathclap";
break;
case mathrlap:
os << "Mathrlap";
break;
} }
} }
void InsetMathPhantom::validate(LaTeXFeatures & features) const
{
InsetMathNest::validate(features);
switch (kind_) {
case phantom:
case vphantom:
case hphantom:
case smash:
break;
case mathclap:
case mathllap:
case mathrlap:
features.require("mathtools");
break;
}
}
bool InsetMathPhantom::visibleContents() const
{
return kind_ == phantom || kind_ == vphantom || kind_ == vphantom;
}
} // namespace lyx } // namespace lyx

View File

@ -23,7 +23,11 @@ public:
enum Kind { enum Kind {
phantom, phantom,
vphantom, vphantom,
hphantom hphantom,
smash,
mathclap,
mathllap,
mathrlap
}; };
/// ///
explicit InsetMathPhantom(Buffer * buf, Kind); explicit InsetMathPhantom(Buffer * buf, Kind);
@ -43,6 +47,10 @@ public:
void mathmlize(MathStream &) const {} void mathmlize(MathStream &) const {}
/// Nothing for HTML /// Nothing for HTML
void htmlize(HtmlStream &) const {} void htmlize(HtmlStream &) const {}
/// request "external features"
void validate(LaTeXFeatures & features) const;
/// Does the contents appear in LaTeX output?
bool visibleContents() const;
private: private:
/// ///

View File

@ -501,6 +501,14 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf)
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::phantom)); return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::phantom));
if (s == "vphantom") if (s == "vphantom")
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::vphantom)); return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::vphantom));
if (s == "smash")
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::smash));
if (s == "mathclap")
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::mathclap));
if (s == "mathllap")
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::mathllap));
if (s == "mathrlap")
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::mathrlap));
if (s == "ensuremath") if (s == "ensuremath")
return MathAtom(new InsetMathEnsureMath(buf)); return MathAtom(new InsetMathEnsureMath(buf));
if (isSpecialChar(s)) if (isSpecialChar(s))