+#include <config.h>
+
#ifdef __GNUG__
#pragma implementation
#endif
+#include "math_data.h"
#include "math_inset.h"
+#include "math_deliminset.h"
#include "math_charinset.h"
#include "math_scriptinset.h"
#include "math_stringinset.h"
+#include "math_matrixinset.h"
#include "math_mathmlstream.h"
#include "math_support.h"
-#include "math_data.h"
+#include "math_replace.h"
#include "debug.h"
#include "support/LAssert.h"
{}
+MathArray::MathArray(iterator from, iterator to)
+ : bf_(from, to)
+{}
+
+
void MathArray::substitute(MathMacro const & m)
{
for (iterator it = begin(); it != end(); ++it)
}
-MathScriptInset const * MathArray::asScript(const_iterator it) const
-{
- if (it->nucleus()->asScriptInset())
- return 0;
- const_iterator jt = it + 1;
- if (jt == end())
- return 0;
- if (!jt->nucleus())
- return 0;
- return jt->nucleus()->asScriptInset();
-}
-
-
MathAtom & MathArray::at(size_type pos)
{
lyx::Assert(pos < size());
void MathArray::push_back(MathAtom const & t)
-{
+{
bf_.push_back(t);
}
void MathArray::swap(MathArray & ar)
{
- if (this != &ar)
+ if (this != &ar)
bf_.swap(ar.bf_);
}
void MathArray::erase()
{
- erase(0, size());
+ bf_.erase(begin(), end());
}
}
-void MathArray::erase(size_type pos1, size_type pos2)
-{
- bf_.erase(begin() + pos1, begin() + pos2);
-}
-
-
-MathAtom & MathArray::back()
-{
- return bf_.back();
-}
-
-
-void MathArray::dump2() const
-{
- NormalStream ns(lyxerr);
- for (const_iterator it = begin(); it != end(); ++it)
- ns << it->nucleus() << ' ';
-}
-
-
-void MathArray::dump() const
-{
- NormalStream ns(lyxerr);
- for (const_iterator it = begin(); it != end(); ++it)
- ns << "<" << it->nucleus() << ">";
-}
-
-
-// returns sequence of char with same code starting at it up to end
-// it might be less, though...
-string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
+void MathArray::erase(iterator pos1, iterator pos2)
{
- string s;
- MathCharInset const * p = it->nucleus()->asCharInset();
- if (!p)
- return s;
-
- for (MathTextCodes c = p->code(); it != end; ++it) {
- if (!it->nucleus())
- break;
- p = it->nucleus()->asCharInset();
- if (!p || p->code() != c)
- break;
- s += p->getChar();
- }
- return s;
+ bf_.erase(pos1, pos2);
}
-MathArray MathArray::glueChars() const
+void MathArray::erase(iterator pos)
{
- MathArray ar;
- const_iterator it = begin();
- while (it != end()) {
- if (it->nucleus() && it->nucleus()->asCharInset()) {
- string s = charSequence(it, end());
- MathTextCodes c = it->nucleus()->asCharInset()->code();
- ar.push_back(MathAtom(new MathStringInset(s, c)));
- it += s.size();
- } else {
- ar.push_back(*it);
- ++it;
- }
- }
- return ar;
+ bf_.erase(pos);
}
-bool needAsterisk(MathAtom const &, MathAtom const &)
-{
- return false;
-}
-
-
-MathArray MathArray::guessAsterisks() const
+void MathArray::erase(size_type pos1, size_type pos2)
{
- if (size() <= 1)
- return *this;
- MathArray ar;
- ar.push_back(*begin());
- for (const_iterator it = begin(), jt = begin()+1 ; jt != end(); ++it, ++jt) {
- if (needAsterisk(*it, *jt))
- ar.push_back(MathAtom(new MathCharInset('*')));
- ar.push_back(*it);
- }
- ar.push_back(*end());
- return ar;
+ bf_.erase(begin() + pos1, begin() + pos2);
}
-void MathArray::write(MathWriteInfo & wi) const
+MathAtom & MathArray::back()
{
- MathArray ar = glueChars();
- for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (MathScriptInset const * q = ar.asScript(it)) {
- q->write(p, wi);
- ++it;
- } else {
- p->write(wi);
- }
- }
+ return bf_.back();
}
-void MathArray::writeNormal(NormalStream & os) const
+MathAtom & MathArray::front()
{
- MathArray ar = glueChars();
- for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (MathScriptInset const * q = ar.asScript(it)) {
- q->writeNormal(p, os);
- ++it;
- } else
- p->writeNormal(os);
- }
+ return bf_.front();
}
-void MathArray::octavize(OctaveStream & os) const
+MathAtom const & MathArray::front() const
{
- MathArray ar = glueChars();
- for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (MathScriptInset const * q = ar.asScript(it)) {
- q->octavize(p, os);
- ++it;
- } else
- p->octavize(os);
- }
+ return bf_.front();
}
-void MathArray::maplize(MapleStream & os) const
+void MathArray::dump2() const
{
- MathArray ar = glueChars();
- for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (MathScriptInset const * q = ar.asScript(it)) {
- q->maplize(p, os);
- ++it;
- } else
- p->maplize(os);
- }
+ NormalStream ns(lyxerr);
+ for (const_iterator it = begin(); it != end(); ++it)
+ ns << it->nucleus() << ' ';
}
-void MathArray::mathmlize(MathMLStream & os) const
+void MathArray::dump() const
{
- MathArray ar = glueChars();
- if (ar.size() == 0)
- os << "<mrow/>";
- else if (ar.size() == 1)
- os << ar.begin()->nucleus();
- else {
- os << MTag("mrow");
- for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (MathScriptInset const * q = ar.asScript(it)) {
- q->mathmlize(p, os);
- ++it;
- } else
- p->mathmlize(os);
- }
- os << ETag("mrow");
- }
+ NormalStream ns(lyxerr);
+ for (const_iterator it = begin(); it != end(); ++it)
+ ns << "<" << it->nucleus() << ">";
}
void MathArray::pop_back()
-{
+{
if (!size()) {
lyxerr << "pop_back from empty array!\n";
return;
}
-bool MathArray::isMatrix() const
+bool MathArray::match(MathArray const & ar) const
+{
+ return size() == ar.size() && matchpart(ar, 0);
+}
+
+
+bool MathArray::matchpart(MathArray const & ar, pos_type pos) const
{
- return size() == 1 && begin()->nucleus() && begin()->nucleus()->isMatrix();
+ if (size() < ar.size() + pos)
+ return false;
+ const_iterator it = begin() + pos;
+ for (const_iterator jt = ar.begin(); jt != ar.end(); ++jt, ++it)
+ if (!jt->nucleus()->match(it->nucleus()))
+ return false;
+ return true;
}
+void MathArray::replace(ReplaceData & rep)
+{
+ for (size_type i = 0; i < size(); ++i) {
+ iterator it = begin() + i;
+ const_iterator rt = rep.from.begin();
+ const_iterator et = rep.from.end();
+ for (const_iterator jt = it; jt != end() && rt != et; ++jt, ++rt)
+ if (!jt->nucleus()->match(rt->nucleus()))
+ break;
+ if (rt == et) {
+ // match found
+ lyxerr << "match found!\n";
+ erase(it, it + rep.from.size());
+ insert(i, rep.to);
+ }
+ }
+
+ for (const_iterator it = begin(); it != end(); ++it)
+ it->nucleus()->replace(rep);
+}
+
+
+bool MathArray::contains(MathArray const & ar) const
+{
+ for (size_type i = 0; i + ar.size() <= size(); ++i) {
+ const_iterator it = begin() + i;
+ const_iterator rt = ar.begin();
+ const_iterator et = ar.end();
+ for (const_iterator jt = it; rt != et; ++jt, ++rt)
+ if (!jt->nucleus()->match(rt->nucleus()))
+ break;
+ if (rt == et)
+ return true;
+ }
+
+ for (const_iterator it = begin(); it != end(); ++it)
+ if (it->nucleus()->contains(ar))
+ return true;
+
+ return false;
+}