]> git.lyx.org Git - lyx.git/commitdiff
improved function function argument detection for math-extern:
authorAndré Pönitz <poenitz@gmx.net>
Tue, 13 Nov 2001 18:33:48 +0000 (18:33 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Tue, 13 Nov 2001 18:33:48 +0000 (18:33 +0000)
\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
src/mathed/math_exfuncinset.h
src/mathed/math_exintinset.C
src/mathed/math_exintinset.h
src/mathed/math_extern.C
src/mathed/math_fracinset.C
src/mathed/math_fracinset.h
src/mathed/math_inset.h

index 7882daa993cecbde9a9e483603bb633725ed468d..1cf2588e09af4d3bd7b78c9df927a2f5bd354270 100644 (file)
@@ -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
index d7832cd28dbe9d59571ece8a1c79fdfa1feb6a80..a0887a39c33e47c31f16db3ef34152ac7c991e81 100644 (file)
@@ -10,7 +10,7 @@
 class MathExFuncInset : public MathNestInset {
 public:
        ///
-       MathExFuncInset(string const & name, MathArray const & arg);
+       explicit MathExFuncInset(string const & name);
        ///
        MathInset * clone() const;
        ///
index b49f2246c585f20328e122b33cf450ea3c04c22d..4fce6e180de03f38fab9f3bd7a28c2347fb0d3fd 100644 (file)
@@ -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_ << "<mo> &InvisibleTimes; </mo>"
+       os << cell(0) << "<mo> &InvisibleTimes; </mo>"
           << MTag("mrow") << "<mo> &DifferentialD; </mo>"
-          << index_ << ETag("mrow");
+          << cell(1) << ETag("mrow");
 }
 
 
index 5e7f51e057f03a9109845da4bee585334db53f31..3767aaaeb593624dd85d05c8560ad1f3365a7ba3 100644 (file)
@@ -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
index a34b045612489bc0d6283ab6102560dc9ecedd2d..4846bf146fb9e12b295135be2e18169bb5b28f0d 100644 (file)
@@ -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";
 }
 
index bd082508647139534105e7fa90e449093a67867f..1799838dacceacb563ae104f204e53eaf107e93a 100644 (file)
@@ -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;
index 2068de0cd9cd6457705ae181eac275b40eaf6d4e..386a95eda72dc5993725b5903e50cea769c0b7a3 100644 (file)
@@ -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;
index 819d3cc21fe0c4172939cab051d189e02db875f1..a6587c43988cec3cc1fd28cf3862b428febdb159 100644 (file)
@@ -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; }