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

View File

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

View File

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

View File

@ -23,6 +23,7 @@
#include "mathed/formulabase.h" #include "mathed/formulabase.h"
#include "math_defs.h" #include "math_defs.h"
#include "math_atom.h"
class MathMatrixInset; class MathMatrixInset;
@ -32,16 +33,10 @@ public:
/// ///
InsetFormula(); InsetFormula();
/// ///
InsetFormula(InsetFormula const &);
///
explicit InsetFormula(MathInsetTypes); explicit InsetFormula(MathInsetTypes);
/// ///
explicit InsetFormula(string const &); explicit InsetFormula(string const &);
/// ///
~InsetFormula();
///
void operator=(InsetFormula const &);
///
int ascent(BufferView *, LyXFont const &) const; int ascent(BufferView *, LyXFont const &) const;
/// ///
int descent(BufferView *, LyXFont const &) const; int descent(BufferView *, LyXFont const &) const;
@ -80,17 +75,22 @@ public:
/// ///
void handleExtern(string const & arg, BufferView * bv); void handleExtern(string const & arg, BufferView * bv);
/// ///
MathInset const * par() const;
///
bool display() const; bool display() const;
/// ///
bool ams() const; bool ams() const;
/// ///
MathInsetTypes getType() 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 #endif

View File

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

View File

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

View File

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

View File

@ -68,12 +68,12 @@ public:
/// ///
MathInsetTypes getType() const; MathInsetTypes getType() const;
/// ///
MathInset const * par() const;
///
void metrics() const; void metrics() const;
private:
/// ///
MathMacroTemplate const & tmacro() const; MathAtom const & par() const;
///
MathAtom & par();
private:
/// prefix in inset /// prefix in inset
string prefix() const; 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 MathInset * MathArrayInset::clone() const
{ {
return new MathArrayInset(*this); return new MathArrayInset(*this);

View File

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

View File

@ -20,34 +20,18 @@
#endif #endif
#include "math_atom.h" #include "math_atom.h"
#include "math_scriptinset.h" #include "math_inset.h"
#include "debug.h"
#include "support.h"
#include "support/LAssert.h" #include "support/LAssert.h"
MathAtom::MathAtom() MathAtom::MathAtom()
: nucleus_(0), limits_(0), xo_(0), yo_(0) : nucleus_(0)
{ {}
script_[0] = 0;
script_[1] = 0;
}
MathAtom::MathAtom(MathInset * p) MathAtom::MathAtom(MathInset * p)
: nucleus_(p), limits_(0), xo_(0), yo_(0) : nucleus_(p)
{ {}
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;
}
MathAtom::MathAtom(MathAtom const & p) MathAtom::MathAtom(MathAtom const & p)
@ -74,73 +58,30 @@ MathAtom::~MathAtom()
void MathAtom::done() void MathAtom::done()
{ {
delete nucleus_; delete nucleus_;
delete script_[0];
delete script_[1];
} }
void MathAtom::copy(MathAtom const & p) void MathAtom::copy(MathAtom const & p)
{ {
//cerr << "calling MathAtom::copy\n"; //cerr << "calling MathAtom::copy\n";
xo_ = p.xo_;
yo_ = p.yo_;
limits_ = p.limits_;
nucleus_ = p.nucleus_; nucleus_ = p.nucleus_;
script_[0] = p.script_[0];
script_[1] = p.script_[1];
if (nucleus_) if (nucleus_)
nucleus_ = nucleus_->clone(); 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 nucleus();
return os;
} }
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) 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 #ifndef MATH_ATOM_H
#define MATH_ATOM_H #define MATH_ATOM_H
#include <config.h>
#include <iosfwd>
#ifdef __GNUG__ #ifdef __GNUG__
#pragma interface #pragma interface
#endif #endif
#include "math_defs.h"
/** /**
The 'atom' is the major blob in math typesetting. And 'atom' consists The 'atom' is the major blob in math typesetting. And 'atom' consists
of a nucleus, an optional superscript, and an optional subscript. 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 Jules
*/ */
class LaTeXFeatures;
class MathCharInset;
class MathScriptInset;
class MathInset; class MathInset;
class MathMacro;
class MathArray;
class Painter;
class MathAtom { class MathAtom {
public: public:
@ -38,129 +27,23 @@ public:
MathAtom(MathAtom const &); MathAtom(MathAtom const &);
/// ///
explicit MathAtom(MathInset * p); explicit MathAtom(MathInset * p);
///
MathAtom(MathInset * p, MathScriptInset * up, MathScriptInset * down);
/// ///
virtual ~MathAtom(); virtual ~MathAtom();
/// ///
void operator=(MathAtom const &); void operator=(MathAtom const &);
/// ///
void swap(MathAtom &); MathInset * nucleus() const;
/// 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;
/// ///
int descent() const; MathInset * operator->() 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_;
private: private:
/// the following are used for positioning the cursor with the mouse ///
/// cached cursor start position in pixels from the document left MathInset * nucleus_;
mutable int xo_;
/// cached cursor start position in pixels from the document top
mutable int yo_;
/// raw copy /// raw copy
void copy(MathAtom const & p); void copy(MathAtom const & p);
/// raw destruction /// raw destruction
void done(); 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 #endif

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -38,8 +38,14 @@
class LaTeXFeatures; class LaTeXFeatures;
class MathArrayInset;
class MathCharInset; class MathCharInset;
class MathGridInset;
class MathNestInset;
class MathScriptInset; class MathScriptInset;
class MathMatrixInset;
class MathSpaceInset;
class MathMacroTemplate;
class MathInset { class MathInset {
public: public:
@ -166,26 +172,37 @@ public:
virtual void getXY(int & x, int & y) const; virtual void getXY(int & x, int & y) const;
/// ///
virtual bool covers(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 NestInsets
/// identifies ScriptInsets virtual MathNestInset * asNestInset() { return 0; }
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 CharInsets /// identifies CharInsets
virtual MathCharInset const * asCharInset() const { return 0; } virtual MathCharInset const * asCharInset() const { return 0; }
/// identifies ScriptInsets /// identifies ScriptInsets
virtual MathScriptInset const * asScriptInset() const { return 0; } 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 isActive() const { return nargs() > 0; }
/// ///
virtual bool isRelOp() const { return false; } virtual bool isRelOp() const { return false; }
/// ///
virtual bool isMacro() const { return false; } virtual bool isMacro() const { return false; }
/// ///
virtual char getChar() const { return 0; } virtual char getChar() const { return 0; }
/// ///

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,6 +50,10 @@ public:
std::vector<string> const getLabelList() const; std::vector<string> const getLabelList() const;
/// ///
void validate(LaTeXFeatures & features) 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); 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()) if (nargs())
cells_.back().data_.push_back(p); cells_.back().data_.push_back(t);
else else
lyxerr << "can't push without a cell\n"; lyxerr << "can't push without a cell\n";
} }

View File

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

View File

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

View File

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

View File

@ -1,6 +1,8 @@
#include <config.h> #include <config.h>
#include "debug.h" #include "debug.h"
#include "support.h"
#include "support/LOstream.h" #include "support/LOstream.h"
#include "support/LAssert.h"
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation #pragma implementation
@ -9,9 +11,21 @@
#include "math_scriptinset.h" #include "math_scriptinset.h"
MathScriptInset::MathScriptInset()
: MathNestInset(2), limits_(0)
{
script_[0] = false;
script_[1] = false;
}
MathScriptInset::MathScriptInset(bool up) MathScriptInset::MathScriptInset(bool up)
: MathNestInset(1), up_(up) : MathNestInset(2), limits_(0)
{} {
script_[0] = !up;
script_[1] = up;
}
MathInset * MathScriptInset::clone() const MathInset * MathScriptInset::clone() const
@ -25,27 +39,258 @@ MathScriptInset const * MathScriptInset::asScriptInset() const
return this; 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 void MathScriptInset::metrics(MathStyles st) const
{ {
size_ = st; metrics(0, st);
xcell(0).metrics(st); }
width_ = xcell(0).width();
ascent_ = xcell(0).ascent();
descent_ = xcell(0).descent(); void MathScriptInset::metrics(MathInset const * nuc, MathStyles st) const
//lyxerr << "MathScriptInset::metrics: w: " << width_ << " a: " << ascent_ {
// << " d: " << descent_ << "\n"; 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 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); xo(x);
yo(y); 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 { class MathScriptInset : public MathNestInset {
public: public:
///
MathScriptInset();
/// ///
explicit MathScriptInset(bool up); explicit MathScriptInset(bool up);
/// ///
@ -24,15 +26,75 @@ public:
void metrics(MathStyles st) const; void metrics(MathStyles st) const;
/// ///
void draw(Painter &, int x, int y) 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; 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: 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 #endif

View File

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

View File

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

View File

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