Use references instead of pointers where possible

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2867 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2001-10-12 12:02:49 +00:00
parent ced0711d20
commit 9295f8236e
37 changed files with 1114 additions and 1289 deletions

View File

@ -8,6 +8,7 @@
#include "debug.h"
#include "array.h"
#include "mathed/support.h"
#include "support/LAssert.h"
using std::ostream;
using std::endl;
@ -25,28 +26,38 @@ MathArray::MathArray(MathArray const & array, size_type from, size_type to)
void MathArray::substitute(MathMacro const & m)
{
for (iterator it = begin(); it != end(); ++it)
it->substitute(m);
it->nucleus()->substitute(m);
}
MathAtom * MathArray::at(size_type pos)
MathScriptInset const * MathArray::asScript(const_iterator it) const
{
return pos < size() ? &bf_[pos] : 0;
if (it->nucleus()->asScriptInset())
return 0;
const_iterator jt = it + 1;
if (jt == end())
return 0;
return jt->nucleus()->asScriptInset();
}
MathAtom const * MathArray::at(size_type pos) const
MathAtom & MathArray::at(size_type pos)
{
return pos < size() ? &bf_[pos] : 0;
lyx::Assert(pos < size());
return bf_[pos];
}
void MathArray::insert(size_type pos, MathInset * p)
MathAtom const & MathArray::at(size_type pos) const
{
//cerr << "\n 1: "; p->write(cerr, true); cerr << p << "\n";
// inserting here invalidates the pointer!
bf_.insert(begin() + pos, MathAtom(p));
//cerr << "\n 2: "; p->write(cerr, true); cerr << p << "\n";
lyx::Assert(pos < size());
return bf_[pos];
}
void MathArray::insert(size_type pos, MathAtom const & t)
{
bf_.insert(begin() + pos, t);
}
@ -62,12 +73,6 @@ void MathArray::push_back(MathAtom const & t)
}
void MathArray::push_back(MathInset * p)
{
bf_.push_back(MathAtom(p));
}
void MathArray::push_back(MathArray const & array)
{
insert(size(), array);
@ -127,14 +132,14 @@ MathAtom & MathArray::back()
void MathArray::dump2(ostream & os) const
{
for (const_iterator it = begin(); it != end(); ++it)
os << *it << ' ';
os << it->nucleus() << ' ';
}
void MathArray::dump(ostream & os) const
{
for (const_iterator it = begin(); it != end(); ++it)
os << "<" << *it << ">";
os << "<" << it->nucleus() << ">";
}
@ -158,7 +163,7 @@ string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
if (!it->nucleus())
break;
p = it->nucleus()->asCharInset();
if (!p || it->up() || it->down() || p->code() != c)
if (!p || p->code() != c)
break;
s += p->getChar();
}
@ -168,19 +173,27 @@ string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
void MathArray::write(ostream & os, bool fragile) const
{
for (const_iterator it = begin(); it != end(); ++it) {
if (it->nucleus() && it->nucleus()->asCharInset()
&& !it->up() && !it->down())
{
MathCharInset const * p = it->nucleus()->asCharInset();
for (const_iterator it = begin(); it != end(); ++it) {
MathInset * p = it->nucleus();
if (!p)
continue;
/*
if (p->asCharInset()) {
MathCharInset const * c = p->asCharInset();
// special handling for character sequences with the same code
string s = charSequence(it, end());
p->writeHeader(os);
c->writeHeader(os);
os << s;
p->writeTrailer(os);
c->writeTrailer(os);
it += s.size() - 1;
} else
*/
if (MathScriptInset const * q = asScript(it)) {
q->write(p, os, fragile);
++it;
} else {
it->write(os, fragile);
p->write(os, fragile);
}
}
}
@ -200,7 +213,7 @@ void MathArray::writeNormal(ostream & os) const
void MathArray::validate(LaTeXFeatures & features) const
{
for (const_iterator it = begin(); it != end(); ++it)
it->validate(features);
it->nucleus()->validate(features);
}

View File

@ -20,7 +20,7 @@
#include <iosfwd>
#include "math_atom.h"
class MathInset;
class MathScriptInset;
class MathMacro;
class LaTeXFeatures;
@ -64,7 +64,7 @@ public:
void swap(MathArray &);
///
void insert(size_type pos, MathInset * inset);
void insert(size_type pos, MathAtom const &);
///
void insert(size_type pos, MathArray const &);
@ -76,12 +76,10 @@ public:
void erase();
///
void push_back(MathInset * inset);
void push_back(MathAtom const &);
///
void push_back(MathArray const &);
///
void push_back(MathAtom const &);
///
void pop_back();
///
MathAtom & back();
@ -94,9 +92,9 @@ public:
void substitute(MathMacro const &);
///
MathAtom * at(size_type pos);
MathAtom & at(size_type pos);
///
MathAtom const * at(size_type pos) const;
MathAtom const & at(size_type pos) const;
///
void write(std::ostream &, bool) const;
///
@ -111,6 +109,8 @@ public:
iterator begin();
///
iterator end();
///
MathScriptInset const * asScript(const_iterator it) const;
private:
/// Buffer
buffer_type bf_;

View File

@ -30,6 +30,7 @@
#include "debug.h"
#include "lyx_gui_misc.h"
#include "support/LOstream.h"
#include "support/LAssert.h"
#include "support/lyxlib.h"
#include "support/syscall.h"
#include "support/lstrings.h"
@ -48,40 +49,32 @@ using std::vector;
InsetFormula::InsetFormula()
: par_(new MathMatrixInset)
{}
InsetFormula::InsetFormula(const InsetFormula & f)
: InsetFormulaBase(f), par_(static_cast<MathMatrixInset *>(f.par_->clone()))
: par_(MathAtom(new MathMatrixInset))
{}
InsetFormula::InsetFormula(MathInsetTypes t)
: par_(new MathMatrixInset(t))
: par_(MathAtom(new MathMatrixInset(t)))
{}
InsetFormula::InsetFormula(string const & s)
: par_(mathed_parse_normal(s))
{
if (!par_)
par_ = mathed_parse_normal("$" + s + "$");
if (s.size()) {
bool res = mathed_parse_normal(par_, s);
if (!par_) {
lyxerr << "cannot interpret '" << s << "' as math\n";
par_ = new MathMatrixInset(LM_OT_SIMPLE);
if (!res)
res = mathed_parse_normal(par_, "$" + s + "$");
if (!res) {
lyxerr << "cannot interpret '" << s << "' as math\n";
par_ = MathAtom(new MathMatrixInset(LM_OT_SIMPLE));
}
}
metrics();
}
InsetFormula::~InsetFormula()
{
delete par_;
}
Inset * InsetFormula::clone(Buffer const &, bool) const
{
return new InsetFormula(*this);
@ -123,7 +116,7 @@ int InsetFormula::docbook(Buffer const * buf, ostream & os) const
void InsetFormula::read(Buffer const *, LyXLex & lex)
{
par(mathed_parse_normal(lex));
mathed_parse_normal(par_, lex);
metrics();
}
@ -163,7 +156,7 @@ void InsetFormula::metrics() const
vector<string> const InsetFormula::getLabelList() const
{
return par_->getLabelList();
return mat()->getLabelList();
}
@ -187,9 +180,9 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
//lyxerr << "toggling all numbers\n";
if (display()) {
bv->lockedInsetStoreUndo(Undo::INSERT);
bool old = par_->numberedType();
bool old = mat()->numberedType();
for (MathInset::row_type row = 0; row < par_->nrows(); ++row)
par_->numbered(row, !old);
mat()->numbered(row, !old);
bv->owner()->message(old ? _("No number") : _("Number"));
updateLocal(bv, true);
}
@ -202,9 +195,9 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
if (display()) {
bv->lockedInsetStoreUndo(Undo::INSERT);
MathCursor::row_type row = mathcursor->row();
bool old = par_->numbered(row);
bool old = mat()->numbered(row);
bv->owner()->message(old ? _("No number") : _("Number"));
par_->numbered(row, !old);
mat()->numbered(row, !old);
updateLocal(bv, true);
}
break;
@ -215,7 +208,7 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
bv->lockedInsetStoreUndo(Undo::INSERT);
MathCursor::row_type row = mathcursor->row();
string old_label = par_->label(row);
string old_label = mat()->label(row);
string new_label = arg;
if (new_label.empty()) {
@ -236,13 +229,13 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
if (!new_label.empty()) {
lyxerr << "setting label to '" << new_label << "'\n";
par_->numbered(row, true);
mat()->numbered(row, true);
}
if (!new_label.empty() && bv->ChangeRefsIfUnique(old_label, new_label))
bv->redraw();
par_->label(row, new_label);
mat()->label(row, new_label);
updateLocal(bv, true);
break;
@ -260,7 +253,7 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
int x;
int y;
mathcursor->getPos(x, y);
par_->mutate(arg);
mat()->mutate(arg);
mathcursor->setPos(x, y);
mathcursor->normalize();
updateLocal(bv, true);
@ -272,10 +265,10 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
int x;
int y;
mathcursor->getPos(x, y);
if (par_->getType() == LM_OT_SIMPLE)
par_->mutate(LM_OT_EQUATION);
if (mat()->getType() == LM_OT_SIMPLE)
mat()->mutate(LM_OT_EQUATION);
else
par_->mutate(LM_OT_SIMPLE);
mat()->mutate(LM_OT_SIMPLE);
mathcursor->setPos(x, y);
mathcursor->normalize();
updateLocal(bv, true);
@ -286,15 +279,15 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
{
string const clip = bv->getClipboard();
if (!clip.empty())
par(mathed_parse_normal(clip));
mathed_parse_normal(par_, clip);
break;
}
case LFUN_MATH_COLUMN_INSERT:
{
if (par_->getType() == LM_OT_ALIGN)
par_->mutate(LM_OT_ALIGNAT);
par_->addCol(par_->ncols());
if (mat()->getType() == LM_OT_ALIGN)
mat()->mutate(LM_OT_ALIGNAT);
mat()->addCol(mat()->ncols());
mathcursor->normalize();
updateLocal(bv, true);
}
@ -312,33 +305,35 @@ void InsetFormula::handleExtern(const string & arg, BufferView *)
//string outfile = lyx::tempName("maple.out");
string outfile = "/tmp/lyx2" + arg + ".out";
ostringstream os;
par_->writeNormal(os);
mat()->writeNormal(os);
string code = os.str().c_str();
string script = "lyx2" + arg + " '" + code + "' " + outfile;
lyxerr << "calling: " << script << endl;
Systemcalls cmd(Systemcalls::System, script, 0);
ifstream is(outfile.c_str());
par(mathed_parse_normal(is));
mathed_parse_normal(par_, is);
metrics();
}
bool InsetFormula::display() const
{
return par_->getType() != LM_OT_SIMPLE;
return mat()->getType() != LM_OT_SIMPLE;
}
MathInset const * InsetFormula::par() const
MathMatrixInset const * InsetFormula::mat() const
{
return par_;
lyx::Assert(par_->asMatrixInset());
return par_->asMatrixInset();
}
void InsetFormula::par(MathMatrixInset * p)
{
delete par_;
par_ = p ? static_cast<MathMatrixInset *>(p) : new MathMatrixInset;
MathMatrixInset * InsetFormula::mat()
{
lyx::Assert(par_->asMatrixInset());
return par_->asMatrixInset();
}
@ -381,5 +376,5 @@ int InsetFormula::width(BufferView *, LyXFont const &) const
MathInsetTypes InsetFormula::getType() const
{
return par_->getType();
return mat()->getType();
}

View File

@ -23,6 +23,7 @@
#include "mathed/formulabase.h"
#include "math_defs.h"
#include "math_atom.h"
class MathMatrixInset;
@ -32,16 +33,10 @@ public:
///
InsetFormula();
///
InsetFormula(InsetFormula const &);
///
explicit InsetFormula(MathInsetTypes);
///
explicit InsetFormula(string const &);
///
~InsetFormula();
///
void operator=(InsetFormula const &);
///
int ascent(BufferView *, LyXFont const &) const;
///
int descent(BufferView *, LyXFont const &) const;
@ -80,17 +75,22 @@ public:
///
void handleExtern(string const & arg, BufferView * bv);
///
MathInset const * par() const;
///
bool display() const;
///
bool ams() const;
///
MathInsetTypes getType() const;
private:
/// Safe setting of contents
void par(MathMatrixInset *);
///
MathMatrixInset * par_;
MathAtom const & par() const { return par_; }
///
MathAtom & par() { return par_; }
public:
///
MathAtom par_;
/// Access
MathMatrixInset * mat();
/// Access
MathMatrixInset const * mat() const;
};
#endif

View File

@ -123,19 +123,14 @@ string const InsetFormulaBase::editMessage() const
void InsetFormulaBase::edit(BufferView * bv, int x, int /*y*/, unsigned int)
{
mathcursor = new MathCursor(this);
if (!bv->lockInset(this))
lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl;
mathcursor = new MathCursor(this, x == 0);
metrics();
// if that is removed, we won't get the magenta box when entering an
// inset for the first time
bv->updateInset(this, false);
if (x == 0)
mathcursor->first();
else
mathcursor->last();
sel_x = 0;
sel_y = 0;
sel_flag = false;
@ -467,7 +462,6 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
case LFUN_VECTOR: handleAccent(bv, "vec"); break;
// Math fonts
case LFUN_GREEK: handleFont(bv, LM_TC_GREEK1); break;
case LFUN_GREEK_TOGGLE: handleFont(bv, LM_TC_GREEK); break;
case LFUN_BOLD: handleFont(bv, LM_TC_BF); break;
case LFUN_SANS: handleFont(bv, LM_TC_SF); break;
@ -477,6 +471,12 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
case LFUN_NOUN: handleFont(bv, LM_TC_BB); break;
case LFUN_DEFAULT: handleFont(bv, LM_TC_VAR); break;
case LFUN_GREEK:
handleFont(bv, LM_TC_GREEK1);
if (arg.size())
mathcursor->interpret(arg[0]);
break;
case LFUN_MATH_MODE:
handleFont(bv, LM_TC_TEXTRM);
//bv->owner()->message(_("math text mode toggled"));
@ -513,7 +513,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
// p->incSpace();
//else
// mathcursor->insert(new MathSpaceInset(1));
mathcursor->insert(new MathSpaceInset(1));
mathcursor->insert(MathAtom(new MathSpaceInset(1)));
updateLocal(bv, true);
break;
}
@ -539,7 +539,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action,
case LFUN_PROTECTEDSPACE:
//lyxerr << " called LFUN_PROTECTEDSPACE\n";
bv->lockedInsetStoreUndo(Undo::INSERT);
mathcursor->insert(new MathSpaceInset(1));
mathcursor->insert(MathAtom(new MathSpaceInset(1)));
updateLocal(bv, true);
break;
@ -776,8 +776,7 @@ void mathDispatchGreek(BufferView * bv, string const & arg)
if (bv->available()) {
InsetFormula * f = new InsetFormula;
if (openNewInset(bv, f)) {
bv->theLockingInset()->localDispatch(bv, LFUN_GREEK, string());
bv->theLockingInset()->localDispatch(bv, LFUN_SELFINSERT, arg);
bv->theLockingInset()->localDispatch(bv, LFUN_GREEK, arg);
bv->unlockInset(f);
}
}

View File

@ -27,7 +27,7 @@
class Buffer;
class BufferView;
class MathInset;
class MathAtom;
///
class InsetFormulaBase : public UpdatableInset {
@ -85,10 +85,11 @@ public:
///
virtual std::vector<string> const getLabelList() const;
///
virtual MathInset const * par() const = 0;
virtual MathAtom const & par() const = 0;
///
virtual MathAtom & par() = 0;
///
virtual void metrics() const = 0;
protected:
///
virtual void updateLocal(BufferView * bv, bool mark_dirty);
private:

View File

@ -52,16 +52,14 @@ InsetFormulaMacro::InsetFormulaMacro()
InsetFormulaMacro::InsetFormulaMacro(string nm, int na)
{
setInsetName(nm);
MathMacroTable::createTemplate(nm, na, string());
MathMacroTable::create(nm, na, string());
}
InsetFormulaMacro::InsetFormulaMacro(string const & s)
{
MathMacroTemplate * t = mathed_parse_macro(s);
MathMacroTable::insertTemplate(*t);
setInsetName(t->name());
delete t;
string name = mathed_parse_macro(s);
setInsetName(name);
metrics();
}
@ -75,20 +73,20 @@ Inset * InsetFormulaMacro::clone(Buffer const &, bool) const
void InsetFormulaMacro::write(Buffer const *, ostream & os) const
{
os << "FormulaMacro ";
tmacro().write(os, false);
par()->write(os, false);
}
int InsetFormulaMacro::latex(Buffer const *, ostream & os, bool fragile,
bool /*free_spacing*/) const
{
tmacro().write(os, fragile);
par()->write(os, fragile);
return 2;
}
int InsetFormulaMacro::ascii(Buffer const *, ostream & os, int) const
{
tmacro().write(os, false);
par()->write(os, false);
return 0;
}
@ -107,38 +105,34 @@ int InsetFormulaMacro::docbook(Buffer const * buf, ostream & os) const
void InsetFormulaMacro::read(Buffer const *, LyXLex & lex)
{
MathMacroTemplate * t = mathed_parse_macro(lex);
if (!t)
t = new MathMacroTemplate("{parse error}", 0);
MathMacroTable::insertTemplate(*t);
setInsetName(t->name());
delete t;
string name = mathed_parse_macro(lex);
setInsetName(name);
metrics();
}
string InsetFormulaMacro::prefix() const
{
return string(" ") + _("Macro: ") + tmacro().name() + ": ";
return string(" ") + _("Macro: ") + getInsetName() + ": ";
}
int InsetFormulaMacro::ascent(BufferView *, LyXFont const &) const
{
return tmacro().ascent() + 5;
return par()->ascent() + 5;
}
int InsetFormulaMacro::descent(BufferView *, LyXFont const &) const
{
return tmacro().descent() + 5;
return par()->descent() + 5;
}
int InsetFormulaMacro::width(BufferView *, LyXFont const & f) const
{
metrics();
return 10 + lyxfont::width(prefix(), f) + tmacro().width();
return 10 + lyxfont::width(prefix(), f) + par()->width();
}
@ -152,12 +146,12 @@ InsetFormulaMacro::localDispatch(BufferView * bv,
case LFUN_MATH_MACROARG: {
int const i = lyx::atoi(arg);
lyxerr << "inserting macro arg " << i << "\n";
if (i > 0 && i <= tmacro().numargs()) {
mathcursor->insert(new MathMacroArgument(i));
//if (i > 0 && i <= par()->numargs()) {
mathcursor->insert(MathAtom(new MathMacroArgument(i)));
updateLocal(bv, true);
} else {
lyxerr << "not in range 0.." << tmacro().numargs() << "\n";
}
//} else {
// lyxerr << "not in range 0.." << par()->numargs() << "\n";
//}
break;
}
@ -168,9 +162,15 @@ InsetFormulaMacro::localDispatch(BufferView * bv,
}
MathMacroTemplate const & InsetFormulaMacro::tmacro() const
MathAtom const & InsetFormulaMacro::par() const
{
return MathMacroTable::provideTemplate(getInsetName());
return MathMacroTable::provide(getInsetName());
}
MathAtom & InsetFormulaMacro::par()
{
return MathMacroTable::provide(getInsetName());
}
@ -186,15 +186,9 @@ MathInsetTypes InsetFormulaMacro::getType() const
}
MathInset const * InsetFormulaMacro::par() const
{
return &tmacro();
}
void InsetFormulaMacro::metrics() const
{
tmacro().metrics(LM_ST_TEXT);
par()->metrics(LM_ST_TEXT);
}
@ -222,9 +216,9 @@ void InsetFormulaMacro::draw(BufferView * bv, LyXFont const & f,
x += width(bv, font);
// formula
float t = tmacro().width() + 5;
float t = par()->width() + 5;
x -= t;
tmacro().draw(pain, int(x), baseline);
par()->draw(pain, int(x), baseline);
x += t;
}

View File

@ -68,12 +68,12 @@ public:
///
MathInsetTypes getType() const;
///
MathInset const * par() const;
///
void metrics() const;
private:
///
MathMacroTemplate const & tmacro() const;
MathAtom const & par() const;
///
MathAtom & par();
private:
/// prefix in inset
string prefix() const;
};

View File

@ -11,6 +11,11 @@ MathArrayInset::MathArrayInset(int m, int n)
{}
MathArrayInset::MathArrayInset(int m, int n, char valign, string const & halign)
: MathGridInset(m, n, valign, halign)
{}
MathInset * MathArrayInset::clone() const
{
return new MathArrayInset(*this);

View File

@ -14,13 +14,15 @@ public:
///
MathArrayInset(int m, int n);
///
MathArrayInset(int m, int n, char valign, string const & halign);
///
MathInset * clone() const;
///
void write(std::ostream &, bool fragile) const;
///
void metrics(MathStyles st) const;
///
bool isArray() const { return true; }
MathArrayInset * asArrayInset() { return this; }
};
#endif

View File

@ -20,34 +20,18 @@
#endif
#include "math_atom.h"
#include "math_scriptinset.h"
#include "debug.h"
#include "support.h"
#include "math_inset.h"
#include "support/LAssert.h"
MathAtom::MathAtom()
: nucleus_(0), limits_(0), xo_(0), yo_(0)
{
script_[0] = 0;
script_[1] = 0;
}
: nucleus_(0)
{}
MathAtom::MathAtom(MathInset * p)
: nucleus_(p), limits_(0), xo_(0), yo_(0)
{
script_[0] = 0;
script_[1] = 0;
}
MathAtom::MathAtom(MathInset * p, MathScriptInset * up, MathScriptInset * down)
: nucleus_(p), limits_(0), xo_(0), yo_(0)
{
script_[0] = down;
script_[1] = up;
}
: nucleus_(p)
{}
MathAtom::MathAtom(MathAtom const & p)
@ -74,73 +58,30 @@ MathAtom::~MathAtom()
void MathAtom::done()
{
delete nucleus_;
delete script_[0];
delete script_[1];
}
void MathAtom::copy(MathAtom const & p)
{
//cerr << "calling MathAtom::copy\n";
xo_ = p.xo_;
yo_ = p.yo_;
limits_ = p.limits_;
nucleus_ = p.nucleus_;
script_[0] = p.script_[0];
script_[1] = p.script_[1];
if (nucleus_)
nucleus_ = nucleus_->clone();
if (script_[0])
script_[0] = new MathScriptInset(*script_[0]);
if (script_[1])
script_[1] = new MathScriptInset(*script_[1]);
}
int MathAtom::height() const
MathInset * MathAtom::nucleus() const
{
return ascent() + descent();
lyx::Assert(nucleus_);
return nucleus_;
}
std::ostream & operator<<(std::ostream & os, MathAtom const & atom)
MathInset * MathAtom::operator->() const
{
atom.write(os, false);
return os;
return nucleus();
}
int MathAtom::xo() const
{
return xo_;
}
int MathAtom::yo() const
{
return yo_;
}
void MathAtom::xo(int x) const
{
xo_ = x;
}
void MathAtom::yo(int y) const
{
yo_ = y;
}
void MathAtom::getXY(int & x, int & y) const
{
x = xo();
y = yo();
}
/*
void MathAtom::userSetSize(MathStyles sz)
{
@ -150,273 +91,3 @@ void MathAtom::userSetSize(MathStyles sz)
}
}
*/
void MathAtom::writeNormal(std::ostream & os) const
{
os << "[unknown] ";
}
void MathAtom::dump() const
{
lyxerr << "---------------------------------------------\n";
write(lyxerr, false);
lyxerr << "\n---------------------------------------------\n";
}
bool MathAtom::covers(int x, int y) const
{
return
x >= xo_ &&
x <= xo_ + width() &&
y >= yo_ - ascent() &&
y <= yo_ + descent();
}
MathScriptInset * MathAtom::ensure(bool up)
{
if (!script_[up])
script_[up] = new MathScriptInset(up);
return script_[up];
}
void MathAtom::validate(LaTeXFeatures &) const
{}
void MathAtom::metrics(MathStyles st) const
{
MathStyles tt = smallerStyleScript(st);
if (nucleus())
nucleus()->metrics(st);
if (up())
up()->metrics(tt);
if (down())
down()->metrics(tt);
}
MathScriptInset * MathAtom::up() const
{
return script_[1];
}
MathScriptInset * MathAtom::down() const
{
return script_[0];
}
MathScriptInset * & MathAtom::up()
{
return script_[1];
}
MathScriptInset * & MathAtom::down()
{
return script_[0];
}
int MathAtom::dy0() const
{
if (!down())
return ndes();
int des = down()->ascent();
if (hasLimits())
des += ndes() + 2;
else
des = std::max(des, ndes());
return des;
}
int MathAtom::dy1() const
{
if (!up())
return nasc();
int asc = up()->descent();
if (hasLimits())
asc += nasc() + 2;
else
asc = std::max(asc, nasc());
asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I'));
return asc;
}
int MathAtom::dx0() const
{
lyx::Assert(down());
return hasLimits() ? (width() - down()->width()) / 2 : nwid();
}
int MathAtom::dx1() const
{
lyx::Assert(up());
return hasLimits() ? (width() - up()->width()) / 2 : nwid();
}
int MathAtom::dxx() const
{
//lyx::Assert(nucleus());
return hasLimits() ? (width() - nwid()) / 2 : 0;
}
int MathAtom::ascent() const
{
return dy1() + (up() ? up()->ascent() : 0);
}
int MathAtom::descent() const
{
return dy0() + (down() ? down()->descent() : 0);
}
int MathAtom::width() const
{
int wid = 0;
if (hasLimits()) {
wid = nwid();
if (up())
wid = std::max(wid, up()->width());
if (down())
wid = std::max(wid, down()->width());
} else {
if (up())
wid = std::max(wid, up()->width());
if (down())
wid = std::max(wid, down()->width());
wid += nwid();
}
return wid;
}
int MathAtom::nwid() const
{
return nucleus() ?
nucleus()->width() :
mathed_char_width(LM_TC_TEX, LM_ST_TEXT, '.');
}
int MathAtom::nasc() const
{
return nucleus() ? nucleus()->ascent()
: mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I');
}
int MathAtom::ndes() const
{
return nucleus() ? nucleus()->descent()
: mathed_char_descent(LM_TC_VAR, LM_ST_TEXT, 'I');
}
void MathAtom::draw(Painter & pain, int x, int y) const
{
xo(x);
yo(y);
if (nucleus())
nucleus()->draw(pain, x + dxx(), y);
else
drawStr(pain, LM_TC_TEX, LM_ST_TEXT, x + dxx(), y, ".");
if (up())
up()->draw(pain, x + dx1(), y - dy1());
if (down())
down()->draw(pain, x + dx0(), y + dy0());
}
void MathAtom::write(std::ostream & os, bool fragile) const
{
if (nucleus()) {
nucleus()->write(os, fragile);
if (nucleus()->takesLimits()) {
if (limits_ == -1)
os << "\\nolimits ";
if (limits_ == 1)
os << "\\limits ";
}
} else
os << "{}";
if (down()) {
os << "_{";
down()->write(os, fragile);
os << "}";
}
if (up()) {
os << "^{";
up()->write(os, fragile);
os << "}";
}
}
bool MathAtom::hasLimits() const
{
return
limits_ == 1 || (limits_ == 0 && nucleus() && nucleus()->isScriptable());
}
bool MathAtom::hasInner() const
{
return nucleus_ && (script_[0] || script_[1]);
}
void MathAtom::substitute(MathMacro const & m)
{
if (nucleus())
nucleus()->substitute(m);
if (up())
up()->substitute(m);
if (down())
down()->substitute(m);
}
void MathAtom::removeEmptyScripts()
{
for (int i = 0; i <= 1; ++i)
if (script_[i] && !script_[i]->cell(0).size()) {
delete script_[i];
script_[i] = 0;
}
}
void MathAtom::removeNucleus()
{
delete nucleus_;
nucleus_ = 0;
}
void MathAtom::removeUp()
{
delete script_[1];
script_[1] = 0;
}
void MathAtom::removeDown()
{
delete script_[0];
script_[0] = 0;
}

View File

@ -3,15 +3,10 @@
#ifndef MATH_ATOM_H
#define MATH_ATOM_H
#include <config.h>
#include <iosfwd>
#ifdef __GNUG__
#pragma interface
#endif
#include "math_defs.h"
/**
The 'atom' is the major blob in math typesetting. And 'atom' consists
of a nucleus, an optional superscript, and an optional subscript.
@ -22,13 +17,7 @@ size, and type, of the nucleus they are attached to.
Jules
*/
class LaTeXFeatures;
class MathCharInset;
class MathScriptInset;
class MathInset;
class MathMacro;
class MathArray;
class Painter;
class MathAtom {
public:
@ -38,129 +27,23 @@ public:
MathAtom(MathAtom const &);
///
explicit MathAtom(MathInset * p);
///
MathAtom(MathInset * p, MathScriptInset * up, MathScriptInset * down);
///
virtual ~MathAtom();
///
void operator=(MathAtom const &);
///
void swap(MathAtom &);
/// draw the object, sets xo_ and yo_ cached values
virtual void draw(Painter &, int x, int y) const;
/// reproduce itself
void metrics(MathStyles st) const;
///
int ascent() const;
MathInset * nucleus() const;
///
int descent() const;
///
int width() const;
///
int height() const;
///
int xo() const;
///
int yo() const;
///
void xo(int tx) const;
///
void yo(int ty) const;
///
///
void getXY(int & x, int & y) const;
///
bool covers(int x, int y) const;
///
void dump() const;
///
void validate(LaTeXFeatures & features) const;
///
void handleFont(MathTextCodes) {}
/// make sure superscript is available
MathScriptInset * ensure(bool up);
/// delete subscript array if empty
void removeEmptyScripts();
/// delete nucleus
void removeNucleus();
/// delete superscript
void removeUp();
/// delete subscript
void removeDown();
/// can we add a super- or subscript?
virtual bool allows(bool up) const { return script_[up] == 0; }
/// can we add a super- or subscript?
virtual bool allowsLimits() const { return true; }
/// set limits
void limits(int lim) { limits_ = lim; }
///
int limits() const { return limits_; }
///
bool hasLimits() const;
/// true if we have an "inner" position
bool hasInner() const;
/// returns superscript
MathScriptInset * up() const;
/// returns subscript
MathScriptInset * down() const;
/// returns superscript
MathScriptInset * & up();
/// returns subscript
MathScriptInset * & down();
///
MathInset * nucleus() const { return nucleus_; }
///
MathInset * & nucleus() { return nucleus_; }
///
void substitute(const MathMacro &);
///
void write(std::ostream &, bool) const;
///
void writeNormal(std::ostream &) const;
/// returns width of nucleus if any
int nwid() const;
protected:
/// possible subscript (index 0) and superscript (index 1)
MathScriptInset * script_[2];
///
MathInset * nucleus_;
///
int limits_;
MathInset * operator->() const;
private:
/// the following are used for positioning the cursor with the mouse
/// cached cursor start position in pixels from the document left
mutable int xo_;
/// cached cursor start position in pixels from the document top
mutable int yo_;
///
MathInset * nucleus_;
/// raw copy
void copy(MathAtom const & p);
/// raw destruction
void done();
/// returns y offset for superscript
int dy0() const;
/// returns y offset for subscript
int dy1() const;
/// returns x offset for main part
int dxx() const;
/// returns x offset for superscript
int dx0() const;
/// returns x offset for subscript
int dx1() const;
/// returns ascent of nucleus if any
int nasc() const;
/// returns descent of nucleus if any
int ndes() const;
};
std::ostream & operator<<(std::ostream &, MathAtom const &);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -35,18 +35,17 @@ class InsetFormulaBase;
class MathArray;
class MathXArray;
class Painter;
class Selection;
class latexkeys;
/// Description of a position
struct MathCursorPos {
/// inset
MathInset * par_;
MathAtom * par_;
/// cell index
MathInset::idx_type idx_;
/// cell position
MathInset::pos_type pos_;
/// faked position "inside an atom"
bool inner_;
/// returns cell corresponding to this position
MathArray & cell() const;
@ -56,9 +55,6 @@ struct MathCursorPos {
MathXArray & xcell() const;
/// returns xcell corresponding to this position
MathXArray & xcell(MathInset::idx_type idx) const;
/// returns atom corresponding to this position
MathAtom * at() const;
};
///
@ -82,12 +78,14 @@ public:
typedef MathInset::col_type col_type;
///
explicit MathCursor(InsetFormulaBase *);
explicit MathCursor(InsetFormulaBase *, bool left);
///
void insert(MathInset *);
void insert(MathAtom const &);
///
void insert(MathArray const &);
///
void paste(MathArray const &);
///
void erase();
///
void backspace();
@ -114,9 +112,9 @@ public:
///
void plainErase();
///
void plainInsert(MathInset * p);
void plainInsert(MathAtom const &);
///
void niceInsert(MathInset * p);
void niceInsert(MathAtom const &);
///
void delLine();
@ -125,14 +123,12 @@ public:
///
void getPos(int & x, int & y);
///
MathInset * par() const;
MathAtom & par() const;
/// return the next enclosing grid inset and the cursor's index in it
MathArrayInset * enclosingArray(idx_type &) const;
///
InsetFormulaBase const * formula();
///
bool inner() const;
///
pos_type pos() const;
///
idx_type idx() const;
@ -202,11 +198,13 @@ public:
MathStyles style() const;
/// Make sure cursor position is valid
void normalize() const;
/// enter a MathInset
void push(MathAtom & par);
/// enter a MathInset from the front
void pushLeft(MathInset * par);
void pushLeft(MathAtom & par);
/// enter a MathInset from the back
void pushRight(MathInset * par);
void pushRight(MathAtom & par);
/// leave current MathInset to the left
bool popLeft();
/// leave current MathInset to the left
@ -217,13 +215,17 @@ public:
///
MathXArray & xarray() const;
///
MathAtom const * prevAtom() const;
bool hasPrevAtom() const;
///
MathAtom * prevAtom();
bool hasNextAtom() const;
///
MathAtom const * nextAtom() const;
MathAtom const & prevAtom() const;
///
MathAtom * nextAtom();
MathAtom & prevAtom();
///
MathAtom const & nextAtom() const;
///
MathAtom & nextAtom();
/// returns the selection
void getSelection(MathCursorPos &, MathCursorPos &) const;
@ -244,8 +246,6 @@ public:
///
pos_type last() const;
///
MathMatrixInset * outerPar() const;
///
void seldump(char const * str) const;
///
void dump(char const * str) const;
@ -253,13 +253,14 @@ public:
///
void merge(MathArray const & arr);
///
MathInset * nextInset() const;
///
MathInset * prevInset() const;
///
MathScriptInset * prevScriptInset() const;
///
MathSpaceInset * prevSpaceInset() const;
/// glue adjacent atoms if possible
bool glueAdjacentAtoms();
///
friend class Selection;
private:
/// moves cursor position one cell to the left
@ -274,8 +275,6 @@ private:
bool goUp();
/// moves position somehow down
bool goDown();
/// glue adjacent atoms if possible
void glueAdjacentAtoms();
///
string macroName() const;
@ -284,11 +283,9 @@ private:
///
void insert(char, MathTextCodes t);
/// can we enter the inset?
bool openable(MathInset *, bool selection) const;
bool openable(MathAtom const &, bool selection) const;
/// can the setPos routine enter that inset?
MathInset * positionable(MathAtom *, int x, int y) const;
/// write access to "inner" flag
bool & inner();
bool positionable(MathAtom const &, int x, int y) const;
/// write access to cursor cell position
pos_type & pos();
/// write access to cursor cell index

View File

@ -20,13 +20,13 @@
#include "math_stackrelinset.h"
MathInset * createMathInset(latexkeys const * l)
MathAtom createMathInset(latexkeys const * l)
{
switch (l->token) {
case LM_TK_FUNCLIM:
return new MathFuncLimInset(l);
return MathAtom(new MathFuncLimInset(l));
case LM_TK_SPECIAL:
return new MathSpecialCharInset(l->id);
return MathAtom(new MathSpecialCharInset(l->id));
case LM_TK_SYM:
case LM_TK_CMR:
case LM_TK_CMSY:
@ -34,51 +34,51 @@ MathInset * createMathInset(latexkeys const * l)
case LM_TK_CMEX:
case LM_TK_MSA:
case LM_TK_MSB:
return new MathSymbolInset(l);
return MathAtom(new MathSymbolInset(l));
case LM_TK_STACK:
return new MathStackrelInset;
return MathAtom(new MathStackrelInset);
case LM_TK_KERN:
return new MathKernInset;
return MathAtom(new MathKernInset);
case LM_TK_BINOM:
case LM_TK_CHOOSE:
return new MathBinomInset;
return MathAtom(new MathBinomInset);
case LM_TK_OVER:
case LM_TK_FRAC:
return new MathFracInset;
return MathAtom(new MathFracInset);
case LM_TK_ATOP:
return new MathFracInset(true);
return MathAtom(new MathFracInset(true));
case LM_TK_NOT:
return new MathNotInset;
return MathAtom(new MathNotInset);
case LM_TK_SQRT:
return new MathSqrtInset;
return MathAtom(new MathSqrtInset);
case LM_TK_ROOT:
return new MathRootInset;
return MathAtom(new MathRootInset);
case LM_TK_DECORATION:
return new MathDecorationInset(l->name);
return MathAtom(new MathDecorationInset(l->name));
case LM_TK_SPACE:
return new MathSpaceInset(l->id);
return MathAtom(new MathSpaceInset(l->id));
case LM_TK_DOTS:
return new MathDotsInset(l->name);
return MathAtom(new MathDotsInset(l->name));
}
return new MathFuncInset(l->name);
return MathAtom(new MathFuncInset(l->name));
}
MathInset * createMathInset(string const & s)
MathAtom createMathInset(string const & s)
{
//cerr << "creating inset with name: '" << s << "'\n";
if (s.size() == 2 && s[0] == '#' && s[1] >= '1' && s[1] <= '9')
return new MathMacroArgument(s[1] - '0');
return MathAtom(new MathMacroArgument(s[1] - '0'));
if (s.size() == 3 && s[0] == '\\' && s[1] == '#' && s[2] >= '1' && s[2] <= '9')
return new MathMacroArgument(s[2] - '0');
return MathAtom(new MathMacroArgument(s[2] - '0'));
latexkeys const * l = in_word_set(s);
if (l)
return createMathInset(l);
if (MathMacroTable::hasTemplate(s))
return new MathMacro(MathMacroTable::provideTemplate(s));
if (MathMacroTable::has(s))
return MathAtom(new MathMacro(s));
return new MathFuncInset(s);
return MathAtom(new MathFuncInset(s));
}

View File

@ -2,11 +2,12 @@
#define MATH_FACTORY_H
#include "LString.h"
#include "math_atom.h"
class MathInset;
class latexkeys;
MathInset * createMathInset(string const &);
MathInset * createMathInset(latexkeys const *);
MathAtom createMathInset(string const &);
MathAtom createMathInset(latexkeys const *);
#endif

View File

@ -19,6 +19,9 @@ int const MATH_BORDER = 2;
}
//////////////////////////////////////////////////////////////
MathGridInset::RowInfo::RowInfo()
: upperline_(false), lowerline_(false)
{}
@ -35,22 +38,33 @@ int MathGridInset::RowInfo::skipPixels() const
//////////////////////////////////////////////////////////////
MathGridInset::ColInfo::ColInfo()
: align_('c'), leftline_(false), rightline_(false), skip_(MATH_COLSEP)
{}
//////////////////////////////////////////////////////////////
MathGridInset::MathGridInset(col_type m, row_type n)
: MathNestInset(m * n), rowinfo_(n), colinfo_(m), v_align_('c')
{
if (m <= 0)
lyxerr << "positve number of columns expected\n";
if (n <= 0)
lyxerr << "positve number of rows expected\n";
setDefaults();
}
MathGridInset::MathGridInset(int m, int n, char v, string const & h)
: MathNestInset(m * n), rowinfo_(n), colinfo_(m), v_align_(v)
{
setDefaults();
valign(v);
halign(h);
}
MathInset::idx_type MathGridInset::index(row_type row, col_type col) const
{
return col + ncols() * row;
@ -59,6 +73,10 @@ MathInset::idx_type MathGridInset::index(row_type row, col_type col) const
void MathGridInset::setDefaults()
{
if (ncols() <= 0)
lyxerr << "positve number of columns expected\n";
if (nrows() <= 0)
lyxerr << "positve number of rows expected\n";
for (col_type col = 0; col < ncols(); ++col) {
colinfo_[col].align_ = defaultColAlign(col);
colinfo_[col].skip_ = defaultColSpace(col);
@ -268,7 +286,7 @@ string MathGridInset::eolString(row_type row) const
// make sure an upcoming '[' does not break anything
MathArray const & c = cell(index(row + 1, 0));
if (c.size() && c.begin()->nucleus()->getChar() == '[')
if (c.size() && (*c.begin())->getChar() == '[')
return "\\\\[0pt]\n";
return "\\\\\n";
@ -367,8 +385,9 @@ bool MathGridInset::idxUp(idx_type & idx, pos_type & pos) const
{
if (idx < ncols())
return false;
int x = cellXOffset(idx) + xcell(idx).pos2x(pos);
idx -= ncols();
pos = 0;
pos = xcell(idx).x2pos(x - cellXOffset(idx));
return true;
}
@ -377,8 +396,9 @@ bool MathGridInset::idxDown(idx_type & idx, pos_type & pos) const
{
if (idx >= ncols() * (nrows() - 1))
return false;
int x = cellXOffset(idx) + xcell(idx).pos2x(pos);
idx += ncols();
pos = 0;
pos = xcell(idx).x2pos(x - cellXOffset(idx));
return true;
}

View File

@ -62,6 +62,8 @@ public:
/// Note: columns first!
MathGridInset(col_type m, row_type n);
///
MathGridInset(int m, int n, char valign, string const & halign);
///
void write(std::ostream &, bool fragile) const;
///
void metrics(MathStyles st) const;
@ -87,8 +89,8 @@ public:
const RowInfo & rowinfo(row_type row) const;
///
RowInfo & rowinfo(row_type row);
///
bool isGrid() const { return true; }
/// identifies GridInset
virtual MathGridInset * asGridInset() { return this; }
///
col_type ncols() const { return colinfo_.size(); }

View File

@ -38,8 +38,14 @@
class LaTeXFeatures;
class MathArrayInset;
class MathCharInset;
class MathGridInset;
class MathNestInset;
class MathScriptInset;
class MathMatrixInset;
class MathSpaceInset;
class MathMacroTemplate;
class MathInset {
public:
@ -166,26 +172,37 @@ public:
virtual void getXY(int & x, int & y) const;
///
virtual bool covers(int x, int y) const;
/// identifies things that can get scripts
virtual bool isScriptable() const { return false; }
/// identifies ScriptInsets
virtual bool isScriptInset() const { return false; }
/// identifies SpaceInsets
virtual bool isSpaceInset() const { return false; }
/// identifies GridInsets
virtual bool isGrid() const { return false; }
/// identifies ArrayInsets
virtual bool isArray() const { return false; }
/// identifies NestInsets
virtual MathNestInset * asNestInset() { return 0; }
/// identifies CharInsets
virtual MathCharInset const * asCharInset() const { return 0; }
/// identifies ScriptInsets
virtual MathScriptInset const * asScriptInset() const { return 0; }
/// identifies ScriptInsets
virtual MathScriptInset * asScriptInset() { return 0; }
/// identifies MatrixInsets
virtual MathMatrixInset const * asMatrixInset() const { return 0; }
/// identifies MatrixInsets
virtual MathMatrixInset * asMatrixInset() { return 0; }
/// identifies SpaceInset
virtual MathSpaceInset * asSpaceInset() { return 0; }
/// identifies GridInset
virtual MathGridInset * asGridInset() { return 0; }
/// identifies ArrayInsets
virtual MathArrayInset * asArrayInset() { return 0; }
/// identifies macro templates
virtual MathMacroTemplate * asMacroTemplate() { return 0; }
/// identifies things that can get scripts
virtual bool isScriptable() const { return false; }
///
virtual bool isActive() const { return nargs() > 0; }
///
virtual bool isRelOp() const { return false; }
///
virtual bool isMacro() const { return false; }
///
virtual char getChar() const { return 0; }
///

View File

@ -32,13 +32,15 @@
using std::endl;
MathMacro::MathMacro(MathMacroTemplate const & t)
: MathNestInset(t.numargs()), tmplate_(&t)
MathMacro::MathMacro(string const & name)
: MathNestInset(MathMacroTable::provide(name)->asMacroTemplate()->numargs()),
tmplate_(MathMacroTable::provide(name))
{}
MathMacro::MathMacro(MathMacro const & t)
: MathNestInset(t), tmplate_(t.tmplate_) // don't copy 'expanded_'!
MathMacro::MathMacro(MathMacro const & m)
: MathNestInset(m),
tmplate_(m.tmplate_) // don't copy 'expanded_'!
{}
@ -51,7 +53,7 @@ MathInset * MathMacro::clone() const
const char * MathMacro::name() const
{
return tmplate_->name().c_str();
return tmplate_->asMacroTemplate()->name().c_str();
}
@ -139,11 +141,11 @@ void MathMacro::dump() const
MathMacroTable::dump();
lyxerr << "\n macro: '" << this << "'\n";
lyxerr << " name: '" << name() << "'\n";
lyxerr << " template: '" << tmplate_ << "'\n";
lyxerr << " template: '" << *tmplate_ << "'\n";
lyxerr << " template: '"; tmplate_->write(lyxerr, false); lyxerr << "'\n";
lyxerr << endl;
}
void MathMacro::write(std::ostream & os, bool fragile) const
{
os << '\\' << name();

View File

@ -26,6 +26,7 @@
#include "math_nestinset.h"
#include "math_macroarg.h"
#include "LString.h"
class MathMacroTemplate;
@ -37,7 +38,7 @@ class MathMacroTemplate;
class MathMacro : public MathNestInset {
public:
/// A macro can be built from an existing template
explicit MathMacro(MathMacroTemplate const &);
explicit MathMacro(string const &);
///
MathMacro(MathMacro const &);
///
@ -74,7 +75,7 @@ private:
char const * name() const;
///
MathMacroTemplate const * const tmplate_;
MathAtom & tmplate_;
///
mutable MathXArray expanded_;
};

View File

@ -24,21 +24,14 @@ void MathMacroTable::dump()
lyxerr << "\n------------------------------------------\n";
table_type::const_iterator it;
for (it = macro_table.begin(); it != macro_table.end(); ++it)
lyxerr << it->first << " [" << it->second.nargs() << "] : "
<< it->second << "\n";
lyxerr << it->first
<< " [" << it->second->asMacroTemplate()->nargs() << "] : "
<< it->second->cell(0) << "\n";
lyxerr << "------------------------------------------\n";
}
void MathMacroTable::insertTemplate(MathMacroTemplate const & p)
{
if (macro_table.find(p.name()) != macro_table.end())
lyxerr << "macro '" << p.name() << "' not new\n";
macro_table[p.name()] = p;
}
MathMacroTemplate & MathMacroTable::provideTemplate(string const & name)
MathAtom & MathMacroTable::provide(string const & name)
{
builtinMacros();
@ -53,28 +46,30 @@ MathMacroTemplate & MathMacroTable::provideTemplate(string const & name)
}
void MathMacroTable::createTemplate
(string const & name, int na, string const & text)
void MathMacroTable::create(string const & name, int na, string const & text)
{
MathMacroTemplate t(name, na);
t.cell(0) = mathed_parse_cell(text);
insertTemplate(t);
MathAtom t(new MathMacroTemplate(name, na));
t->cell(0) = mathed_parse_cell(text);
macro_table[name] = t;
}
bool MathMacroTable::hasTemplate(string const & name)
void MathMacroTable::create(string const & name, int na, MathArray const & ar)
{
MathAtom t(new MathMacroTemplate(name, na));
t->cell(0) = ar;
macro_table[name] = t;
}
bool MathMacroTable::has(string const & name)
{
builtinMacros();
return macro_table.find(name) != macro_table.end();
}
MathMacro * MathMacroTable::cloneTemplate(string const & name)
{
return new MathMacro(provideTemplate(name));
}
void MathMacroTable::builtinMacros()
{
static bool built = false;
@ -85,68 +80,68 @@ void MathMacroTable::builtinMacros()
built = true;
//lyxerr[Debug::MATHED] << "Building macros\n";
//createTemplate("emptyset", 0, "\\not0");
createTemplate("notin", 0, "\\not\\in");
createTemplate("slash", 0, "/");
//create("emptyset", 0, "\\not0");
create("notin", 0, "\\not\\in");
create("slash", 0, "/");
// fontmath.ltx
createTemplate("lnot", 0, "\\neg");
createTemplate("land", 0, "\\wedge");
createTemplate("lor", 0, "\\vee");
createTemplate("ne", 0, "\\neq");
createTemplate("le", 0, "\\leq");
createTemplate("ge", 0, "\\geq");
createTemplate("owns", 0, "\\ni");
createTemplate("gets", 0, "\\leftarrow");
createTemplate("to", 0, "\\rightarrow");
createTemplate("|", 0, "\\parallel");
create("lnot", 0, "\\neg");
create("land", 0, "\\wedge");
create("lor", 0, "\\vee");
create("ne", 0, "\\neq");
create("le", 0, "\\leq");
create("ge", 0, "\\geq");
create("owns", 0, "\\ni");
create("gets", 0, "\\leftarrow");
create("to", 0, "\\rightarrow");
create("|", 0, "\\parallel");
createTemplate("longleftrightarrow", 0, "\\leftarrow\\kern-6mu\\rightarrow");
createTemplate("Longleftrightarrow", 0, "\\Leftarrow\\kern-6mu\\Rightarrow");
createTemplate("doteq", 0, "\\stackrel{\\cdot}{=}");
create("longleftrightarrow", 0, "\\leftarrow\\kern-6mu\\rightarrow");
create("Longleftrightarrow", 0, "\\Leftarrow\\kern-6mu\\Rightarrow");
create("doteq", 0, "\\stackrel{\\cdot}{=}");
//createTemplate("models", 0, "|\\kern-9mu=");
//create("models", 0, "|\\kern-9mu=");
if (math_font_available(LM_TC_CMSY)) {
createTemplate("longrightarrow", 0, "\\lyxbar\\kern-5mu\\rightarrow");
createTemplate("longleftarrow", 0, "\\leftarrow\\kern-5mu\\lyxbar");
createTemplate("mapsto", 0, "\\mapstochar\\rightarrow");
createTemplate("longmapsto", 0, "\\mapstochar\\lyxbar\\kern-5mu\\rightarrow");
create("longrightarrow", 0, "\\lyxbar\\kern-5mu\\rightarrow");
create("longleftarrow", 0, "\\leftarrow\\kern-5mu\\lyxbar");
create("mapsto", 0, "\\mapstochar\\rightarrow");
create("longmapsto", 0, "\\mapstochar\\lyxbar\\kern-5mu\\rightarrow");
}
if (math_font_available(LM_TC_CMR)) {
createTemplate("Longrightarrow", 0, "\\lyxeq\\kern-3mu\\Rightarrow");
createTemplate("Longleftarrow", 0, "\\Leftarrow\\kern-9mu\\lyxeq");
create("Longrightarrow", 0, "\\lyxeq\\kern-3mu\\Rightarrow");
create("Longleftarrow", 0, "\\Leftarrow\\kern-9mu\\lyxeq");
}
if (math_font_available(LM_TC_CMM)) {
createTemplate("hookrightarrow", 0, "\\lhook\\kern-5mu\\rightarrow");
createTemplate("hookleftarrow", 0, "\\leftarrow\\kern-5mu\\rhook");
createTemplate("bowtie", 0, "\\triangleright\\kern-3mu\\triangleleft");
create("hookrightarrow", 0, "\\lhook\\kern-5mu\\rightarrow");
create("hookleftarrow", 0, "\\leftarrow\\kern-5mu\\rhook");
create("bowtie", 0, "\\triangleright\\kern-3mu\\triangleleft");
}
if (math_font_available(LM_TC_MSA)) {
//amsfonts.sty
createTemplate("dashrightarrow", 0, "\\lyxdabar\\lyxdabar\\lyxright");
createTemplate("dashleftarrow", 0, "\\lyxleft\\lyxdabar\\lyxdabar");
createTemplate("dasharrow", 0, "\\dashrightarrow");
createTemplate("Box", 0, "\\square");
createTemplate("Diamond", 0, "\\lozenge");
createTemplate("leadsto", 0, "\\rightsquigarrow");
create("dashrightarrow", 0, "\\lyxdabar\\lyxdabar\\lyxright");
create("dashleftarrow", 0, "\\lyxleft\\lyxdabar\\lyxdabar");
create("dasharrow", 0, "\\dashrightarrow");
create("Box", 0, "\\square");
create("Diamond", 0, "\\lozenge");
create("leadsto", 0, "\\rightsquigarrow");
// amssymb.sty
createTemplate("restriction", 0, "\\upharpoonright");
createTemplate("Doteq", 0, "\\doteqdot");
createTemplate("doublecup", 0, "\\Cup");
createTemplate("doublecap", 0, "\\Cap");
createTemplate("llless", 0, "\\lll");
createTemplate("gggtr", 0, "\\ggg");
create("restriction", 0, "\\upharpoonright");
create("Doteq", 0, "\\doteqdot");
create("doublecup", 0, "\\Cup");
create("doublecap", 0, "\\Cap");
create("llless", 0, "\\lll");
create("gggtr", 0, "\\ggg");
}
//createTemplate("lint", 4, "\\int_#1^#2#3 d#4");
//createTemplate("silentmult", 0, "\\cdot");
//createTemplate("binom", 2, "\\left(\\frac#1#2\\right)");
//create("lint", 4, "\\int_#1^#2#3 d#4");
//create("silentmult", 0, "\\cdot");
//create("binom", 2, "\\left(\\frac#1#2\\right)");
}

View File

@ -4,34 +4,30 @@
#include <map>
#include "LString.h"
#include "math_macrotemplate.h"
#include "math_atom.h"
#ifdef __GNUG__
#pragma interface
#endif
class MathMacro;
class MathArray;
///
struct MathMacroTable {
public:
///
static void insertTemplate(MathMacroTemplate const &);
static void create(string const &, int, string const &);
///
static MathMacroTemplate & provideTemplate(string const &);
static void create(string const &, int, MathArray const &);
///
static bool hasTemplate(string const &);
static MathAtom & provide(string const &);
///
static MathMacro * cloneTemplate(string const &);
///
static void createTemplate(string const &, int, string const &);
static bool has(string const &);
///
static void builtinMacros();
private:
///
typedef std::map<string, MathMacroTemplate> table_type;
typedef std::map<string, MathAtom> table_type;
//
static table_type macro_table;
public:

View File

@ -24,7 +24,7 @@ MathMacroTemplate::MathMacroTemplate(string const & nm, int numargs)
MathInset * MathMacroTemplate::clone() const
{
lyxerr << "cloning MacroTemplate!\n";
//lyxerr << "cloning MacroTemplate!\n";
return new MathMacroTemplate(*this);
}

View File

@ -36,6 +36,8 @@ public:
void draw(Painter &, int x, int y) const;
///
void metrics(MathStyles st) const;
/// identifies macro templates
MathMacroTemplate * asMacroTemplate() { return this; }
private:
///
int numargs_;

View File

@ -36,7 +36,7 @@ int getCols(MathInsetTypes type)
int firstRelOp(MathArray const & array)
{
for (MathArray::const_iterator it = array.begin(); it != array.end(); ++it)
if (it->nucleus()->isRelOp())
if ((*it)->isRelOp())
return it - array.begin();
return array.size();
}

View File

@ -50,6 +50,10 @@ public:
std::vector<string> const getLabelList() const;
///
void validate(LaTeXFeatures & features) const;
/// identifies MatrixInsets
virtual MathMatrixInset const * asMatrixInset() const { return this; }
/// identifies MatrixInsets
virtual MathMatrixInset * asMatrixInset() { return this; }
///
void addRow(row_type);

View File

@ -148,10 +148,10 @@ void MathNestInset::dump() const
}
void MathNestInset::push_back(MathInset * p)
void MathNestInset::push_back(MathAtom const & t)
{
if (nargs())
cells_.back().data_.push_back(p);
cells_.back().data_.push_back(t);
else
lyxerr << "can't push without a cell\n";
}

View File

@ -24,6 +24,8 @@ public:
void draw(Painter &, int x, int y) const;
/// appends itself with macro arguments substituted
void substitute(MathMacro const & macro);
/// identifies NestInsets
MathNestInset * asNestInset() { return this; }
/// The left key
bool idxLeft(idx_type & idx, pos_type & pos) const;
@ -60,7 +62,7 @@ public:
///
bool isActive() const { return nargs() > 0; }
///
void push_back(MathInset *);
void push_back(MathAtom const &);
///
void dump() const;

View File

@ -62,6 +62,11 @@ bool stared(string const & s)
}
void add(MathArray & ar, char c, MathTextCodes code)
{
ar.push_back(MathAtom(new MathCharInset(c, code)));
}
// These are TeX's catcodes
enum CatCode {
@ -199,9 +204,9 @@ public:
Parser(istream & is);
///
MathMacroTemplate * parse_macro();
string parse_macro();
///
MathMatrixInset * parse_normal();
bool parse_normal(MathAtom &);
///
void parse_into(MathArray & array, unsigned flags, MathTextCodes = LM_TC_MIN);
///
@ -217,7 +222,7 @@ private:
///
void error(string const & msg);
///
void parse_lines(MathGridInset * p, bool numbered, bool outmost);
bool parse_lines(MathAtom & t, bool numbered, bool outmost);
private:
///
@ -426,8 +431,14 @@ void Parser::error(string const & msg)
}
void Parser::parse_lines(MathGridInset * p, bool numbered, bool outmost)
{
bool Parser::parse_lines(MathAtom & t, bool numbered, bool outmost)
{
MathGridInset * p = t->asGridInset();
if (!p) {
lyxerr << "error in Parser::parse_lines() 1\n";
return false;
}
const int cols = p->ncols();
// save global variables
@ -453,7 +464,11 @@ void Parser::parse_lines(MathGridInset * p, bool numbered, bool outmost)
}
if (outmost) {
MathMatrixInset * m = static_cast<MathMatrixInset *>(p);
MathMatrixInset * m = t->asMatrixInset();
if (!m) {
lyxerr << "error in Parser::parse_lines() 2\n";
return false;
}
m->numbered(row, curr_num_);
m->label(row, curr_label_);
if (curr_skip_.size()) {
@ -474,41 +489,46 @@ void Parser::parse_lines(MathGridInset * p, bool numbered, bool outmost)
// restore "global" variables
curr_num_ = saved_num;
curr_label_ = saved_label;
return true;
}
MathMacroTemplate * Parser::parse_macro()
string Parser::parse_macro()
{
string name = "{error}";
while (nextToken().cat() == catSpace)
getToken();
if (getToken().cs() != "newcommand") {
lyxerr << "\\newcommand expected\n";
return 0;
return name;
}
if (getToken().cat() != catBegin) {
lyxerr << "'{' expected\n";
return 0;
return name;
}
string name = getToken().cs();
name = getToken().cs();
if (getToken().cat() != catEnd) {
lyxerr << "'}' expected\n";
return 0;
return name;
}
string arg = getArg('[', ']');
int narg = arg.empty() ? 0 : atoi(arg.c_str());
//lyxerr << "creating macro " << name << " with " << narg << "args\n";
MathMacroTemplate * p = new MathMacroTemplate(name, narg);
parse_into(p->cell(0), FLAG_BRACE | FLAG_BRACE_LAST);
return p;
string arg = getArg('[', ']');
int narg = arg.empty() ? 0 : atoi(arg.c_str());
MathArray ar;
parse_into(ar, FLAG_BRACE | FLAG_BRACE_LAST);
MathMacroTable::create(name, narg, ar);
return name;
}
MathMatrixInset * Parser::parse_normal()
bool Parser::parse_normal(MathAtom & matrix)
{
while (nextToken().cat() == catSpace)
getToken();
@ -516,14 +536,14 @@ MathMatrixInset * Parser::parse_normal()
Token const & t = getToken();
if (t.cat() == catMath || t.cs() == "(") {
MathMatrixInset * p = new MathMatrixInset(LM_OT_SIMPLE);
parse_into(p->cell(0), 0);
return p;
matrix = MathAtom(new MathMatrixInset(LM_OT_SIMPLE));
parse_into(matrix->cell(0), 0);
return true;
}
if (!t.cs().size()) {
lyxerr << "start of math expected, got '" << t << "'\n";
return 0;
return false;
}
string const & cs = t.cs();
@ -531,7 +551,8 @@ MathMatrixInset * Parser::parse_normal()
if (cs == "[") {
curr_num_ = 0;
curr_label_.erase();
MathMatrixInset * p = new MathMatrixInset(LM_OT_EQUATION);
matrix = MathAtom(new MathMatrixInset(LM_OT_EQUATION));
MathMatrixInset * p = matrix->asMatrixInset();
parse_into(p->cell(0), 0);
p->numbered(0, curr_num_);
p->label(0, curr_label_);
@ -540,7 +561,7 @@ MathMatrixInset * Parser::parse_normal()
if (cs != "begin") {
lyxerr << "'begin' of un-simple math expected, got '" << cs << "'\n";
return 0;
return false;
}
string const name = getArg('{', '}');
@ -548,60 +569,54 @@ MathMatrixInset * Parser::parse_normal()
if (name == "equation" || name == "equation*") {
curr_num_ = !stared(name);
curr_label_.erase();
MathMatrixInset * p = new MathMatrixInset(LM_OT_EQUATION);
matrix = MathAtom(new MathMatrixInset(LM_OT_EQUATION));
MathMatrixInset * p = matrix->asMatrixInset();
parse_into(p->cell(0), FLAG_END);
p->numbered(0, curr_num_);
p->label(0, curr_label_);
return p;
return true;
}
if (name == "eqnarray" || name == "eqnarray*") {
MathMatrixInset * p = new MathMatrixInset(LM_OT_EQNARRAY);
parse_lines(p, !stared(name), true);
return p;
matrix = MathAtom(new MathMatrixInset(LM_OT_EQNARRAY));
return parse_lines(matrix, !stared(name), true);
}
if (name == "align" || name == "align*") {
MathMatrixInset * p = new MathMatrixInset(LM_OT_ALIGN);
parse_lines(p, !stared(name), true);
return p;
matrix = MathAtom(new MathMatrixInset(LM_OT_ALIGN));
return parse_lines(matrix, !stared(name), true);
}
if (name == "alignat" || name == "alignat*") {
MathMatrixInset * p =
new MathMatrixInset(LM_OT_ALIGNAT, 2 * atoi(getArg('{', '}').c_str()));
parse_lines(p, !stared(name), true);
return p;
int nc = 2 * atoi(getArg('{', '}').c_str());
matrix = MathAtom(new MathMatrixInset(LM_OT_ALIGNAT, nc));
return parse_lines(matrix, !stared(name), true);
}
if (name == "xalignat" || name == "xalignat*") {
MathMatrixInset * p =
new MathMatrixInset(LM_OT_XALIGNAT, 2 * atoi(getArg('{', '}').c_str()));
parse_lines(p, !stared(name), true);
return p;
int nc = 2 * atoi(getArg('{', '}').c_str());
matrix = MathAtom(new MathMatrixInset(LM_OT_XALIGNAT, nc));
return parse_lines(matrix, !stared(name), true);
}
if (name == "xxalignat") {
MathMatrixInset * p =
new MathMatrixInset(LM_OT_XXALIGNAT, 2 * atoi(getArg('{', '}').c_str()));
parse_lines(p, !stared(name), true);
return p;
int nc = 2 * atoi(getArg('{', '}').c_str());
matrix = MathAtom(new MathMatrixInset(LM_OT_XXALIGNAT, nc));
return parse_lines(matrix, !stared(name), true);
}
if (name == "multline" || name == "multline*") {
MathMatrixInset * p = new MathMatrixInset(LM_OT_MULTLINE);
parse_lines(p, !stared(name), true);
return p;
matrix = MathAtom(new MathMatrixInset(LM_OT_MULTLINE));
return parse_lines(matrix, !stared(name), true);
}
if (name == "gather" || name == "gather*") {
MathMatrixInset * p = new MathMatrixInset(LM_OT_GATHER);
parse_lines(p, !stared(name), true);
return p;
matrix = MathAtom(new MathMatrixInset(LM_OT_GATHER));
return parse_lines(matrix, !stared(name), true);
}
lyxerr[Debug::MATHED] << "1: unknown math environment: " << name << "\n";
return 0;
return false;
}
@ -610,6 +625,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
MathTextCodes yyvarcode = LM_TC_MIN;
bool panic = false;
int limits = 0;
while (good()) {
Token const & t = getToken();
@ -658,45 +674,52 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
break;
else if (t.cat() == catLetter)
array.push_back(new MathCharInset(t.character(), yyvarcode));
add(array, t.character(), yyvarcode);
else if (t.cat() == catSpace &&
(yyvarcode == LM_TC_TEXTRM || code == LM_TC_TEXTRM))
array.push_back(new MathCharInset(' ', yyvarcode));
add(array, ' ', yyvarcode);
else if (t.cat() == catParameter) {
Token const & n = getToken();
MathMacroArgument * p = new MathMacroArgument(n.character() - '0');
array.push_back(p);
array.push_back(MathAtom(new MathMacroArgument(n.character() - '0')));
}
else if (t.cat() == catBegin) {
array.push_back(new MathCharInset('{', LM_TC_TEX));
add(array, '{', LM_TC_TEX);
}
else if (t.cat() == catEnd) {
if (flags & FLAG_BRACE_LAST)
return;
array.push_back(new MathCharInset('}', LM_TC_TEX));
add(array, '}', LM_TC_TEX);
}
else if (t.cat() == catAlign) {
lyxerr << "found tab unexpectedly, array: '" << array << "'\n";
array.push_back(new MathCharInset('&', LM_TC_TEX));
add(array, '&', LM_TC_TEX);
}
else if (t.cat() == catSuper || t.cat() == catSub) {
bool up = (t.cat() == catSuper);
if (array.empty())
array.push_back(new MathCharInset(' '));
parse_into(array.back().ensure(up)->cell(0), FLAG_ITEM);
MathScriptInset * p = 0;
if (array.size())
p = array.back()->asScriptInset();
if (!p || p->has(up)) {
array.push_back(MathAtom(new MathScriptInset(up)));
p = array.back()->asScriptInset();
}
p->ensure(up);
parse_into(p->cell(up), FLAG_ITEM);
p->limits(limits);
limits = 0;
}
else if (t.character() == ']' && (flags & FLAG_BRACK_END))
return;
else if (t.cat() == catOther)
array.push_back(new MathCharInset(t.character(), yyvarcode));
add(array, t.character(), yyvarcode);
//
// codesequences
@ -722,11 +745,11 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
array.push_back(createMathInset("\\"));
}
else if (t.cs() == "limits" && array.size())
array.back().limits(1);
else if (t.cs() == "limits")
limits = 1;
else if (t.cs() == "nolimits" && array.size())
array.back().limits(-1);
else if (t.cs() == "nolimits")
limits = -1;
else if (t.cs() == "nonumber")
curr_num_ = false;
@ -737,13 +760,13 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
else if (t.cs() == "sqrt") {
char c = getChar();
if (c == '[') {
array.push_back(new MathRootInset);
parse_into(array.back().nucleus()->cell(0), FLAG_BRACK_END);
parse_into(array.back().nucleus()->cell(1), FLAG_ITEM);
array.push_back(MathAtom(new MathRootInset));
parse_into(array.back()->cell(0), FLAG_BRACK_END);
parse_into(array.back()->cell(1), FLAG_ITEM);
} else {
putback();
array.push_back(new MathSqrtInset);
parse_into(array.back().nucleus()->cell(0), FLAG_ITEM);
array.push_back(MathAtom(new MathSqrtInset));
parse_into(array.back()->cell(0), FLAG_ITEM);
}
}
@ -752,7 +775,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
MathArray ar;
parse_into(ar, FLAG_RIGHT);
string r = getToken().asString();
MathDelimInset * dl = new MathDelimInset(l, r);
MathAtom dl(new MathDelimInset(l, r));
dl->cell(0) = ar;
array.push_back(dl);
}
@ -783,15 +806,12 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
if (name == "array") {
string const valign = getArg('[', ']') + 'c';
string const halign = getArg('{', '}');
MathArrayInset * m = new MathArrayInset(halign.size(), 1);
m->valign(valign[0]);
m->halign(halign);
parse_lines(m, false, false);
array.push_back(m);
array.push_back(
MathAtom(new MathArrayInset(halign.size(), 1, valign[0], halign)));
parse_lines(array.back(), false, false);
} else if (name == "split") {
MathSplitInset * m = new MathSplitInset(1);
parse_lines(m, false, false);
array.push_back(m);
array.push_back(MathAtom(new MathSplitInset(1)));
parse_lines(array.back(), false, false);
} else
lyxerr[Debug::MATHED] << "unknow math inset begin '" << name << "'\n";
}
@ -811,7 +831,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
if (isValidLength(s))
break;
}
array.push_back(new MathKernInset(s));
array.push_back(MathAtom(new MathKernInset(s)));
}
else if (t.cs() == "label") {
@ -825,11 +845,11 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
}
else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") {
MathInset * p = createMathInset(t.cs());
MathAtom p = createMathInset(t.cs());
// search backward for position of last '{' if any
int pos;
for (pos = array.size() - 1; pos >= 0; --pos)
if (array.at(pos)->nucleus()->getChar() == '{')
if (array.at(pos)->getChar() == '{')
break;
if (pos >= 0) {
// found it -> use the part after '{' as "numerator"
@ -849,7 +869,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
p->cell(0).swap(array);
parse_into(p->cell(1), FLAG_BLOCK);
}
array.push_back(p);
array.push_back(MathAtom(p));
}
else if (t.cs().size()) {
@ -867,7 +887,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
MathArray ar;
parse_into(ar, FLAG_ITEM, t);
for (MathArray::iterator it = ar.begin(); it != ar.end(); ++it)
it->nucleus()->handleFont(t);
(*it)->handleFont(t);
array.push_back(ar);
// undo catcode changes
@ -879,7 +899,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
yyvarcode = static_cast<MathTextCodes>(l->id);
else {
MathInset * p = createMathInset(t.cs());
MathAtom p = createMathInset(t.cs());
for (MathInset::idx_type i = 0; i < p->nargs(); ++i)
parse_into(p->cell(i), FLAG_ITEM);
array.push_back(p);
@ -887,16 +907,10 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
}
else {
MathInset * p = createMathInset(t.cs());
if (p) {
for (MathInset::idx_type i = 0; i < p->nargs(); ++i)
parse_into(p->cell(i), FLAG_ITEM);
array.push_back(p);
} else {
error("Unrecognized token");
//lyxerr[Debug::MATHED] << "[" << t << "]\n";
lyxerr << t << "\n";
}
MathAtom p = createMathInset(t.cs());
for (MathInset::idx_type i = 0; i < p->nargs(); ++i)
parse_into(p->cell(i), FLAG_ITEM);
array.push_back(p);
}
}
@ -917,6 +931,8 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code)
}
}
} // anonymous namespace
@ -932,20 +948,20 @@ MathArray mathed_parse_cell(string const & str)
MathMacroTemplate * mathed_parse_macro(string const & str)
string mathed_parse_macro(string const & str)
{
istringstream is(str.c_str());
Parser parser(is);
return parser.parse_macro();
}
MathMacroTemplate * mathed_parse_macro(istream & is)
string mathed_parse_macro(istream & is)
{
Parser parser(is);
return parser.parse_macro();
}
MathMacroTemplate * mathed_parse_macro(LyXLex & lex)
string mathed_parse_macro(LyXLex & lex)
{
Parser parser(lex);
return parser.parse_macro();
@ -953,21 +969,21 @@ MathMacroTemplate * mathed_parse_macro(LyXLex & lex)
MathMatrixInset * mathed_parse_normal(string const & str)
bool mathed_parse_normal(MathAtom & t, string const & str)
{
istringstream is(str.c_str());
Parser parser(is);
return parser.parse_normal();
return parser.parse_normal(t);
}
MathMatrixInset * mathed_parse_normal(istream & is)
bool mathed_parse_normal(MathAtom & t, istream & is)
{
Parser parser(is);
return parser.parse_normal();
return parser.parse_normal(t);
}
MathMatrixInset * mathed_parse_normal(LyXLex & lex)
bool mathed_parse_normal(MathAtom & t, LyXLex & lex)
{
Parser parser(lex);
return parser.parse_normal();
return parser.parse_normal(t);
}

View File

@ -28,6 +28,8 @@
class MathMatrixInset;
class MathMacroTemplate;
class MathAtom;
class MathArray;
class LyXLex;
///
@ -133,12 +135,12 @@ latexkeys const * in_word_set(string const & str);
///
void ReadSymbols(string const & file);
MathMatrixInset * mathed_parse_normal(string const &);
MathMatrixInset * mathed_parse_normal(std::istream &);
MathMatrixInset * mathed_parse_normal(LyXLex &);
bool mathed_parse_normal(MathAtom &, string const &);
bool mathed_parse_normal(MathAtom &, std::istream &);
bool mathed_parse_normal(MathAtom &, LyXLex &);
MathMacroTemplate * mathed_parse_macro(string const &);
MathMacroTemplate * mathed_parse_macro(std::istream &);
MathMacroTemplate * mathed_parse_macro(LyXLex &);
string mathed_parse_macro(string const &);
string mathed_parse_macro(std::istream &);
string mathed_parse_macro(LyXLex &);
#endif

View File

@ -79,15 +79,17 @@ void MathRootInset::writeNormal(std::ostream & os) const
os << "] ";
}
bool MathRootInset::idxUp(int & idx, int & pos) const
{
if (idx == 0)
return false;
idx = 0;
pos = 0;
pos = cell(0).size();
return true;
}
bool MathRootInset::idxDown(int & idx, int & pos) const
{
if (idx == 1)

View File

@ -1,6 +1,8 @@
#include <config.h>
#include "debug.h"
#include "support.h"
#include "support/LOstream.h"
#include "support/LAssert.h"
#ifdef __GNUG__
#pragma implementation
@ -9,9 +11,21 @@
#include "math_scriptinset.h"
MathScriptInset::MathScriptInset()
: MathNestInset(2), limits_(0)
{
script_[0] = false;
script_[1] = false;
}
MathScriptInset::MathScriptInset(bool up)
: MathNestInset(1), up_(up)
{}
: MathNestInset(2), limits_(0)
{
script_[0] = !up;
script_[1] = up;
}
MathInset * MathScriptInset::clone() const
@ -25,27 +39,258 @@ MathScriptInset const * MathScriptInset::asScriptInset() const
return this;
}
void MathScriptInset::write(std::ostream & os, bool fragile) const
MathScriptInset * MathScriptInset::asScriptInset()
{
cell(0).write(os, fragile);
return this;
}
MathXArray const & MathScriptInset::up() const
{
return xcell(1);
}
MathXArray const & MathScriptInset::down() const
{
return xcell(0);
}
MathXArray & MathScriptInset::up()
{
return xcell(1);
}
MathXArray & MathScriptInset::down()
{
return xcell(0);
}
void MathScriptInset::ensure(bool up)
{
script_[up] = true;
}
int MathScriptInset::dy0(MathInset const * nuc) const
{
int nd = ndes(nuc);
if (!hasDown())
return nd;
int des = down().ascent();
if (hasLimits(nuc))
des += nd + 2;
else
des = std::max(des, nd);
return des;
}
int MathScriptInset::dy1(MathInset const * nuc) const
{
int na = nasc(nuc);
if (!hasUp())
return na;
int asc = up().descent();
if (hasLimits(nuc))
asc += na + 2;
else
asc = std::max(asc, na);
asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I'));
return asc;
}
int MathScriptInset::dx0(MathInset const * nuc) const
{
lyx::Assert(hasDown());
return hasLimits(nuc) ? (width(nuc) - down().width()) / 2 : nwid(nuc);
}
int MathScriptInset::dx1(MathInset const * nuc) const
{
lyx::Assert(hasUp());
return hasLimits(nuc) ? (width(nuc) - up().width()) / 2 : nwid(nuc);
}
int MathScriptInset::dxx(MathInset const * nuc) const
{
//lyx::Assert(nuc());
return hasLimits(nuc) ? (width(nuc) - nwid(nuc)) / 2 : 0;
}
int MathScriptInset::ascent(MathInset const * nuc) const
{
return dy1(nuc) + (hasUp() ? up().ascent() : 0);
}
int MathScriptInset::descent(MathInset const * nuc) const
{
return dy0(nuc) + (hasDown() ? down().descent() : 0);
}
int MathScriptInset::width(MathInset const * nuc) const
{
int wid = 0;
if (hasLimits(nuc)) {
wid = nwid(nuc);
if (hasUp())
wid = std::max(wid, up().width());
if (hasDown())
wid = std::max(wid, down().width());
} else {
if (hasUp())
wid = std::max(wid, up().width());
if (hasDown())
wid = std::max(wid, down().width());
wid += nwid(nuc);
}
return wid;
}
int MathScriptInset::nwid(MathInset const * nuc) const
{
return nuc ?
nuc->width() :
mathed_char_width(LM_TC_TEX, LM_ST_TEXT, '.');
}
int MathScriptInset::nasc(MathInset const * nuc) const
{
return nuc ? nuc->ascent()
: mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I');
}
int MathScriptInset::ndes(MathInset const * nuc) const
{
return nuc ? nuc->descent()
: mathed_char_descent(LM_TC_VAR, LM_ST_TEXT, 'I');
}
void MathScriptInset::metrics(MathStyles st) const
{
size_ = st;
xcell(0).metrics(st);
width_ = xcell(0).width();
ascent_ = xcell(0).ascent();
descent_ = xcell(0).descent();
//lyxerr << "MathScriptInset::metrics: w: " << width_ << " a: " << ascent_
// << " d: " << descent_ << "\n";
{
metrics(0, st);
}
void MathScriptInset::metrics(MathInset const * nuc, MathStyles st) const
{
MathNestInset::metrics(st);
if (nuc)
nuc->metrics(st);
ascent_ = ascent(nuc);
descent_ = descent(nuc);
width_ = width(nuc);
}
void MathScriptInset::draw(Painter & pain, int x, int y) const
{
{
//lyxerr << "unexpected call to MathScriptInset::draw()\n";
draw(0, pain, x, y);
}
void MathScriptInset::draw(MathInset const * nuc, Painter & pain,
int x, int y) const
{
xo(x);
yo(y);
xcell(0).draw(pain, x, y);
if (nuc)
nuc->draw(pain, x + dxx(nuc), y);
else
drawStr(pain, LM_TC_TEX, LM_ST_TEXT, x + dxx(nuc), y, ".");
if (hasUp())
up().draw(pain, x + dx1(nuc), y - dy1(nuc));
if (hasDown())
down().draw(pain, x + dx0(nuc), y + dy0(nuc));
}
void MathScriptInset::write(std::ostream & os, bool fragile) const
{
//lyxerr << "unexpected call to MathScriptInset::write()\n";
write(0, os, fragile);
}
void MathScriptInset::write(MathInset const * nuc, std::ostream & os,
bool fragile) const
{
if (nuc) {
nuc->write(os, fragile);
if (nuc->takesLimits()) {
if (limits_ == -1)
os << "\\nolimits ";
if (limits_ == 1)
os << "\\limits ";
}
}
else
os << "{}";
if (hasDown() && down().data_.size()) {
os << "_{";
down().data_.write(os, fragile);
os << "}";
}
if (hasUp() && up().data_.size()) {
os << "^{";
up().data_.write(os, fragile);
os << "}";
}
}
bool MathScriptInset::hasLimits(MathInset const * nuc) const
{
return limits_ == 1 || (limits_ == 0 && nuc && nuc->isScriptable());
}
void MathScriptInset::removeEmptyScripts()
{
for (int i = 0; i <= 1; ++i)
if (script_[i] && !cell(i).size())
script_[i] = false;
}
void MathScriptInset::removeScript(bool up)
{
cell(up).clear();
script_[up] = false;
}
bool MathScriptInset::has(bool up) const
{
return script_[up];
}
bool MathScriptInset::hasUp() const
{
return script_[1];
}
bool MathScriptInset::hasDown() const
{
return script_[0];
}

View File

@ -14,6 +14,8 @@
class MathScriptInset : public MathNestInset {
public:
///
MathScriptInset();
///
explicit MathScriptInset(bool up);
///
@ -24,15 +26,75 @@ public:
void metrics(MathStyles st) const;
///
void draw(Painter &, int x, int y) const;
///
void write(MathInset const * nucleus, std::ostream &, bool fragile) const;
///
void metrics(MathInset const * nucleus, MathStyles st) const;
///
void draw(MathInset const * nucleus, Painter &, int x, int y) const;
///
int ascent(MathInset const * nucleus) const;
///
int descent(MathInset const * nucleus) const;
///
int width(MathInset const * nucleus) const;
///
MathScriptInset const * asScriptInset() const;
///
bool up() const { return up_; }
MathScriptInset * asScriptInset();
/// set limits
void limits(int lim) { limits_ = lim; }
///
int limits() const { return limits_; }
///
bool down() const { return !up_; }
bool hasLimits(MathInset const * nucleus) const;
/// true if we have an "inner" position
MathXArray const & up() const;
/// returns subscript
MathXArray const & down() const;
/// returns superscript
MathXArray & up();
/// returns subscript
MathXArray & down();
/// do we have a superscript?
bool hasUp() const;
/// do we have a subscript?
bool hasDown() const;
/// do we have a script?
bool has(bool up) const;
/// remove script
void removeScript(bool up);
/// remove script
void removeEmptyScripts();
///
void ensure(bool up);
public:
/// returns x offset for main part
int dxx(MathInset const * nuc) const;
/// returns width of nucleus if any
int nwid(MathInset const * nuc) const;
private:
/// returns y offset for superscript
int dy0(MathInset const * nuc) const;
/// returns y offset for subscript
int dy1(MathInset const * nuc) const;
/// returns x offset for superscript
int dx0(MathInset const * nuc) const;
/// returns x offset for subscript
int dx1(MathInset const * nuc) const;
/// returns ascent of nucleus if any
int nasc(MathInset const * nuc) const;
/// returns descent of nucleus if any
int ndes(MathInset const * nuc) const;
/// possible subscript (index 0) and superscript (index 1)
bool script_[2];
///
bool up_;
int limits_;
};
#endif

View File

@ -25,7 +25,9 @@ public:
///
void metrics(MathStyles st) const;
///
bool isSpaceInset() const { return true; }
MathSpaceInset const * asSpaceInset() const { return this; }
///
MathSpaceInset * asSpaceInset() { return this; }
///
void incSpace();
private:

View File

@ -6,6 +6,7 @@
#include "xarray.h"
#include "math_inset.h"
#include "math_scriptinset.h"
#include "mathed/support.h"
#include "math_defs.h"
#include "Painter.h"
@ -29,12 +30,21 @@ void MathXArray::metrics(MathStyles st) const
width_ = 0;
//lyxerr << "MathXArray::metrics(): '" << data_ << "'\n";
for (size_type pos = 0; pos < data_.size(); ++pos) {
MathAtom const * p = data_.at(pos);
p->metrics(st);
ascent_ = std::max(ascent_, p->ascent());
descent_ = std::max(descent_, p->descent());
width_ += p->width();
for (const_iterator it = begin(); it != end(); ++it) {
MathInset const * p = it->nucleus();
if (MathScriptInset const * q = data_.asScript(it)) {
q->metrics(p, st);
ascent_ = std::max(ascent_, q->ascent(p));
descent_ = std::max(descent_, q->descent(p));
width_ += q->width(p);
++it;
} else {
p->metrics(st);
ascent_ = std::max(ascent_, p->ascent());
descent_ = std::max(descent_, p->descent());
width_ += p->width();
}
}
//lyxerr << "MathXArray::metrics(): '" << ascent_ << " "
// << descent_ << " " << width_ << "'\n";
@ -51,52 +61,60 @@ void MathXArray::draw(Painter & pain, int x, int y) const
return;
}
for (size_type pos = 0; pos < data_.size(); ++pos) {
MathAtom const * p = data_.at(pos);
p->draw(pain, x, y);
x += p->width();
for (const_iterator it = begin(); it != end(); ++it) {
MathInset const * p = it->nucleus();
if (MathScriptInset const * q = data_.asScript(it)) {
q->draw(p, pain, x, y);
x += q->width(p);
++it;
} else {
p->draw(pain, x, y);
x += p->width();
}
}
}
int MathXArray::pos2x(size_type targetpos, bool inner) const
int MathXArray::pos2x(size_type targetpos) const
{
int x = 0;
targetpos = std::min(targetpos, data_.size());
for (size_type pos = 0; pos < targetpos; ++pos)
x += width(pos);
if (inner)
x += innerwidth(targetpos);
const_iterator target = std::min(begin() + targetpos, end());
for (const_iterator it = begin(); it < target; ++it) {
MathInset const * p = it->nucleus();
if (MathScriptInset const * q = data_.asScript(it)) {
++it;
if (it < target)
x += q->width(p);
else // "half" position
x += q->dxx(p) + q->nwid(p);
} else
x += p->width();
}
return x;
}
MathArray::size_type MathXArray::x2pos(int targetx) const
{
size_type pos = 0;
int lastx = 0;
int currx = 0;
for ( ; currx < targetx && pos < data_.size(); ++pos) {
const_iterator it = begin();
int lastx = 0;
int currx = 0;
for ( ; currx < targetx && it < end(); ++it) {
lastx = currx;
currx += width(pos);
int wid = 0;
MathInset const * p = it->nucleus();
if (MathScriptInset const * q = data_.asScript(it)) {
wid = q->width(p);
++it;
} else
wid = p->width();
currx += wid;
}
if (abs(lastx - targetx) < abs(currx - targetx) && pos > 0)
--pos;
return pos;
}
int MathXArray::width(size_type pos) const
{
MathAtom const * t = data_.at(pos);
return t ? t->width() : 0;
}
int MathXArray::innerwidth(size_type pos) const
{
MathAtom const * t = data_.at(pos);
return t ? t->nwid() : 0;
if (abs(lastx - targetx) < abs(currx - targetx) && it != begin())
--it;
return it - begin();
}

View File

@ -17,7 +17,9 @@ class MathXArray
{
public:
///
typedef MathArray::size_type size_type;
typedef MathArray::size_type size_type;
///
typedef MathArray::const_iterator const_iterator;
///
MathXArray();
@ -31,13 +33,9 @@ public:
///
int yo() const { return yo_; }
///
int pos2x(size_type pos, bool inner) const;
int pos2x(size_type pos) const;
///
size_type x2pos(int pos) const;
///
int width(size_type pos) const;
///
int innerwidth(size_type pos) const;
///
int ascent() const { return ascent_; }
@ -49,8 +47,13 @@ public:
int width() const { return width_; }
///
MathStyles style() const { return style_; }
///
const_iterator begin() const { return data_.begin(); }
///
const_iterator end() const { return data_.end(); }
public:
///
MathArray data_;
///