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
This commit is contained in:
André Pönitz 2001-11-13 18:33:48 +00:00
parent f3c27aa1f5
commit c80a4abde9
8 changed files with 176 additions and 86 deletions

View 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

View 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;
///

View 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");
}

View 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

View 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";
}
}
// 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";
@ -235,20 +292,17 @@ void extractFunctions(MathArray & ar)
continue;
}
// 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);
// create a proper inset as replacement
MathExFuncInset * p = new MathExFuncInset(func->name());
// 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 intSymbolTest(MathInset * p)
bool symbolTest(MathInset * p, string const & name)
{
return p->asSymbolInset() && p->asSymbolInset()->name() == "int";
return p->asSymbolInset() && p->asSymbolInset()->name() == name;
}
bool differentialTest(MathInset * p)
bool intSymbolTest(MathInset * p)
{
return extractString(p) == "d";
return symbolTest(p, "int");
}
bool intDiffTest(MathInset * p)
{
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);
MathArray::iterator tt = extractArgument(p->cell(1), jt + 1, ar.end());
p->index(ind);
// 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";
}

View 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;

View 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;

View 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; }