Fix parsing of functions and arguments for MathML.

The enum is overkill for now, but will be useful if anyone decides
really to return to this stuff. It's apparent that there are some 
powerful tools here---like the ability to pipe expressions through
Mathematica.



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@31989 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2009-11-14 20:20:17 +00:00
parent 963c22353a
commit 9ba340b218
2 changed files with 116 additions and 111 deletions

View File

@ -19,6 +19,7 @@
#include "support/debug.h" #include "support/debug.h"
#include "support/gettext.h" #include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/textutils.h" #include "support/textutils.h"
@ -90,16 +91,8 @@ void InsetMathString::octave(OctaveStream & os) const
void InsetMathString::mathmlize(MathStream & os) const void InsetMathString::mathmlize(MathStream & os) const
{ {
/* // useless, no doubt, but we should not be here
if (code_ == LM_TC_VAR) LASSERT(false, /* */);
os << "<mi> " << str_ << " </mi>";
else if (code_ == LM_TC_CONST)
os << "<mn> " << str_ << " </mn>";
else if (code_ == LM_TC_RM || code_ == LM_TC_TEXTRM)
os << "<mtext> " << str_ << " </mtext>";
else
*/
os << str_;
} }

View File

@ -50,6 +50,17 @@ using namespace lyx::support;
namespace lyx { namespace lyx {
namespace {
enum ExternalMath {
MAPLE,
MAXIMA,
MATHEMATICA,
MATHML,
OCTAVE
};
static char const * function_names[] = { static char const * function_names[] = {
"arccos", "arcsin", "arctan", "arg", "bmod", "arccos", "arcsin", "arctan", "arg", "bmod",
"cos", "cosh", "cot", "coth", "csc", "deg", "cos", "cosh", "cot", "coth", "csc", "deg",
@ -96,7 +107,8 @@ bool extractScript(MathData & ar,
// try to extract an "argument" to some function. // try to extract an "argument" to some function.
// returns position behind the argument // returns position behind the argument
MathData::iterator extractArgument(MathData & ar, MathData::iterator extractArgument(MathData & ar,
MathData::iterator pos, MathData::iterator last, bool function = false) MathData::iterator pos, MathData::iterator last,
ExternalMath kind, bool function = false)
{ {
// nothing to get here // nothing to get here
if (pos == last) if (pos == last)
@ -105,7 +117,7 @@ MathData::iterator extractArgument(MathData & ar,
// something delimited _is_ an argument // something delimited _is_ an argument
if ((*pos)->asDelimInset()) { if ((*pos)->asDelimInset()) {
// leave out delimiters if this is a function argument // leave out delimiters if this is a function argument
if (function) { if (function && kind != MATHML) {
MathData const & arg = (*pos)->asDelimInset()->cell(0); MathData const & arg = (*pos)->asDelimInset()->cell(0);
MathData::const_iterator cur = arg.begin(); MathData::const_iterator cur = arg.begin();
MathData::const_iterator end = arg.end(); MathData::const_iterator end = arg.end();
@ -247,23 +259,6 @@ bool extractFunctionName(MathAtom const & at, docstring & str)
} }
// convert this inset somehow to a number
bool extractNumber(MathData const & ar, int & i)
{
idocstringstream is(charSequence(ar.begin(), ar.end()));
is >> i;
return is;
}
bool extractNumber(MathData const & ar, double & d)
{
idocstringstream is(charSequence(ar.begin(), ar.end()));
is >> d;
return is;
}
bool testString(MathAtom const & at, docstring const & str) bool testString(MathAtom const & at, docstring const & str)
{ {
docstring s; docstring s;
@ -525,7 +520,7 @@ void extractDelims(MathData & ar)
// replace 'f' '(...)' and 'f' '^n' '(...)' sequences by a real InsetMathExFunc // replace 'f' '(...)' and 'f' '^n' '(...)' sequences by a real InsetMathExFunc
// assume 'extractDelims' ran before // assume 'extractDelims' ran before
void extractFunctions(MathData & ar) void extractFunctions(MathData & ar, ExternalMath kind)
{ {
// we need at least two items... // we need at least two items...
if (ar.size() < 2) if (ar.size() < 2)
@ -566,7 +561,8 @@ void extractFunctions(MathData & ar)
auto_ptr<InsetMathExFunc> p(new InsetMathExFunc(buf, name)); auto_ptr<InsetMathExFunc> p(new InsetMathExFunc(buf, name));
// jt points to the "argument". Get hold of this. // jt points to the "argument". Get hold of this.
MathData::iterator st = extractArgument(p->cell(0), jt, ar.end(), true); MathData::iterator st =
extractArgument(p->cell(0), jt, ar.end(), kind, true);
// replace the function name by a real function inset // replace the function name by a real function inset
*it = MathAtom(p.release()); *it = MathAtom(p.release());
@ -622,7 +618,7 @@ bool testIntDiff(MathAtom const & at)
// replace '\int' ['_^'] x 'd''x'(...)' sequences by a real InsetMathExInt // replace '\int' ['_^'] x 'd''x'(...)' sequences by a real InsetMathExInt
// assume 'extractDelims' ran before // assume 'extractDelims' ran before
void extractIntegrals(MathData & ar) void extractIntegrals(MathData & ar, ExternalMath kind)
{ {
// we need at least three items... // we need at least three items...
if (ar.size() < 3) if (ar.size() < 3)
@ -657,7 +653,7 @@ void extractIntegrals(MathData & ar)
p->cell(0) = MathData(buf, it + 1, jt); p->cell(0) = MathData(buf, it + 1, jt);
// use the "thing" behind the 'd' as differential // use the "thing" behind the 'd' as differential
MathData::iterator tt = extractArgument(p->cell(1), jt + 1, ar.end()); MathData::iterator tt = extractArgument(p->cell(1), jt + 1, ar.end(), kind);
// remove used parts // remove used parts
ar.erase(it + 1, tt); ar.erase(it + 1, tt);
@ -935,99 +931,26 @@ void extractLims(MathData & ar)
// combine searches // combine searches
// //
void extractStructure(MathData & ar) void extractStructure(MathData & ar, ExternalMath kind)
{ {
//lyxerr << "\nStructure from: " << ar << endl; //lyxerr << "\nStructure from: " << ar << endl;
splitScripts(ar); splitScripts(ar);
extractDelims(ar); extractDelims(ar);
extractIntegrals(ar); extractIntegrals(ar, kind);
extractSums(ar); extractSums(ar);
extractNumbers(ar); extractNumbers(ar);
extractMatrices(ar); extractMatrices(ar);
extractFunctions(ar); extractFunctions(ar, kind);
extractDets(ar); extractDets(ar);
extractDiff(ar); extractDiff(ar);
extractExps(ar); extractExps(ar);
extractLims(ar); extractLims(ar);
extractStrings(ar); if (kind != MATHML)
extractStrings(ar);
//lyxerr << "\nStructure to: " << ar << endl; //lyxerr << "\nStructure to: " << ar << endl;
} }
void write(MathData const & dat, WriteStream & wi)
{
MathData ar = dat;
extractStrings(ar);
wi.firstitem() = true;
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) {
(*it)->write(wi);
wi.firstitem() = false;
}
}
void normalize(MathData const & ar, NormalStream & os)
{
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->normalize(os);
}
void octave(MathData const & dat, OctaveStream & os)
{
MathData ar = dat;
extractStructure(ar);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->octave(os);
}
void maple(MathData const & dat, MapleStream & os)
{
MathData ar = dat;
extractStructure(ar);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->maple(os);
}
void maxima(MathData const & dat, MaximaStream & os)
{
MathData ar = dat;
extractStructure(ar);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->maxima(os);
}
void mathematica(MathData const & dat, MathematicaStream & os)
{
MathData ar = dat;
extractStructure(ar);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->mathematica(os);
}
void mathmlize(MathData const & dat, MathStream & os)
{
MathData ar = dat;
extractStructure(ar);
if (ar.size() == 0)
os << "<mrow/>";
else if (ar.size() == 1)
os << ar.front();
else {
os << MTag("mrow");
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->mathmlize(os);
os << ETag("mrow");
}
}
namespace { namespace {
string captureOutput(string const & cmd, string const & data) string captureOutput(string const & cmd, string const & data)
@ -1417,6 +1340,95 @@ namespace {
} }
} // anon namespace
void write(MathData const & dat, WriteStream & wi)
{
MathData ar = dat;
extractStrings(ar);
wi.firstitem() = true;
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) {
(*it)->write(wi);
wi.firstitem() = false;
}
}
void normalize(MathData const & ar, NormalStream & os)
{
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->normalize(os);
}
void octave(MathData const & dat, OctaveStream & os)
{
MathData ar = dat;
extractStructure(ar, OCTAVE);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->octave(os);
}
void maple(MathData const & dat, MapleStream & os)
{
MathData ar = dat;
extractStructure(ar, MAPLE);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->maple(os);
}
void maxima(MathData const & dat, MaximaStream & os)
{
MathData ar = dat;
extractStructure(ar, MAXIMA);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->maxima(os);
}
void mathematica(MathData const & dat, MathematicaStream & os)
{
MathData ar = dat;
extractStructure(ar, MATHEMATICA);
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->mathematica(os);
}
void mathmlize(MathData const & dat, MathStream & os)
{
MathData ar = dat;
extractStructure(ar, MATHML);
if (ar.size() == 0)
os << "<mrow/>";
else if (ar.size() == 1)
os << ar.front();
else {
os << MTag("mrow");
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->mathmlize(os);
os << ETag("mrow");
}
}
// convert this inset somehow to a number
bool extractNumber(MathData const & ar, int & i)
{
idocstringstream is(charSequence(ar.begin(), ar.end()));
is >> i;
return is;
}
bool extractNumber(MathData const & ar, double & d)
{
idocstringstream is(charSequence(ar.begin(), ar.end()));
is >> d;
return is;
}
MathData pipeThroughExtern(string const & lang, docstring const & extra, MathData pipeThroughExtern(string const & lang, docstring const & extra,
MathData const & ar) MathData const & ar)