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);

Reply via email to