X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fmath_matrixinset.C;h=4fa1ebd1f10c906d02d9809b933d45848cc59df9;hb=dff2911bda426ad439e6475f62183cedd7044801;hp=96a4c0db74aa544adfedd9bac80419ca9ad47325;hpb=76ef051b1cb1fb51c3ffd8ccc9105be4471e74d4;p=features.git diff --git a/src/mathed/math_matrixinset.C b/src/mathed/math_matrixinset.C index 96a4c0db74..4fa1ebd1f1 100644 --- a/src/mathed/math_matrixinset.C +++ b/src/mathed/math_matrixinset.C @@ -1,95 +1,152 @@ -#include - #ifdef __GNUG__ #pragma implementation #endif +#include + #include "math_matrixinset.h" +#include "support.h" #include "debug.h" #include "support/LOstream.h" #include "Painter.h" #include "LaTeXFeatures.h" -LyXFont WhichFont(short type, int size); - namespace { -string getAlign(short int type, int cols) -{ - string align; - switch (type) { - case LM_OT_ALIGN: - for (int i = 0; i < cols; ++i) - align += "Rl"; - break; + int getCols(MathInsetTypes type) + { + switch (type) { + case LM_OT_EQNARRAY: + return 3; + case LM_OT_ALIGN: + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: + return 2; + default:; + } + return 1; + } - case LM_OT_ALIGNAT: - for (int i = 0; i < cols; ++i) - align += "rl"; - break; - case LM_OT_MULTLINE: - align = "C"; - break; + // returns position of first relation operator in the array + // used for "intelligent splitting" + int firstRelOp(MathArray const & ar) + { + for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) + if ((*it)->isRelOp()) + return it - ar.begin(); + return ar.size(); + } - default: - align = "rcl"; - break; + + char const * star(bool numbered) + { + return numbered ? "" : "*"; } - return align; -} + MathInsetTypes typecode(string const & s) + { + if (s == "equation") return LM_OT_EQUATION; + if (s == "display") return LM_OT_EQUATION; + if (s == "eqnarray") return LM_OT_EQNARRAY; + if (s == "align") return LM_OT_ALIGN; + if (s == "alignat") return LM_OT_ALIGNAT; + if (s == "xalignat") return LM_OT_XALIGNAT; + if (s == "xxalignat") return LM_OT_XXALIGNAT; + if (s == "multline") return LM_OT_MULTLINE; + if (s == "gather") return LM_OT_GATHER; + return LM_OT_SIMPLE; + } + + + string normalName(MathInsetTypes t) + { + switch (t) { + case LM_OT_EQUATION: return "equation"; + case LM_OT_EQNARRAY: return "eqnarray"; + case LM_OT_ALIGN: return "align"; + case LM_OT_ALIGNAT: return "alignat"; + case LM_OT_XALIGNAT: return "xalignat"; + case LM_OT_XXALIGNAT: return "xxalignat"; + case LM_OT_MULTLINE: return "multline"; + case LM_OT_GATHER: return "gather"; + case LM_OT_SIMPLE: return "simple"; + default: break; + } + return "unknown"; + } -string star(bool n) +} // end anon namespace + + +MathMatrixInset::MathMatrixInset() + : MathGridInset(1, 1), objtype_(LM_OT_SIMPLE), nonum_(1), label_(1) { - return n ? "" : "*"; + setDefaults(); } -int getCols(short int type) + +MathMatrixInset::MathMatrixInset(MathInsetTypes t) + : MathGridInset(getCols(t), 1), objtype_(t), nonum_(1), label_(1) { - int col; - switch (type) { - case LM_OT_EQNARRAY: - col = 3; - break; + setDefaults(); +} - case LM_OT_ALIGN: - case LM_OT_ALIGNAT: - col = 2; - break; - default: - col = 1; - } - return col; +MathMatrixInset::MathMatrixInset(MathInsetTypes t, col_type cols) + : MathGridInset(cols, 1), objtype_(t), nonum_(1), label_(1) +{ + setDefaults(); } + +MathInset * MathMatrixInset::clone() const +{ + return new MathMatrixInset(*this); } -MathMatrixInset::MathMatrixInset(MathInsetTypes t) - : MathGridInset(getCols(t), 1, "formula", t), nonum_(1), label_(1) -{} +char MathMatrixInset::defaultColAlign(col_type col) +{ + switch (getType()) { + case LM_OT_ALIGN: + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: + return "rl"[col & 1]; + case LM_OT_EQNARRAY: + return "rcl"[col]; + default:; + } + return 'c'; +} -MathMatrixInset::MathMatrixInset() - : MathGridInset(1, 1, "formula", LM_OT_SIMPLE), nonum_(1), label_(1) -{} -MathInset * MathMatrixInset::Clone() const +int MathMatrixInset::defaultColSpace(col_type col) { - return new MathMatrixInset(*this); + switch (getType()) { + case LM_OT_ALIGN: + case LM_OT_ALIGNAT: + return 0; + case LM_OT_XALIGNAT: + return (col & 1) ? 20 : 0; + case LM_OT_XXALIGNAT: + return (col & 1) ? 40 : 0; + default:; + } + return 10; } -void MathMatrixInset::Metrics(MathStyles st) +void MathMatrixInset::metrics(MathMetricsInfo const & mi) const { - size_ = st; - //LyXFont wfont = WhichFont(LM_TC_BF, size()); - //wfont.setLatex(LyXFont::OFF); + mi_ = mi; + mi_.style = (getType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY; // let the cells adjust themselves - MathGridInset::Metrics(st); + MathGridInset::metrics(mi_); if (display()) { ascent_ += 12; @@ -98,78 +155,86 @@ void MathMatrixInset::Metrics(MathStyles st) if (numberedType()) { int l = 0; - for (int row = 0; row < nrows(); ++row) - l = max(l, mathed_string_width(LM_TC_TEXTRM, size(), nicelabel(row))); + for (row_type row = 0; row < nrows(); ++row) + l = std::max(l, mathed_string_width(LM_TC_BF, mi_, nicelabel(row))); if (l) width_ += 30 + l; } + + // make it at least as high as the current font + int asc = 0; + int des = 0; + math_font_max_dim(LM_TC_TEXTRM, mi_, asc, des); + ascent_ = std::max(ascent_, asc); + descent_ = std::max(descent_, des); } -void MathMatrixInset::draw(Painter & pain, int x, int y) +void MathMatrixInset::draw(Painter & pain, int x, int y) const { - xo(x); - yo(y); - MathGridInset::draw(pain, x, y); if (numberedType()) { - LyXFont wfont = WhichFont(LM_TC_BF, size()); -#ifndef NO_LATEX - wfont.setLatex(LyXFont::OFF); -#endif - int xx = x + colinfo_.back().offset_ + colinfo_.back().width_ + 20; - for (int row = 0; row < nrows(); ++row) - pain.text(xx, y + rowinfo_[row].offset_, nicelabel(row), wfont); + int const xx = x + colinfo_.back().offset_ + colinfo_.back().width_ + 20; + for (row_type row = 0; row < nrows(); ++row) { + int const yy = y + rowinfo_[row].offset_; + drawStr(pain, LM_TC_BF, mi_, xx, yy, nicelabel(row)); + } } } -void MathMatrixInset::Write(std::ostream & os, bool fragile) const +void MathMatrixInset::write(MathWriteInfo & os) const { - header_write(os); + header_write(os.os); bool n = numberedType(); - for (int row = 0; row < nrows(); ++row) { - if (row) - os << " \\\\\n"; - for (int col = 0; col < ncols(); ++col) { - if (col) - os << " & "; - cell(index(row, col)).Write(os, fragile); - } + for (row_type row = 0; row < nrows(); ++row) { + for (col_type col = 0; col < ncols(); ++col) + os << cell(index(row, col)) << eocString(col); if (n) { if (!label_[row].empty()) os << "\\label{" << label_[row] << "}"; if (nonum_[row]) os << "\\nonumber "; } + os << eolString(row); } - footer_write(os); + footer_write(os.os); } -string MathMatrixInset::label(int row) const +void MathMatrixInset::writeNormal(std::ostream & os) const +{ + os << "[formula " << normalName(getType()) << " "; + MathGridInset::writeNormal(os); + os << "] "; +} + + + +string MathMatrixInset::label(row_type row) const { return label_[row]; } -void MathMatrixInset::label(int row, string const & label) + +void MathMatrixInset::label(row_type row, string const & label) { label_[row] = label; } -void MathMatrixInset::numbered(int row, bool num) +void MathMatrixInset::numbered(row_type row, bool num) { nonum_[row] = !num; } -bool MathMatrixInset::numbered(int row) const +bool MathMatrixInset::numbered(row_type row) const { return !nonum_[row]; } @@ -178,19 +243,27 @@ bool MathMatrixInset::numbered(int row) const bool MathMatrixInset::ams() const { return true; + + return + objtype_ == LM_OT_ALIGN || + objtype_ == LM_OT_MULTLINE || + objtype_ == LM_OT_GATHER || + objtype_ == LM_OT_ALIGNAT || + objtype_ == LM_OT_XALIGNAT || + objtype_ == LM_OT_XXALIGNAT; } bool MathMatrixInset::display() const { - return GetType() != LM_OT_SIMPLE; + return getType() != LM_OT_SIMPLE; } -vector const MathMatrixInset::getLabelList() const +std::vector const MathMatrixInset::getLabelList() const { std::vector res; - for (int row = 0; row < nrows(); ++row) + for (row_type row = 0; row < nrows(); ++row) if (!label_[row].empty() && nonum_[row] != 1) res.push_back(label_[row]); return res; @@ -199,67 +272,40 @@ vector const MathMatrixInset::getLabelList() const bool MathMatrixInset::numberedType() const { - if (GetType() == LM_OT_SIMPLE) + if (getType() == LM_OT_SIMPLE || getType() == LM_OT_XXALIGNAT) return false; - for (int row = 0; row < nrows(); ++row) + for (row_type row = 0; row < nrows(); ++row) if (!nonum_[row]) return true; return false; } -void MathMatrixInset::Validate(LaTeXFeatures & features) +void MathMatrixInset::validate(LaTeXFeatures & features) const { features.amsstyle = ams(); // Validation is necessary only if not using AMS math. - // To be safe, we will always run mathedValidate. + // To be safe, we will always run mathedvalidate. //if (features.amsstyle) // return; - //Validate1(features); - features.boldsymbol = true; - features.binom = true; -} - -/* -void MathMatrixInset::Validate1(LaTeXFeatures & features) -{ - MathIter it(cell()); - - while (it.OK() && !(features.binom && features.boldsymbol)) { - MathInset * p = it.GetInset(); - if (p) { - p = it.GetActiveInset(); - if (p) { - if (!features.binom && p->GetType() == LM_OT_MACRO && - p->name() == "binom") { - features.binom = true; - } else { - for (int i = 0; i <= p->getMaxArgumentIdx(); ++i) { - p->setArgumentIdx(i); - Validate1(features, p); - } - } - } else { - if (!features.boldsymbol && p->name() == "boldsymbol") - features.boldsymbol = true; - } - } - it.Next(); - } + //features.binom = true; + + MathNestInset::validate(features); } -*/ -void MathMatrixInset::header_write(ostream & os) const +void MathMatrixInset::header_write(std::ostream & os) const { bool n = numberedType(); - switch (GetType()) { + switch (getType()) { case LM_OT_SIMPLE: - os << "\\("; + os << '$'; + if (cell(0).empty()) + os << ' '; break; case LM_OT_EQUATION: @@ -274,24 +320,42 @@ void MathMatrixInset::header_write(ostream & os) const break; case LM_OT_ALIGN: - os << "\\begin{align" << star(n) << "}"; + os << "\\begin{align" << star(n) << "}\n"; break; case LM_OT_ALIGNAT: - os << "\\begin{alignat" << star(n) << "}" - << "{" << ncols()/2 << "}\n"; + os << "\\begin{alignat" << star(n) << "}" << "{" << ncols()/2 << "}\n"; break; + + case LM_OT_XALIGNAT: + os << "\\begin{xalignat" << star(n) << "}" << "{" << ncols()/2 << "}\n"; + break; + + case LM_OT_XXALIGNAT: + os << "\\begin{xxalignat}" << "{" << ncols()/2 << "}\n"; + break; + + case LM_OT_MULTLINE: + os << "\\begin{multline}\n"; + break; + + case LM_OT_GATHER: + os << "\\begin{gather}\n"; + break; + + default: + os << "\\begin{unknown" << star(n) << "}"; } } -void MathMatrixInset::footer_write(ostream & os) const +void MathMatrixInset::footer_write(std::ostream & os) const { bool n = numberedType(); - switch (GetType()) { + switch (getType()) { case LM_OT_SIMPLE: - os << "\\)"; + os << '$'; break; case LM_OT_EQUATION: @@ -302,27 +366,47 @@ void MathMatrixInset::footer_write(ostream & os) const break; case LM_OT_EQNARRAY: - os << "\\end{eqnarray" << star(n) << "}\n"; + os << "\n\\end{eqnarray" << star(n) << "}\n"; break; case LM_OT_ALIGN: - os << "\\end{align" << star(n) << "}\n"; + os << "\n\\end{align" << star(n) << "}\n"; break; case LM_OT_ALIGNAT: - os << "\\end{alignat" << star(n) << "}\n"; + os << "\n\\end{alignat" << star(n) << "}\n"; + break; + + case LM_OT_XALIGNAT: + os << "\n\\end{xalignat" << star(n) << "}\n"; break; + + case LM_OT_XXALIGNAT: + os << "\n\\end{xxalignat}\n"; + break; + + case LM_OT_MULTLINE: + os << "\n\\end{multline}\n"; + break; + + case LM_OT_GATHER: + os << "\n\\end{gather}\n"; + break; + + default: + os << "\\end{unknown" << star(n) << "}"; } } -void MathMatrixInset::addRow(int row) +void MathMatrixInset::addRow(row_type row) { nonum_.insert(nonum_.begin() + row + 1, !numberedType()); label_.insert(label_.begin() + row + 1, string()); MathGridInset::addRow(row); } + void MathMatrixInset::appendRow() { nonum_.push_back(!numberedType()); @@ -331,16 +415,17 @@ void MathMatrixInset::appendRow() } -void MathMatrixInset::delRow(int row) +void MathMatrixInset::delRow(row_type row) { MathGridInset::delRow(row); nonum_.erase(nonum_.begin() + row); label_.erase(label_.begin() + row); } -void MathMatrixInset::addCol(int col) + +void MathMatrixInset::addCol(col_type col) { - switch (GetType()) { + switch (getType()) { case LM_OT_EQUATION: mutate(LM_OT_EQNARRAY); break; @@ -351,11 +436,15 @@ void MathMatrixInset::addCol(int col) break; case LM_OT_ALIGN: + mutate(LM_OT_ALIGNAT); + addCol(col); + break; + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: MathGridInset::addCol(col); - halign(col, 'l'); - MathGridInset::addCol(col); - halign(col, 'r'); + MathGridInset::addCol(col + 1); break; default: @@ -363,38 +452,23 @@ void MathMatrixInset::addCol(int col) } } -void MathMatrixInset::delCol(int col) + +void MathMatrixInset::delCol(col_type col) { - switch (GetType()) { - case LM_OT_ALIGN: + switch (getType()) { + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: + MathGridInset::delCol(col + 1); MathGridInset::delCol(col); break; - default: break; } } -void MathMatrixInset::breakLine() -{ - if (GetType() == LM_OT_SIMPLE || GetType() == LM_OT_EQUATION) - mutate(LM_OT_EQNARRAY); - addRow(nrows() - 1); -} - -void MathMatrixInset::splitCell(int idx) -{ - if (idx == nargs() - 1) { - lyxerr << "can't split last cell\n"; - return; - } - - lyxerr << "unimplemented\n"; -} - - -string MathMatrixInset::nicelabel(int row) const +string MathMatrixInset::nicelabel(row_type row) const { if (nonum_[row]) return string(); @@ -404,77 +478,96 @@ string MathMatrixInset::nicelabel(int row) const } -namespace { - short typecode(string const & s) - { - if (s == "equation") - return LM_OT_EQUATION; - if (s == "display") - return LM_OT_EQUATION; - if (s == "eqnarray") - return LM_OT_EQNARRAY; - if (s == "align") - return LM_OT_ALIGN; - if (s == "xalign") - return LM_OT_XALIGN; - if (s == "xxalign") - return LM_OT_XXALIGN; - if (s == "multline") - return LM_OT_MULTLINE; - return LM_OT_SIMPLE; - } -} - void MathMatrixInset::mutate(string const & newtype) { if (newtype == "dump") { dump(); return; } - //lyxerr << "mutating from '" << GetType() << "' to '" << newtype << "'\n"; + //lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n"; mutate(typecode(newtype)); } + void MathMatrixInset::glueall() { MathArray ar; - for (int i = 0; i < nargs(); ++i) + for (idx_type i = 0; i < nargs(); ++i) ar.push_back(cell(i)); *this = MathMatrixInset(LM_OT_SIMPLE); cell(0) = ar; } -void MathMatrixInset::mutate(short newtype) + +MathInsetTypes MathMatrixInset::getType() const +{ + return objtype_; +} + + +void MathMatrixInset::setType(MathInsetTypes t) +{ + objtype_ = t; + setDefaults(); +} + + + +void MathMatrixInset::mutate(MathInsetTypes newtype) { - //lyxerr << "mutating from '" << GetType() << "' to '" << newtype << "'\n"; + //lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n"; - if (newtype == GetType()) + if (newtype == getType()) return; - switch (GetType()) { + switch (getType()) { case LM_OT_SIMPLE: - SetType(LM_OT_EQUATION); - numbered(false); + setType(LM_OT_EQUATION); + numbered(0, false); mutate(newtype); break; case LM_OT_EQUATION: switch (newtype) { case LM_OT_SIMPLE: - SetType(LM_OT_SIMPLE); + setType(LM_OT_SIMPLE); break; - case LM_OT_ALIGN: + case LM_OT_ALIGN: + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: { + MathGridInset::addCol(1); - halign("rl"); - SetType(LM_OT_ALIGN); + + // split it "nicely" + pos_type pos = firstRelOp(cell(0)); + cell(1) = cell(0); + cell(0).erase(pos, cell(0).size()); + cell(1).erase(0, pos); + setType(LM_OT_ALIGN); + mutate(newtype); break; + } + case LM_OT_EQNARRAY: default: MathGridInset::addCol(1); MathGridInset::addCol(1); - halign("rcl"); - SetType(LM_OT_EQNARRAY); + + // split it "nicely" on the firest relop + pos_type pos = firstRelOp(cell(0)); + cell(1) = cell(0); + cell(0).erase(pos, cell(0).size()); + cell(1).erase(0, pos); + + if (cell(1).size()) { + cell(2) = cell(1); + cell(1).erase(1, cell(1).size()); + cell(2).erase(0); + } + + setType(LM_OT_EQNARRAY); mutate(newtype); break; } @@ -483,30 +576,45 @@ void MathMatrixInset::mutate(short newtype) case LM_OT_EQNARRAY: switch (newtype) { case LM_OT_SIMPLE: + case LM_OT_EQUATION: { + // set correct (no)numbering + bool allnonum = true; + for (row_type row = 0; row < nrows(); ++row) { + if (!nonum_[row]) + allnonum = false; + } + + // set first non-empty label + string label; + for (row_type row = 0; row < nrows(); ++row) { + if (!label_[row].empty()) { + label = label_[row]; + break; + } + } + glueall(); - break; - case LM_OT_EQUATION: - if (nrows() == 1) { - MathGridInset::delCol(2); - MathGridInset::delCol(1); - SetType(LM_OT_EQUATION); - mutate(newtype); - } else - lyxerr << "need to delete rows first\n"; + nonum_[0] = allnonum; + label_[0] = label; + mutate(newtype); break; + } case LM_OT_ALIGN: - default: - for (int row = 0; row < nrows(); ++row) { - int c = 3 * row + 1; + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: + default: { + for (row_type row = 0; row < nrows(); ++row) { + idx_type c = 3 * row + 1; cell(c).push_back(cell(c + 1)); } MathGridInset::delCol(2); - SetType(LM_OT_ALIGN); - halign("rl"); + setType(LM_OT_ALIGN); mutate(newtype); break; + } } break; @@ -516,20 +624,47 @@ void MathMatrixInset::mutate(short newtype) case LM_OT_EQUATION: case LM_OT_EQNARRAY: MathGridInset::addCol(1); - SetType(LM_OT_EQNARRAY); - halign("lrl"); + setType(LM_OT_EQNARRAY); mutate(newtype); break; + case LM_OT_ALIGNAT: + case LM_OT_XALIGNAT: + case LM_OT_XXALIGNAT: + setType(newtype); + break; + default: - lyxerr << "mutation from '" << GetType() + lyxerr << "mutation from '" << getType() << "' to '" << newtype << "' not implemented\n"; break; } break; + case LM_OT_MULTLINE: + switch (newtype) { + case LM_OT_GATHER: + setType(LM_OT_GATHER); + break; + default: + lyxerr << "mutation from '" << getType() + << "' to '" << newtype << "' not implemented\n"; + break; + } + + case LM_OT_GATHER: + switch (newtype) { + case LM_OT_MULTLINE: + setType(LM_OT_MULTLINE); + break; + default: + lyxerr << "mutation from '" << getType() + << "' to '" << newtype << "' not implemented\n"; + break; + } + default: - lyxerr << "mutation from '" << GetType() + lyxerr << "mutation from '" << getType() << "' to '" << newtype << "' not implemented\n"; } }