diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index 692c1a900d..f8988ad326 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -26,6 +26,8 @@ libmathed_la_SOURCES = \ math_boxinset.h \ math_binaryopinset.C \ math_binaryopinset.h \ + math_casesinset.C \ + math_casesinset.h \ math_charinset.C \ math_charinset.h \ math_cursor.C \ diff --git a/src/mathed/formula.C b/src/mathed/formula.C index af74148b79..39b119586b 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -207,15 +207,9 @@ namespace { } - MathArray pipeThroughExtern(string const & arg, MathArray const & ar) + MathArray pipeThroughExtern(string const & lang, string const & extra, + MathArray const & ar) { - string lang; - string extra; - istringstream iss(arg.c_str()); - iss >> lang >> extra; - if (extra.empty()) - extra = "noextra"; - if (lang == "octave") return pipeThroughOctave(extra, ar); @@ -507,27 +501,44 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, } +bool needEqnArray(string const & extra) +{ + return extra == "dsolve"; +} + + void InsetFormula::handleExtern(const string & arg) { // where are we? if (!mathcursor) return; + string lang; + string extra; + istringstream iss(arg.c_str()); + iss >> lang >> extra; + if (extra.empty()) + extra = "noextra"; + bool selected = mathcursor->selection(); MathArray ar; - if (selected) { + if (needEqnArray(extra)) { + mathcursor->last(); + mathcursor->readLine(ar); + mathcursor->breakLine(); + } else if (selected) { mathcursor->selGet(ar); //lyxerr << "use selection: " << ar << "\n"; } else { - mathcursor->end(); + mathcursor->last(); mathcursor->stripFromLastEqualSign(); ar = mathcursor->cursor().cell(); mathcursor->insert(MathAtom(new MathCharInset('=', LM_TC_VAR))); //lyxerr << "use whole cell: " << ar << "\n"; } - mathcursor->insert(pipeThroughExtern(arg, ar)); + mathcursor->insert(pipeThroughExtern(lang, extra, ar)); } diff --git a/src/mathed/math_casesinset.C b/src/mathed/math_casesinset.C new file mode 100644 index 0000000000..183e955060 --- /dev/null +++ b/src/mathed/math_casesinset.C @@ -0,0 +1,62 @@ +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "math_casesinset.h" +#include "math_parser.h" +#include "math_mathmlstream.h" +#include "math_support.h" +#include "Painter.h" + + +MathCasesInset::MathCasesInset(row_type n) + : MathGridInset(2, n, 'c', "ll") +{} + + +MathInset * MathCasesInset::clone() const +{ + return new MathCasesInset(*this); +} + + +void MathCasesInset::metrics(MathMetricsInfo const & mi) const +{ + MathGridInset::metrics(mi); + width_ += 8; +} + + +void MathCasesInset::draw(Painter & pain, int x, int y) const +{ + mathed_draw_deco(pain, x + 1, y - ascent(), 6, height(), "{"); + MathGridInset::draw(pain, x + 8, y); +} + + +void MathCasesInset::write(WriteStream & os) const +{ + if (os.fragile) + os << "\\protect"; + os << "\\begin{cases}"; + MathGridInset::write(os); + if (os.fragile) + os << "\\protect"; + os << "\\end{cases}\n"; +} + + +void MathCasesInset::normalize(NormalStream & os) const +{ + os << "[cases "; + MathGridInset::normalize(os); + os << "]"; +} + + +void MathCasesInset::maplize(MapleStream & os) const +{ + os << "cases("; + MathGridInset::maplize(os); + os << ")"; +} diff --git a/src/mathed/math_casesinset.h b/src/mathed/math_casesinset.h new file mode 100644 index 0000000000..ca1ce4b431 --- /dev/null +++ b/src/mathed/math_casesinset.h @@ -0,0 +1,31 @@ +// -*- C++ -*- +#ifndef MATH_CASESINSET_H +#define MATH_CASESINSET_H + +#include "math_gridinset.h" + +#ifdef __GNUG__ +#pragma interface +#endif + + +class MathCasesInset : public MathGridInset { +public: + /// + explicit MathCasesInset(row_type rows = 1u); + /// + MathInset * clone() const; + /// + void metrics(MathMetricsInfo const & st) const; + /// + void draw(Painter & pain, int x, int y) const; + + /// + void normalize(NormalStream &) const; + /// + void maplize(MapleStream &) const; + /// + void write(WriteStream & os) const; +}; + +#endif diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index d44609d64c..51230e0066 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -31,6 +31,7 @@ #include "math_support.h" #include "formulabase.h" #include "math_cursor.h" +#include "math_casesinset.h" #include "math_factory.h" #include "math_arrayinset.h" #include "math_braceinset.h" @@ -1114,6 +1115,14 @@ void MathCursor::breakLine() } +void MathCursor::readLine(MathArray & ar) const +{ + idx_type base = row() * par()->ncols(); + for (idx_type off = 0; off < par()->ncols(); ++off) + ar.push_back(par()->cell(base + off)); +} + + char MathCursor::valign() const { idx_type idx; @@ -1277,7 +1286,16 @@ void MathCursor::interpret(string const & s) //owner_->getIntl()->getTrans().TranslateAndInsert(s[0], lt); //lyxerr << "trans: '" << s[0] << "' int: " << int(s[0]) << endl; - if (s.size() > 7 && s.substr(0, 7) == "matrix ") { + if (s.size() >= 5 && s.substr(0, 5) == "cases") { + unsigned int n = 1; + istringstream is(s.substr(6).c_str()); + is >> n; + n = std::max(1u, n); + niceInsert(MathAtom(new MathCasesInset(n))); + return; + } + + if (s.size() >= 6 && s.substr(0, 6) == "matrix") { unsigned int m = 1; unsigned int n = 1; string v_align; diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index e0f9649a42..cd110890ed 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -178,6 +178,8 @@ public: void splitCell(); /// Splits line and insert new row of cell void breakLine(); + /// read contents of line into an array + void readLine(MathArray & ar) const; /// MathTextCodes getLastCode() const; /// @@ -191,6 +193,8 @@ public: /// char halign() const; /// + col_type ncols() const; + /// col_type col() const; /// row_type row() const; diff --git a/src/mathed/math_gridinset.C b/src/mathed/math_gridinset.C index f6eaa1144b..fea6255d2d 100644 --- a/src/mathed/math_gridinset.C +++ b/src/mathed/math_gridinset.C @@ -57,7 +57,7 @@ MathGridInset::MathGridInset(col_type m, row_type n) } -MathGridInset::MathGridInset(int m, int n, char v, string const & h) +MathGridInset::MathGridInset(col_type m, row_type n, char v, string const & h) : MathNestInset(m * n), rowinfo_(n), colinfo_(m), v_align_(v) { setDefaults(); diff --git a/src/mathed/math_gridinset.h b/src/mathed/math_gridinset.h index 9567068798..968ed13254 100644 --- a/src/mathed/math_gridinset.h +++ b/src/mathed/math_gridinset.h @@ -62,7 +62,7 @@ public: /// Note: columns first! MathGridInset(col_type m, row_type n); /// - MathGridInset(int m, int n, char valign, string const & halign); + MathGridInset(col_type m, row_type n, char valign, string const & halign); /// void metrics(MathMetricsInfo const & st) const; /// diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index b9bc7e43e3..c55c0b4ad1 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -56,6 +56,7 @@ point to write some macros: #include "math_inset.h" #include "math_arrayinset.h" #include "math_braceinset.h" +#include "math_casesinset.h" #include "math_charinset.h" #include "math_deliminset.h" #include "math_factory.h" @@ -667,6 +668,7 @@ bool Parser::parse_normal(MathAtom & matrix) } lyxerr[Debug::MATHED] << "1: unknown math environment: " << name << "\n"; + lyxerr << "1: unknown math environment: " << name << "\n"; return false; } @@ -862,8 +864,11 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) } else if (name == "split") { array.push_back(MathAtom(new MathSplitInset(1))); parse_lines(array.back(), false, false); + } else if (name == "cases") { + array.push_back(MathAtom(new MathCasesInset)); + parse_lines(array.back(), false, false); } else - lyxerr[Debug::MATHED] << "unknow math inset begin '" << name << "'\n"; + lyxerr << "unknow math inset begin '" << name << "'\n"; } else if (t.cs() == "kern") {