some support for the [x][x]alignat environments

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2684 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2001-09-04 13:32:06 +00:00
parent e63b166d6d
commit 98e9f5f2b6
8 changed files with 182 additions and 85 deletions

View File

@ -290,6 +290,15 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action,
break; 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: default:
result = InsetFormulaBase::localDispatch(bv, action, arg); result = InsetFormulaBase::localDispatch(bv, action, arg);
} }
@ -344,6 +353,7 @@ void InsetFormula::validate(LaTeXFeatures & features) const
par_->validate(features); par_->validate(features);
} }
bool InsetFormula::insetAllowed(Inset::Code code) const bool InsetFormula::insetAllowed(Inset::Code code) const
{ {
return code == Inset::LABEL_CODE; return code == Inset::LABEL_CODE;
@ -371,5 +381,5 @@ int InsetFormula::width(BufferView *, LyXFont const &) const
MathInsetTypes InsetFormula::getType() const MathInsetTypes InsetFormula::getType() const
{ {
return par_->getType();; return par_->getType();
} }

View File

@ -28,7 +28,7 @@ void MathArrayInset::write(std::ostream & os, bool fragile) const
os << '{'; os << '{';
for (int col = 0; col < ncols(); ++col) for (int col = 0; col < ncols(); ++col)
os << colinfo_[col].h_align_; os << colinfo_[col].align_;
os << "}\n"; os << "}\n";
MathGridInset::write(os, fragile); MathGridInset::write(os, fragile);

View File

@ -118,9 +118,9 @@ enum MathInsetTypes {
/// ///
LM_OT_ALIGNAT, LM_OT_ALIGNAT,
/// ///
LM_OT_XALIGN, LM_OT_XALIGNAT,
/// ///
LM_OT_XXALIGN, LM_OT_XXALIGNAT,
/// ///
LM_OT_MULTLINE, LM_OT_MULTLINE,
/// An array /// An array

View File

@ -35,7 +35,7 @@ int MathGridInset::RowInfo::skipPixels() const
MathGridInset::ColInfo::ColInfo() MathGridInset::ColInfo::ColInfo()
: h_align_('c'), leftline_(false), rightline_(false) : align_('c'), leftline_(false), rightline_(false), skip_(MATH_COLSEP)
{} {}
@ -46,6 +46,10 @@ MathGridInset::MathGridInset(int m, int n)
lyxerr << "positve number of columns expected\n"; lyxerr << "positve number of columns expected\n";
if (n <= 0) if (n <= 0)
lyxerr << "positve number of rows expected\n"; lyxerr << "positve number of rows expected\n";
for (int col = 0; col < m; ++col) {
colinfo_[col].skip_ = defaultColSpace(col);
colinfo_[col].align_ = defaultColAlign(col);
}
} }
@ -62,19 +66,19 @@ void MathGridInset::halign(string const & hh)
if (n > ncols()) if (n > ncols())
n = ncols(); n = ncols();
for (int i = 0; i < n; ++i) 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) void MathGridInset::halign(char h, int col)
{ {
colinfo_[col].h_align_ = h; colinfo_[col].align_ = h;
} }
char MathGridInset::halign(int col) const char MathGridInset::halign(int col) const
{ {
return colinfo_[col].h_align_; return colinfo_[col].align_;
} }
@ -161,7 +165,9 @@ void MathGridInset::metrics(MathStyles st) const
if (col) if (col)
colinfo_[col].offset_ = 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 else
colinfo_[col].offset_ = 0; colinfo_[col].offset_ = 0;
@ -175,10 +181,10 @@ void MathGridInset::metrics(MathStyles st) const
/* /*
// Increase ws_[i] for 'R' columns (except the first one) // Increase ws_[i] for 'R' columns (except the first one)
for (int i = 1; i < nc_; ++i) for (int i = 1; i < nc_; ++i)
if (h_align_[i] == 'R') if (align_[i] == 'R')
ws_[i] += 10 * df_width; ws_[i] += 10 * df_width;
// Increase ws_[i] for 'C' column // Increase ws_[i] for 'C' column
if (h_align_[0] == 'C') if (align_[0] == 'C')
if (ws_[0] < 7 * workwidth / 8) if (ws_[0] < 7 * workwidth / 8)
ws_[0] = 7 * workwidth / 8; ws_[0] = 7 * workwidth / 8;
@ -193,7 +199,7 @@ void MathGridInset::metrics(MathStyles st) const
cxrow->setTab(i, df_width); cxrow->setTab(i, df_width);
isvoid = true; isvoid = true;
} }
switch (h_align_[i]) { switch (align_[i]) {
case 'l': case 'l':
lf = 0; lf = 0;
break; break;
@ -310,7 +316,10 @@ void MathGridInset::addCol(int newcol)
= cells_[row * nc + col]; = cells_[row * nc + col];
std::swap(cells_, new_cells); 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);
} }
@ -333,7 +342,7 @@ int MathGridInset::cellXOffset(int idx) const
{ {
int c = col(idx); int c = col(idx);
int x = colinfo_[c].offset_; int x = colinfo_[c].offset_;
char align = colinfo_[c].h_align_; char align = colinfo_[c].align_;
if (align == 'r' || align == 'R') if (align == 'r' || align == 'R')
x += colinfo_[c].width_ - xcell(idx).width(); x += colinfo_[c].width_ - xcell(idx).width();
if (align == 'c' || align == 'C') if (align == 'c' || align == 'C')

View File

@ -42,18 +42,20 @@ class MathGridInset : public MathNestInset {
struct ColInfo { struct ColInfo {
/// ///
ColInfo(); ColInfo();
/// /// currently possible: 'l', 'c', 'r'
char h_align_; char align_;
/// cache for drawing /// cache for drawing
int h_offset; int h_offset;
/// cached width /// cached width
mutable int width_; mutable int width_;
/// cached offset /// cached offset
mutable int offset_; mutable int offset_;
/// /// do we need a line to the left?
bool leftline_; bool leftline_;
/// /// do we need a line to the right?
bool rightline_; bool rightline_;
/// additional amount to be skipped when drawing
int skip_;
}; };
public: public:
@ -132,6 +134,10 @@ public:
int index(int row, int col) const; int index(int row, int col) const;
/// ///
std::vector<int> idxBetween(int from, int to) const; std::vector<int> idxBetween(int from, int to) const;
///
virtual int defaultColSpace(int) { return 10; }
///
virtual char defaultColAlign(int) { return 'c'; }
protected: protected:
/// returns proper 'end of line' code for LaTeX /// returns proper 'end of line' code for LaTeX

View File

@ -14,57 +14,23 @@
namespace { namespace {
string getAlign(MathInsetTypes type, int cols)
int getCols(MathInsetTypes type)
{ {
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)
{
return n ? "" : "*";
}
int getCols(short int type)
{
int col;
switch (type) { switch (type) {
case LM_OT_EQNARRAY: case LM_OT_EQNARRAY:
col = 3; return 3;
break;
case LM_OT_ALIGN: case LM_OT_ALIGN:
case LM_OT_ALIGNAT: case LM_OT_ALIGNAT:
col = 2; case LM_OT_XALIGNAT:
break; case LM_OT_XXALIGNAT:
return 2;
default: default:;
col = 1;
} }
return col; return 1;
} }
// returns position of first relation operator in the array // returns position of first relation operator in the array
// used for "intelligent splitting" // used for "intelligent splitting"
int firstRelOp(MathArray const & array) int firstRelOp(MathArray const & array)
@ -75,25 +41,33 @@ int firstRelOp(MathArray const & array)
return array.size(); return array.size();
} }
char const * star(bool numbered)
{
return numbered ? "" : "*";
}
} }
MathMatrixInset::MathMatrixInset() MathMatrixInset::MathMatrixInset()
: MathGridInset(1, 1), objtype_(LM_OT_SIMPLE), nonum_(1), label_(1) : MathGridInset(1, 1), objtype_(LM_OT_SIMPLE), nonum_(1), label_(1)
{} {
setDefaults();
}
MathMatrixInset::MathMatrixInset(MathInsetTypes t) MathMatrixInset::MathMatrixInset(MathInsetTypes t)
: MathGridInset(getCols(t), 1), objtype_(t), nonum_(1), label_(1) : MathGridInset(getCols(t), 1), objtype_(t), nonum_(1), label_(1)
{ {
halign(getAlign(t, ncols())); setDefaults();
} }
MathMatrixInset::MathMatrixInset(MathInsetTypes t, int cols) MathMatrixInset::MathMatrixInset(MathInsetTypes t, int cols)
: MathGridInset(cols, 1), objtype_(t), nonum_(1), label_(1) : MathGridInset(cols, 1), objtype_(t), nonum_(1), label_(1)
{ {
halign(getAlign(t, ncols())); setDefaults();
} }
@ -103,6 +77,46 @@ MathInset * MathMatrixInset::clone() const
} }
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 void MathMatrixInset::metrics(MathStyles) const
{ {
size_ = (getType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY; size_ = (getType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY;
@ -274,9 +288,17 @@ void MathMatrixInset::header_write(std::ostream & os) const
break; break;
case LM_OT_ALIGNAT: case LM_OT_ALIGNAT:
os << "\\begin{alignat" << star(n) << "}" os << "\\begin{alignat" << star(n) << "}" << "{" << ncols()/2 << "}\n";
<< "{" << ncols()/2 << "}\n";
break; 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: default:
os << "\\begin{unknown" << star(n) << "}"; os << "\\begin{unknown" << star(n) << "}";
} }
@ -311,6 +333,14 @@ void MathMatrixInset::footer_write(std::ostream & os) const
os << "\\end{alignat" << star(n) << "}\n"; os << "\\end{alignat" << star(n) << "}\n";
break; break;
case LM_OT_XALIGNAT:
os << "\\end{xalignat" << star(n) << "}\n";
break;
case LM_OT_XXALIGNAT:
os << "\\end{xxalignat}\n";
break;
default: default:
os << "\\end{unknown" << star(n) << "}"; os << "\\end{unknown" << star(n) << "}";
} }
@ -324,6 +354,7 @@ void MathMatrixInset::addRow(int row)
MathGridInset::addRow(row); MathGridInset::addRow(row);
} }
void MathMatrixInset::appendRow() void MathMatrixInset::appendRow()
{ {
nonum_.push_back(!numberedType()); nonum_.push_back(!numberedType());
@ -339,6 +370,7 @@ void MathMatrixInset::delRow(int row)
label_.erase(label_.begin() + row); label_.erase(label_.begin() + row);
} }
void MathMatrixInset::addCol(int col) void MathMatrixInset::addCol(int col)
{ {
switch (getType()) { switch (getType()) {
@ -352,11 +384,15 @@ void MathMatrixInset::addCol(int col)
break; break;
case LM_OT_ALIGN: case LM_OT_ALIGN:
mutate(LM_OT_ALIGNAT);
addCol(col);
break;
case LM_OT_ALIGNAT: case LM_OT_ALIGNAT:
case LM_OT_XALIGNAT:
case LM_OT_XXALIGNAT:
MathGridInset::addCol(col); MathGridInset::addCol(col);
halign(col, 'l'); MathGridInset::addCol(col + 1);
MathGridInset::addCol(col);
halign(col, 'r');
break; break;
default: default:
@ -364,13 +400,16 @@ void MathMatrixInset::addCol(int col)
} }
} }
void MathMatrixInset::delCol(int col) void MathMatrixInset::delCol(int col)
{ {
switch (getType()) { 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); MathGridInset::delCol(col);
break; break;
default: default:
break; break;
} }
@ -388,7 +427,7 @@ string MathMatrixInset::nicelabel(int row) const
namespace { namespace {
short typecode(string const & s) MathInsetTypes typecode(string const & s)
{ {
if (s == "equation") if (s == "equation")
return LM_OT_EQUATION; return LM_OT_EQUATION;
@ -398,10 +437,12 @@ namespace {
return LM_OT_EQNARRAY; return LM_OT_EQNARRAY;
if (s == "align") if (s == "align")
return LM_OT_ALIGN; return LM_OT_ALIGN;
if (s == "xalign") if (s == "alignat")
return LM_OT_XALIGN; return LM_OT_ALIGN;
if (s == "xxalign") if (s == "xalignat")
return LM_OT_XXALIGN; return LM_OT_XALIGNAT;
if (s == "xxalignat")
return LM_OT_XXALIGNAT;
if (s == "multline") if (s == "multline")
return LM_OT_MULTLINE; return LM_OT_MULTLINE;
return LM_OT_SIMPLE; return LM_OT_SIMPLE;
@ -437,11 +478,12 @@ MathInsetTypes MathMatrixInset::getType() const
void MathMatrixInset::setType(MathInsetTypes t) void MathMatrixInset::setType(MathInsetTypes t)
{ {
objtype_ = t; objtype_ = t;
setDefaults();
} }
void MathMatrixInset::mutate(short newtype) void MathMatrixInset::mutate(MathInsetTypes newtype)
{ {
//lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n"; //lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n";
@ -461,7 +503,11 @@ void MathMatrixInset::mutate(short newtype)
setType(LM_OT_SIMPLE); setType(LM_OT_SIMPLE);
break; break;
case LM_OT_ALIGN: { case LM_OT_ALIGN:
case LM_OT_ALIGNAT:
case LM_OT_XALIGNAT:
case LM_OT_XXALIGNAT: {
MathGridInset::addCol(1); MathGridInset::addCol(1);
// split it "nicely" // split it "nicely"
@ -469,9 +515,8 @@ void MathMatrixInset::mutate(short newtype)
cell(1) = cell(0); cell(1) = cell(0);
cell(0).erase(pos, cell(0).size()); cell(0).erase(pos, cell(0).size());
cell(1).erase(0, pos); cell(1).erase(0, pos);
halign("rl");
setType(LM_OT_ALIGN); setType(LM_OT_ALIGN);
mutate(newtype);
break; break;
} }
@ -492,7 +537,6 @@ void MathMatrixInset::mutate(short newtype)
cell(2).erase(0); cell(2).erase(0);
} }
halign("rcl");
setType(LM_OT_EQNARRAY); setType(LM_OT_EQNARRAY);
mutate(newtype); mutate(newtype);
break; break;
@ -528,6 +572,9 @@ void MathMatrixInset::mutate(short newtype)
} }
case LM_OT_ALIGN: case LM_OT_ALIGN:
case LM_OT_ALIGNAT:
case LM_OT_XALIGNAT:
case LM_OT_XXALIGNAT:
default: { default: {
for (int row = 0; row < nrows(); ++row) { for (int row = 0; row < nrows(); ++row) {
int c = 3 * row + 1; int c = 3 * row + 1;
@ -535,7 +582,6 @@ void MathMatrixInset::mutate(short newtype)
} }
MathGridInset::delCol(2); MathGridInset::delCol(2);
setType(LM_OT_ALIGN); setType(LM_OT_ALIGN);
halign("rl");
mutate(newtype); mutate(newtype);
break; break;
} }
@ -549,10 +595,15 @@ void MathMatrixInset::mutate(short newtype)
case LM_OT_EQNARRAY: case LM_OT_EQNARRAY:
MathGridInset::addCol(1); MathGridInset::addCol(1);
setType(LM_OT_EQNARRAY); setType(LM_OT_EQNARRAY);
halign("rcl");
mutate(newtype); mutate(newtype);
break; break;
case LM_OT_ALIGNAT:
case LM_OT_XALIGNAT:
case LM_OT_XXALIGNAT:
setType(newtype);
break;
default: default:
lyxerr << "mutation from '" << getType() lyxerr << "mutation from '" << getType()
<< "' to '" << newtype << "' not implemented\n"; << "' to '" << newtype << "' not implemented\n";

View File

@ -65,14 +65,21 @@ public:
/// change type /// change type
void mutate(string const &); void mutate(string const &);
/// ///
void mutate(short); void mutate(MathInsetTypes);
///
int defaultColSpace(int col);
///
char defaultColAlign(int col);
/// ///
MathInsetTypes getType() const; MathInsetTypes getType() const;
private: private:
/// ///
virtual void setType(MathInsetTypes t); void setDefaults();
///
void setType(MathInsetTypes t);
/// ///
void validate1(LaTeXFeatures & features); void validate1(LaTeXFeatures & features);
/// ///

View File

@ -602,6 +602,20 @@ MathMatrixInset * Parser::parse_normal()
return p; 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"; lyxerr[Debug::MATHED] << "1: unknown math environment: " << name << "\n";
return 0; return 0;
} }