Fix regression of 5261ae6a2

Somehow I overlooked that \sideset also supports nonscript arguments for
left and right. This is now fixed, although I do not like the toolbar names.
If somebody knows something better, please improve.
This commit is contained in:
Georg Baum 2013-02-24 21:23:50 +01:00
parent 284f991519
commit efaae780db
9 changed files with 216 additions and 95 deletions

View File

@ -1110,6 +1110,9 @@ dist_imagesmath_DATA = \
images/math/shortrightarrow.png \
images/math/shortuparrow.png \
images/math/sideset.png \
images/math/sideset1.png \
images/math/sideset2.png \
images/math/sideset3.png \
images/math/sigma.png \
images/math/sigma2.png \
images/math/sim.png \

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

View File

@ -183,7 +183,10 @@ ToolbarSet
Item "Insert sum" "math-insert \sum"
Item "Insert integral" "math-insert \int"
Item "Insert product" "math-insert \prod"
Item "Insert side scripts" "math-insert \sideset"
Item "Insert left/right side scripts" "math-insert \sideset"
Item "Insert right side scripts" "math-insert \sideset1"
Item "Insert left side scripts" "math-insert \sideset2"
Item "Insert side scripts" "math-insert \sideset3"
Separator
Item "Insert ( )" "math-delim ( )"
Item "Insert [ ]" "math-delim [ ]"

View File

@ -39,13 +39,16 @@ namespace {
namespace lyx {
InsetMathSideset::InsetMathSideset(Buffer * buf)
: InsetMathNest(buf, 5)
InsetMathSideset::InsetMathSideset(Buffer * buf, bool scriptl, bool scriptr)
: InsetMathNest(buf, 3 + scriptl + scriptr), scriptl_(scriptl),
scriptr_(scriptr)
{}
InsetMathSideset::InsetMathSideset(Buffer * buf, MathAtom const & at)
: InsetMathNest(buf, 5)
InsetMathSideset::InsetMathSideset(Buffer * buf, bool scriptl, bool scriptr,
MathAtom const & at)
: InsetMathNest(buf, 3 + scriptl + scriptr), scriptl_(scriptl),
scriptr_(scriptr)
{
nuc().push_back(at);
}
@ -76,7 +79,13 @@ bool InsetMathSideset::idxLast(Cursor & cur) const
int InsetMathSideset::dybt(BufferView const & bv, int asc, int des, bool top) const
{
bool isCharBox = nuc().empty() ? false : isAlphaSymbol(nuc().back());
int dasc = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
int dasc = 0;
if (scriptl_ && scriptr_)
dasc = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
else if (scriptl_)
dasc = bl().dimension(bv).ascent();
else if (scriptr_)
dasc = br().dimension(bv).ascent();
int slevel = nuc().slevel();
int ascdrop = dasc - slevel;
int desdrop = isCharBox ? 0 : des + nuc().sshift();
@ -84,8 +93,20 @@ int InsetMathSideset::dybt(BufferView const & bv, int asc, int des, bool top) co
des = max(desdrop, ascdrop);
des = max(mindes, des);
int minasc = nuc().minasc();
ascdrop = isCharBox ? 0 : asc - min(tl().mindes(), tr().mindes());
int udes = max(bl().dimension(bv).descent(), tr().dimension(bv).descent());
ascdrop = 0;
if (!isCharBox && (scriptl_ || scriptr_)) {
if (scriptl_ && scriptr_)
ascdrop = asc - min(tl().mindes(), tr().mindes());
else if (scriptl_)
ascdrop = asc - tl().mindes();
else if (scriptr_)
ascdrop = asc - tr().mindes();
}
int udes = 0;
if (scriptl_)
udes = bl().dimension(bv).descent();
if (scriptr_)
udes = max(udes, br().dimension(bv).descent());
asc = udes + nuc().sshift();
asc = max(ascdrop, asc);
asc = max(minasc, asc);
@ -106,7 +127,13 @@ int InsetMathSideset::dybt(BufferView const & bv, int asc, int des, bool top) co
int InsetMathSideset::dyb(BufferView const & bv) const
{
int nd = ndes(bv);
int des = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
int des = 0;
if (scriptl_ && scriptr_)
des = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
else if (scriptl_)
des = bl().dimension(bv).ascent();
else if (scriptr_)
des = br().dimension(bv).ascent();
int na = nasc(bv);
des = dybt(bv, na, nd, false);
return des;
@ -116,7 +143,13 @@ int InsetMathSideset::dyb(BufferView const & bv) const
int InsetMathSideset::dyt(BufferView const & bv) const
{
int na = nasc(bv);
int asc = max(tl().dimension(bv).descent(), tr().dimension(bv).descent());
int asc = 0;
if (scriptl_ && scriptr_)
asc = max(tl().dimension(bv).descent(), tr().dimension(bv).descent());
else if (scriptl_)
asc = tl().dimension(bv).descent();
else if (scriptr_)
asc = tr().dimension(bv).descent();
int nd = ndes(bv);
asc = dybt(bv, na, nd, true);
return asc;
@ -170,11 +203,23 @@ void InsetMathSideset::metrics(MetricsInfo & mi, Dimension & dim) const
Dimension dimbr;
Dimension dimtr;
nuc().metrics(mi, dimn);
if (!scriptl_) {
bl().metrics(mi, dimbl);
dimtl = dimbl;
}
if (!scriptr_) {
br().metrics(mi, dimbr);
dimtr = dimbr;
}
ScriptChanger dummy(mi.base);
bl().metrics(mi, dimbl);
tl().metrics(mi, dimtl);
br().metrics(mi, dimbr);
tr().metrics(mi, dimtr);
if (scriptl_) {
bl().metrics(mi, dimbl);
tl().metrics(mi, dimtl);
}
if (scriptr_) {
br().metrics(mi, dimbr);
tr().metrics(mi, dimtr);
}
BufferView & bv = *mi.base.bv;
// FIXME: data copying... not very efficient.
@ -196,11 +241,19 @@ void InsetMathSideset::draw(PainterInfo & pi, int x, int y) const
{
BufferView & bv = *pi.base.bv;
nuc().draw(pi, x + dxn(bv), y);
if (!scriptl_)
bl().draw(pi, x , y);
if (!scriptr_)
br().draw(pi, x + dxr(bv), y);
ScriptChanger dummy(pi.base);
bl().draw(pi, x , y + dyb(bv));
tl().draw(pi, x , y - dyt(bv));
br().draw(pi, x + dxr(bv), y + dyb(bv));
tr().draw(pi, x + dxr(bv), y - dyt(bv));
if (scriptl_) {
bl().draw(pi, x , y + dyb(bv));
tl().draw(pi, x , y - dyt(bv));
}
if (scriptr_) {
br().draw(pi, x + dxr(bv), y + dyb(bv));
tr().draw(pi, x + dxr(bv), y - dyt(bv));
}
drawMarkers(pi, x, y);
}
@ -227,14 +280,32 @@ void InsetMathSideset::drawT(TextPainter & pain, int x, int y) const
bool InsetMathSideset::idxForward(Cursor &) const
bool InsetMathSideset::idxForward(Cursor & cur) const
{
if (!scriptl_ && cur.idx() == 1) {
// left => nucleus
cur.idx() = 0;
return true;
} else if (!scriptr_ && cur.idx() == 0) {
// nucleus => right
cur.idx() = 2 + scriptl_;
return true;
}
return false;
}
bool InsetMathSideset::idxBackward(Cursor &) const
bool InsetMathSideset::idxBackward(Cursor & cur) const
{
if (!scriptr_ && cur.idx() == (scriptl_ ? 3 : 2)) {
// right => nucleus
cur.idx() = 0;
return true;
} else if (!scriptl_ && cur.idx() == 0) {
// nucleus => left
cur.idx() = 1;
return true;
}
return false;
}
@ -245,11 +316,12 @@ bool InsetMathSideset::idxUpDown(Cursor & cur, bool up) const
if (cur.idx() == 0) {
// go up/down only if in the last position
// or in the first position
if (cur.pos() == cur.lastpos() || cur.pos() == 0) {
if ((scriptr_ && cur.pos() == cur.lastpos()) ||
(scriptl_ && cur.pos() == 0)) {
if (cur.pos() == 0)
cur.idx() = up ? 2 : 1;
else
cur.idx() = up ? 4 : 3;
cur.idx() = (up ? 3 : 2) + scriptl_;
cur.pos() = 0;
return true;
}
@ -257,7 +329,8 @@ bool InsetMathSideset::idxUpDown(Cursor & cur, bool up) const
}
// Are we 'up'?
if (cur.idx() == 2 || cur.idx() == 4) {
if ((scriptl_ && cur.idx() == 2) ||
(scriptr_ && cur.idx() == (scriptl_ ? 4 : 3))) {
// can't go further up
if (up)
return false;
@ -271,7 +344,8 @@ bool InsetMathSideset::idxUpDown(Cursor & cur, bool up) const
}
// Are we 'down'?
if (cur.idx() == 1 || cur.idx() == 3) {
if ((scriptl_ && cur.idx() == 1) ||
(scriptr_ && cur.idx() == (scriptl_ ? 3 : 2))) {
// can't go further down
if (!up)
return false;
@ -293,15 +367,24 @@ void InsetMathSideset::write(WriteStream & os) const
MathEnsurer ensurer(os);
os << "\\sideset";
for (int i = 0; i < 2; ++i) {
os << '{';
if (!cell(2*i+1).empty())
os << "_{" << cell(2*i+1) << '}';
if (!cell(2*i+2).empty())
os << "^{" << cell(2*i+2) << '}';
os << '}';
}
os << '{' << nuc() << '}';
os << '{';
if (scriptl_) {
if (!bl().empty())
os << "_{" << bl() << '}';
if (!tl().empty())
os << "^{" << tl() << '}';
} else
os << bl();
os << "}{";
if (scriptr_) {
if (!br().empty())
os << "_{" << br() << '}';
if (!tr().empty())
os << "^{" << tr() << '}';
} else
os << br();
os << '}';
os << nuc();
if (lock_ && !os.latex())
os << "\\lyxlock ";
@ -314,7 +397,7 @@ void InsetMathSideset::normalize(NormalStream & os) const
if (!bl().empty())
os << bl() << ' ';
if (!tl().empty())
if (scriptl_ && !tl().empty())
os << tl() << ' ';
if (!nuc().empty())
@ -324,7 +407,7 @@ void InsetMathSideset::normalize(NormalStream & os) const
if (!br().empty())
os << br() << ' ';
if (!tr().empty())
if (scriptr_ && !tr().empty())
os << tr() << ' ';
os << ']';
}
@ -332,41 +415,52 @@ void InsetMathSideset::normalize(NormalStream & os) const
void InsetMathSideset::mathmlize(MathStream & os) const
{
os << MTag("mmultiscripts");
if (nuc().empty())
os << "<mrow />";
else
os << MTag("mrow") << nuc() << ETag("mrow");
if (br().empty())
os << "<none />";
else
os << MTag("mrow") << br() << ETag("mrow");
if (tr().empty())
os << "<none />";
else
os << MTag("mrow") << tr() << ETag("mrow");
if (bl().empty())
os << "<none />";
else
// FIXME This is only accurate if both scriptl_ and scriptr_ are true
if (!scriptl_)
os << MTag("mrow") << bl() << ETag("mrow");
if (tl().empty())
os << "<none />";
else
os << MTag("mrow") << tl() << ETag("mrow");
if (scriptl_ || scriptr_) {
os << MTag("mmultiscripts");
os << ETag("mmultiscripts");
if (nuc().empty())
os << "<mrow />";
else
os << MTag("mrow") << nuc() << ETag("mrow");
if (br().empty() || !scriptr_)
os << "<none />";
else
os << MTag("mrow") << br() << ETag("mrow");
if (tr().empty() || !scriptr_)
os << "<none />";
else
os << MTag("mrow") << tr() << ETag("mrow");
if (bl().empty() || !scriptl_)
os << "<none />";
else
os << MTag("mrow") << bl() << ETag("mrow");
if (tl().empty() || !scriptl_)
os << "<none />";
else
os << MTag("mrow") << tl() << ETag("mrow");
os << ETag("mmultiscripts");
}
if (!scriptr_)
os << MTag("mrow") << br() << ETag("mrow");
}
void InsetMathSideset::htmlize(HtmlStream & os) const
{
bool const havebl = !bl().empty();
bool const havetl = !tl().empty();
bool const havebr = !br().empty();
bool const havetr = !tr().empty();
// FIXME This is only accurate if both scriptl_ and scriptr_ are true
bool const havebl = scriptl_ && !bl().empty();
bool const havetl = scriptl_ && !tl().empty();
bool const havebr = scriptr_ && !br().empty();
bool const havetr = scriptr_ && !tr().empty();
if (!scriptl_ && !bl().empty())
os << bl();
if (havebl && havetl)
os << MTag("span", "class='scripts'")
@ -390,6 +484,9 @@ void InsetMathSideset::htmlize(HtmlStream & os) const
os << MTag("sub", "class='math'") << br() << ETag("sub");
else if (havetr)
os << MTag("sup", "class='math'") << tr() << ETag("sup");
if (!scriptr_ && !br().empty())
os << br();
}

View File

@ -25,9 +25,10 @@ namespace lyx {
class InsetMathSideset : public InsetMathNest {
public:
///
InsetMathSideset(Buffer * buf);
InsetMathSideset(Buffer * buf, bool scriptl, bool scriptr);
/// create inset with given nucleus
InsetMathSideset(Buffer * buf, MathAtom const & at);
InsetMathSideset(Buffer * buf, bool scriptl, bool scriptr,
MathAtom const & at);
///
mode_type currentMode() const { return MATH_MODE; }
///
@ -63,22 +64,22 @@ public:
MathData const & nuc() const { return cell(0); };
/// returns nucleus
MathData & nuc() { return cell(0); };
/// bottom left index
/// bottom left index or single left cell
MathData const & bl() const { return cell(1); }
/// bottom left index
/// bottom left index or single left cell
MathData & bl() { return cell(1); }
/// top left index
MathData const & tl() const { return cell(2); }
/// top left index
MathData & tl() { return cell(2); }
/// bottom right index
MathData const & br() const { return cell(3); }
/// bottom right index
MathData & br() { return cell(3); }
/// top right index
MathData const & tr() const { return cell(4); }
/// top right index
MathData & tr() { return cell(4); }
/// top left index or single left cell
MathData const & tl() const { return cell(1 + scriptl_); }
/// top left index or single left cell
MathData & tl() { return cell(1 + scriptl_); }
/// bottom right index or single right cell
MathData const & br() const { return cell(2 + scriptl_); }
/// bottom right index or single right cell
MathData & br() { return cell(2 + scriptl_); }
/// top right index or single right cell
MathData const & tr() const { return cell(2 + scriptl_ + scriptr_); }
/// top right index or single right cell
MathData & tr() { return cell(2 + scriptl_ + scriptr_); }
/// say that we have scripts
void infoize(odocstream & os) const;
///
@ -105,6 +106,10 @@ private:
int ndes(BufferView const &) const;
/// returns subscript and superscript kerning of nucleus if any
int nker(BufferView const * bv) const;
/// Whether there are two left scripts or one single cell
bool scriptl_;
/// Whether there are two right scripts or one single cell
bool scriptr_;
};

View File

@ -537,7 +537,14 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf)
if (s == "ensuremath")
return MathAtom(new InsetMathEnsureMath(buf));
if (s == "sideset")
return MathAtom(new InsetMathSideset(buf));
return MathAtom(new InsetMathSideset(buf, true, true));
// The following 3 string values are only for math toolbar use, no LaTeX names
if (s == "sideset1")
return MathAtom(new InsetMathSideset(buf, false, true));
if (s == "sideset2")
return MathAtom(new InsetMathSideset(buf, true, false));
if (s == "sideset3")
return MathAtom(new InsetMathSideset(buf, false, false));
if (isSpecialChar(s))
return MathAtom(new InsetMathSpecialChar(s));
if (s == " ")

View File

@ -1445,23 +1445,29 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
else if (t.cs() == "sideset") {
// Here allowed formats are \sideset{_{bl}^{tl}}{_{br}^{tr}}{operator}
cell->push_back(MathAtom(new InsetMathSideset(buf)));
MathData ar[2];
InsetMathScript * script[2] = {0, 0};
for (int i = 0; i < 2; ++i) {
MathData ar;
parse(ar, FLAG_ITEM, mode);
if (!ar.empty()) {
InsetMathScript * script = (ar.size() == 1) ?
ar[0].nucleus()->asScriptInset() : 0;
if (!script) {
error("found invalid sideset argument");
break;
}
if (script->hasDown())
cell->back().nucleus()->cell(2 * i + 1) = script->down();
if (script->hasUp())
cell->back().nucleus()->cell(2 * i + 2) = script->up();
}
parse(ar[i], FLAG_ITEM, mode);
if (ar[i].size() == 1)
script[i] = ar[i][0].nucleus()->asScriptInset();
}
bool const hasscript[2] = {script[0] ? true : false, script[1] ? true : false};
cell->push_back(MathAtom(new InsetMathSideset(buf, hasscript[0], hasscript[1])));
if (hasscript[0]) {
if (script[0]->hasDown())
cell->back().nucleus()->cell(1) = script[0]->down();
if (script[0]->hasUp())
cell->back().nucleus()->cell(2) = script[0]->up();
} else
cell->back().nucleus()->cell(1) = ar[0];
if (hasscript[1]) {
if (script[1]->hasDown())
cell->back().nucleus()->cell(2 + hasscript[0]) = script[1]->down();
if (script[1]->hasUp())
cell->back().nucleus()->cell(3 + hasscript[0]) = script[1]->up();
} else
cell->back().nucleus()->cell(2 + hasscript[0]) = ar[1];
parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
}