X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathScript.cpp;h=fc72b6b078e1052002cd045701c607767e57ac40;hb=28be7d552f62cc02fa86d7f79201d089bfb2d7b5;hp=6ce45d4b0a0a36e5c6f2a693b98d84c6713804db;hpb=8cf5ff6fbf7ba229db407d33c179db50d8c73150;p=lyx.git diff --git a/src/mathed/InsetMathScript.cpp b/src/mathed/InsetMathScript.cpp index 6ce45d4b0a..fc72b6b078 100644 --- a/src/mathed/InsetMathScript.cpp +++ b/src/mathed/InsetMathScript.cpp @@ -10,23 +10,26 @@ #include -#include "BufferView.h" -#include "Cursor.h" -#include "DispatchResult.h" -#include "FuncRequest.h" -#include "InsetMathFont.h" #include "InsetMathScript.h" + +#include "InsetMathBrace.h" #include "InsetMathSymbol.h" -#include "LaTeXFeatures.h" #include "MathData.h" #include "MathStream.h" #include "MathSupport.h" -#include "support/debug.h" +#include "BufferView.h" +#include "Cursor.h" +#include "DispatchResult.h" +#include "FuncRequest.h" +#include "FuncStatus.h" +#include "LaTeXFeatures.h" +#include "MetricsInfo.h" +#include "support/debug.h" +#include "support/gettext.h" #include "support/lassert.h" -#include using namespace std; @@ -46,7 +49,7 @@ InsetMathScript::InsetMathScript(Buffer * buf, bool up) InsetMathScript::InsetMathScript(Buffer * buf, MathAtom const & at, bool up) : InsetMathNest(buf, 2), cell_1_is_up_(up), limits_(0) { - LASSERT(nargs() >= 1, /**/); + LATTEST(nargs() >= 1); cell(0).push_back(at); } @@ -89,7 +92,7 @@ MathData const & InsetMathScript::down() const { if (nargs() == 3) return cell(2); - LASSERT(nargs() > 1, /**/); + LBUFERR(nargs() > 1); return cell(1); } @@ -98,21 +101,21 @@ MathData & InsetMathScript::down() { if (nargs() == 3) return cell(2); - LASSERT(nargs() > 1, /**/); + LBUFERR(nargs() > 1); return cell(1); } MathData const & InsetMathScript::up() const { - LASSERT(nargs() > 1, /**/); + LBUFERR(nargs() > 1); return cell(1); } MathData & InsetMathScript::up() { - LASSERT(nargs() > 1, /**/); + LBUFERR(nargs() > 1); return cell(1); } @@ -146,36 +149,11 @@ MathData & InsetMathScript::nuc() } -namespace { - -bool isAlphaSymbol(MathAtom const & at) -{ - if (at->asCharInset() || - (at->asSymbolInset() && - at->asSymbolInset()->isOrdAlpha())) - return true; - - if (at->asFontInset()) { - MathData const & ar = at->asFontInset()->cell(0); - for (size_t i = 0; i < ar.size(); ++i) { - if (!(ar[i]->asCharInset() || - (ar[i]->asSymbolInset() && - ar[i]->asSymbolInset()->isOrdAlpha()))) - return false; - } - return true; - } - return false; -} - -} // namespace anon - - int InsetMathScript::dy01(BufferView const & bv, int asc, int des, int what) const { int dasc = 0; int slevel = 0; - bool isCharBox = nuc().size() ? isAlphaSymbol(nuc().back()) : false; + bool isCharBox = !nuc().empty() ? isAlphaSymbol(nuc().back()) : false; if (hasDown()) { Dimension const & dimdown = down().dimension(bv); dasc = dimdown.ascent(); @@ -246,17 +224,19 @@ int InsetMathScript::dy1(BufferView const & bv) const int InsetMathScript::dx0(BufferView const & bv) const { - LASSERT(hasDown(), /**/); + LASSERT(hasDown(), return 0); Dimension const dim = dimension(bv); - return hasLimits() ? (dim.wid - down().dimension(bv).width()) / 2 : nwid(bv); + return hasLimits() ? (dim.wid - down().dimension(bv).width()) / 2 + : nwid(bv) + min(nker(&bv), 0); } int InsetMathScript::dx1(BufferView const & bv) const { - LASSERT(hasUp(), /**/); + LASSERT(hasUp(), return 0); Dimension const dim = dimension(bv); - return hasLimits() ? (dim.wid - up().dimension(bv).width()) / 2 : nwid(bv) + nker(&bv); + return hasLimits() ? (dim.wid - up().dimension(bv).width()) / 2 + : nwid(bv) + max(nker(&bv), 0); } @@ -269,39 +249,54 @@ int InsetMathScript::dxx(BufferView const & bv) const int InsetMathScript::nwid(BufferView const & bv) const { - return nuc().size() ? nuc().dimension(bv).width() : 2; + return !nuc().empty() ? nuc().dimension(bv).width() : 2; } int InsetMathScript::nasc(BufferView const & bv) const { - return nuc().size() ? nuc().dimension(bv).ascent() : 5; + return !nuc().empty() ? nuc().dimension(bv).ascent() : 5; } int InsetMathScript::ndes(BufferView const & bv) const { - return nuc().size() ? nuc().dimension(bv).descent() : 0; + return !nuc().empty() ? nuc().dimension(bv).descent() : 0; } int InsetMathScript::nker(BufferView const * bv) const { - if (nuc().size()) { - int kerning = nuc().kerning(bv); - return kerning > 0 ? kerning : 0; - } + if (!nuc().empty()) + return nuc().kerning(bv); return 0; } +MathClass InsetMathScript::mathClass() const +{ + // FIXME: this is a hack, since the class will not be correct if + // the nucleus has several elements or if the last element is a math macro + // or a macro argument proxy. + // The correct implementation would require to linearize the nucleus. + if (nuc().empty()) + return MC_ORD; + else { + // return the class of last element since this is the one that counts. + MathClass mc = nuc().back()->mathClass(); + return (mc == MC_UNKNOWN) ? MC_ORD : mc; + } +} + + void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const { + Changer dummy2 = mi.base.changeEnsureMath(); Dimension dim0; Dimension dim1; Dimension dim2; cell(0).metrics(mi, dim0); - ScriptChanger dummy(mi.base); + Changer dummy = mi.base.changeScript(); if (nargs() > 1) cell(1).metrics(mi, dim1); if (nargs() > 2) @@ -325,9 +320,9 @@ void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = max(dim.wid, dimdown.width()); } else { if (hasUp()) - dim.wid = max(dim.wid, nker(mi.base.bv) + dimup.width()); + dim.wid = max(dim.wid, max(nker(mi.base.bv), 0) + dimup.width()); if (hasDown()) - dim.wid = max(dim.wid, dimdown.width()); + dim.wid = max(dim.wid, min(nker(mi.base.bv), 0) + dimdown.width()); dim.wid += nwid(bv); } int na = nasc(bv); @@ -342,26 +337,25 @@ void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const dim.des = max(nd, des); } else dim.des = nd; - metricsMarkers(dim); } void InsetMathScript::draw(PainterInfo & pi, int x, int y) const { + Changer dummy2 = pi.base.changeEnsureMath(); BufferView & bv = *pi.base.bv; - if (nuc().size()) + if (!nuc().empty()) nuc().draw(pi, x + dxx(bv), y); else { nuc().setXY(bv, x + dxx(bv), y); if (editing(&bv)) pi.draw(x + dxx(bv), y, char_type('.')); } - ScriptChanger dummy(pi.base); + Changer dummy = pi.base.changeScript(); if (hasUp()) up().draw(pi, x + dx1(bv), y - dy1(bv)); if (hasDown()) down().draw(pi, x + dx0(bv), y + dy0(bv)); - drawMarkers(pi, x, y); } @@ -378,7 +372,7 @@ void InsetMathScript::metricsT(TextMetricsInfo const & mi, Dimension & dim) cons void InsetMathScript::drawT(TextPainter & pain, int x, int y) const { // FIXME: BROKEN - if (nuc().size()) + if (!nuc().empty()) nuc().drawT(pain, x + 1, y); if (hasUp()) up().drawT(pain, x + 1, y - 1 /*dy1()*/); @@ -397,7 +391,7 @@ bool InsetMathScript::hasLimits() const return false; // we can only display limits if the nucleus wants some - if (!nuc().size()) + if (nuc().empty()) return false; if (!nuc().back()->isScriptable()) return false; @@ -463,9 +457,7 @@ Inset::idx_type InsetMathScript::idxOfScript(bool up) const return (cell_1_is_up_ == up) ? 1 : 0; if (nargs() == 3) return up ? 1 : 2; - LASSERT(false, /**/); - // Silence compiler - return 0; + LASSERT(false, return 0); } @@ -528,7 +520,7 @@ void InsetMathScript::write(WriteStream & os) const { MathEnsurer ensurer(os); - if (nuc().size()) { + if (!nuc().empty()) { os << nuc(); //if (nuc().back()->takesLimits()) { if (limits_ == -1) @@ -543,11 +535,19 @@ void InsetMathScript::write(WriteStream & os) const os << "{}"; } - if (hasDown() /*&& down().size()*/) + if (hasDown() /*&& !down().empty()*/) os << "_{" << down() << '}'; - if (hasUp() /*&& up().size()*/) - os << "^{" << up() << '}'; + if (hasUp() /*&& !up().empty()*/) { + // insert space if up() is empty or an empty brace inset + // (see bug 8305) + if (os.latex() && (up().empty() || + (up().size() == 1 && up().back()->asBraceInset() && + up().back()->asBraceInset()->cell(0).empty()))) + os << "^ {}"; + else + os << "^{" << up() << '}'; + } if (lock_ && !os.latex()) os << "\\lyxlock "; @@ -556,8 +556,8 @@ void InsetMathScript::write(WriteStream & os) const void InsetMathScript::normalize(NormalStream & os) const { - bool d = hasDown() && down().size(); - bool u = hasUp() && up().size(); + bool d = hasDown() && !down().empty(); + bool u = hasUp() && !up().empty(); if (u && d) os << "[subsup "; @@ -566,7 +566,7 @@ void InsetMathScript::normalize(NormalStream & os) const else if (d) os << "[sub "; - if (nuc().size()) + if (!nuc().empty()) os << nuc() << ' '; else os << "[par]"; @@ -582,21 +582,21 @@ void InsetMathScript::normalize(NormalStream & os) const void InsetMathScript::maple(MapleStream & os) const { - if (nuc().size()) + if (!nuc().empty()) os << nuc(); - if (hasDown() && down().size()) + if (hasDown() && !down().empty()) os << '[' << down() << ']'; - if (hasUp() && up().size()) + if (hasUp() && !up().empty()) os << "^(" << up() << ')'; } void InsetMathScript::mathematica(MathematicaStream & os) const { - bool d = hasDown() && down().size(); - bool u = hasUp() && up().size(); + bool d = hasDown() && !down().empty(); + bool u = hasUp() && !up().empty(); - if (nuc().size()) { + if (!nuc().empty()) { if (d) os << "Subscript[" << nuc(); else @@ -606,30 +606,27 @@ void InsetMathScript::mathematica(MathematicaStream & os) const if (u) os << "^(" << up() << ')'; - if (nuc().size()) { + if (!nuc().empty()) { if (d) os << ',' << down() << ']'; } } -// FIXME XHTML -// It may be worth trying to output munder, mover, and munderover -// in certain cases, e.g., for display formulas. But then we would -// need to know if we're in a display formula. void InsetMathScript::mathmlize(MathStream & os) const { - bool d = hasDown() && down().size(); - bool u = hasUp() && up().size(); + bool d = hasDown() && !down().empty(); + bool u = hasUp() && !up().empty(); + bool l = hasLimits(); if (u && d) - os << MTag("msubsup"); + os << MTag(l ? "munderover" : "msubsup"); else if (u) - os << MTag("msup"); + os << MTag(l ? "mover" : "msup"); else if (d) - os << MTag("msub"); + os << MTag(l ? "munder" : "msub"); - if (nuc().size()) + if (!nuc().empty()) os << MTag("mrow") << nuc() << ETag("mrow"); else os << ""; @@ -637,20 +634,20 @@ void InsetMathScript::mathmlize(MathStream & os) const if (u && d) os << MTag("mrow") << down() << ETag("mrow") << MTag("mrow") << up() << ETag("mrow") - << ETag("msubsup"); + << ETag(l ? "munderover" : "msubsup"); else if (u) - os << MTag("mrow") << up() << ETag("mrow") << ETag("msup"); + os << MTag("mrow") << up() << ETag("mrow") << ETag(l ? "mover" : "msup"); else if (d) - os << MTag("mrow") << down() << ETag("mrow") << ETag("msub"); + os << MTag("mrow") << down() << ETag("mrow") << ETag(l ? "munder" : "msub"); } void InsetMathScript::htmlize(HtmlStream & os) const { - bool d = hasDown() && down().size(); - bool u = hasUp() && up().size(); + bool d = hasDown() && !down().empty(); + bool u = hasUp() && !up().empty(); - if (nuc().size()) + if (!nuc().empty()) os << nuc(); if (u && d) @@ -667,11 +664,11 @@ void InsetMathScript::htmlize(HtmlStream & os) const void InsetMathScript::octave(OctaveStream & os) const { - if (nuc().size()) + if (!nuc().empty()) os << nuc(); - if (hasDown() && down().size()) + if (hasDown() && !down().empty()) os << '[' << down() << ']'; - if (hasUp() && up().size()) + if (hasUp() && !up().empty()) os << "^(" << up() << ')'; } @@ -704,13 +701,13 @@ bool InsetMathScript::notifyCursorLeaves(Cursor const & old, Cursor & cur) // must be a subscript... old.recordUndoInset(); removeScript(false); - cur.updateFlags(cur.disp_.update() | Update::SinglePar); + cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar); return true; } else if (cell(1).empty()) { // must be a superscript... old.recordUndoInset(); removeScript(true); - cur.updateFlags(cur.disp_.update() | Update::SinglePar); + cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar); return true; } } @@ -740,7 +737,7 @@ bool InsetMathScript::notifyCursorLeaves(Cursor const & old, Cursor & cur) insetCur.cell().insert(insetCur.pos(), ar); // redraw - cur.updateFlags(cur.disp_.update() | Update::SinglePar); + cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar); return true; } @@ -753,7 +750,8 @@ void InsetMathScript::doDispatch(Cursor & cur, FuncRequest & cmd) { //LYXERR("InsetMathScript: request: " << cmd); - if (cmd.action == LFUN_MATH_LIMITS) { + if (cmd.action() == LFUN_MATH_LIMITS) { + cur.recordUndoInset(); if (!cmd.argument().empty()) { if (cmd.argument() == "limits") limits_ = 1; @@ -772,16 +770,36 @@ void InsetMathScript::doDispatch(Cursor & cur, FuncRequest & cmd) } +bool InsetMathScript::getStatus(Cursor & cur, FuncRequest const & cmd, + FuncStatus & flag) const +{ + if (cmd.action() == LFUN_MATH_LIMITS) { + if (!cmd.argument().empty()) { + if (cmd.argument() == "limits") + flag.setOnOff(limits_ == 1); + else if (cmd.argument() == "nolimits") + flag.setOnOff(limits_ == -1); + else + flag.setOnOff(limits_ == 0); + } + flag.setEnabled(true); + return true; + } + + return InsetMathNest::getStatus(cur, cmd, flag); +} + + // the idea for dual scripts came from the eLyXer code void InsetMathScript::validate(LaTeXFeatures & features) const { - if (features.runparams().flavor == OutputParams::HTML) - features.addPreambleSnippet(""); + "sup.math{font-size: 75%;}"); + InsetMathNest::validate(features); } } // namespace lyx