diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index 17977d84b4..081ea86918 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -43,6 +43,8 @@ libmathed_la_SOURCES = \ math_diminset.h \ math_dotsinset.C \ math_dotsinset.h \ + math_exfuncinset.C \ + math_exfuncinset.h \ math_factory.C \ math_factory.h \ math_fracinset.C \ diff --git a/src/mathed/formula.C b/src/mathed/formula.C index fcd4fec992..a3cb00613f 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -24,6 +24,8 @@ #include "math_cursor.h" #include "math_parser.h" #include "math_charinset.h" +#include "math_arrayinset.h" +#include "math_deliminset.h" #include "lyx_main.h" #include "BufferView.h" #include "gettext.h" @@ -63,7 +65,7 @@ namespace { } - string pipeThroughMaple(string const & extra, MathArray const & ar) + MathArray pipeThroughMaple(string const & extra, MathArray const & ar) { string header = "readlib(latex):\n" @@ -101,12 +103,35 @@ namespace { } string full = "latex(" + extra + '(' + expr + "));"; - string res = captureOutput("maple -q", header + full + trailer); + string out = captureOutput("maple -q", header + full + trailer); // change \_ into _ + + // + MathArray res; + mathed_parse_cell(res, out); return res; } + + MathArray pipeThroughOctave(string const &, MathArray const & ar) + { + string out = captureOutput("octave -q", ar.octavize()); + if (out.size() > 6) // remove 'ans = ' + out = out.substr(6); + + // parse output as matrix or single number + MathAtom at(new MathArrayInset(out)); + MathArrayInset const * mat = at.nucleus()->asArrayInset(); + MathArray res; + if (mat->ncols() == 1 && mat->nrows() == 1) + res.push_back(mat->cell(0)); + else { + res.push_back(MathAtom(new MathDelimInset("(", ")"))); + res.back()->cell(0).push_back(at); + } + return res; + } MathArray pipeThroughExtern(string const & arg, MathArray const & ar) @@ -118,40 +143,30 @@ namespace { if (extra.empty()) extra = "noextra"; - MathArray res; + if (lang == "octave") + return pipeThroughOctave(extra, ar); - if (lang == "octave") { + if (lang == "maple") + return pipeThroughMaple(extra, ar); - string out = captureOutput("octave -q", ar.octavize()); - if (out.size() > 6) - out = out.substr(6); - mathed_parse_cell(res, out); + // create normalized expression + ostringstream os; + os << "[" << extra << ' '; + ar.writeNormal(os); + os << "]"; + string data = os.str().c_str(); - } else if (lang == "maple") { - - mathed_parse_cell(res, pipeThroughMaple(extra, ar)); - - } else { - - // create normalized expression - ostringstream os; - os << "[" << extra << ' '; - ar.writeNormal(os); - os << "]"; - string data = os.str().c_str(); - - // search external script - string file = LibFileSearch("mathed", "extern_" + lang); - if (file.empty()) { - lyxerr << "converter to '" << lang << "' not found\n"; - return MathArray(); - } - - // run external sript - string out = captureOutput(file, data); - mathed_parse_cell(res, out); + // search external script + string file = LibFileSearch("mathed", "extern_" + lang); + if (file.empty()) { + lyxerr << "converter to '" << lang << "' not found\n"; + return MathArray(); } - + + // run external sript + string out = captureOutput(file, data); + MathArray res; + mathed_parse_cell(res, out); return res; } @@ -425,6 +440,7 @@ void InsetFormula::handleExtern(const string & arg) mathcursor->selGet(ar); lyxerr << "use selection: " << ar << "\n"; } else { + mathcursor->end(); mathcursor->stripFromLastEqualSign(); ar = mathcursor->cursor().cell(); mathcursor->insert(MathAtom(new MathCharInset('=', LM_TC_VAR))); diff --git a/src/mathed/math_arrayinset.C b/src/mathed/math_arrayinset.C index 4cd48211ec..b2a3fbee52 100644 --- a/src/mathed/math_arrayinset.C +++ b/src/mathed/math_arrayinset.C @@ -3,7 +3,9 @@ #endif #include "math_arrayinset.h" +#include "math_parser.h" #include "support/LOstream.h" +#include "Lsstream.h" MathArrayInset::MathArrayInset(int m, int n) @@ -16,6 +18,31 @@ MathArrayInset::MathArrayInset(int m, int n, char valign, string const & halign) {} +MathArrayInset::MathArrayInset(string const & str) + : MathGridInset(1, 1) +{ + vector< vector > dat; + istringstream is(str); + while (is) { + string line; + getline(is, line); + istringstream ls(line); + typedef std::istream_iterator iter; + vector v = vector(iter(ls), iter()); + if (v.size()) + dat.push_back(v); + } + + for (row_type row = 1; row < dat.size(); ++row) + addRow(0); + for (col_type col = 1; col < dat[0].size(); ++col) + addCol(0); + for (row_type row = 0; row < dat.size(); ++row) + for (col_type col = 0; col < dat[row].size(); ++col) + mathed_parse_cell(cell(index(row, col)), dat[row][col]); +} + + MathInset * MathArrayInset::clone() const { return new MathArrayInset(*this); diff --git a/src/mathed/math_arrayinset.h b/src/mathed/math_arrayinset.h index e80acf6d0a..13f2ee5736 100644 --- a/src/mathed/math_arrayinset.h +++ b/src/mathed/math_arrayinset.h @@ -15,6 +15,8 @@ public: MathArrayInset(int m, int n); /// MathArrayInset(int m, int n, char valign, string const & halign); + /// convienience constructor from whitespace/newline seperated data + MathArrayInset(string const & str); /// MathInset * clone() const; /// diff --git a/src/mathed/math_exfuncinset.C b/src/mathed/math_exfuncinset.C new file mode 100644 index 0000000000..162792e320 --- /dev/null +++ b/src/mathed/math_exfuncinset.C @@ -0,0 +1,55 @@ +#include "math_exfuncinset.h" +#include "support.h" +#include "debug.h" +#include "support/LOstream.h" + + +using std::ostream; + + +MathExFuncInset::MathExFuncInset(string const & name) + : MathNestInset(1), name_(name) +{} + + +MathInset * MathExFuncInset::clone() const +{ + return new MathExFuncInset(*this); +} + + +void MathExFuncInset::write(MathWriteInfo & os) const +{ + os << '\\' << name_ << '{'; + cell(0).write(os); + os << '}'; +} + + +void MathExFuncInset::writeNormal(ostream & os) const +{ + os << "[" << name_ << ' '; + cell(0).writeNormal(os); + os << "] "; +} + + +void MathExFuncInset::metrics(MathMetricsInfo const & mi) const +{ + mi_ = mi; + mathed_string_dim(LM_TC_TEXTRM, mi_, name_, ascent_, descent_, width_); + lyxerr << "should not happen\n"; +} + + +void MathExFuncInset::draw(Painter & pain, int x, int y) const +{ + drawStr(pain, LM_TC_TEXTRM, mi_, x, y, name_); + lyxerr << "should not happen\n"; +} + + +string MathExFuncInset::octavize() const +{ + return name_ + '(' + cell(0).octavize() + ')'; +} diff --git a/src/mathed/math_exfuncinset.h b/src/mathed/math_exfuncinset.h new file mode 100644 index 0000000000..3f434f6921 --- /dev/null +++ b/src/mathed/math_exfuncinset.h @@ -0,0 +1,33 @@ +// -*- C++ -*- +#ifndef MATH_EXFUNCINSET_H +#define MATH_EXFUNCINSET_H + +#include "math_nestinset.h" + +// f(x) in one block (as opposed to 'f','(','x',')' or 'f','x') +// for interfacing external programs + +class MathExFuncInset : public MathNestInset { +public: + /// + explicit MathExFuncInset(string const & name); + /// + MathInset * clone() const; + /// + void write(MathWriteInfo & os) const; + /// + void writeNormal(std::ostream &) const; + /// + void metrics(MathMetricsInfo const & st) const; + /// + void draw(Painter &, int x, int y) const; + /// + string octavize() const; + +private: + /// + string const name_; + /// + mutable MathMetricsInfo mi_; +}; +#endif diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index 10f0082e76..a23ea6e197 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -26,7 +26,7 @@ MathAtom createMathInset(latexkeys const * l) { switch (l->token) { case LM_TK_FUNCLIM: - return MathAtom(new MathFuncLimInset(l)); + return MathAtom(new MathFuncLimInset(l->name)); case LM_TK_SPECIAL: return MathAtom(new MathSpecialCharInset(l->id)); case LM_TK_SYM: diff --git a/src/mathed/math_funcliminset.C b/src/mathed/math_funcliminset.C index 5af941b386..472b6e0807 100644 --- a/src/mathed/math_funcliminset.C +++ b/src/mathed/math_funcliminset.C @@ -1,13 +1,12 @@ #include "math_funcliminset.h" -#include "mathed/math_parser.h" -#include "mathed/support.h" +#include "support.h" #include "support/LOstream.h" using std::ostream; -MathFuncLimInset::MathFuncLimInset(const latexkeys * l) - : sym_(l) +MathFuncLimInset::MathFuncLimInset(string const & name) + : name_(name) {} @@ -25,24 +24,24 @@ bool MathFuncLimInset::isScriptable() const void MathFuncLimInset::write(MathWriteInfo & os) const { - os << '\\' << sym_->name << ' '; + os << '\\' << name_ << ' '; } void MathFuncLimInset::writeNormal(ostream & os) const { - os << "[" << sym_->name << "] "; + os << "[" << name_ << "] "; } void MathFuncLimInset::metrics(MathMetricsInfo const & mi) const { mi_ = mi; - mathed_string_dim(LM_TC_TEXTRM, mi_, sym_->name, ascent_, descent_, width_); + mathed_string_dim(LM_TC_TEXTRM, mi_, name_, ascent_, descent_, width_); } void MathFuncLimInset::draw(Painter & pain, int x, int y) const { - drawStr(pain, LM_TC_TEXTRM, mi_, x, y, sym_->name); + drawStr(pain, LM_TC_TEXTRM, mi_, x, y, name_); } diff --git a/src/mathed/math_funcliminset.h b/src/mathed/math_funcliminset.h index 0d4e8dcc85..86736136ac 100644 --- a/src/mathed/math_funcliminset.h +++ b/src/mathed/math_funcliminset.h @@ -4,15 +4,13 @@ #include "math_diminset.h" -struct latexkeys; - // "normal" symbols that don't take limits and don't grow in displayed // formulae class MathFuncLimInset : public MathDimInset { public: /// - explicit MathFuncLimInset(latexkeys const *); + explicit MathFuncLimInset(string const & name); /// MathInset * clone() const; /// @@ -28,7 +26,7 @@ public: private: /// - latexkeys const * sym_; + string const name_; /// mutable MathMetricsInfo mi_; }; diff --git a/src/mathed/math_rootinset.C b/src/mathed/math_rootinset.C index d7dbad4943..cc143bef37 100644 --- a/src/mathed/math_rootinset.C +++ b/src/mathed/math_rootinset.C @@ -92,3 +92,9 @@ bool MathRootInset::idxDown(int & idx, int & pos) const pos = 0; return true; } + + +string MathRootInset::octavize() const +{ + return "root(" + cell(1).octavize() + ',' + cell(0).octavize() + ')'; +} diff --git a/src/mathed/math_rootinset.h b/src/mathed/math_rootinset.h index 95174881c7..e85e074c2e 100644 --- a/src/mathed/math_rootinset.h +++ b/src/mathed/math_rootinset.h @@ -43,6 +43,8 @@ public: bool idxUp(int & idx, int & pos) const; /// bool idxDown(int & idx, int & pos) const; + /// + string octavize() const; }; #endif