Title: RE: Renaming macros

OK, here is a better formatted patch, preserving encoding etc. Thanks
for the feedback. The update is still being done in metrics() in the
same way that the macro expansion was being done previously. I have
changed it to cast away the const-ness rather than make cells_ mutable.
Assuming that the interface & function of the patch is acceptable I
will now implement a doDispatch(). In addition to changing the name
& number of arguments, I will also remove the expansion from metrics().
This will also negate the need for the mutable on MathMacro::tmpl_ and
MathMacro::expanded_.
If I rename a macro template, does it seem reasonable to automatically
update the name in all instantiations of that template?

thanks,
andrew


Index: text3.C
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/text3.C,v
retrieving revision 1.323
diff -u -r1.323 text3.C
--- text3.C	31 Dec 2005 11:40:32 -0000	1.323
+++ text3.C	27 Jan 2006 02:06:30 -0000
@@ -1254,10 +1254,10 @@
 		else {
 			string s = cmd.argument;
 			string const s1 = token(s, ' ', 1);
-			int const nargs = s1.empty() ? 0 : convert<int>(s1);
+//			int const nargs = s1.empty() ? 0 : convert<int>(s1);
 			string const s2 = token(s, ' ', 2);
 			string const type = s2.empty() ? "newcommand" : s2;
-			cur.insert(new MathMacroTemplate(token(s, ' ', 0), nargs, type));
+			cur.insert(new MathMacroTemplate(token(s, ' ', 0), s1, type));
 			//cur.nextInset()->edit(cur, true);
 		}
 		break;
Index: mathed/math_macro.C
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_macro.C,v
retrieving revision 1.136
diff -u -r1.136 math_macro.C
--- mathed/math_macro.C	5 Oct 2005 21:19:32 -0000	1.136
+++ mathed/math_macro.C	27 Jan 2006 02:06:39 -0000
@@ -59,22 +59,28 @@
 {
 	if (!MacroTable::globalMacros().has(name())) {
 		mathed_string_dim(mi.base.font, "Unknown: " + name(), dim);
-	} else if (editing(mi.base.bv)) {
-		asArray(MacroTable::globalMacros().get(name()).def(), tmpl_);
-		LyXFont font = mi.base.font;
-		augmentFont(font, "lyxtex");
-		tmpl_.metrics(mi, dim);
-		dim.wid += mathed_string_width(font, name()) + 10;
-		int ww = mathed_string_width(font, "#1: ");
-		for (idx_type i = 0; i < nargs(); ++i) {
-			MathArray const & c = cell(i);
-			c.metrics(mi);
-			dim.wid  = max(dim.wid, c.width() + ww);
-			dim.des += c.height() + 10;
-		}
 	} else {
-		MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
-		expanded_.metrics(mi, dim);
+		const idx_type defArgs = static_cast<idx_type>(MacroTable::globalMacros().get(name()).numargs());
+		if (nargs() < defArgs)
+			((MathMacro*)this)->cells_.resize(defArgs);
+  
+		if (editing(mi.base.bv)) {
+			asArray(MacroTable::globalMacros().get(name()).def(), tmpl_);
+			LyXFont font = mi.base.font;
+			augmentFont(font, "lyxtex");
+			tmpl_.metrics(mi, dim);
+			dim.wid += mathed_string_width(font, name()) + 10;
+    		int ww = mathed_string_width(font, "#1: ");
+			for (idx_type i = 0; i < nargs(); ++i) {
+				MathArray const & c = cell(i);
+				c.metrics(mi);
+				dim.wid  = max(dim.wid, c.width() + ww);
+				dim.des += c.height() + 10;
+			}
+		} else {
+			MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
+			expanded_.metrics(mi, dim);
+		}
 	}
 	metricsMarkers2(dim);
 	dim_ = dim;
@@ -158,6 +164,8 @@
 
 void MathMacro::updateExpansion() const
 {
+	if (MacroTable::globalMacros().has(name()))
+		MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
 	//expanded_.substitute(*this);
 }
 
@@ -173,3 +181,4 @@
 	os << "Macro: " << name();
 
 }
+
Index: mathed/math_macro.h
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_macro.h,v
retrieving revision 1.103
diff -u -r1.103 math_macro.h
--- mathed/math_macro.h	5 Oct 2005 21:19:32 -0000	1.103
+++ mathed/math_macro.h	27 Jan 2006 02:06:39 -0000
@@ -55,10 +55,14 @@
 	///
 	void infoize2(std::ostream &) const;
 
-private:
-	virtual std::auto_ptr<InsetBase> doClone() const;
+	virtual MathMacro *asMacro() { return this; }
+	virtual MathMacro const *asMacro() const { return this; }
+
 	///
 	void updateExpansion() const;
+
+private:
+	virtual std::auto_ptr<InsetBase> doClone() const;
 	///
 	void expand() const;
 
Index: mathed/math_macrotable.C
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_macrotable.C,v
retrieving revision 1.74
diff -u -r1.74 math_macrotable.C
--- mathed/math_macrotable.C	24 Jul 2004 10:55:28 -0000	1.74
+++ mathed/math_macrotable.C	27 Jan 2006 02:06:40 -0000
@@ -15,6 +15,7 @@
 #include "math_macroarg.h"
 #include "math_support.h"
 #include "math_sqrtinset.h"
+#include "math_parser.h"
 
 #include "debug.h"
 #include "dociterator.h"
@@ -42,15 +43,58 @@
 {}
 
 
-void MacroData::expand(vector<MathArray> const & args, MathArray & to) const
+void MacroData::doExpand(vector<MathArray> const & args, MathArray const &from, MathArray & to)
 {
-	MathSqrtInset inset; // Hack. Any inset with a cell would do.
-	asArray(disp_.empty() ? def_ : disp_, inset.cell(0));
-	//lyxerr << "MathData::expand: args: " << args << endl;
-	//lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl;
-	for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) {
+	if (from.size() == 0)
+		return;
+
+	MathSqrtInset inset;
+	inset.cell(0) = from; // Hack. Any inset with a cell would do.
+
+//	for (size_t j=0; j<args.size(); j++)
+//		lyxerr << "MathData::expand: args(" << j << "): " << args[j] << endl;
+//	lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl;
+	for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) {		
 		if (!it.nextInset())
 			continue;
+
+		if (it.nextInset()->lyxCode() == InsetBase::MATHMACRO_CODE) {
+			MathMacroTemplate *p = static_cast<MathMacroTemplate*>(it.nextInset());
+
+			// first we parse the name, replacing any macro args
+			MathArray arNameRes;
+			doExpand(args, p->cell(0), arNameRes);
+			string parsedName = asString(arNameRes);
+
+			MathArray arNumArgsRes;
+			doExpand(args, p->cell(1), arNumArgsRes);
+			string numArgs = asString(arNumArgsRes);
+
+			// then we replace the definition and display
+			MathArray ar1;
+			doExpand(args, p->cell(2), ar1);
+
+			MathArray ar2;
+			doExpand(args, p->cell(3), ar2);
+
+			MathMacroTemplate *p1 = new MathMacroTemplate(parsedName, numArgs, "newcommand", ar1, ar2);
+
+			// add the resulting macro to the global table
+			MacroTable::globalMacros().insert(p1->name(), p1->asMacroData());
+
+			// replace the one in the array with the new parsed version
+			MathArray tmpAr;
+			tmpAr.push_back(MathAtom(p1));
+        
+			it.cell().erase(it.pos());
+			DocIterator::pos_type oldSize = it.lastpos();
+			it.cell().insert(it.pos(), tmpAr);
+			// attempt to skip the macro since it's already expanded
+			it.pos() = it.pos() + it.lastpos() - oldSize;
+
+			continue;
+		}
+
 		if (it.nextInset()->lyxCode() != InsetBase::MATHMACROARG_CODE)
 			continue;
 		//it.cell().erase(it.pos());
@@ -58,13 +102,22 @@
 		size_t n = static_cast<MathMacroArgument*>(it.nextInset())->number();
 		if (n <= args.size()) {
 			it.cell().erase(it.pos());
+			DocIterator::pos_type oldSize = it.lastpos();
 			it.cell().insert(it.pos(), args[n - 1]);
+    		// attempt to skip the argument value just inserted    
+    		it.pos() = it.pos() + it.lastpos() - oldSize;
 		}
 	}
 	//lyxerr << "MathData::expand: res: " << inset.cell(0) << endl;
 	to = inset.cell(0);
 }
 
+void MacroData::expand(vector<MathArray> const & args, MathArray & to) const
+{
+	MathArray fromAr;
+	asArray(disp_.empty() ? def_ : disp_, fromAr);
+	doExpand(args, fromAr, to);
+} 
 
 // The global table.
 MacroTable & MacroTable::globalMacros()
Index: mathed/math_macrotable.h
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_macrotable.h,v
retrieving revision 1.23
diff -u -r1.23 math_macrotable.h
--- mathed/math_macrotable.h	20 Apr 2004 08:51:15 -0000	1.23
+++ mathed/math_macrotable.h	27 Jan 2006 02:06:40 -0000
@@ -33,7 +33,9 @@
 	///
 	int numargs() const { return numargs_; }
 	/// replace #1,#2,... by given MathAtom 0,1,..
-	void expand(std::vector<MathArray> const & from, MathArray & to) const;
+	void expand(std::vector<MathArray> const & args, MathArray & to) const;
+	/// 
+	static void doExpand(std::vector<MathArray> const & args, MathArray const &from, MathArray & to);
 
 private:
 	///
Index: mathed/math_macrotemplate.C
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_macrotemplate.C,v
retrieving revision 1.72
diff -u -r1.72 math_macrotemplate.C
--- mathed/math_macrotemplate.C	24 Jan 2006 11:04:30 -0000	1.72
+++ mathed/math_macrotemplate.C	27 Jan 2006 02:06:41 -0000
@@ -15,6 +15,8 @@
 #include "math_parser.h"
 #include "math_support.h"
 
+#include "funcrequest.h"
+
 #include "cursor.h"
 #include "debug.h"
 #include "gettext.h"
@@ -25,6 +27,7 @@
 #include "frontends/font_metrics.h"
 
 #include "support/lstrings.h"
+#include "support/convert.h"
 
 using lyx::support::bformat;
 
@@ -35,28 +38,45 @@
 
 
 MathMacroTemplate::MathMacroTemplate()
-	: MathNestInset(2), numargs_(0), name_(), type_("newcommand")
+	: MathNestInset(4), type_("newcommand")
 {
 	initMath();
 }
 
 
+/*
 MathMacroTemplate::MathMacroTemplate(string const & nm, int numargs,
 		string const & type, MathArray const & ar1, MathArray const & ar2)
-	: MathNestInset(2), numargs_(numargs), name_(nm), type_(type)
+	: MathNestInset(4), type_(type)
 {
 	initMath();
 
 	if (numargs_ > 9)
 		lyxerr << "MathMacroTemplate::MathMacroTemplate: wrong # of arguments: "
-			<< numargs_ << std::endl;
-	cell(0) = ar1;
-	cell(1) = ar2;
+			<< numargs << std::endl;
+  
+	asArray(nm, cell(0));
+
+	asArray(convert<string>(numargs), cell(1));
+    
+	cell(2) = ar1;
+	cell(3) = ar2;
+}
+*/
+
+MathMacroTemplate::MathMacroTemplate(string const & nm, string const & numargs,
+		string const & type, MathArray const & ar1, MathArray const & ar2)
+	: MathNestInset(4), type_(type)
+{ 
+	asArray(nm, cell(0));
+	asArray(numargs, cell(1));
+	cell(2) = ar1;
+	cell(3) = ar2;
 }
 
 
 MathMacroTemplate::MathMacroTemplate(std::istream & is)
-	: MathNestInset(2), numargs_(0), name_()
+	: MathNestInset(4)
 {
 	initMath();
 
@@ -85,25 +105,25 @@
 
 int MathMacroTemplate::numargs() const
 {
-	return numargs_;
+	return convert<int>(asString(cell(1)));
 }
 
 
 void MathMacroTemplate::numargs(int numargs)
 {
-	numargs_ = numargs;
+	asArray(convert<string>(numargs), cell(1));
 }
 
 
 string MathMacroTemplate::name() const
 {
-	return name_;
+	return asString(cell(0));
 }
 
 
 string MathMacroTemplate::prefix() const
 {
-	return bformat(_(" Macro: %1$s: "), name_);
+	return string(" Macro: ");
 }
 
 
@@ -111,10 +131,13 @@
 {
 	cell(0).metrics(mi);
 	cell(1).metrics(mi);
-	dim.wid = cell(0).width() + cell(1).width() + 20
-		+ font_metrics::width(prefix(), mi.base.font);
-	dim.asc = std::max(cell(0).ascent(),  cell(1).ascent())  + 7;
-	dim.des = std::max(cell(0).descent(), cell(1).descent()) + 7;
+	cell(2).metrics(mi);
+	cell(3).metrics(mi);
+	dim.wid = cell(0).width() + cell(1).width() + cell(2).width() + cell(3).width() + 26 +
+		font_metrics::width(prefix(), mi.base.font) + 8 +
+		font_metrics::width(":[]", mi.base.font);
+	dim.asc = std::max(cell(2).ascent(),  cell(3).ascent())  + 7;
+	dim.des = std::max(cell(2).descent(), cell(3).descent()) + 7;
 	dim_ = dim;
 }
 
@@ -154,12 +177,27 @@
 
 	int const w0 = cell(0).width();
 	int const w1 = cell(1).width();
+	int const w2 = cell(2).width();
+	int const w3 = cell(3).width();
+  
 	cell(0).draw(pi, x + 2, y + 1);
+	x += w0 + 4;
+  
+	pi.pain.text(x, y, ": [", font);
+	x += font_metrics::width(": [", pi.base.font) + 2;
+	  cell(1).draw(pi, x, y + 1);
+	x += w1 + 2;
+	pi.pain.text(x, y, "]", font);
+	x += font_metrics::width("]", pi.base.font);
+	
+	cell(2).draw(pi, x + 2, y + 1);
+	pi.pain.rectangle(x, y - dim_.ascent() + 3,
+		w2 + 4, dim_.height() - 6, LColor::mathline);
+  	x += w2 + 6;
+	
+  	cell(3).draw(pi, x + 2, y + 1);
 	pi.pain.rectangle(x, y - dim_.ascent() + 3,
-		w0 + 4, dim_.height() - 6, LColor::mathline);
-	cell(1).draw(pi, x + 8 + w0, y + 1);
-	pi.pain.rectangle(x + w0 + 6, y - dim_.ascent() + 3,
-		w1 + 4, dim_.height() - 6, LColor::mathline);
+		w3 + 4, dim_.height() - 6, LColor::mathline);
 }
 
 
@@ -186,17 +224,17 @@
 void MathMacroTemplate::write(WriteStream & os) const
 {
 	if (type_ == "def") {
-		os << "\\def\\" << name_.c_str();
-		for (int i = 1; i <= numargs_; ++i)
+		os << "\\def\\" << name().c_str();
+		for (int i = 1; i <= numargs(); ++i)
 			os << '#' << i;
 	} else {
 		// newcommand or renewcommand
-		os << "\\" << type_.c_str() << "{\\" << name_.c_str() << '}';
-		if (numargs_ > 0)
-			os << '[' << numargs_ << ']';
+		os << "\\" << type_.c_str() << "{\\" << name().c_str() << '}';
+		if (cell(1).size() > 0)
+			os << '[' << asString(cell(1)).c_str() << ']';
 	}
 
-	os << '{' << cell(0) << "}";
+	os << '{' << cell(2) << "}";
 
 	if (os.latex()) {
 		// writing .tex. done.
@@ -204,12 +242,12 @@
 	} else {
 		// writing .lyx, write special .tex export only if necessary
 		if (!cell(1).empty())
-			os << "\n{" << cell(1) << '}';
+			os << "\n{" << cell(3) << '}';
 	}
 }
 
 
 MacroData MathMacroTemplate::asMacroData() const
 {
-	return MacroData(asString(cell(0)), numargs(), asString(cell(1)));
+	return MacroData(asString(cell(2)), numargs(), asString(cell(3)));
 }
Index: mathed/math_macrotemplate.h
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_macrotemplate.h,v
retrieving revision 1.47
diff -u -r1.47 math_macrotemplate.h
--- mathed/math_macrotemplate.h	23 Nov 2004 23:04:51 -0000	1.47
+++ mathed/math_macrotemplate.h	27 Jan 2006 02:06:41 -0000
@@ -24,11 +24,17 @@
 	///
 	MathMacroTemplate();
 	///
-	MathMacroTemplate(std::string const & name, int nargs,
+/*	MathMacroTemplate(std::string const & name, int nargs,
 		std::string const & type,
 		MathArray const & = MathArray(),
 		MathArray const & = MathArray());
-	///
+*/    
+  ///
+	MathMacroTemplate(std::string const & name, std::string const & nargs,
+		std::string const & type,
+		MathArray const & = MathArray(),
+		MathArray const & = MathArray());	
+  ///
 	explicit MathMacroTemplate(std::istream & is);
 	///
 	void edit(LCursor & cur, bool left);
@@ -64,10 +70,6 @@
 	/// prefix in inset
 	std::string prefix() const;
 
-	///
-	int numargs_;
-	///
-	std::string name_;
 	/// newcommand or renewcommand or def
 	std::string type_;
 };
Index: mathed/math_parser.C
===================================================================
RCS file: /var/cvs/lyx/lyx-devel/src/mathed/math_parser.C,v
retrieving revision 1.316
diff -u -r1.316 math_parser.C
--- mathed/math_parser.C	8 Nov 2005 15:12:05 -0000	1.316
+++ mathed/math_parser.C	27 Jan 2006 02:06:45 -0000
@@ -856,38 +856,33 @@
 		{
 			string const type = t.cs();
 			string name;
-			int nargs = 0;
+			string nargs;
 			if (t.cs() == "def") {
 				// get name
 				name = getToken().cs();
 
 				// read parameter
 				string pars;
+				int tmpArgC = 0;
 				while (good() && nextToken().cat() != catBegin) {
 					pars += getToken().cs();
-					++nargs;
+					++tmpArgC;
 				}
-				nargs /= 2;
+				tmpArgC /= 2;
+				if (tmpArgC > 0)
+				  nargs = convert<string>(tmpArgC);
 				//lyxerr << "read \\def parameter list '" << pars << "'" << endl;
 
 			} else { // t.cs() == "newcommand" || t.cs() == "renewcommand"
 
-				if (getToken().cat() != catBegin) {
-					error("'{' in \\newcommand expected (1) ");
+				name = parse_verbatim_item();
+				if (name.length() == 0)
+				{
+					error("<\\name> in \\newcommand expected");
 					return;
 				}
-
-				name = getToken().cs();
-
-				if (getToken().cat() != catEnd) {
-					error("'}' in \\newcommand expected");
-					return;
-				}
-
-				string const arg  = getArg('[', ']');
-				if (!arg.empty())
-					nargs = convert<int>(arg);
-
+					
+				nargs  = getArg('[', ']');
 			}
 
 			MathArray ar1;
@@ -907,8 +902,7 @@
 			if (nextToken().cat() == catBegin)
 				parse(ar2, FLAG_ITEM, MathInset::MATH_MODE);
 
-			cell->push_back(MathAtom(new MathMacroTemplate(name, nargs, type,
-				ar1, ar2)));
+			cell->push_back(MathAtom(new MathMacroTemplate(name, nargs, type, ar1, ar2)));
 		}
 
 		else if (t.cs() == "(") {
@@ -1339,6 +1333,8 @@
 					parse(at.nucleus()->cell(i), FLAG_ITEM, m);
 					skipSpaces();
 				}
+				if (at.nucleus()->asMacro())
+					at.nucleus()->asMacro()->updateExpansion();
 				cell->push_back(at);
 			}
 		}

Reply via email to