+ void grab(MathCursor const & cursor)
+ {
+ data_.clear();
+ MathCursorPos i1;
+ MathCursorPos i2;
+ cursor.getSelection(i1, i2);
+ if (i1.idx_ == i2.idx_)
+ data_.push_back(MathArray(i1.cell(), i1.pos_, i2.pos_));
+ else {
+#ifdef RECTANGULAR_SELECT
+ std::vector<int> indices = i1.par_->idxBetween(i1.idx_, i2.idx_);
+ for (unsigned i = 0; i < indices.size(); ++i)
+ data_.push_back(i1.cell(indices[i]));
+#else
+ data_.push_back(MathArray(i1.cell(), i1.pos_, i1.cell().size()));
+ for (int i = i1.idx_ + 1; i < i2.idx_; ++i)
+ data_.push_back(i1.cell(i));
+ data_.push_back(MathArray(i2.cell(), 0, i2.pos_));
+#endif
+ }
+ }
+
+ void erase(MathCursor & cursor)
+ {
+ MathCursorPos i1;
+ MathCursorPos i2;
+ cursor.getSelection(i1, i2);
+ if (i1.idx_ == i2.idx_) {
+ i1.cell().erase(i1.pos_, i2.pos_);
+ } else {
+#ifdef RECTANGULAR_SELECT
+ std::vector<int> indices = i1.par_->idxBetween(i1.idx_, i2.idx_);
+ for (unsigned i = 0; i < indices.size(); ++i)
+ i1.cell(indices[i]).erase();
+#else
+ i1.cell().erase(i1.pos_, i1.cell().size());
+ for (int i = i1.idx_ + 1; i < i2.idx_; ++i)
+ i1.cell(i).erase();
+ i2.cell().erase(0, i2.pos_);
+
+ int from = i1.cell().size() ? i1.idx_ + 1 : i1.idx_;
+ int to = i2.cell().size() ? i2.idx_ : i2.idx_ + 1;
+ i1.par_->idxDeleteRange(from, to);
+#endif
+ }
+ cursor.cursor() = i1;
+ }
+
+ void paste(MathCursor & cursor) const
+ {
+#ifdef RECTANGULAR_SELECT
+ cursor.cursor().cell().push_back(glue());
+#else
+ unsigned na = cursor.cursor().par_->nargs();
+ unsigned idx = cursor.cursor().idx_;
+ unsigned end = std::min(idx + data_.size(), na);
+ for (int i = 0; i < end - idx; ++i)
+ cursor.cursor().cell(idx + i).push_back(data_[i]);
+ for (unsigned i = end - idx; i < data_.size(); ++i)
+ cursor.cursor().cell(end - 1).push_back(data_[i]);
+#endif
+ }
+
+ // glues selection to one cell
+ MathArray glue() const
+ {
+ MathArray ar;
+ for (unsigned i = 0; i < data_.size(); ++i)
+ ar.push_back(data_[i]);
+ return ar;
+ }
+
+ void clear()
+ {
+ data_.clear();
+ }
+
+
+
+ std::vector<MathArray> data_;
+};
+
+
+Selection theSelection;
+
+
+bool IsMacro(short tok, int id)
+{
+ return tok != LM_TK_STACK &&
+ tok != LM_TK_FRAC &&
+ tok != LM_TK_SQRT &&
+ tok != LM_TK_DECORATION &&
+ tok != LM_TK_SPACE &&
+ tok != LM_TK_DOTS &&
+ tok != LM_TK_FUNCLIM &&
+ tok != LM_TK_BIGSYM &&
+ !(tok == LM_TK_SYM && id < 255);
+}
+
+
+std::ostream & operator<<(std::ostream & os, MathCursorPos const & p)
+{
+ os << "(par: " << p.par_ << " idx: " << p.idx_
+ << " pos: " << p.pos_ << ")";
+ return os;
+}
+