On Mon, Sep 17, 2007 at 06:49:00PM +0200, Georg Baum wrote: > Martin Vermeer wrote: > > > Oops. Too difficult. > > I don't think so. Just look how the two variants of sqrt (\sqrt{a}{b} and > \sqrt[a]{b}{c}) are handled and copy the relevant portions of code. If you > think that you do not really understand how the different parts of mathed > work together make Andre write some documentation :-) > > > Probably best to revert it. > > If you revert, then please remove all \unitfrac variants. Otherwise you > create a regression, because \unitfrac[a]{b}{c} in 1.4 works fine as ERT, > and it would not if you only kept the short variant.
OK, the attached. Wasn't too hard, but I couldn't really spare the time. Seems to work. - Martin
Index: InsetMathFrac.h =================================================================== --- InsetMathFrac.h (revision 20290) +++ InsetMathFrac.h (working copy) @@ -29,8 +29,7 @@ ATOP, NICEFRAC, UNITFRAC, - UNIT, - UNITFRAC3 + UNIT }; /// Index: MathFactory.cpp =================================================================== --- MathFactory.cpp (revision 20290) +++ MathFactory.cpp (working copy) @@ -372,8 +372,9 @@ return MathAtom(new InsetMathFrac(InsetMathFrac::NICEFRAC)); if (s == "unitfrac") return MathAtom(new InsetMathFrac(InsetMathFrac::UNITFRAC)); + // This string value is only for math toolbar use. Not a LaTeX name if (s == "unitfracthree") - return MathAtom(new InsetMathFrac(InsetMathFrac::UNITFRAC3, 3)); + return MathAtom(new InsetMathFrac(InsetMathFrac::UNIT, 3)); if (s == "unit") return MathAtom(new InsetMathFrac(InsetMathFrac::UNIT)); //if (s == "infer") Index: InsetMathFrac.cpp =================================================================== --- InsetMathFrac.cpp (revision 20290) +++ InsetMathFrac.cpp (working copy) @@ -49,11 +49,12 @@ bool InsetMathFrac::idxRight(Cursor & cur) const { InsetMath::idx_type target; - if (kind_ == UNITFRAC3) - target = 0; - else if (kind_ == UNIT) - target = 1; - else + if (kind_ == UNIT) { + if (nargs() == 3) + target = 0; + else + target = 1; + } else return false; if (cur.idx() == target) return false; @@ -66,11 +67,12 @@ bool InsetMathFrac::idxLeft(Cursor & cur) const { InsetMath::idx_type target; - if (kind_ == UNITFRAC3) - target = 2; - else if (kind_ == UNIT) - target = 0; - else + if (kind_ == UNIT) { + if (nargs() == 3) + target = 2; + else + target = 0; + } else return false; if (cur.idx() == target) return false; @@ -83,21 +85,23 @@ bool InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const { if (kind_ == UNIT) { - cell(0).metrics(mi); - ShapeChanger dummy2(mi.base.font, Font::UP_SHAPE); - cell(1).metrics(mi); - dim.wid = cell(0).width() + cell(1).width() + 5; - dim.asc = std::max(cell(0).ascent(), cell(1).ascent()); - dim.des = std::max(cell(0).descent(), cell(1).descent()); - } else if (kind_ == UNITFRAC3) { - cell(2).metrics(mi); - ShapeChanger dummy2(mi.base.font, Font::UP_SHAPE); - FracChanger dummy(mi.base); - cell(0).metrics(mi); - cell(1).metrics(mi); - dim.wid = cell(0).width() + cell(1).width() + cell(2).width() + 10; - dim.asc = std::max(cell(2).ascent(), cell(0).height() + 5); - dim.des = std::max(cell(2).descent(), cell(1).height() - 5); + if (nargs() == 2) { + cell(0).metrics(mi); + ShapeChanger dummy2(mi.base.font, Font::UP_SHAPE); + cell(1).metrics(mi); + dim.wid = cell(0).width() + cell(1).width() + 5; + dim.asc = std::max(cell(0).ascent(), cell(1).ascent()); + dim.des = std::max(cell(0).descent(), cell(1).descent()); + } else { + cell(2).metrics(mi); + ShapeChanger dummy2(mi.base.font, Font::UP_SHAPE); + FracChanger dummy(mi.base); + cell(0).metrics(mi); + cell(1).metrics(mi); + dim.wid = cell(0).width() + cell(1).width() + cell(2).width() + 10; + dim.asc = std::max(cell(2).ascent(), cell(0).height() + 5); + dim.des = std::max(cell(2).descent(), cell(1).height() - 5); + } } else { FracChanger dummy(mi.base); cell(0).metrics(mi); @@ -130,18 +134,20 @@ setPosCache(pi, x, y); int m = x + dim_.wid / 2; if (kind_ == UNIT) { - cell(0).draw(pi, x + 1, y); - ShapeChanger dummy2(pi.base.font, Font::UP_SHAPE); - cell(1).draw(pi, x + cell(0).width() + 5, y); - } else if (kind_ == UNITFRAC3) { - cell(2).draw(pi, x + 1, y); - ShapeChanger dummy2(pi.base.font, Font::UP_SHAPE); - FracChanger dummy(pi.base); - int xx = x + cell(2).width() + 5; - cell(0).draw(pi, xx + 2, - y - cell(0).descent() - 5); - cell(1).draw(pi, xx + cell(0).width() + 5, - y + cell(1).ascent() / 2); + if (nargs() == 2) { + cell(0).draw(pi, x + 1, y); + ShapeChanger dummy2(pi.base.font, Font::UP_SHAPE); + cell(1).draw(pi, x + cell(0).width() + 5, y); + } else { + cell(2).draw(pi, x + 1, y); + ShapeChanger dummy2(pi.base.font, Font::UP_SHAPE); + FracChanger dummy(pi.base); + int xx = x + cell(2).width() + 5; + cell(0).draw(pi, xx + 2, + y - cell(0).descent() - 5); + cell(1).draw(pi, xx + cell(0).width() + 5, + y + cell(1).ascent() / 2); + } } else { FracChanger dummy(pi.base); if (kind_ == NICEFRAC) { @@ -163,10 +169,11 @@ y + cell(1).ascent() + 2 - 5); } } - if (kind_ == NICEFRAC || kind_ == UNITFRAC || kind_ == UNITFRAC3) { + if (kind_ == NICEFRAC || kind_ == UNITFRAC + || (kind_ == UNIT && nargs() == 3)) { // Diag line: int xx = x; - if (kind_ == UNITFRAC3) + if (nargs() == 3) xx += cell(2).width() + 5; pi.pain.line(xx + cell(0).width(), y + dim_.des - 2, @@ -218,11 +225,11 @@ InsetMathNest::write(os); break; case UNIT: - os << "\\unit[" << cell(0) << "]{" << cell(1) << '}'; + if (nargs() == 2) + os << "\\unit[" << cell(0) << "]{" << cell(1) << '}'; + else + os << "\\unitfrac[" << cell(2) << "]{" << cell(0) << "}{" << cell(1) << '}'; break; - case UNITFRAC3: - os << "\\unitfrac[" << cell(2) << "]{" << cell(0) << "}{" << cell(1) << '}'; - break; } } @@ -238,10 +245,15 @@ return from_ascii("nicefrac"); case UNITFRAC: return from_ascii("unitfrac"); - case UNITFRAC3: - return from_ascii("unitfracthree"); case UNIT: - return from_ascii("unit"); + // Note the illogicity. The enum is UNIT, but it + // collects both non-fractional and fractional + // values + units, having only in common the use + // of the optional value field. + if (nargs() == 3) + return from_ascii("unitfrac"); + else + return from_ascii("unit"); case ATOP: return from_ascii("atop"); } @@ -282,8 +294,7 @@ void InsetMathFrac::validate(LaTeXFeatures & features) const { - if (kind_ == NICEFRAC || kind_ == UNITFRAC - || kind_ == UNIT || kind_ == UNITFRAC3) + if (kind_ == NICEFRAC || kind_ == UNITFRAC || kind_ == UNIT) features.require("units"); InsetMathNest::validate(features); } Index: MathParser.cpp =================================================================== --- MathParser.cpp (revision 20282) +++ MathParser.cpp (working copy) @@ -47,6 +47,7 @@ #include "InsetMathComment.h" #include "InsetMathDelim.h" #include "InsetMathEnv.h" +#include "InsetMathFrac.h" #include "InsetMathKern.h" #include "MathMacro.h" #include "InsetMathPar.h" @@ -241,7 +242,7 @@ FLAG_END = 1 << 3, // next \\end ends the parsing process FLAG_BRACK_LAST = 1 << 4, // next closing bracket ends the parsing FLAG_TEXTMODE = 1 << 5, // we are in a box - FLAG_ITEM = 1 << 6, // read a (possibly braced token) + FLAG_ITEM = 1 << 6, // read a (possibly braced) token FLAG_LEAVE = 1 << 7, // leave the loop at the end FLAG_SIMPLE = 1 << 8, // next $ leaves the loop FLAG_EQUATION = 1 << 9, // next \] leaves the loop @@ -1097,6 +1098,33 @@ } } + else if (t.cs() == "unit") { + // Allowed formats \unit[val]{unit} + MathData ar; + parse(ar, FLAG_OPTION, mode); + cell->push_back(MathAtom(new InsetMathFrac(InsetMathFrac::UNIT))); + if (ar.size()) { + cell->back().nucleus()->cell(0) = ar; + parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode); + } else { + // Not implemented, should not be reached: + parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode); + } + } + else if (t.cs() == "unitfrac") { + // Here allowed formats are \unitfrac[val]{num}{denom} + MathData ar; + parse(ar, FLAG_OPTION, mode); + if (ar.size()) { + cell->push_back(MathAtom(new InsetMathFrac(InsetMathFrac::UNIT, 3))); + cell->back().nucleus()->cell(2) = ar; + } else { + cell->push_back(MathAtom(new InsetMathFrac(InsetMathFrac::UNITFRAC))); + } + parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode); + parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode); + } + else if (t.cs() == "xrightarrow" || t.cs() == "xleftarrow") { cell->push_back(createInsetMath(t.cs())); parse(cell->back().nucleus()->cell(1), FLAG_OPTION, mode);