break;
}
+ case LFUN_MATH_COLUMN_INSERT:
+ {
+ if (par_->getType() == LM_OT_ALIGN)
+ par_->mutate(LM_OT_ALIGNAT);
+ par_->addCol(par_->ncols());
+ mathcursor->normalize();
+ updateLocal(bv, true);
+ }
+
default:
result = InsetFormulaBase::localDispatch(bv, action, arg);
}
par_->validate(features);
}
+
bool InsetFormula::insetAllowed(Inset::Code code) const
{
return code == Inset::LABEL_CODE;
MathInsetTypes InsetFormula::getType() const
{
- return par_->getType();;
+ return par_->getType();
}
os << '{';
for (int col = 0; col < ncols(); ++col)
- os << colinfo_[col].h_align_;
+ os << colinfo_[col].align_;
os << "}\n";
MathGridInset::write(os, fragile);
///
LM_OT_ALIGNAT,
///
- LM_OT_XALIGN,
+ LM_OT_XALIGNAT,
///
- LM_OT_XXALIGN,
+ LM_OT_XXALIGNAT,
///
LM_OT_MULTLINE,
/// An array
MathGridInset::ColInfo::ColInfo()
- : h_align_('c'), leftline_(false), rightline_(false)
+ : align_('c'), leftline_(false), rightline_(false), skip_(MATH_COLSEP)
{}
lyxerr << "positve number of columns expected\n";
if (n <= 0)
lyxerr << "positve number of rows expected\n";
+ for (int col = 0; col < m; ++col) {
+ colinfo_[col].skip_ = defaultColSpace(col);
+ colinfo_[col].align_ = defaultColAlign(col);
+ }
}
if (n > ncols())
n = ncols();
for (int i = 0; i < n; ++i)
- colinfo_[i].h_align_ = hh[i];
+ colinfo_[i].align_ = hh[i];
}
void MathGridInset::halign(char h, int col)
{
- colinfo_[col].h_align_ = h;
+ colinfo_[col].align_ = h;
}
char MathGridInset::halign(int col) const
{
- return colinfo_[col].h_align_;
+ return colinfo_[col].align_;
}
if (col)
colinfo_[col].offset_ =
- colinfo_[col - 1].offset_ + colinfo_[col - 1].width_ + MATH_COLSEP;
+ colinfo_[col - 1].offset_ +
+ colinfo_[col - 1].width_ +
+ colinfo_[col - 1].skip_;
else
colinfo_[col].offset_ = 0;
/*
// Increase ws_[i] for 'R' columns (except the first one)
for (int i = 1; i < nc_; ++i)
- if (h_align_[i] == 'R')
+ if (align_[i] == 'R')
ws_[i] += 10 * df_width;
// Increase ws_[i] for 'C' column
- if (h_align_[0] == 'C')
+ if (align_[0] == 'C')
if (ws_[0] < 7 * workwidth / 8)
ws_[0] = 7 * workwidth / 8;
cxrow->setTab(i, df_width);
isvoid = true;
}
- switch (h_align_[i]) {
+ switch (align_[i]) {
case 'l':
lf = 0;
break;
= cells_[row * nc + col];
std::swap(cells_, new_cells);
- colinfo_.insert(colinfo_.begin() + newcol, ColInfo());
+ ColInfo inf;
+ inf.skip_ = defaultColSpace(newcol);
+ inf.align_ = defaultColAlign(newcol);
+ colinfo_.insert(colinfo_.begin() + newcol, inf);
}
{
int c = col(idx);
int x = colinfo_[c].offset_;
- char align = colinfo_[c].h_align_;
+ char align = colinfo_[c].align_;
if (align == 'r' || align == 'R')
x += colinfo_[c].width_ - xcell(idx).width();
if (align == 'c' || align == 'C')
struct ColInfo {
///
ColInfo();
- ///
- char h_align_;
+ /// currently possible: 'l', 'c', 'r'
+ char align_;
/// cache for drawing
int h_offset;
/// cached width
mutable int width_;
/// cached offset
mutable int offset_;
- ///
+ /// do we need a line to the left?
bool leftline_;
- ///
+ /// do we need a line to the right?
bool rightline_;
+ /// additional amount to be skipped when drawing
+ int skip_;
};
public:
int index(int row, int col) const;
///
std::vector<int> idxBetween(int from, int to) const;
+ ///
+ virtual int defaultColSpace(int) { return 10; }
+ ///
+ virtual char defaultColAlign(int) { return 'c'; }
protected:
/// returns proper 'end of line' code for LaTeX
namespace {
-string getAlign(MathInsetTypes type, int cols)
-{
- string align;
- switch (type) {
- case LM_OT_ALIGN:
- for (int i = 0; i < cols; ++i)
- align += "Rl";
- break;
-
- case LM_OT_ALIGNAT:
- for (int i = 0; i < cols; ++i)
- align += "rl";
- break;
-
- case LM_OT_MULTLINE:
- align = "C";
- break;
-
- default:
- align = "rcl";
- break;
- }
- return align;
-}
-
-string const star(bool n)
+int getCols(MathInsetTypes type)
{
- return n ? "" : "*";
-}
-
-
-int getCols(short int type)
-{
- int col;
switch (type) {
case LM_OT_EQNARRAY:
- col = 3;
- break;
-
+ return 3;
case LM_OT_ALIGN:
case LM_OT_ALIGNAT:
- col = 2;
- break;
-
- default:
- col = 1;
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT:
+ return 2;
+ default:;
}
- return col;
+ return 1;
}
+
// returns position of first relation operator in the array
// used for "intelligent splitting"
int firstRelOp(MathArray const & array)
return array.size();
}
+
+char const * star(bool numbered)
+{
+ return numbered ? "" : "*";
+}
+
}
MathMatrixInset::MathMatrixInset()
: MathGridInset(1, 1), objtype_(LM_OT_SIMPLE), nonum_(1), label_(1)
-{}
+{
+ setDefaults();
+}
MathMatrixInset::MathMatrixInset(MathInsetTypes t)
: MathGridInset(getCols(t), 1), objtype_(t), nonum_(1), label_(1)
{
- halign(getAlign(t, ncols()));
+ setDefaults();
}
MathMatrixInset::MathMatrixInset(MathInsetTypes t, int cols)
: MathGridInset(cols, 1), objtype_(t), nonum_(1), label_(1)
{
- halign(getAlign(t, ncols()));
+ setDefaults();
}
}
+char MathMatrixInset::defaultColAlign(int col)
+{
+ switch (getType()) {
+ case LM_OT_ALIGN:
+ case LM_OT_ALIGNAT:
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT:
+ return "rl"[col & 1];
+ case LM_OT_EQNARRAY:
+ return "rcl"[col];
+ default:;
+ }
+ return 'c';
+}
+
+int MathMatrixInset::defaultColSpace(int col)
+{
+ switch (getType()) {
+ case LM_OT_ALIGN:
+ case LM_OT_ALIGNAT:
+ return 0;
+ case LM_OT_XALIGNAT:
+ return (col & 1) ? 20 : 0;
+ case LM_OT_XXALIGNAT:
+ return (col & 1) ? 40 : 0;
+ default:;
+ }
+ return 10;
+}
+
+
+void MathMatrixInset::setDefaults()
+{
+ for (int col = 0; col < ncols(); ++col) {
+ colinfo_[col].align_ = defaultColAlign(col);
+ colinfo_[col].skip_ = defaultColSpace(col);
+ }
+}
+
+
void MathMatrixInset::metrics(MathStyles) const
{
size_ = (getType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY;
break;
case LM_OT_ALIGNAT:
- os << "\\begin{alignat" << star(n) << "}"
- << "{" << ncols()/2 << "}\n";
+ os << "\\begin{alignat" << star(n) << "}" << "{" << ncols()/2 << "}\n";
+ break;
+
+ case LM_OT_XALIGNAT:
+ os << "\\begin{xalignat" << star(n) << "}" << "{" << ncols()/2 << "}\n";
break;
+
+ case LM_OT_XXALIGNAT:
+ os << "\\begin{xxalignat}" << "{" << ncols()/2 << "}\n";
+ break;
+
default:
os << "\\begin{unknown" << star(n) << "}";
}
os << "\\end{alignat" << star(n) << "}\n";
break;
+ case LM_OT_XALIGNAT:
+ os << "\\end{xalignat" << star(n) << "}\n";
+ break;
+
+ case LM_OT_XXALIGNAT:
+ os << "\\end{xxalignat}\n";
+ break;
+
default:
os << "\\end{unknown" << star(n) << "}";
}
MathGridInset::addRow(row);
}
+
void MathMatrixInset::appendRow()
{
nonum_.push_back(!numberedType());
label_.erase(label_.begin() + row);
}
+
void MathMatrixInset::addCol(int col)
{
switch (getType()) {
break;
case LM_OT_ALIGN:
+ mutate(LM_OT_ALIGNAT);
+ addCol(col);
+ break;
+
case LM_OT_ALIGNAT:
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT:
MathGridInset::addCol(col);
- halign(col, 'l');
- MathGridInset::addCol(col);
- halign(col, 'r');
+ MathGridInset::addCol(col + 1);
break;
default:
}
}
+
void MathMatrixInset::delCol(int col)
{
switch (getType()) {
- case LM_OT_ALIGN:
+ case LM_OT_ALIGNAT:
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT:
+ MathGridInset::delCol(col + 1);
MathGridInset::delCol(col);
break;
-
default:
break;
}
namespace {
- short typecode(string const & s)
+ MathInsetTypes typecode(string const & s)
{
if (s == "equation")
return LM_OT_EQUATION;
return LM_OT_EQNARRAY;
if (s == "align")
return LM_OT_ALIGN;
- if (s == "xalign")
- return LM_OT_XALIGN;
- if (s == "xxalign")
- return LM_OT_XXALIGN;
+ if (s == "alignat")
+ return LM_OT_ALIGN;
+ if (s == "xalignat")
+ return LM_OT_XALIGNAT;
+ if (s == "xxalignat")
+ return LM_OT_XXALIGNAT;
if (s == "multline")
return LM_OT_MULTLINE;
return LM_OT_SIMPLE;
void MathMatrixInset::setType(MathInsetTypes t)
{
objtype_ = t;
+ setDefaults();
}
-void MathMatrixInset::mutate(short newtype)
+void MathMatrixInset::mutate(MathInsetTypes newtype)
{
//lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n";
setType(LM_OT_SIMPLE);
break;
- case LM_OT_ALIGN: {
+ case LM_OT_ALIGN:
+ case LM_OT_ALIGNAT:
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT: {
+
MathGridInset::addCol(1);
// split it "nicely"
cell(1) = cell(0);
cell(0).erase(pos, cell(0).size());
cell(1).erase(0, pos);
-
- halign("rl");
setType(LM_OT_ALIGN);
+ mutate(newtype);
break;
}
cell(2).erase(0);
}
- halign("rcl");
setType(LM_OT_EQNARRAY);
mutate(newtype);
break;
}
case LM_OT_ALIGN:
+ case LM_OT_ALIGNAT:
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT:
default: {
for (int row = 0; row < nrows(); ++row) {
int c = 3 * row + 1;
}
MathGridInset::delCol(2);
setType(LM_OT_ALIGN);
- halign("rl");
mutate(newtype);
break;
}
case LM_OT_EQNARRAY:
MathGridInset::addCol(1);
setType(LM_OT_EQNARRAY);
- halign("rcl");
mutate(newtype);
break;
+ case LM_OT_ALIGNAT:
+ case LM_OT_XALIGNAT:
+ case LM_OT_XXALIGNAT:
+ setType(newtype);
+ break;
+
default:
lyxerr << "mutation from '" << getType()
<< "' to '" << newtype << "' not implemented\n";
/// change type
void mutate(string const &);
///
- void mutate(short);
+ void mutate(MathInsetTypes);
+
+ ///
+ int defaultColSpace(int col);
+ ///
+ char defaultColAlign(int col);
///
MathInsetTypes getType() const;
private:
///
- virtual void setType(MathInsetTypes t);
+ void setDefaults();
+ ///
+ void setType(MathInsetTypes t);
///
void validate1(LaTeXFeatures & features);
///
return p;
}
+ if (name == "xalignat" || name == "xalignat*") {
+ MathMatrixInset * p =
+ new MathMatrixInset(LM_OT_XALIGNAT, 2 * atoi(getArg('{', '}').c_str()));
+ parse_lines(p, !stared(name), true);
+ return p;
+ }
+
+ if (name == "xxalignat") {
+ MathMatrixInset * p =
+ new MathMatrixInset(LM_OT_XXALIGNAT, 2 * atoi(getArg('{', '}').c_str()));
+ parse_lines(p, !stared(name), true);
+ return p;
+ }
+
lyxerr[Debug::MATHED] << "1: unknown math environment: " << name << "\n";
return 0;
}