Add support for multline and alignat environments from amsmath.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@1445 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Dekel Tsur 2001-02-03 21:02:22 +00:00
parent db2a042267
commit d59aaf992a
9 changed files with 191 additions and 64 deletions

View File

@ -1,3 +1,7 @@
2001-02-03 Dekel Tsur <dekelts@tau.ac.il>
* ui/default.ui: Add Edit->Math menu.
2001-02-02 John Levon <moz@compsoc.man.ac.uk>
* Makefile.am: fix permissions on configure and configure.cmd

View File

@ -96,6 +96,7 @@ Menuset
Submenu "Tabular|T" "edit_tabular"
Submenu "Floats & Insets|I" "edit_floats"
Item "Math Panel|l" "math-panel"
Submenu "Math|M" "edit_math"
Separator
Item "Spellchecker...|S" "spellchecker"
Item "Check TeX|h" "buffer-chktex"
@ -142,6 +143,18 @@ Menuset
Item "Delete Column|D" "tabular-feature delete-column"
End
Menu "edit_math"
Item "Make eqnarray|e" "break-line e"
Item "Make multline|m" "break-line m"
Item "Make alignat 1 column|1" "break-line 1"
Item "Make alignat 2 columns|2" "break-line 2"
Item "Make alignat 3 columns|3" "break-line 3"
Separator
Item "Toggle numbering|n" "math-number"
Item "Toggle numbering of line|u" "math-nonumber"
Item "Toggle limits|l" "math-limits"
End
#
# INSERT MENU
#

View File

@ -1888,7 +1888,7 @@ void Buffer::makeLaTeXFile(string const & fname,
ofs << "}\n";
texrow.newline();
}
if (params.use_amsmath
if (features.amsstyle
&& !tclass.provides(LyXTextClass::amsmath)) {
ofs << "\\usepackage{amsmath}\n";
texrow.newline();

View File

@ -1,3 +1,8 @@
2001-02-02 Dekel Tsur <dekelts@tau.ac.il>
* Many files: Add support for multline and alignat environments from
amsmath.
2001-02-02 Dekel Tsur <dekelts@tau.ac.il>
* math_symbols.C (math_insert_greek): Move cursor right when

View File

@ -292,7 +292,9 @@ InsetFormula::InsetFormula(bool display)
InsetFormula::InsetFormula(MathParInset * p)
{
par = (p->GetType()>= LM_OT_MPAR) ?
if (is_matrix_type(p->GetType()))
lyxerr << "InsetFormula::InsetFormula: This shouldn't happen" << endl;
par = is_multiline(p->GetType()) ?
new MathMatrixInset(static_cast<MathMatrixInset*>(p)):
new MathParInset(p);
// mathcursor = 0;
@ -355,9 +357,13 @@ int InsetFormula::DocBook(Buffer const * buf, ostream & os) const
// Check if uses AMS macros
void InsetFormula::Validate(LaTeXFeatures & features) const
{
// Validation only necesary if not using an AMS Style
if (!features.amsstyle)
mathedValidate(features, par);
if (is_ams(par->GetType()))
features.amsstyle = true;
// Validation is necessary only if not using AMS math.
// To be safe, we will always run mathedValidate.
//if (!features.amsstyle)
mathedValidate(features, par);
}
@ -447,18 +453,18 @@ void InsetFormula::draw(BufferView * bv, LyXFont const & f,
}
x += float(width(bv, font));
if (par->GetType() == LM_OT_PARN || par->GetType() == LM_OT_MPARN) {
if (is_numbered(par->GetType())) {
LyXFont wfont = WhichFont(LM_TC_BF, par->size);
wfont.setLatex(LyXFont::OFF);
if (par->GetType() == LM_OT_PARN) {
if (is_singlely_numbered(par->GetType())) {
string str;
if (!label.empty())
str = string("(") + label + ")";
else
str = string("(#)");
pain.text(int(x + 20), baseline, str, wfont);
} else if (par->GetType() == LM_OT_MPARN) {
} else {
MathMatrixInset * mt =
static_cast<MathMatrixInset*>(par);
int y;
@ -606,7 +612,7 @@ void InsetFormula::display(bool dspf)
par->SetType(LM_OT_PAR);
par->SetStyle(LM_ST_DISPLAY);
} else {
if (par->GetType() >= LM_OT_MPAR) {
if (is_multiline(par->GetType())) {
MathParInset * p = new MathParInset(par);
delete par;
par = p;
@ -615,7 +621,7 @@ void InsetFormula::display(bool dspf)
}
par->SetType(LM_OT_MIN);
par->SetStyle(LM_ST_TEXT);
if (!label.empty() && par->GetType() != LM_OT_MPARN) {
if (!label.empty()) {
label.erase();
}
}
@ -631,7 +637,7 @@ vector<string> const InsetFormula::getLabelList() const
vector<string> label_list;
if (par->GetType() == LM_OT_MPARN) {
if (is_multi_numbered(par->GetType())) {
MathMatrixInset * mt = static_cast<MathMatrixInset*>(par);
MathedRowSt const * crow = mt->getRowSt();
while (crow) {
@ -719,7 +725,7 @@ bool InsetFormula::SetNumber(bool numbf)
{
if (disp_flag) {
short type = par->GetType();
bool oldf = (type == LM_OT_PARN || type == LM_OT_MPARN);
bool oldf = is_numbered(type);
if (numbf && !oldf) ++type;
if (!numbf && oldf) --type;
par->SetType(type);
@ -793,8 +799,10 @@ InsetFormula::LocalDispatch(BufferView * bv,
UpdateLocal(bv);
break;
case LFUN_BREAKLINE:
{
bv->lockedInsetStoreUndo(Undo::INSERT);
mathcursor->Insert(' ', LM_TC_CR);
byte c = arg.empty() ? 'e' : arg[0];
mathcursor->Insert(c, LM_TC_CR);
if (!label.empty()) {
mathcursor->setLabel(label);
label.erase();
@ -802,6 +810,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
par = mathcursor->GetPar();
UpdateLocal(bv);
break;
}
case LFUN_TAB:
bv->lockedInsetStoreUndo(Undo::INSERT);
mathcursor->Insert(0, LM_TC_TAB);
@ -915,8 +924,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
bv->lockedInsetStoreUndo(Undo::INSERT);
if (disp_flag) {
short type = par->GetType();
bool oldf = (type == LM_OT_PARN || type == LM_OT_MPARN);
if (oldf) {
if (is_numbered(type)) {
--type;
if (!label.empty()) {
label.erase();
@ -934,7 +942,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
case LFUN_MATH_NONUMBER:
{
if (par->GetType() == LM_OT_MPARN) {
if (is_multi_numbered(par->GetType())) {
// MathMatrixInset *mt = (MathMatrixInset*)par;
//BUG
// mt->SetNumbered(!mt->IsNumbered());
@ -1060,8 +1068,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
if (par->GetType() < LM_OT_PAR)
break;
string old_label = (par->GetType() == LM_OT_MPARN ||
par->GetType() == LM_OT_MPAR)
string old_label = is_multiline(par->GetType())
? mathcursor->getLabel() : label;
#warning This is a terrible hack! We should find a better solution.
@ -1094,7 +1101,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
if (!new_label.empty() && bv->ChangeRefsIfUnique(old_label, new_label))
bv->redraw();
if (par->GetType() == LM_OT_MPARN)
if (is_multi_numbered(par->GetType()))
mathcursor->setLabel(new_label);
// MathMatrixInset *mt = (MathMatrixInset*)par;
// mt->SetLabel(new_label);

View File

@ -329,6 +329,38 @@ void MathedCursor::End()
}
MathMatrixInset * create_multiline(short int type, int cols)
{
int columns;
string align;
if (cols < 1)
cols = 1;
switch (type) {
case LM_OT_ALIGNAT:
case LM_OT_ALIGNATN:
columns = 2*cols;
for (int i = 0; i < cols; ++i)
align += "rl";
break;
case LM_OT_MULTLINE:
case LM_OT_MULTLINEN:
columns = 1;
align = "c"; // This is incorrect!
break;
case LM_OT_MPAR:
case LM_OT_MPARN:
default:
columns = 3;
align = "rcl";
break;
}
MathMatrixInset * mt = new MathMatrixInset(columns, -1);
mt->SetAlign(' ', align);
return mt;
}
void MathedCursor::Insert(byte c, MathedTextCodes t)
{
if (selection) SelDel();
@ -342,10 +374,21 @@ void MathedCursor::Insert(byte c, MathedTextCodes t)
if (t == LM_TC_CR) {
MathParInset * p = cursor->p;
if (p == par && p->GetType()<LM_OT_MPAR && p->GetType()>LM_OT_MIN) {
MathMatrixInset * mt = new MathMatrixInset(3, 0);
mt->SetAlign(' ', "rcl");
short int type = LM_OT_MPAR;
int cols = 1;
if (c >= '1' && c <= '9') {
type = LM_OT_ALIGNAT;
cols = c - '0';
} else if (c == 'm')
type = LM_OT_MULTLINE;
else if (c == 'e')
type = LM_OT_MPAR;
if (p->GetType() == LM_OT_PARN)
++type;
MathMatrixInset * mt = create_multiline(type, cols);
mt->SetStyle(LM_ST_DISPLAY);
mt->SetType((p->GetType() == LM_OT_PARN) ? LM_OT_MPARN: LM_OT_MPAR);
mt->SetType(type);
mt->SetData(p->GetData());
p->SetData(0);//BUG duda
delete p;
@ -448,7 +491,7 @@ void MathedCursor::DelLine()
return;
}
MathParInset *p= cursor->p;
if (p && (p->GetType()<= LM_OT_MATRIX && p->GetType()>= LM_OT_MPAR)) {
if (p && p->GetType() <= LM_OT_MATRIX && p->GetType() >= LM_OT_MPAR) {
cursor->delRow();
}
}

View File

@ -63,23 +63,6 @@ enum MathedStyles {
};
/// Standard LaTeX Math Environments
enum MathedEnvironment {
///
LM_EN_INTEXT = 0,
///
LM_EN_DISPLAY,
///
LM_EN_EQUATION,
///
LM_EN_EQNARRAYAST,
///
LM_EN_EQNARRAY,
///
LM_EN_ARRAY
};
/** The restrictions of a standard LaTeX math paragraph
allows to get a small number of text codes (<30) */
enum MathedTextCodes {
@ -161,8 +144,17 @@ enum MathedInsetTypes {
LM_OT_MPAR,
/// A multiline numbered paragraph
LM_OT_MPARN,
///
LM_OT_ALIGNAT,
///
LM_OT_ALIGNATN,
///
LM_OT_MULTLINE,
///
LM_OT_MULTLINEN,
/// An array
LM_OT_MATRIX,
/// A big operator
LM_OT_BIGOP,
/// A LaTeX macro
@ -657,4 +649,53 @@ void MathParInset::SetStyle(short sz)
}
}
inline
bool is_eqn_type(short int type)
{
return type >= LM_OT_MIN && type < LM_OT_MATRIX;
}
inline
bool is_matrix_type(short int type)
{
return type == LM_OT_MATRIX;
}
inline
bool is_multiline(short int type)
{
return type >= LM_OT_MPAR && type < LM_OT_MATRIX;
}
inline bool is_ams(short int type)
{
return type > LM_OT_MPARN && type < LM_OT_MATRIX;
}
inline
bool is_singlely_numbered(short int type)
{
return type == LM_OT_PARN || type == LM_OT_MULTLINEN;
}
inline
bool is_multi_numbered(short int type)
{
return type == LM_OT_MPARN || type == LM_OT_ALIGNATN;
}
inline
bool is_numbered(short int type)
{
return is_singlely_numbered(type) || is_multi_numbered(type);
}
inline
bool is_multicolumn(short int type)
{
return type == LM_OT_ALIGNAT || type == LM_OT_ALIGNATN;
}
#endif

View File

@ -40,6 +40,9 @@ using std::isdigit;
using std::isspace;
#endif
extern MathMatrixInset * create_multiline(short int type, int cols);
enum {
FLAG_BRACE = 1, // A { needed
FLAG_BRACE_ARG = 2, // Next { is argument
@ -57,22 +60,26 @@ YYSTYPE yylval;
static
short mathed_env = LM_EN_INTEXT;
MathedInsetTypes mathed_env = LM_OT_MIN;
string mathed_label;
char const * latex_mathenv[] = {
int const latex_mathenv_num = 10;
char const * latex_mathenv[latex_mathenv_num] = {
"math",
"displaymath",
"equation",
"eqnarray*",
"eqnarray",
"alignat*",
"alignat",
"multline*",
"multline",
"array"
};
char const * latex_mathspace[] = {
"!", ",", ":", ";", "quad", "qquad"
};
@ -252,19 +259,19 @@ int yylex(void)
return LM_TK_NEWLINE;
}
if (c == '(') {
yylval.i = LM_EN_INTEXT;
yylval.i = LM_OT_MIN;
return LM_TK_BEGIN;
}
if (c == ')') {
yylval.i = LM_EN_INTEXT;
yylval.i = LM_OT_MIN;
return LM_TK_END;
}
if (c == '[') {
yylval.i = LM_EN_DISPLAY;
yylval.i = LM_OT_PAR;
return LM_TK_BEGIN;
}
if (c == ']') {
yylval.i = LM_EN_DISPLAY;
yylval.i = LM_OT_PAR;
return LM_TK_END;
}
if (strchr(latex_special_chars, c)) {
@ -296,7 +303,8 @@ int yylex(void)
// for (i = 0; i < 5 && strncmp(yytext, latex_mathenv[i],
// strlen(latex_mathenv[i])); ++i);
for (i = 0; i < 6 && strcmp(yytext, latex_mathenv[i]); ++i);
for (i = 0; i < latex_mathenv_num
&& strcmp(yytext, latex_mathenv[i]); ++i);
yylval.i = i;
} else
if (l->token == LM_TK_SPACE)
@ -757,7 +765,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
}
case LM_TK_END:
{
if (mathed_env != yylval.i && yylval.i!= LM_EN_ARRAY)
if (mathed_env != yylval.i && yylval.i != LM_OT_MATRIX)
mathPrintError("Unmatched environment");
// debug info [made that conditional -JMarc]
if (lyxerr.debugging(Debug::MATHED))
@ -771,7 +779,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
}
case LM_TK_BEGIN:
{
if (yylval.i == LM_EN_ARRAY) {
if (yylval.i == LM_OT_MATRIX) {
char ar[120], ar2[8];
ar[0] = ar2[0] = '\0';
char rg = LexGetArg(0);
@ -785,7 +793,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
mm->SetAlign(ar2[0], ar);
data.Insert(mm, LM_TC_ACTIVE_INSET);
mathed_parse(FLAG_END, mm->GetData(), &mm);
} else if (yylval.i >= LM_EN_INTEXT && yylval.i<= LM_EN_EQNARRAY) {
} else if (is_eqn_type(yylval.i)) {
if (plevel!= 0) {
mathPrintError("Misplaced environment");
break;
@ -796,11 +804,15 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
}
mathed_env = yylval.i;
if (mathed_env>= LM_EN_DISPLAY) {
if (mathed_env != LM_OT_MIN) {
size = LM_ST_DISPLAY;
if (mathed_env>LM_EN_EQUATION) {
mt = new MathMatrixInset(3, -1);
mt->SetAlign(' ', "rcl");
if (is_multiline(mathed_env)) {
int cols = 1;
if (is_multicolumn(mathed_env)) {
LexGetArg('{');
cols = strToInt(string(yytext));
}
mt = create_multiline(mathed_env, cols);
if (mtx) *mtx = mt;
flags |= FLAG_END;
// data.Insert(' ', LM_TC_TAB);

View File

@ -318,29 +318,31 @@ void MathMatrixInset::Write(ostream & os, bool fragile)
}
}
void mathed_write(MathParInset * p, ostream & os, int * newlines,
bool fragile, string const & label)
{
number_of_newlines = 0;
short mathed_env = p->GetType();
if (mathed_env == LM_EN_INTEXT) {
if (mathed_env == LM_OT_MIN) {
if (fragile) os << "\\protect";
os << "\\( "; // changed from " \\( " (Albrecht Dress)
}
else {
if (mathed_env == LM_EN_DISPLAY){
if (mathed_env == LM_OT_PAR){
os << "\\[\n";
} else {
os << "\\begin{"
<< latex_mathenv[mathed_env]
<< "}\n";
<< "}";
if (mathed_env == LM_OT_ALIGNAT || mathed_env == LM_OT_ALIGNATN)
os << "{" << p->GetColumns()/2 << "}";
os << "\n";
}
++number_of_newlines;
}
if (!label.empty() && label[0] > ' ' && mathed_env == LM_EN_EQUATION){
if (!label.empty() && label[0] > ' ' && is_singlely_numbered(mathed_env)) {
os << "\\label{"
<< label
<< "}\n";
@ -349,11 +351,11 @@ void mathed_write(MathParInset * p, ostream & os, int * newlines,
p->Write(os, fragile);
if (mathed_env == LM_EN_INTEXT){
if (mathed_env == LM_OT_MIN){
if (fragile) os << "\\protect";
os << " \\)";
}
else if (mathed_env == LM_EN_DISPLAY) {
else if (mathed_env == LM_OT_PAR) {
os << "\\]\n";
++number_of_newlines;
}