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";
math-array-test.lyx
Description: application/lyx