Am Montag, 3. Oktober 2005 18:09 schrieb Juergen Spitzmueller:
> Georg Baum wrote:
> > Yes, although my first thought was wrong. Actually the patch is almost
> > right, but it fails if you have a row with extra space (\\[2mm]).
> > Although there is no GUI for the latter and it is not documented, we
> > should get this right.
> 
> OK.
> 
> > I am working on this now (unfortunately I found more bugs while
> > testing...)
> 
> Did you also notice that if you insert the array which your fix in 
math_parser 
> addresses at [1], save and reload, that the last \hline has vanished?

Almost: It does not vanish, but appears one row above. And I found out 
that deleting the last row if it is empty is needed for all matrix like 
structures, not only array and subarray. The attached patch addresses bug 
2067 and those bugs that I have found during testing that lead to data 
loss and therefore need to be fixed for 1.4.0
I have tested reading and writing with the attached document. I did not 
test undo. I am pretty sure that I did not introduce new bugs, but would 
nevertheless appreciate more testing by others.
There are more bugs (e. g. a subarray has a fixed number of columns (2), a 
multline can't have hlines etc.). I guess that they will look familiar to 
Martin, but since these bugs don't lead to data loss we don't need to fix 
them for 1.4.0.

The test document is BTW also a good demonstration of the scrollbar 
problems: The scrollbar is locked although the document height is several 
times the screen height.


Georg
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/ChangeLog lyx-1.4-cvs/src/mathed/ChangeLog
--- lyx-1.4-clean/src/mathed/ChangeLog	2005-10-05 22:12:57.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/ChangeLog	2005-10-05 22:55:38.077646576 +0200
@@ -1,3 +1,17 @@
+2005-10-05  Georg Baum  <[EMAIL PROTECTED]>
+
+	* math_gridinset.[Ch] (eolString, write): Output \\ at the end of the last
+	line if it is empty (fixes bug 2067)
+	* math_hullinset.[Ch] (eolString): Adjust to the changes above
+	* math_hullinset.C (delRow): Allow to delete the last dummy row
+	* math_parser.C (delEmptyLastRow): Delete the last dummy row.
+	The last hline appears in the wrong row otherwise.
+	* math_parser.C (parse1): Call delEmptyLastRow for all matrix like
+	insets. This fixes bug 2067 and avoids data loss on load/save cycles.
+	* math_parser.C (parse1): Ignore the number of columns of alignedat
+	* math_splitinset.C (write): Write the number of column of alignedat.
+	This prevents data loss together with the math parser change above.
+
 2005-10-04  Georg Baum  <[EMAIL PROTECTED]>
 
 	* math_macro.C (editXY): new, fix crash (bug 2060)
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/math_gridinset.C lyx-1.4-cvs/src/mathed/math_gridinset.C
--- lyx-1.4-clean/src/mathed/math_gridinset.C	2005-07-18 21:19:33.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/math_gridinset.C	2005-10-05 22:37:40.772421864 +0200
@@ -606,7 +645,7 @@ void MathGridInset::drawT(TextPainter & 
 }
 
 
-string MathGridInset::eolString(row_type row, bool fragile) const
+string MathGridInset::eolString(row_type row, bool emptyline, bool fragile) const
 {
 	string eol;
 
@@ -622,7 +661,7 @@ string MathGridInset::eolString(row_type
 	}
 
 	// only add \\ if necessary
-	if (eol.empty() && row + 1 == nrows())
+	if (eol.empty() && row + 1 == nrows() && (nrows() == 1 || !emptyline))
 		return string();
 
 	return (fragile ? "\\protect\\\\" : "\\\\") + eol;
@@ -951,6 +990,7 @@ void MathGridInset::mathmlize(MathMLStre
 
 void MathGridInset::write(WriteStream & os) const
 {
+	string eol;
 	for (row_type row = 0; row < nrows(); ++row) {
 		os << verboseHLine(rowinfo_[row].lines_);
 		// don't write & and empty cells at end of line
@@ -963,17 +1003,21 @@ void MathGridInset::write(WriteStream & 
 			}
 		for (col_type col = 0; col < lastcol; ++col)
 			os << cell(index(row, col)) << eocString(col, lastcol);
-		os << eolString(row, os.fragile());
+		eol = eolString(row, emptyline, os.fragile());
+		os << eol;
 		// append newline only if line wasn't completely empty
 		// and this was not the last line in the grid
 		if (!emptyline && row + 1 < nrows())
 			os << "\n";
 	}
 	string const s = verboseHLine(rowinfo_[nrows()].lines_);
-	if (!s.empty() && s != " ") {
-		if (os.fragile())
-			os << "\\protect";
-		os << "\\\\" << s;
+	if (!s.empty()) {
+		if (eol.empty()) {
+			if (os.fragile())
+				os << "\\protect";
+			os << "\\\\";
+		}
+		os << s;
 	}
 }
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/math_gridinset.h lyx-1.4-cvs/src/mathed/math_gridinset.h
--- lyx-1.4-clean/src/mathed/math_gridinset.h	2005-04-26 17:37:18.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/math_gridinset.h	2005-10-05 21:46:20.000000000 +0200
@@ -219,7 +219,8 @@ protected:
 	/// returns y offset of cell compared to inset
 	int cellYOffset(idx_type idx) const;
 	/// returns proper 'end of line' code for LaTeX
-	virtual std::string eolString(row_type row, bool fragile = false) const;
+	virtual std::string eolString(row_type row, bool emptyline,
+	                              bool fragile) const;
 	/// returns proper 'end of column' code for LaTeX
 	virtual std::string eocString(col_type col, col_type lastcol) const;
 	/// extract number of columns from alignment string
@@ -227,7 +228,6 @@ protected:
 	/// splits cells and shifts right part to the next cell
 	void splitCell(LCursor & cur);
 
-public:
 	/// row info.
 	/// rowinfo_[nrows()] is a dummy row used only for hlines.
 	std::vector<RowInfo> rowinfo_;
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/math_hullinset.C lyx-1.4-cvs/src/mathed/math_hullinset.C
--- lyx-1.4-clean/src/mathed/math_hullinset.C	2005-07-18 21:19:33.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/math_hullinset.C	2005-10-05 22:47:22.375004832 +0200
@@ -588,6 +636,10 @@ void MathHullInset::delRow(row_type row)
 	if (nrows() <= 1 || !rowChangeOK())
 		return;
 	MathGridInset::delRow(row);
+	// The last dummy row has no number info nor a label.
+	// Test nrows() + 1 because we have already erased the row.
+	if (row == nrows() + 1)
+		row--;
 	nonum_.erase(nonum_.begin() + row);
 	label_.erase(label_.begin() + row);
 }
@@ -850,7 +920,7 @@ void MathHullInset::mutate(string const 
 }
 
 
-string MathHullInset::eolString(row_type row, bool fragile) const
+string MathHullInset::eolString(row_type row, bool emptyline, bool fragile) const
 {
 	string res;
 	if (numberedType()) {
@@ -859,7 +929,7 @@ string MathHullInset::eolString(row_type
 		if (nonum_[row] && (type_ != "multline"))
 			res += "\\nonumber ";
 	}
-	return res + MathGridInset::eolString(row, fragile);
+	return res + MathGridInset::eolString(row, emptyline, fragile);
 }
 
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/math_hullinset.h lyx-1.4-cvs/src/mathed/math_hullinset.h
--- lyx-1.4-clean/src/mathed/math_hullinset.h	2005-07-18 21:19:33.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/math_hullinset.h	2005-10-05 21:40:54.000000000 +0200
@@ -56,7 +58,7 @@ public:
 			  std::vector<std::string> & list) const;
 	///
 	void validate(LaTeXFeatures & features) const;
-	/// identifies MatrixInsets
+	/// identifies HullInset
 	MathHullInset const * asHullInset() const { return this; }
 	/// identifies HullInset
 	MathHullInset * asHullInset() { return this; }
@@ -126,7 +128,7 @@ protected:
 	bool getStatus(LCursor & cur, FuncRequest const & cmd,
 		FuncStatus & status) const;
 	///
-	std::string eolString(row_type row, bool fragile) const;
+	std::string eolString(row_type row, bool emptyline, bool fragile) const;
 
 private:
 	virtual std::auto_ptr<InsetBase> doClone() const;
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/math_parser.C lyx-1.4-cvs/src/mathed/math_parser.C
--- lyx-1.4-clean/src/mathed/math_parser.C	2005-07-16 10:59:25.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/math_parser.C	2005-10-05 22:29:56.513999872 +0200
@@ -181,7 +181,9 @@ void delEmptyLastRow(MathGridInset & gri
 		if (!grid.cell(grid.index(row, col)).empty())
 			return;
 	}
-	grid.delRow(row);
+	// Remove the dummy row, so that the previous last row (that would
+	// contain the last hline in the example above) becomes the dummy row.
+	grid.delRow(row + 1);
 }
 
 
@@ -935,8 +939,14 @@ void Parser::parse1(MathGridInset & grid
 					      environments_.back() + "}'");
 				else {
 					environments_.pop_back();
-					if (name == "array" ||
-					    name == "subarray")
+					// Delete empty last row in matrix
+					// like insets.
+					// If you abuse MathGridInset for
+					// non-matrix like structures you
+					// probably need to refine this test.
+					// Right now we only have to test for
+					// single line hull insets.
+					if (grid.nrows() > 1)
 						delEmptyLastRow(grid);
 					return;
 				}
@@ -1091,6 +1101,9 @@ void Parser::parse1(MathGridInset & grid
 			else if (name == "split" || name == "cases" ||
 			         name == "gathered" || name == "aligned" ||
 			         name == "alignedat") {
+				if (name == "alignedat")
+					// ignore this for a while
+					getArg('{', '}');
 				cell->push_back(createMathInset(name));
 				parse2(cell->back(), FLAG_END, mode, false);
 			}
@@ -1187,6 +1210,7 @@ void Parser::parse1(MathGridInset & grid
 		}
 
 		else if (t.cs() == "label") {
+			// FIXME: This is swallowed in inline formulas
 			string label = parse_verbatim_item();
 			MathArray ar;
 			asArray(label, ar);
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/mathed/math_splitinset.C lyx-1.4-cvs/src/mathed/math_splitinset.C
--- lyx-1.4-clean/src/mathed/math_splitinset.C	2005-04-13 11:38:42.000000000 +0200
+++ lyx-1.4-cvs/src/mathed/math_splitinset.C	2005-10-05 22:32:22.581794192 +0200
@@ -88,6 +134,8 @@ void MathSplitInset::write(WriteStream &
 	if (ws.fragile())
 		ws << "\\protect";
 	ws << "\\begin{" << name_ << '}';
+	if (name_ == "alignedat")
+		ws << '{' << static_cast<unsigned int>((ncols() + 1)/2) << '}';
 	MathGridInset::write(ws);
 	if (ws.fragile())
 		ws << "\\protect";

Attachment: math-array-test.lyx
Description: application/lyx

Reply via email to