- Just moving the cursor in a math inset causes changing the buffer status
to (changed).
+- disable the insert->label menu item when in inline formula.
+
Eran Tromer:
- Entering \mathbf{c} in math mode is displayed as written (without
backslash)
+- I know the latex code of a lot of math symbols displayed by lyx,
+ but not all of them. Thus I have to use the math panel for only a single
+ symbol in a formula. I think it would be very useful, if the latex code
+ of the symbol would be displayed as a hint, if the mouse positioned over
+ it.
+
Marcus (Suran@gmx.net)
formulamacro.h \
math_arrayinset.C \
math_arrayinset.h \
+ math_charinset.C \
+ math_charinset.h \
math_cursor.C \
math_cursor.h \
math_decorationinset.C \
math_macrotable.h \
math_matrixinset.C \
math_matrixinset.h \
+ math_nestinset.C \
+ math_nestinset.h \
math_parser.C \
math_parser.h \
math_rootinset.C \
-
#ifdef __GNUG__
#pragma implementation
#endif
#include "math_inset.h"
+#include "math_charinset.h"
#include "debug.h"
#include "array.h"
#include "math_scriptinset.h"
-#include "math_parser.h"
#include "mathed/support.h"
using std::ostream;
void MathArray::deep_copy(int pos1, int pos2)
{
- for (int pos = pos1; pos < pos2; next(pos))
- if (isInset(pos)) {
- MathInset * p = nextInset(pos)->clone();
- memcpy(&bf_[pos + 1], &p, sizeof(p));
- }
+ for (int pos = pos1; pos < pos2; ++pos)
+ bf_[pos] = bf_[pos]->clone();
}
if (pos >= size() - 1)
return false;
- pos += item_size(pos);
+ ++pos;
return true;
}
if (pos == 0)
return false;
- pos -= item_size(pos - 1);
+ --pos;
return true;
}
}
-int MathArray::item_size(int pos) const
-{
- return 2 + (isInset(pos) ? sizeof(MathInset*) : 1);
-}
-
-
void MathArray::substitute(MathMacro const & m)
{
MathArray tmp;
- for (int pos = 0; pos < size(); next(pos)) {
- if (isInset(pos))
- nextInset(pos)->substitute(tmp, m);
- else
- tmp.push_back(getChar(pos), getCode(pos));
- }
+ for (int pos = 0; pos < size(); ++pos)
+ bf_[pos]->substitute(tmp, m);
swap(tmp);
}
MathInset * MathArray::nextInset(int pos) const
{
- if (!isInset(pos))
- return 0;
- MathInset * p;
- memcpy(&p, &bf_[0] + pos + 1, sizeof(p));
- return p;
+ return (pos == size()) ? 0 : bf_[pos];
}
MathInset * MathArray::prevInset(int pos) const
{
- if (!prev(pos))
- return 0;
- return nextInset(pos);
+ return (pos == 0) ? 0 : bf_[pos - 1];
}
unsigned char MathArray::getChar(int pos) const
{
- return pos < size() ? bf_[pos + 1] : '\0';
+ return (pos == size()) ? 0 : (bf_[pos]->getChar());
}
+/*
string MathArray::getString(int & pos) const
{
string s;
return s;
}
+*/
MathTextCodes MathArray::getCode(int pos) const
{
- return pos < size() ? MathTextCodes(bf_[pos]) : LM_TC_MIN;
+ return pos < size() ? (bf_[pos]->code()) : LM_TC_MIN;
}
void MathArray::setCode(int pos, MathTextCodes t)
{
- if (pos > size() || isInset(pos))
- return;
- bf_[pos] = t;
- bf_[pos + 2] = t;
+ bf_[pos]->code(t);
}
-
void MathArray::insert(int pos, MathInset * p)
{
- bf_.insert(bf_.begin() + pos, 2 + sizeof(p), LM_TC_INSET);
- memcpy(&bf_[pos + 1], &p, sizeof(p));
+ bf_.insert(bf_.begin() + pos, p);
}
void MathArray::insert(int pos, unsigned char b, MathTextCodes t)
{
- bf_.insert(bf_.begin() + pos, 3, t);
- bf_[pos + 1] = b;
+ bf_.insert(bf_.begin() + pos, new MathCharInset(b, t));
}
void MathArray::erase(int pos)
{
- if (pos < static_cast<int>(bf_.size()))
- erase(pos, pos + item_size(pos));
+ if (pos < size())
+ bf_.erase(bf_.begin() + pos);
}
void MathArray::erase(int pos1, int pos2)
{
- for (int pos = pos1; pos < pos2; next(pos))
- if (isInset(pos))
- delete nextInset(pos);
+ for (int pos = pos1; pos < pos2; ++pos)
+ delete nextInset(pos);
bf_.erase(bf_.begin() + pos1, bf_.begin() + pos2);
}
-bool MathArray::isInset(int pos) const
-{
- if (pos >= size())
- return false;
- return MathIsInset(static_cast<MathTextCodes>(bf_[pos]));
-}
-
-
-MathInset * MathArray::back_inset() const
+MathInset * MathArray::back() const
{
return prevInset(size());
}
void MathArray::dump(ostream & os) const
{
- for (int pos = 0; pos < size(); next(pos)) {
- if (isInset(pos))
- os << "<inset: " << nextInset(pos) << ">";
- else
- os << "<" << int(bf_[pos]) << " " << int(bf_[pos+1]) << ">";
- }
+ for (int pos = 0; pos < size(); ++pos)
+ os << "<" << nextInset(pos) << ">";
}
void MathArray::write(ostream & os, bool fragile) const
{
- if (empty())
- return;
-
- int brace = 0;
-
- for (int pos = 0; pos < size(); next(pos)) {
- if (isInset(pos)) {
-
- nextInset(pos)->write(os, fragile);
-
- } else {
-
- MathTextCodes fcode = getCode(pos);
- unsigned char c = getChar(pos);
-
- if (MathIsSymbol(fcode)) {
- latexkeys const * l = lm_get_key_by_id(c, LM_TK_SYM);
-
- if (l == 0) {
- l = lm_get_key_by_id(c, LM_TK_BIGSYM);
- }
-
- if (l) {
- os << '\\' << l->name << ' ';
- } else {
- lyxerr << "Could not find the LaTeX name for " << c << " and fcode " << fcode << "!" << std::endl;
- }
- } else {
- if (fcode >= LM_TC_RM && fcode <= LM_TC_TEXTRM)
- os << '\\' << math_font_name[fcode - LM_TC_RM] << '{';
-
- // Is there a standard logical XOR?
- if ((fcode == LM_TC_TEX && c != '{' && c != '}') ||
- (fcode == LM_TC_SPECIAL))
- os << '\\';
- else {
- if (c == '{')
- ++brace;
- if (c == '}')
- --brace;
- }
- if (c == '}' && fcode == LM_TC_TEX && brace < 0)
- lyxerr <<"Math warning: Unexpected closing brace.\n";
- else
- os << c;
- }
-
- if (fcode >= LM_TC_RM && fcode <= LM_TC_TEXTRM)
- os << '}';
-
- }
- }
-
- if (brace > 0)
- os << string(brace, '}');
+ for (int pos = 0; pos < size(); ++pos)
+ nextInset(pos)->write(os, fragile);
}
void MathArray::validate(LaTeXFeatures & features) const
{
- for (int pos = 0; pos < size(); next(pos))
- if (isInset(pos))
- nextInset(pos)->validate(features);
+ for (int pos = 0; pos < size(); ++pos)
+ nextInset(pos)->validate(features);
}
///
void pop_back();
///
- MathInset * back_inset() const;
+ MathInset * back() const;
///
void dump(std::ostream &) const;
///
void setCode(int pos, MathTextCodes t);
///
- bool isInset(int pos) const;
- ///
void write(std::ostream &, bool) const;
///
void writeNormal(std::ostream &) const;
void validate(LaTeXFeatures &) const;
private:
///
- typedef std::vector<unsigned char> buffer_type;
- ///
- typedef unsigned char value_type;
-
- ///
- int item_size(int pos) const;
+ typedef std::vector<MathInset *> buffer_type;
///
void deep_copy(int pos1, int pos2);
/// Buffer
}
-bool MathCursor::plainRight()
+void MathCursor::plainRight()
{
- return array().next(cursor().pos_);
+ ++cursor().pos_;
}
}
array().insert(cursor().pos_, p);
- array().next(cursor().pos_);
+ ++cursor().pos_;
}
if (!imacro_) {
imacro_ = new MathFuncInset("");
array().insert(cursor().pos_, imacro_);
- array().next(cursor().pos_);
+ ++cursor().pos_;
//insert(imacro_);
} else
lyxerr << "Math Warning: Already in macro mode" << endl;
getSelection(i1, i2);
if (i1.idx_ == i2.idx_) {
MathArray & ar = i1.cell();
- for (int pos = i1.pos_; pos != i2.pos_; ar.next(pos))
- if (!ar.isInset(pos) && isalnum(ar.getChar(pos))) {
+ for (int pos = i1.pos_; pos != i2.pos_; ++pos)
+ if (isalnum(ar.getChar(pos))) {
MathTextCodes c = ar.getCode(pos) == t ? LM_TC_VAR : t;
ar.setCode(pos, c);
}
///
bool plainLeft();
///
- bool plainRight();
+ void plainRight();
///
void plainErase();
///
MathDecorationInset::MathDecorationInset(latexkeys const * key)
- : MathInset(1), key_(key)
+ : MathNestInset(1), key_(key)
{
upper_ = key_->id != LM_underline && key_->id != LM_underbrace;
}
#ifndef MATH_DECORATIONINSET_H
#define MATH_DECORATIONINSET_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
struct latexkeys;
-class MathDecorationInset : public MathInset {
+class MathDecorationInset : public MathNestInset {
public:
///
explicit MathDecorationInset(latexkeys const *);
MathDelimInset::MathDelimInset(int l, int r)
- : MathInset(1), left_(l), right_(r)
+ : MathNestInset(1), left_(l), right_(r)
{}
#ifndef MATH_DELIMINSET_H
#define MATH_DELIMINSET_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
/** A delimiter
\author Alejandro Aguilar Sierra
*/
-class MathDelimInset : public MathInset {
+class MathDelimInset : public MathNestInset {
public:
///
MathDelimInset(int, int);
MathFracInset::MathFracInset(string const & name)
- : MathInset(2, name)
+ : MathNestInset(2, name)
{}
#ifndef MATH_FRACINSET_H
#define MATH_FRACINSET_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
/** Fraction like objects (frac, stackrel, binom)
\author Alejandro Aguilar Sierra
*/
-class MathFracInset : public MathInset {
+class MathFracInset : public MathNestInset {
public:
///
explicit MathFracInset(const string & name);
MathFuncInset::MathFuncInset(string const & nm)
- : MathInset(0, nm)
+ : MathInset(nm)
{}
MathGridInset::MathGridInset(int m, int n, string const & nm)
- : MathInset(m * n, nm), rowinfo_(n), colinfo_(m), v_align_('c')
+ : MathNestInset(m * n, nm), rowinfo_(n), colinfo_(m), v_align_('c')
{
if (m <= 0)
lyxerr << "positve number of columns expected\n";
void MathGridInset::metrics(MathStyles st)
{
// let the cells adjust themselves
- MathInset::metrics(st);
+ MathNestInset::metrics(st);
size_ = st;
// adjust vertical structure
#ifndef MATH_GRID_H
#define MATH_GRID_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
\author André Pönitz 2001
*/
-class MathGridInset : public MathInset {
+class MathGridInset : public MathNestInset {
/// additional per-row information
struct RowInfo {
int MathInset::workwidth;
-MathInset::MathInset(int nargs, string const & name)
+MathInset::MathInset(string const & name)
: name_(name), width_(0), ascent_(0), descent_(0),
- size_(LM_ST_DISPLAY), code_(LM_TC_MIN), cells_(nargs), xo_(0), yo_(0)
+ size_(LM_ST_DISPLAY), code_(LM_TC_MIN), xo_(0), yo_(0)
{}
int MathInset::nargs() const
{
- return cells_.size();
+ return 0;
}
-MathXArray & MathInset::xcell(int i)
-{
- return cells_[i];
-}
-
+MathXArray dummyCell;
-MathXArray const & MathInset::xcell(int i) const
+MathXArray & MathInset::xcell(int)
{
- return cells_[i];
+ lyxerr << "I don't have a cell\n";
+ return dummyCell;
}
-MathArray & MathInset::cell(int i)
+MathXArray const & MathInset::xcell(int) const
{
- return cells_[i].data_;
+ lyxerr << "I don't have a cell\n";
+ return dummyCell;
}
-MathArray const & MathInset::cell(int i) const
+MathArray & MathInset::cell(int)
{
- return cells_[i].data_;
+ lyxerr << "I don't have a cell\n";
+ return dummyCell.data_;
}
-void MathInset::substitute(MathArray & array, MathMacro const & m) const
+MathArray const & MathInset::cell(int) const
{
- MathInset * p = clone();
- for (int i = 0; i < nargs(); ++i)
- p->cell(i).substitute(m);
- array.push_back(p);
+ lyxerr << "I don't have a cell\n";
+ return dummyCell.data_;
}
-void MathInset::metrics(MathStyles st)
+void MathInset::substitute(MathArray & array, MathMacro const &) const
{
- size_ = st;
- for (int i = 0; i < nargs(); ++i)
- xcell(i).metrics(st);
+ array.push_back(clone());
}
-void MathInset::draw(Painter & pain, int x, int y)
+bool MathInset::idxNext(int &, int &) const
{
- xo_ = x;
- yo_ = y;
- for (int i = 0; i < nargs(); ++i)
- xcell(i).draw(pain, x + xcell(i).xo(), y + xcell(i).yo());
-}
-
-
-bool MathInset::idxNext(int & idx, int & pos) const
-{
- if (idx + 1 >= nargs())
- return false;
- ++idx;
- pos = 0;
- return true;
+ return false;
}
-bool MathInset::idxRight(int & idx, int & pos) const
+bool MathInset::idxRight(int &, int &) const
{
- return idxNext(idx, pos);
+ return false;
}
-bool MathInset::idxPrev(int & idx, int & pos) const
+bool MathInset::idxPrev(int &, int &) const
{
- if (idx == 0)
- return false;
- --idx;
- pos = cell(idx).size();
- return true;
+ return false;
}
-bool MathInset::idxLeft(int & idx, int & pos) const
+bool MathInset::idxLeft(int &, int &) const
{
- return idxPrev(idx, pos);
+ return false;
}
}
-bool MathInset::idxFirst(int & i, int & pos) const
+bool MathInset::idxFirst(int &, int &) const
{
- if (nargs() == 0)
- return false;
- i = 0;
- pos = 0;
- return true;
+ return false;
}
-bool MathInset::idxLast(int & i, int & pos) const
+bool MathInset::idxLast(int &, int &) const
{
- if (nargs() == 0)
- return false;
- i = nargs() - 1;
- pos = cell(i).size();
- return true;
+ return false;
}
-bool MathInset::idxHome(int & /* idx */, int & pos) const
+bool MathInset::idxHome(int &, int &) const
{
- if (pos == 0)
- return false;
- pos = 0;
- return true;
+ return false;
}
-bool MathInset::idxEnd(int & idx, int & pos) const
+bool MathInset::idxEnd(int &, int &) const
{
- if (pos == cell(idx).size())
- return false;
-
- pos = cell(idx).size();
- return true;
+ return false;
}
{
lyxerr << "---------------------------------------------\n";
write(lyxerr, false);
- lyxerr << "\n";
- for (int i = 0; i < nargs(); ++i)
- lyxerr << cell(i) << "\n";
- lyxerr << "---------------------------------------------\n";
+ lyxerr << "\n---------------------------------------------\n";
}
-void MathInset::push_back(unsigned char ch, MathTextCodes fcode)
+void MathInset::push_back(unsigned char, MathTextCodes)
{
- if (nargs())
- cells_.back().data_.push_back(ch, fcode);
- else
- lyxerr << "can't push without a cell\n";
+ lyxerr << "can't push without a cell\n";
}
void MathInset::push_back(MathInset * p)
{
- if (nargs())
- cells_.back().data_.push_back(p);
- else
- lyxerr << "can't push without a cell\n";
+ lyxerr << "can't push without a cell\n";
}
}
-void MathInset::validate(LaTeXFeatures & features) const
-{
- for (int i = 0; i < nargs(); ++i)
- cell(i).validate(features);
-}
+void MathInset::validate(LaTeXFeatures &) const
+{}
std::vector<int> MathInset::idxBetween(int from, int to) const
class MathInset {
public:
///
- explicit MathInset(int na = 0, string const & nm = string());
+ explicit MathInset(string const & nm = string());
/// the virtual base destructor
virtual ~MathInset() {}
///
virtual void setName(string const & n);
///
- MathStyles size() const;
+ virtual MathStyles size() const;
/// Where should we go when we press the up cursor key?
virtual bool idxUp(int & idx, int & pos) const;
// deletes a cell range and moves the cursor
virtual void idxDeleteRange(int from, int to);
// returns list of cell indices that are "between" from and to for
- // selction purposes
+ // selection purposes
virtual std::vector<int> idxBetween(int from, int to) const;
///
- int nargs() const;
+ virtual int nargs() const;
///
- MathArray & cell(int);
+ virtual MathArray & cell(int);
///
- MathArray const & cell(int) const;
+ virtual MathArray const & cell(int) const;
///
- MathXArray & xcell(int);
+ virtual MathXArray & xcell(int);
///
- MathXArray const & xcell(int) const;
+ virtual MathXArray const & xcell(int) const;
///
- int xo() const;
+ virtual int xo() const;
///
- int yo() const;
+ virtual int yo() const;
///
- void xo(int tx);
+ virtual void xo(int tx);
///
- void yo(int ty);
+ virtual void yo(int ty);
///
///
virtual void userSetSize(MathStyles &) {}
///
- void getXY(int & x, int & y) const;
+ virtual void getXY(int & x, int & y) const;
///
- 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 ScriptInsets
virtual bool isGrid() const { return false; }
/// identifies ArrayInsets
virtual bool isArray() const { return false; }
+ /// identifies Charinsets
+ virtual bool isCharInset() const { return false; }
///
virtual bool isActive() const { return nargs() > 0; }
- /// identifies insets that display scripts directly above and below
-
+ ///
+ virtual char getChar() const { return 0; }
///
- void push_back(MathInset *);
+ virtual void push_back(MathInset *);
///
- void push_back(unsigned char ch, MathTextCodes fcode);
+ virtual void push_back(unsigned char ch, MathTextCodes fcode);
///
- void dump() const;
+ virtual void dump() const;
///
- void validate(LaTeXFeatures & features) const;
+ virtual void validate(LaTeXFeatures & features) const;
///
static int workwidth;
/// the inherited text style
- MathTextCodes code() const;
+ virtual MathTextCodes code() const;
///
- void code(MathTextCodes t);
+ virtual void code(MathTextCodes t);
protected:
/// usually the LaTeX name of the thingy
/// the inherited text style
MathTextCodes code_;
-protected:
- ///
- typedef std::vector<MathXArray> cells_type;
- /**
- * The contents of the inset are contained here.
- * Each inset is build from a number of insets.
- */
- cells_type cells_;
-
private:
/// the following are used for positioning the cursor with the mouse
/// cached cursor start position in pixels from the document left
using std::endl;
MathMacro::MathMacro(MathMacroTemplate const & t)
- : MathInset(t.numargs(), t.name()), tmplate_(&t)
+ : MathNestInset(t.numargs(), t.name()), tmplate_(&t)
{}
MathMacro::MathMacro(MathMacro const & t)
- : MathInset(t), tmplate_(t.tmplate_) // don't copy 'expanded_'!
+ : MathNestInset(t), tmplate_(t.tmplate_) // don't copy 'expanded_'!
{}
bool MathMacro::idxUp(int & idx, int & pos) const
{
- return MathInset::idxLeft(idx, pos);
+ return MathNestInset::idxLeft(idx, pos);
}
bool MathMacro::idxDown(int & idx, int & pos) const
{
- return MathInset::idxRight(idx, pos);
+ return MathNestInset::idxRight(idx, pos);
}
#include <vector>
#include <iosfwd>
-#include "math_inset.h"
+#include "math_nestinset.h"
#include "math_macroarg.h"
class MathMacroTemplate;
\author Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
\version November 1996
*/
-class MathMacro : public MathInset {
+class MathMacro : public MathNestInset {
public:
/// A macro can be built from an existing template
explicit MathMacro(MathMacroTemplate const &);
MathMacroTemplate::MathMacroTemplate()
- : MathInset(1), numargs_(0)
+ : MathNestInset(1), numargs_(0)
{}
MathMacroTemplate::MathMacroTemplate(string const & nm, int numargs)
- : MathInset(1, nm), numargs_(numargs)
+ : MathNestInset(1, nm), numargs_(numargs)
{}
#ifndef MATH_MACROTEMPLATE_H
#define MATH_MACROTEMPLATE_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
*/
//class MathMacroTemplate : public MathInset, boost::noncopyable
-class MathMacroTemplate : public MathInset {
+class MathMacroTemplate : public MathNestInset {
public:
///
MathMacroTemplate();
// used for "intelligent splitting"
int firstRelOp(MathArray const & array)
{
- for (int pos = 0; pos < array.size(); array.next(pos))
- if (!array.isInset(pos) &&
- MathIsRelOp(array.getChar(pos), array.getCode(pos)))
+ for (int pos = 0; pos < array.size(); ++pos)
+ if (MathIsRelOp(array.getChar(pos), array.getCode(pos)))
return pos;
return array.size();
}
features.boldsymbol = true;
//features.binom = true;
- MathInset::validate(features);
+ MathNestInset::validate(features);
}
--- /dev/null
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "math_nestinset.h"
+#include "debug.h"
+
+
+MathNestInset::MathNestInset(int nargs, string const & name)
+ : MathInset(name), cells_(nargs)
+{}
+
+
+int MathNestInset::nargs() const
+{
+ return cells_.size();
+}
+
+
+MathXArray & MathNestInset::xcell(int i)
+{
+ return cells_[i];
+}
+
+
+MathXArray const & MathNestInset::xcell(int i) const
+{
+ return cells_[i];
+}
+
+
+MathArray & MathNestInset::cell(int i)
+{
+ return cells_[i].data_;
+}
+
+
+MathArray const & MathNestInset::cell(int i) const
+{
+ return cells_[i].data_;
+}
+
+
+void MathNestInset::substitute(MathArray & array, MathMacro const & m) const
+{
+ MathNestInset * p = static_cast<MathNestInset *>(clone());
+ for (int i = 0; i < nargs(); ++i)
+ p->cell(i).substitute(m);
+ array.push_back(p);
+}
+
+
+void MathNestInset::metrics(MathStyles st)
+{
+ size_ = st;
+ for (int i = 0; i < nargs(); ++i)
+ xcell(i).metrics(st);
+}
+
+
+void MathNestInset::draw(Painter & pain, int x, int y)
+{
+ xo(x);
+ yo(y);
+ for (int i = 0; i < nargs(); ++i)
+ xcell(i).draw(pain, x + xcell(i).xo(), y + xcell(i).yo());
+}
+
+
+bool MathNestInset::idxNext(int & idx, int & pos) const
+{
+ if (idx + 1 >= nargs())
+ return false;
+ ++idx;
+ pos = 0;
+ return true;
+}
+
+
+bool MathNestInset::idxRight(int & idx, int & pos) const
+{
+ return idxNext(idx, pos);
+}
+
+
+bool MathNestInset::idxPrev(int & idx, int & pos) const
+{
+ if (idx == 0)
+ return false;
+ --idx;
+ pos = cell(idx).size();
+ return true;
+}
+
+
+bool MathNestInset::idxLeft(int & idx, int & pos) const
+{
+ return idxPrev(idx, pos);
+}
+
+
+bool MathNestInset::idxFirst(int & i, int & pos) const
+{
+ if (nargs() == 0)
+ return false;
+ i = 0;
+ pos = 0;
+ return true;
+}
+
+
+bool MathNestInset::idxLast(int & i, int & pos) const
+{
+ if (nargs() == 0)
+ return false;
+ i = nargs() - 1;
+ pos = cell(i).size();
+ return true;
+}
+
+
+bool MathNestInset::idxHome(int & /* idx */, int & pos) const
+{
+ if (pos == 0)
+ return false;
+ pos = 0;
+ return true;
+}
+
+
+bool MathNestInset::idxEnd(int & idx, int & pos) const
+{
+ if (pos == cell(idx).size())
+ return false;
+
+ pos = cell(idx).size();
+ return true;
+}
+
+
+void MathNestInset::dump() const
+{
+ lyxerr << "---------------------------------------------\n";
+ write(lyxerr, false);
+ lyxerr << "\n";
+ for (int i = 0; i < nargs(); ++i)
+ lyxerr << cell(i) << "\n";
+ lyxerr << "---------------------------------------------\n";
+}
+
+
+void MathNestInset::push_back(unsigned char ch, MathTextCodes fcode)
+{
+ if (nargs())
+ cells_.back().data_.push_back(ch, fcode);
+ else
+ lyxerr << "can't push without a cell\n";
+}
+
+
+void MathNestInset::push_back(MathInset * p)
+{
+ if (nargs())
+ cells_.back().data_.push_back(p);
+ else
+ lyxerr << "can't push without a cell\n";
+}
+
+
+void MathNestInset::validate(LaTeXFeatures & features) const
+{
+ for (int i = 0; i < nargs(); ++i)
+ cell(i).validate(features);
+}
--- /dev/null
+#ifndef MATH_NESTINSET_H
+#define MATH_NESTINSET_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "math_inset.h"
+
+/** Abstract base class for all math objects that conatin nested items.
+*/
+
+
+class LaTeXFeatures;
+
+class MathNestInset : public MathInset {
+public:
+ ///
+ explicit MathNestInset(int na = 0, string const & nm = string());
+
+ /// draw the object, sets xo_ and yo_ cached values
+ virtual void draw(Painter &, int x, int baseline);
+ /// appends itself with macro arguments substituted
+ virtual void substitute(MathArray & array, MathMacro const & macro) const;
+ /// compute the size of the object, sets ascend_, descend_ and width_
+ virtual void metrics(MathStyles st) = 0;
+
+ /// The left key
+ virtual bool idxLeft(int & idx, int & pos) const;
+ /// The right key
+ virtual bool idxRight(int & idx, int & pos) const;
+
+ /// Move one physical cell up
+ virtual bool idxNext(int & idx, int & pos) const;
+ /// Move one physical cell down
+ virtual bool idxPrev(int & idx, int & pos) const;
+
+ /// Target pos when we enter the inset from the left by pressing "Right"
+ virtual bool idxFirst(int & idx, int & pos) const;
+ /// Target pos when we enter the inset from the right by pressing "Left"
+ virtual bool idxLast(int & idx, int & pos) const;
+
+ /// Where should we go if we press home?
+ virtual bool idxHome(int & idx, int & pos) const;
+ /// Where should we go if we press end?
+ virtual bool idxEnd(int & idx, int & pos) const;
+
+ ///
+ int nargs() const;
+
+ ///
+ MathArray & cell(int);
+ ///
+ MathArray const & cell(int) const;
+ ///
+ MathXArray & xcell(int);
+ ///
+ MathXArray const & xcell(int) const;
+
+ ///
+ bool isActive() const { return nargs() > 0; }
+ ///
+ void push_back(MathInset *);
+ ///
+ void push_back(unsigned char ch, MathTextCodes fcode);
+ ///
+ void dump() const;
+
+ ///
+ void validate(LaTeXFeatures & features) const;
+
+protected:
+ ///
+ typedef std::vector<MathXArray> cells_type;
+ /// The nested contents of the inset are contained here.
+ cells_type cells_;
+};
+
+#endif
{
char c = 0;
is->get(c);
- if (!is->good()) {
+ if (!is->good())
lyxerr << "The input stream is not well..." << endl;
- }
return static_cast<unsigned char>(c);
}
}
while (lexcode[c] == LexSpace && yyis->good())
c = getuchar(yyis);
- if (yyis->good() && lexcode[c] != LexSpace)
+ if (lexcode[c] != LexSpace)
yyis->putback(c);
//lyxerr[Debug::MATHED] << "reading: text '" << yytext << "'\n";
MathScriptInset * prevScriptInset(MathArray const & array)
{
- MathInset * p = array.back_inset();
+ MathInset * p = array.back();
return (p && p->isScriptInset()) ? static_cast<MathScriptInset *>(p) : 0;
}
{
MathScriptInset * p = prevScriptInset(array);
if (!p) {
- MathInset * b = array.back_inset();
+ MathInset * b = array.back();
if (b && b->isScriptable()) {
p = new MathScriptInset(up, down, b->clone());
array.pop_back();
unsigned char c = getuchar(yyis);
if (c == '[') {
array.push_back(new MathRootInset);
- mathed_parse_into(array.back_inset()->cell(0), FLAG_BRACK_END);
- mathed_parse_into(array.back_inset()->cell(1), FLAG_ITEM);
+ mathed_parse_into(array.back()->cell(0), FLAG_BRACK_END);
+ mathed_parse_into(array.back()->cell(1), FLAG_ITEM);
} else {
yyis->putback(c);
array.push_back(new MathSqrtInset);
- mathed_parse_into(array.back_inset()->cell(0), FLAG_ITEM);
+ mathed_parse_into(array.back()->cell(0), FLAG_ITEM);
}
break;
}
#include "Painter.h"
MathRootInset::MathRootInset()
- : MathInset(2)
+ : MathNestInset(2)
{}
void MathRootInset::metrics(MathStyles st)
{
- MathInset::metrics(st);
+ MathNestInset::metrics(st);
size_ = st;
ascent_ = std::max(xcell(0).ascent() + 5, xcell(1).ascent()) + 2;
descent_ = std::max(xcell(1).descent() + 5, xcell(0).descent()) + 2;
#ifndef MATH_ROOT_H
#define MATH_ROOT_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#include "symbol_def.h"
#ifdef __GNUG__
\author Alejandro Aguilar Sierra
\version January 1999
*/
-class MathRootInset : public MathInset {
+class MathRootInset : public MathNestInset {
public:
///
MathRootInset();
MathScriptInset::MathScriptInset()
- : MathInset(2), up_(false), down_(false), limits_(0), symbol_(0)
+ : MathNestInset(2), up_(false), down_(false), limits_(0), symbol_(0)
{}
MathScriptInset::MathScriptInset(bool up, bool down, MathInset * symbol)
- : MathInset(2), up_(up), down_(down), limits_(0), symbol_(symbol)
+ : MathNestInset(2), up_(up), down_(down), limits_(0), symbol_(symbol)
{}
MathScriptInset::MathScriptInset(MathScriptInset const & p)
- : MathInset(p), up_(p.up_), down_(p.down_),
+ : MathNestInset(p), up_(p.up_), down_(p.down_),
limits_(p.limits_), symbol_(p.symbol_ ? p.symbol_->clone() : 0)
{}
#ifndef MATH_SCRIPTINSET_H
#define MATH_SCRIPTINSET_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
*/
-class MathScriptInset : public MathInset {
+class MathScriptInset : public MathNestInset {
public:
///
MathScriptInset();
MathSizeInset::MathSizeInset(MathStyles st)
- : MathInset(1), style_(st)
+ : MathNestInset(1), style_(st)
{
name_ = verbose();
}
#ifndef MATHSIZEINSET_H
#define MATHSIZEINSET_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#include "math_defs.h"
#ifdef __GNUG__
\author André Poenitz
*/
-class MathSizeInset : public MathInset {
+class MathSizeInset : public MathNestInset {
public:
///
explicit MathSizeInset(MathStyles st);
MathSqrtInset::MathSqrtInset()
- : MathInset(1)
+ : MathNestInset(1)
{}
#ifndef MATH_SQRTINSET_H
#define MATH_SQRTINSET_H
-#include "math_inset.h"
+#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
/** The square root inset.
\author Alejandro Aguilar Siearra
*/
-class MathSqrtInset : public MathInset {
+class MathSqrtInset : public MathNestInset {
public:
///
MathSqrtInset();
width_ = 0;
style_ = st;
- for (int pos = 0; pos < data_.size(); data_.next(pos)) {
- int asc;
- int des;
- int wid;
+ for (int pos = 0; pos < data_.size(); ++pos) {
MathInset * p = data_.nextInset(pos);
- if (p) {
- p->metrics(st);
- asc = p->ascent();
- des = p->descent();
- wid = p->width();
- } else {
- char cx = data_.getChar(pos);
- MathTextCodes fc = data_.getCode(pos);
- mathed_char_dim(fc, style_, cx, asc, des, wid);
- }
+ p->metrics(st);
+ int asc = p->ascent();
+ int des = p->descent();
+ int wid = p->width();
ascent_ = max(ascent_, asc);
descent_ = max(descent_, des);
width_ += wid;
return;
}
- for (int pos = 0; pos < data_.size(); data_.next(pos)) {
+ for (int pos = 0; pos < data_.size(); ++pos) {
MathInset * p = data_.nextInset(pos);
- if (p) {
- p->draw(pain, x, y);
- x += p->width();
- } else {
- char cx = data_.getChar(pos);
- MathTextCodes fc = data_.getCode(pos);
- string s;
- s += cx;
- drawStr(pain, fc, style_, x, y, s);
- x += mathed_char_width(fc, style_, cx);
- }
+ p->draw(pain, x, y);
+ x += p->width();
}
}
{
int x = 0;
targetpos = min(targetpos, data_.size());
- for (int pos = 0; pos < targetpos; data_.next(pos))
+ for (int pos = 0; pos < targetpos; ++pos)
x += width(pos);
return x;
}
int pos = 0;
int lastx = 0;
int currx = 0;
- while (currx < targetx && pos < data_.size()) {
+ for ( ; currx < targetx && pos < data_.size(); ++pos) {
lastx = currx;
currx += width(pos);
- data_.next(pos);
}
if (abs(lastx - targetx) < abs(currx - targetx))
data_.prev(pos);
return pos;
}
+
int MathXArray::width(int pos) const
{
if (pos >= data_.size())
return 0;
-
- if (data_.isInset(pos))
- return data_.nextInset(pos)->width();
- else
- return mathed_char_width(data_.getCode(pos), style_, data_.getChar(pos));
+ return data_.nextInset(pos)->width();
}
+
std::ostream & operator<<(std::ostream & os, MathXArray const & ar)
{
os << ar.data_;