]> git.lyx.org Git - features.git/commitdiff
Add support for multline and alignat environments from amsmath.
authorDekel Tsur <dekelts@tau.ac.il>
Sat, 3 Feb 2001 21:02:22 +0000 (21:02 +0000)
committerDekel Tsur <dekelts@tau.ac.il>
Sat, 3 Feb 2001 21:02:22 +0000 (21:02 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@1445 a592a061-630c-0410-9148-cb99ea01b6c8

lib/ChangeLog
lib/ui/default.ui
src/buffer.C
src/mathed/ChangeLog
src/mathed/formula.C
src/mathed/math_cursor.C
src/mathed/math_defs.h
src/mathed/math_parser.C
src/mathed/math_write.C

index f213f41d1b00f07d9620814bee7a08369f7d90ec..573ab5eaef2a49b939a7ce057a2a934cd4b8efdb 100644 (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
index 722eec78aed0d0e49c249c5453a6e115b2da94f8..588929d489a95c249b73881dfeca220bcb168a11 100644 (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
 #
index 26cdc9c87353f30c38ce925043eeac99f2186578..754477906bf7fdc5c629e5ffcc78cfbb2924ea46 100644 (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();
index d6c67177b229ffc06c0c09273519d45dfe32df59..03218b7ef3a06147acaaedd3e24119d6c8396883 100644 (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
index 386be2062b7c1280178b55652f9d49c79abdb062..4c31c53b2a47148e1f55bf7179e238a6081fec91 100644 (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);
 }
 
 
@@ -446,19 +452,19 @@ void InsetFormula::draw(BufferView * bv, LyXFont const & f,
                par->draw(pain, int(x), baseline);
        }
        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);
index 1e6902055430271abe6776638a55e15d1914d5e3..f525f2a964652886e91febc8db0407cf024f0c1a 100644 (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();
     }
 }
index 2f1d9aa1148f6b5e1c7ee8fc1166d0ceca61d0e2..06c997773ba85b078fccb359ae44a01041f2a782 100644 (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
index c57e2becfe937ecffed6d9c5252780165bd3cd0f..330ea9cc3098a6ef5857824e41ebef492955bf85 100644 (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);
@@ -811,7 +823,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
                 mt->SetType(mathed_env);
                 crow = mt->getRowSt();
             }
-                              
+
 #ifdef DEBUG
             lyxerr << "MATH BEGIN[" << mathed_env << "]" << endl;
 #endif
index 56e03464b5dbc86d9837ac1c702a6b313d12329e..c212f1a7facb2c5f1caee4b3f92ad13327338959 100644 (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;
    }