From c80a4abde986318a05931e034f3e666cd3b33659 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Tue, 13 Nov 2001 18:33:48 +0000 Subject: [PATCH] improved function function argument detection for math-extern: \sum_i{i=1}^n i^2 is now parsed properly. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3025 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/math_exfuncinset.C | 6 +- src/mathed/math_exfuncinset.h | 2 +- src/mathed/math_exintinset.C | 30 ++---- src/mathed/math_exintinset.h | 15 +-- src/mathed/math_extern.C | 197 ++++++++++++++++++++++++++-------- src/mathed/math_fracinset.C | 6 ++ src/mathed/math_fracinset.h | 2 + src/mathed/math_inset.h | 2 + 8 files changed, 175 insertions(+), 85 deletions(-) diff --git a/src/mathed/math_exfuncinset.C b/src/mathed/math_exfuncinset.C index 7882daa993..1cf2588e09 100644 --- a/src/mathed/math_exfuncinset.C +++ b/src/mathed/math_exfuncinset.C @@ -6,11 +6,9 @@ using std::ostream; -MathExFuncInset::MathExFuncInset(string const & name, MathArray const & arg) +MathExFuncInset::MathExFuncInset(string const & name) : MathNestInset(1), name_(name) -{ - cell(0) = arg; -} +{} MathInset * MathExFuncInset::clone() const diff --git a/src/mathed/math_exfuncinset.h b/src/mathed/math_exfuncinset.h index d7832cd28d..a0887a39c3 100644 --- a/src/mathed/math_exfuncinset.h +++ b/src/mathed/math_exfuncinset.h @@ -10,7 +10,7 @@ class MathExFuncInset : public MathNestInset { public: /// - MathExFuncInset(string const & name, MathArray const & arg); + explicit MathExFuncInset(string const & name); /// MathInset * clone() const; /// diff --git a/src/mathed/math_exintinset.C b/src/mathed/math_exintinset.C index b49f2246c5..4fce6e180d 100644 --- a/src/mathed/math_exintinset.C +++ b/src/mathed/math_exintinset.C @@ -6,7 +6,7 @@ MathExIntInset::MathExIntInset(string const & name) - : symbol_(name) + : MathNestInset(2), symbol_(name) {} @@ -16,18 +16,6 @@ MathInset * MathExIntInset::clone() const } -void MathExIntInset::index(MathArray const & ar) -{ - index_ = ar; -} - - -void MathExIntInset::core(MathArray const & ar) -{ - core_ = ar; -} - - void MathExIntInset::scripts(MathAtom const & at) { scripts_ = at; @@ -55,12 +43,10 @@ bool MathExIntInset::hasScripts() const void MathExIntInset::normalize(NormalStream & os) const { - os << '[' << symbol_.c_str() << ' '; + os << '[' << symbol_.c_str() << ' ' << cell(0) << ' ' << cell(1); if (hasScripts()) os << scripts_.nucleus(); - else - os << "{}"; - os << ' ' << core_ << ' ' << index_ << ']'; + os << ']'; } @@ -79,11 +65,11 @@ void MathExIntInset::draw(Painter &, int, int) const void MathExIntInset::maplize(MapleStream & os) const { os << symbol_.c_str() << '('; - if (core_.size()) - os << core_; + if (cell(0).size()) + os << cell(0); else os << '1'; - os << ',' << index_; + os << ',' << cell(1); if (hasScripts()) { MathScriptInset * p = scripts_->asScriptInset(); os << '=' << p->down().data_ << ".." << p->up().data_; @@ -100,9 +86,9 @@ void MathExIntInset::mathmlize(MathMLStream & os) const else sym->mathmlize(os); delete sym; - os << core_ << "" + os << cell(0) << "" << MTag("mrow") << "" - << index_ << ETag("mrow"); + << cell(1) << ETag("mrow"); } diff --git a/src/mathed/math_exintinset.h b/src/mathed/math_exintinset.h index 5e7f51e057..3767aaaeb5 100644 --- a/src/mathed/math_exintinset.h +++ b/src/mathed/math_exintinset.h @@ -2,22 +2,19 @@ #ifndef MATH_EXINTINSET_H #define MATH_EXINTINSET_H -// /\int_l^u f(x) dxin one block (as opposed to 'f','(','x',')' or 'f','x') -// for interfacing external programs +// \int_l^u f(x) dx in one block (as opposed to 'f','(','x',')' or 'f','x') +// or \sum, \prod... for interfacing external programs #include "math_scriptinset.h" -class MathExIntInset : public MathInset { +// cell(0) is stuff before the 'd', cell(1) the stuff after +class MathExIntInset : public MathNestInset { public: /// explicit MathExIntInset(string const & name_); /// MathInset * clone() const; /// - void index(MathArray const &); - /// - void core(MathArray const &); - /// void scripts(MathAtom const &); /// MathAtom & scripts(); @@ -44,10 +41,6 @@ private: string symbol_; /// MathAtom scripts_; - /// - MathArray core_; - /// - MathArray index_; }; #endif diff --git a/src/mathed/math_extern.C b/src/mathed/math_extern.C index a34b045612..4846bf146f 100644 --- a/src/mathed/math_extern.C +++ b/src/mathed/math_extern.C @@ -7,9 +7,11 @@ #include "math_charinset.h" #include "math_deliminset.h" +#include "math_diffinset.h" #include "math_exfuncinset.h" #include "math_exintinset.h" #include "math_funcinset.h" +#include "math_fracinset.h" #include "math_matrixinset.h" #include "math_mathmlstream.h" #include "math_scriptinset.h" @@ -26,6 +28,60 @@ std::ostream & operator<<(std::ostream & os, MathArray const & ar) } +// define a function for tests +typedef bool TestItemFunc(MathInset *); + +// define a function for replacing subexpressions +typedef MathInset * ReplaceArgumentFunc(const MathArray & ar); + + + +// try to extract an "argument" to some function. +// returns position behind the argument +MathArray::iterator extractArgument(MathArray & ar, + MathArray::iterator pos, MathArray::iterator last, string const & = "") +{ + // nothing to get here + if (pos == last) + return pos; + + // something deliminited _is_ an argument + if ((*pos)->asDelimInset()) { + ar.push_back(*pos); + return pos + 1; + } + + // always take the first thing, no matter what it is + ar.push_back(*pos); + + // go ahead if possible + ++pos; + if (pos == last) + return pos; + + // if the next item is a subscript, it most certainly belongs to the + // thing we have + if ((*pos)->asScriptInset()) { + ar.push_back(*pos); + // go ahead if possible + ++pos; + if (pos == last) + return pos; + } + + // but it might be more than that. + // FIXME: not implemented + //for (MathArray::iterator it = pos + 1; it != last; ++it) { + // // always take the first thing, no matter + // if (it == pos) { + // ar.push_back(*it); + // continue; + // } + //} + return pos; +} + + MathScriptInset const * asScript(MathArray::const_iterator it) { if (it->nucleus()->asScriptInset()) @@ -94,9 +150,10 @@ void extractMatrices(MathArray & ar) if (!arr || !arr->asArrayInset()) continue; *it = MathAtom(new MathMatrixInset(*(arr->asArrayInset()))); - lyxerr << "\nMatrices to: " << ar << "\n"; } -} + lyxerr << "\nMatrices to: " << ar << "\n"; +} + // convert this inset somehow to a string string extractString(MathInset * p) @@ -109,11 +166,10 @@ string extractString(MathInset * p) } -// define a function for tests -typedef bool TestItemFunc(MathInset *); - -// define a function for replacing subexpressions -typedef MathInset * ReplaceArgumentFunc(const MathArray & ar); +bool stringTest(MathInset * p, const string & str) +{ + return extractString(p) == str; +} // search end of nested sequence @@ -173,13 +229,13 @@ void replaceNested( bool openParanTest(MathInset * p) { - return extractString(p) == "("; + return stringTest(p, "("); } bool closeParanTest(MathInset * p) { - return extractString(p) == ")"; + return stringTest(p, ")"); } @@ -192,7 +248,8 @@ MathInset * delimReplacement(const MathArray & ar) // replace '('...')' sequences by a real MathDelimInset -void extractDelims(MathArray & ar) { +void extractDelims(MathArray & ar) +{ lyxerr << "\nDelims from: " << ar << "\n"; replaceNested(ar, openParanTest, closeParanTest, delimReplacement); lyxerr << "\nDelims to: " << ar << "\n"; @@ -234,21 +291,18 @@ void extractFunctions(MathArray & ar) if (jt == ar.end()) continue; } + + // create a proper inset as replacement + MathExFuncInset * p = new MathExFuncInset(func->name()); - // jt points now to the "argument". Since we had run "extractDelims" - // before, this could be a single argument only. Get hold of this. - MathArray arg; - MathDelimInset * del = (*jt)->asDelimInset(); - if (del && del->isParanthesis()) - arg = del->cell(0); - else - arg.push_back(*jt); + // jt points to the "argument". Get hold of this. + MathArray::iterator st = extractArgument(p->cell(0), jt, ar.end()); // replace the function name by a real function inset - (*it).reset(new MathExFuncInset(func->name(), arg)); + (*it).reset(p); // remove the source of the argument from the array - ar.erase(jt); + ar.erase(jt, st); lyxerr << "\nFunctions to: " << ar << "\n"; } } @@ -258,15 +312,21 @@ void extractFunctions(MathArray & ar) // search integrals // +bool symbolTest(MathInset * p, string const & name) +{ + return p->asSymbolInset() && p->asSymbolInset()->name() == name; +} + + bool intSymbolTest(MathInset * p) { - return p->asSymbolInset() && p->asSymbolInset()->name() == "int"; + return symbolTest(p, "int"); } -bool differentialTest(MathInset * p) +bool intDiffTest(MathInset * p) { - return extractString(p) == "d"; + return stringTest(p, "d"); } @@ -288,7 +348,7 @@ void extractIntegrals(MathArray & ar) // search 'd' MathArray::iterator jt = - endNestSearch(it, ar.end(), intSymbolTest, differentialTest); + endNestSearch(it, ar.end(), intSymbolTest, intDiffTest); // something sensible found? if (jt == ar.end()) @@ -301,20 +361,16 @@ void extractIntegrals(MathArray & ar) MathArray::iterator st = it + 1; if ((*st)->asScriptInset()) { p->scripts(*st); - p->core(MathArray(st + 1, jt)); + p->cell(0) = MathArray(st + 1, jt); } else { - p->core(MathArray(st, jt)); + p->cell(0) = MathArray(st, jt); } // use the atom behind the 'd' as differential - MathArray ind; - if (jt + 1 != ar.end()) { - ind.push_back(*(jt + 1)); - ++jt; - } - ar.erase(it + 1, jt + 1); - - p->index(ind); + MathArray::iterator tt = extractArgument(p->cell(1), jt + 1, ar.end()); + + // remove used parts + ar.erase(it + 1, tt); (*it).reset(p); } lyxerr << "\nIntegrals to: " << ar << "\n"; @@ -333,7 +389,7 @@ bool sumSymbolTest(MathInset * p) bool equalSign(MathInset * p) { - return extractString(p) == "="; + return stringTest(p, "="); } @@ -378,25 +434,21 @@ void extractSums(MathArray & ar) if (it != ar.end()) { // we found a '=', use everything in front of that as index, // and everything behind as start value - p->index(MathArray(ar.begin(), it)); + p->cell(1) = MathArray(ar.begin(), it); ar.erase(ar.begin(), it + 1); } else { - // use everything as summation index - p->index(ar); + // use everything as summation index, don't use scripts. + p->cell(1) = ar; p->scripts().reset(0); } } } - // use the atom behind the script as core - MathArray ind; - if (st != ar.end()) { - MathArray core; - core.push_back(*st); - p->core(core); - ++st; - } - ar.erase(it + 1, st); + // use some behind the script as core + MathArray::iterator tt = extractArgument(p->cell(0), st, ar.end()); + + // cleanup + ar.erase(it + 1, tt); (*it).reset(p); } lyxerr << "\nSums to: " << ar << "\n"; @@ -407,9 +459,60 @@ void extractSums(MathArray & ar) // search differential stuff // +// tests for 'd' or '\partial' +bool diffItemTest(MathInset * p) +{ + return stringTest(p, "d"); +} + + +bool diffItemTest(MathArray const & ar) +{ + return ar.size() && diffItemTest(ar.front().nucleus()); +} + + +bool diffFracTest(MathInset * p) +{ + return + p->asFracInset() && + diffItemTest(p->asFracInset()->cell(0)) && + diffItemTest(p->asFracInset()->cell(1)); +} + void extractDiff(MathArray & ar) { lyxerr << "\nDiffs from: " << ar << "\n"; + for (MathArray::size_type i = 0; i < ar.size() - 1; ++i) { + MathArray::iterator it = ar.begin() + i; + + // is this a "differential fraction"? + if (!diffFracTest(it->nucleus())) + continue; + + MathFracInset * f = (*it)->asFracInset(); + if (!f) { + lyxerr << "should not happen\n"; + continue; + } + + // create a proper diff inset + MathDiffInset * p = new MathDiffInset; + + // collect function + MathArray::iterator jt = it + 1; + if (f->cell(0).size() > 1) + p->cell(0) = MathArray(f->cell(0).begin() + 1, f->cell(0).end()); + else + jt = extractArgument(p->cell(0), jt, ar.end()); + + // collect denominator + + + // cleanup + ar.erase(it + 1, jt); + (*it).reset(p); + } lyxerr << "\nDiffs to: " << ar << "\n"; } diff --git a/src/mathed/math_fracinset.C b/src/mathed/math_fracinset.C index bd08250864..1799838dac 100644 --- a/src/mathed/math_fracinset.C +++ b/src/mathed/math_fracinset.C @@ -19,6 +19,12 @@ MathInset * MathFracInset::clone() const } +MathFracInset * MathFracInset::asFracInset() +{ + return atop_ ? 0 : this; +} + + void MathFracInset::metrics(MathMetricsInfo const & mi) const { MathMetricsInfo m = mi; diff --git a/src/mathed/math_fracinset.h b/src/mathed/math_fracinset.h index 2068de0cd9..386a95eda7 100644 --- a/src/mathed/math_fracinset.h +++ b/src/mathed/math_fracinset.h @@ -21,6 +21,8 @@ public: void metrics(MathMetricsInfo const & st) const; /// void draw(Painter &, int x, int y) const; + /// + MathFracInset * asFracInset(); /// void write(WriteStream & os) const; diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index 819d3cc21f..a6587c4398 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -44,6 +44,7 @@ class MathCharInset; class MathDelimInset; class MathFuncInset; class MathGridInset; +class MathFracInset; class MathHullInset; class MathMatrixInset; class MathNestInset; @@ -179,6 +180,7 @@ public: virtual MathDelimInset * asDelimInset() { return 0; } virtual MathDelimInset const * asDelimInset() const { return 0; } virtual MathFuncInset * asFuncInset() { return 0; } + virtual MathFracInset * asFracInset() { return 0; } virtual MathGridInset * asGridInset() { return 0; } virtual MathHullInset * asHullInset() { return 0; } virtual MathHullInset const * asHullInset() const { return 0; } -- 2.39.2