mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-11 05:33:33 +00:00
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:
parent
f3c27aa1f5
commit
c80a4abde9
@ -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
|
||||
|
@ -10,7 +10,7 @@
|
||||
class MathExFuncInset : public MathNestInset {
|
||||
public:
|
||||
///
|
||||
MathExFuncInset(string const & name, MathArray const & arg);
|
||||
explicit MathExFuncInset(string const & name);
|
||||
///
|
||||
MathInset * clone() const;
|
||||
///
|
||||
|
@ -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> ⁢ </mo>"
|
||||
os << cell(0) << "<mo> ⁢ </mo>"
|
||||
<< MTag("mrow") << "<mo> ⅆ </mo>"
|
||||
<< index_ << ETag("mrow");
|
||||
<< cell(1) << ETag("mrow");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,10 +150,11 @@ 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";
|
||||
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user