]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_extern.C
try to fix rounding errors
[lyx.git] / src / mathed / math_extern.C
index 3d7593540d69da3fd93073cfd2271dd3bba611a9..502c640e2d2d236725422e4b5f67f7bedd49e667 100644 (file)
@@ -1,29 +1,34 @@
-
 // This file contains most of the magic that extracts "context
 // information" from the unstructered layout-oriented stuff in an
 // MathArray.
 
 #include <algorithm>
 
+#include "math_amsarrayinset.h"
 #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"
 #include "math_stringinset.h"
 #include "math_symbolinset.h"
+#include "math_unknowninset.h"
 #include "Lsstream.h"
 #include "debug.h"
 
 
-std::ostream & operator<<(std::ostream & os, MathArray const & ar)
+using std::ostream;
+using std::istringstream;
+using std::find_if;
+
+
+ostream & operator<<(ostream & os, MathArray const & ar)
 {
-       NormalStream ns(os);    
+       NormalStream ns(os);
        ns << ar;
        return os;
 }
@@ -37,7 +42,7 @@ typedef MathInset * ReplaceArgumentFunc(const MathArray & ar);
 
 
 
-// try to extract a super/subscript 
+// try to extract a super/subscript
 // modify iterator position to point behind the thing
 bool extractScript(MathArray & ar,
        MathArray::iterator & pos, MathArray::iterator last)
@@ -101,6 +106,8 @@ MathArray::iterator extractArgument(MathArray & ar,
 
 MathScriptInset const * asScript(MathArray::const_iterator it)
 {
+       if (!it->nucleus())
+               return 0;
        if (it->nucleus()->asScriptInset())
                return 0;
        ++it;
@@ -114,16 +121,10 @@ MathScriptInset const * asScript(MathArray::const_iterator it)
 // returns sequence of char with same code starting at it up to end
 // it might be less, though...
 MathArray::const_iterator charSequence(MathArray::const_iterator it,
-       MathArray::const_iterator end, string & s, MathTextCodes & c)
+       MathArray::const_iterator end, string & s)
 {
-       MathCharInset const * p = (*it)->asCharInset();
-       c = p->code();
-       for (; it != end; ++it) {
-               p = (*it)->asCharInset();
-               if (!p || p->code() != c)
-                       break;
-               s += p->getChar();
-       }
+       for (; it != end && (*it)->asCharInset(); ++it)
+               s += (*it)->getChar();
        return it;
 }
 
@@ -139,7 +140,7 @@ void extractStrings(MathArray & ar)
                // create proper string inset
                MathStringInset * p = new MathStringInset;
                MathArray::const_iterator
-                       jt = charSequence(it, ar.end(), p->str_, p->code_);
+                       jt = charSequence(it, ar.end(), p->str_);
 
                // clean up
                (*it).reset(p);
@@ -157,17 +158,26 @@ MathInset * singleItem(MathArray & ar)
 
 void extractMatrices(MathArray & ar)
 {
-       lyxerr << "\nMatrices from: " << ar << "\n";
+       //lyxerr << "\nMatrices from: " << ar << "\n";
+       // first pass for explicitly delimited stuff
        for (MathArray::iterator it = ar.begin(); it != ar.end(); ++it) {
                MathDelimInset * del = (*it)->asDelimInset();
                if (!del)
                        continue;
                MathInset * arr = singleItem(del->cell(0));
-               if (!arr || !arr->asArrayInset())
+               if (!arr || !arr->asGridInset())
+                       continue;
+               *it = MathAtom(new MathMatrixInset(*(arr->asGridInset())));
+       }
+
+       // second pass for AMS "pmatrix" etc
+       for (MathArray::iterator it = ar.begin(); it != ar.end(); ++it) {
+               MathAMSArrayInset * ams = (*it)->asAMSArrayInset();
+               if (!ams)
                        continue;
-               *it = MathAtom(new MathMatrixInset(*(arr->asArrayInset())));
+               *it = MathAtom(new MathMatrixInset(*ams));
        }
-       lyxerr << "\nMatrices to: " << ar << "\n";
+       //lyxerr << "\nMatrices to: " << ar << "\n";
 }
 
 
@@ -192,9 +202,18 @@ bool extractString(MathInset * p, string & str)
 bool extractNumber(MathArray const & ar, int & i)
 {
        string s;
-       MathTextCodes c;
-       charSequence(ar.begin(), ar.end(), s, c);
-       std::istringstream is(s.c_str());
+       charSequence(ar.begin(), ar.end(), s);
+       istringstream is(s.c_str());
+       is >> i;
+       return is;
+}
+
+
+bool extractNumber(MathArray const & ar, double & i)
+{
+       string s;
+       charSequence(ar.begin(), ar.end(), s);
+       istringstream is(s.c_str());
        is >> i;
        return is;
 }
@@ -255,18 +274,18 @@ void replaceNested(
                ar.erase(it + 1, jt + 1);
                (*it).reset(p);
        }
-} 
+}
 
 
 
 //
 // split scripts into seperate super- and subscript insets. sub goes in
-// front of super... 
+// front of super...
 //
 
 void splitScripts(MathArray & ar)
 {
-       lyxerr << "\nScripts from: " << ar << "\n";
+       //lyxerr << "\nScripts from: " << ar << "\n";
        for (MathArray::size_type i = 0; i < ar.size(); ++i) {
                MathArray::iterator it = ar.begin() + i;
 
@@ -281,15 +300,15 @@ void splitScripts(MathArray & ar)
 
                // create extra script inset and move superscript over
                MathScriptInset * q = new MathScriptInset;
-               q->ensure(true); 
+               q->ensure(true);
                q->up().data_.swap(p->up().data_);
                p->removeScript(true);
 
                // insert new inset behind
                ++i;
-               ar.insert(i, MathAtom(q)); 
+               ar.insert(i, MathAtom(q));
        }
-       lyxerr << "\nScripts to: " << ar << "\n";
+       //lyxerr << "\nScripts to: " << ar << "\n";
 }
 
 
@@ -299,7 +318,7 @@ void splitScripts(MathArray & ar)
 
 void extractExps(MathArray & ar)
 {
-       lyxerr << "\nExps from: " << ar << "\n";
+       //lyxerr << "\nExps from: " << ar << "\n";
 
        for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
                MathArray::iterator it = ar.begin() + i;
@@ -322,7 +341,7 @@ void extractExps(MathArray & ar)
                (*it).reset(func);
                ar.erase(it + 1);
        }
-       lyxerr << "\nExps to: " << ar << "\n";
+       //lyxerr << "\nExps to: " << ar << "\n";
 }
 
 
@@ -353,9 +372,9 @@ MathInset * replaceDelims(const MathArray & ar)
 // replace '('...')' sequences by a real MathDelimInset
 void extractDelims(MathArray & ar)
 {
-       lyxerr << "\nDelims from: " << ar << "\n";
+       //lyxerr << "\nDelims from: " << ar << "\n";
        replaceNested(ar, testOpenParan, testCloseParan, replaceDelims);
-       lyxerr << "\nDelims to: " << ar << "\n";
+       //lyxerr << "\nDelims to: " << ar << "\n";
 }
 
 
@@ -373,17 +392,17 @@ void extractFunctions(MathArray & ar)
        if (ar.size() <= 1)
                return;
 
-       lyxerr << "\nFunctions from: " << ar << "\n";
+       //lyxerr << "\nFunctions from: " << ar << "\n";
        for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
                MathArray::iterator it = ar.begin() + i;
                MathArray::iterator jt = it + 1;
 
                string name;
                // is it a function?
-               if ((*it)->asFuncInset()) { 
+               if ((*it)->asUnknownInset()) {
                        // it certainly is if it is well known...
-                       name = (*it)->asFuncInset()->name();
-               } else {
+                       name = (*it)->asUnknownInset()->name();
+               } else {
                        // is this a user defined function?
                        // it it probably not, if it doesn't have a name.
                        if (!extractString((*it).nucleus(), name))
@@ -403,7 +422,7 @@ void extractFunctions(MathArray & ar)
                // 'sin' '^2' 'x' -> 'sin(x)' '^2'
                MathArray exp;
                extractScript(exp, jt, ar.end());
-       
+
                // create a proper inset as replacement
                MathExFuncInset * p = new MathExFuncInset(name);
 
@@ -412,15 +431,15 @@ void extractFunctions(MathArray & ar)
 
                // replace the function name by a real function inset
                (*it).reset(p);
-               
+
                // remove the source of the argument from the array
                ar.erase(it + 1, st);
 
                // re-insert exponent
                ar.insert(i + 1, exp);
-               lyxerr << "\nFunctions to: " << ar << "\n";
+               //lyxerr << "\nFunctions to: " << ar << "\n";
        }
-} 
+}
 
 
 //
@@ -453,7 +472,7 @@ void extractIntegrals(MathArray & ar)
        if (ar.size() <= 2)
                return;
 
-       lyxerr << "\nIntegrals from: " << ar << "\n";
+       //lyxerr << "\nIntegrals from: " << ar << "\n";
        for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
                MathArray::iterator it = ar.begin() + i;
 
@@ -475,7 +494,7 @@ void extractIntegrals(MathArray & ar)
                // collect subscript if any
                MathArray::iterator st = it + 1;
                if (st != ar.end())
-                       if (MathScriptInset * sub = (*st)->asScriptInset()) 
+                       if (MathScriptInset * sub = (*st)->asScriptInset())
                                if (sub->hasDown()) {
                                        p->cell(2) = sub->down().data_;
                                        ++st;
@@ -483,7 +502,7 @@ void extractIntegrals(MathArray & ar)
 
                // collect superscript if any
                if (st != ar.end())
-                       if (MathScriptInset * sup = (*st)->asScriptInset()) 
+                       if (MathScriptInset * sup = (*st)->asScriptInset())
                                if (sup->hasUp()) {
                                        p->cell(3) = sup->up().data_;
                                        ++st;
@@ -494,12 +513,12 @@ void extractIntegrals(MathArray & ar)
 
                // use the "thing" behind the 'd' as differential
                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";
+       //lyxerr << "\nIntegrals to: " << ar << "\n";
 }
 
 
@@ -528,7 +547,7 @@ void extractSums(MathArray & ar)
        if (ar.size() <= 1)
                return;
 
-       lyxerr << "\nSums from: " << ar << "\n";
+       //lyxerr << "\nSums from: " << ar << "\n";
        for (MathArray::size_type i = 0; i + 1< ar.size(); ++i) {
                MathArray::iterator it = ar.begin() + i;
 
@@ -547,7 +566,7 @@ void extractSums(MathArray & ar)
                                        // try to figure out the summation index from the subscript
                                        MathArray & ar = sub->down().data_;
                                        MathArray::iterator it =
-                                               std::find_if(ar.begin(), ar.end(), &testEqualSign);
+                                               find_if(ar.begin(), ar.end(), &testEqualSign);
                                        if (it != ar.end()) {
                                                // we found a '=', use everything in front of that as index,
                                                // and everything behind as lower index
@@ -575,7 +594,7 @@ void extractSums(MathArray & ar)
                ar.erase(it + 1, tt);
                (*it).reset(p);
        }
-       lyxerr << "\nSums to: " << ar << "\n";
+       //lyxerr << "\nSums to: " << ar << "\n";
 }
 
 
@@ -612,7 +631,7 @@ bool extractDiffExponent(MathArray::iterator it, int & i)
        string s;
        if (!extractString((*it).nucleus(), s))
                return false;
-       std::istringstream is(s.c_str());
+       istringstream is(s.c_str());
        is >> i;
        return is;
 }
@@ -620,14 +639,14 @@ bool extractDiffExponent(MathArray::iterator it, int & i)
 
 void extractDiff(MathArray & ar)
 {
-       lyxerr << "\nDiffs from: " << ar << "\n";
+       //lyxerr << "\nDiffs from: " << ar << "\n";
        for (MathArray::size_type i = 0; i < ar.size(); ++i) {
                MathArray::iterator it = ar.begin() + i;
 
                // is this a "differential fraction"?
                if (!testDiffFrac(it->nucleus()))
                        continue;
-               
+
                MathFracInset * f = (*it)->asFracInset();
                if (!f) {
                        lyxerr << "should not happen\n";
@@ -638,20 +657,20 @@ void extractDiff(MathArray & ar)
                MathDiffInset * diff = new MathDiffInset;
 
                // collect function, let jt point behind last used item
-               MathArray::iterator jt = it + 1; 
-               //int n = 1; 
+               MathArray::iterator jt = it + 1;
+               //int n = 1;
                MathArray & numer = f->cell(0);
                if (numer.size() > 1 && numer.at(1)->asScriptInset()) {
                        // this is something like  d^n f(x) / d... or  d^n / d...
                        // FIXME
-                       //n = 1;        
-                       if (numer.size() > 2) 
+                       //n = 1;
+                       if (numer.size() > 2)
                                diff->cell(0) = MathArray(numer.begin() + 2, numer.end());
                        else
                                jt = extractArgument(diff->cell(0), jt, ar.end());
                } else {
                        // simply d f(x) / d... or  d/d...
-                       if (numer.size() > 1) 
+                       if (numer.size() > 1)
                                diff->cell(0) = MathArray(numer.begin() + 1, numer.end());
                        else
                                jt = extractArgument(diff->cell(0), jt, ar.end());
@@ -659,9 +678,9 @@ void extractDiff(MathArray & ar)
 
                // collect denominator parts
                MathArray & denom = f->cell(1);
-               for (MathArray::iterator dt = denom.begin(); dt != denom.end(); ) {
+               for (MathArray::iterator dt = denom.begin(); dt != denom.end();) {
                        // find the next 'd'
-                       MathArray::iterator et = std::find_if(dt + 1, denom.end(), &testDiffItem);
+                       MathArray::iterator et = find_if(dt + 1, denom.end(), &testDiffItem);
 
                        // point before this
                        MathArray::iterator st = et - 1;
@@ -670,7 +689,7 @@ void extractDiff(MathArray & ar)
                                // things like   d.../dx^n
                                int mult = 1;
                                if (extractNumber(script->up().data_, mult)) {
-                                       lyxerr << "mult: " << mult << std::endl;
+                                       //lyxerr << "mult: " << mult << endl;
                                        for (int i = 0; i < mult; ++i)
                                                diff->addDer(MathArray(dt + 1, st));
                                }
@@ -685,7 +704,7 @@ void extractDiff(MathArray & ar)
                ar.erase(it + 1, jt);
                (*it).reset(diff);
        }
-       lyxerr << "\nDiffs to: " << ar << "\n";
+       //lyxerr << "\nDiffs to: " << ar << "\n";
 }
 
 
@@ -713,14 +732,14 @@ void write(MathArray const & dat, WriteStream & wi)
        MathArray ar = dat;
        extractStrings(ar);
        for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
-               wi.firstitem = (it == ar.begin());
+               wi.firstitem() = (it == ar.begin());
                MathInset const * p = it->nucleus();
                if (it + 1 != ar.end()) {
                        if (MathScriptInset const * q = asScript(it)) {
                                q->write2(p, wi);
                                ++it;
                                continue;
-                       } 
+                       }
                }
                p->write(wi);
        }
@@ -743,7 +762,7 @@ void octavize(MathArray const & dat, OctaveStream & os)
                if (it + 1 != ar.end()) {
                        if (MathScriptInset const * q = asScript(it)) {
                                q->octavize2(p, os);
-                               ++it;   
+                               ++it;
                                continue;
                        }
                }
@@ -761,7 +780,7 @@ void maplize(MathArray const & dat, MapleStream & os)
                if (it + 1 != ar.end()) {
                        if (MathScriptInset const * q = asScript(it)) {
                                q->maplize2(p, os);
-                               ++it;   
+                               ++it;
                                continue;
                        }
                }
@@ -785,7 +804,7 @@ void mathmlize(MathArray const & dat, MathMLStream & os)
                        if (it + 1 != ar.end()) {
                                if (MathScriptInset const * q = asScript(it)) {
                                        q->mathmlize2(p, os);
-                                       ++it;   
+                                       ++it;
                                        continue;
                                }
                        }
@@ -794,4 +813,3 @@ void mathmlize(MathArray const & dat, MathMLStream & os)
                os << ETag("mrow");
        }
 }
-