]> git.lyx.org Git - lyx.git/blobdiff - src/layout.C
update all .po files ot latestes pot
[lyx.git] / src / layout.C
index 4e6c5781c1f8b9fb962907c7520b62bbe38ee166..bad3b274118812ec634e630be50b5cb6c8520857 100644 (file)
@@ -1,26 +1,12 @@
 /* This file is part of
- * ======================================================
+ * ====================================================== 
  * 
  *           LyX, The Document Processor
  *      
  *          Copyright 1995 Matthias Ettrich
- *          Copyright 1995-1999 The LyX Team.
+ *          Copyright 1995-2000 The LyX Team.
  *
- * ======================================================*/
-
-/* Change log:
- * 
- *  14/11/1995,   Pascal AndrĂ© <andre@via.ecp.fr>
- *  Modified for external style definition. 
- * 
- *  15/11/1995,   Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
- *  Modified to use binary search and a small pseudo lexical analyzer.
- *  
- *  29/03/1996,  Dirk Niggeman
- *  Created classes LyXTextClass & LyXLayout.
- * 
- *  30/03/1996,  asierra
- *  Created class LyxLex and improved the lexical analyzer. 
+ * ======================================================
  */
 
 #include <config.h>
 #pragma implementation
 #endif
 
-#include "definitions.h"
-#include <cstdlib>
+#include <algorithm>
+
 #include "layout.h"
 #include "lyxlex.h"
 #include "support/filetools.h"
 #include "lyx_gui_misc.h"
-#include "error.h"
+#include "debug.h"
 #include "gettext.h"
+#include "support/LAssert.h"
+#include "support/lyxfunctional.h"
+
+using std::pair;
+using std::make_pair;
+using std::sort;
+using std::endl;
+using std::find_if;
+using std::remove_if;
+
+// Global variable: textclass table.
+LyXTextClassList textclasslist;
 
-/* Global variable: textclass table */
-LyXTextClassList lyxstyle;
 
 // Reads the style files
 void LyXSetStyle()
 {
-       lyxerr.debug("LyXSetStyle: parsing configuration...");
+       lyxerr[Debug::TCLASS] << "LyXSetStyle: parsing configuration...\n";
        
-       if (!lyxstyle.Read()) {
-               lyxerr.print("LyXSetStyle: an error occured during parsing.");
-               lyxerr.print("             Exiting.");
+       if (!textclasslist.Read()) {
+               lyxerr[Debug::TCLASS] << "LyXSetStyle: an error occured "
+                       "during parsing.\n             Exiting." << endl;
                exit(1);
        }
 
-       lyxerr.debug("LyXSetStyle: configuration parsed.");
+       lyxerr[Debug::TCLASS] << "LyXSetStyle: configuration parsed." << endl;
 }
 
 
 //  The order of the LayoutTags enum is no more important. [asierra300396]
-/* tags indexes */
-enum _LayoutTags {
-       LT_ALIGN, LT_ALIGNPOSSIBLE, 
-       LT_BLOCK, LT_MARGIN,
-       LT_BOTTOMSEP, LT_CENTER, LT_CENTERED_TOP_ENVIRONMENT, LT_COLUMNS,
-       LT_COPYSTYLE, LT_OBSOLETEDBY,
-       LT_COMMAND, LT_COUNTER_CHAPTER, LT_COUNTER_ENUMI, LT_COUNTER_ENUMII,
-       LT_COUNTER_ENUMIII, LT_COUNTER_ENUMIV, LT_COUNTER_PARAGRAPH,
-       LT_COUNTER_SECTION, LT_COUNTER_SUBPARAGRAPH, LT_COUNTER_SUBSECTION,
-       LT_COUNTER_SUBSUBSECTION, LT_DEFAULTFONT, LT_DYNAMIC, LT_EMPTY,
-       LT_END, LT_ENVIRONMENT, LT_ENVIRONMENT_DEFAULT, 
-       LT_FANCYHDR, LT_FILL_BOTTOM, LT_FILL_TOP, LT_FIRST_COUNTER,
-       LT_FIRST_DYNAMIC, LT_FONT, LT_FREE_SPACING, LT_HEADINGS, LT_INPUT,
-       LT_ITEM_ENVIRONMENT, LT_ITEMSEP, LT_KEEPEMPTY,
-       LT_LABEL_BOTTOMSEP, LT_LABELFONT, LT_TEXTFONT,
-       LT_LABELINDENT, LT_LABELSEP, LT_LABELSTRING,
-       LT_LABELSTRING_APPENDIX, LT_LABELTYPE,
-       LT_LATEXNAME, LT_LATEXPARAM, LT_LATEXTYPE, LT_LAYOUT, LT_LEFT,
-       LT_LEFTMARGIN,
-       LT_LIST_ENVIRONMENT , LT_MANUAL, LT_MAXCOUNTER, 
-       LT_NEED_PROTECT, LT_NEWLINE,
-       LT_NEXTNOINDENT, LT_NO_LABEL, LT_NOSTYLE,
-       LT_PAGESTYLE, LT_PARAGRAPH,
-       LT_PARINDENT, LT_PARSEP, LT_PARSKIP, LT_PLAIN, LT_PREAMBLE, 
-       LT_PROVIDESAMSMATH, LT_PROVIDESMAKEIDX, LT_PROVIDESURL, LT_RIGHT,
-       LT_RIGHT_ADDRESS_BOX, LT_RIGHTMARGIN, LT_SENSITIVE, LT_SIDES,
-       LT_SPACING, LT_SPACING_SINGLE, LT_SPACING_ONEHALF,
-       LT_SPACING_DOUBLE, LT_OTHER,  LT_CLASSOPTIONS, LT_FONTSIZE,
-       LT_STATIC, LT_STYLE, LT_TOP_ENVIRONMENT, LT_TOPSEP, LT_BIBLIO,
-        LT_INTITLE, LT_SECNUMDEPTH, LT_TOCDEPTH,
-       LT_OUTPUTTYPE, LT_OTLATEX, LT_OTLINUXDOC, LT_OTDOCBOOK, LT_OTLITERATE
+// Tags indexes.
+enum LayoutTags {
+       LT_ALIGN = 1, 
+       LT_ALIGNPOSSIBLE, 
+       LT_MARGIN, 
+       LT_BOTTOMSEP, 
+       LT_COPYSTYLE, 
+       LT_OBSOLETEDBY, 
+       //LT_EMPTY,
+       LT_END, 
+       //LT_ENVIRONMENT_DEFAULT, 
+       //LT_FANCYHDR,
+       LT_FILL_BOTTOM, 
+       LT_FILL_TOP, 
+       //LT_FIRST_COUNTER,
+       LT_FONT, 
+       LT_FREE_SPACING, 
+       //LT_HEADINGS,
+       LT_ITEMSEP, 
+       LT_KEEPEMPTY, 
+       LT_LABEL_BOTTOMSEP, 
+       LT_LABELFONT, 
+       LT_TEXTFONT,
+       LT_LABELINDENT, 
+       LT_LABELSEP, 
+       LT_LABELSTRING, 
+       LT_LABELSTRING_APPENDIX, 
+       LT_LABELTYPE,
+       LT_ENDLABELSTRING,
+       LT_ENDLABELTYPE,
+       LT_LATEXNAME, 
+       LT_LATEXPARAM, 
+       LT_LATEXTYPE, 
+       LT_LEFTMARGIN, 
+       LT_NEED_PROTECT, 
+       LT_NEWLINE, 
+       LT_NEXTNOINDENT, 
+       LT_PARINDENT, 
+       LT_PARSEP, 
+       LT_PARSKIP, 
+       //LT_PLAIN,
+       LT_PREAMBLE, 
+       LT_RIGHTMARGIN, 
+       LT_SPACING, 
+       LT_TOPSEP, 
+        LT_INTITLE 
 };
 
 
-// This table is sorted alphabetically [asierra 30March96]
-static keyword_item layoutTags[] = {
-       { "align",                      LT_ALIGN },
-       { "alignpossible",              LT_ALIGNPOSSIBLE },
-       { "bibliography",               LT_BIBLIO },
-       { "block",                      LT_BLOCK },
-       { "bottomsep",                  LT_BOTTOMSEP },
-       { "center",                     LT_CENTER },
-       { "centered_top_environment",   LT_CENTERED_TOP_ENVIRONMENT },
-        { "classoptions",               LT_CLASSOPTIONS },
-       { "columns",                    LT_COLUMNS },
-       { "command",                    LT_COMMAND },
-       { "copystyle",                  LT_COPYSTYLE },
-       { "counter_chapter",            LT_COUNTER_CHAPTER },
-       { "counter_enumi",              LT_COUNTER_ENUMI },
-       { "counter_enumii",             LT_COUNTER_ENUMII },
-       { "counter_enumiii",            LT_COUNTER_ENUMIII },
-       { "counter_enumiv",             LT_COUNTER_ENUMIV },
-       { "counter_paragraph",          LT_COUNTER_PARAGRAPH },
-       { "counter_section",            LT_COUNTER_SECTION },
-       { "counter_subparagraph",       LT_COUNTER_SUBPARAGRAPH },
-       { "counter_subsection",         LT_COUNTER_SUBSECTION },
-       { "counter_subsubsection",      LT_COUNTER_SUBSUBSECTION },
-       { "defaultfont",                LT_DEFAULTFONT },
-       { "docbook",                    LT_OTDOCBOOK },
-       { "double",                     LT_SPACING_DOUBLE },
-       { "dynamic",                    LT_DYNAMIC },
-       { "empty",                      LT_EMPTY },
-       { "end",                        LT_END },
-       { "environment",                LT_ENVIRONMENT },
-       { "environment_default",        LT_ENVIRONMENT_DEFAULT },
-       { "fancyhdr",                   LT_FANCYHDR },
-       { "fill_bottom",                LT_FILL_BOTTOM },
-       { "fill_top",                   LT_FILL_TOP },
-       { "first_counter",              LT_FIRST_COUNTER },
-       { "first_dynamic",              LT_FIRST_DYNAMIC },
-       { "font",                       LT_FONT },
-       { "fontsize",                   LT_FONTSIZE },
-       { "freespacing",                LT_FREE_SPACING },
-       { "headings",                   LT_HEADINGS },
-       { "input",                      LT_INPUT },
-       { "intitle",                    LT_INTITLE },
-       { "item_environment",           LT_ITEM_ENVIRONMENT },
-       { "itemsep",                    LT_ITEMSEP },
-       { "keepempty",                  LT_KEEPEMPTY },
-       { "labelbottomsep",             LT_LABEL_BOTTOMSEP },
-       { "labelfont",                  LT_LABELFONT },
-       { "labelindent",                LT_LABELINDENT },
-       { "labelsep",                   LT_LABELSEP },
-       { "labelstring",                LT_LABELSTRING },
-       { "labelstringappendix",                LT_LABELSTRING_APPENDIX },
-       { "labeltype",                  LT_LABELTYPE },
-       { "latex",                      LT_OTLATEX },
-       { "latexname",                  LT_LATEXNAME },
-       { "latexparam",                 LT_LATEXPARAM },    //arrae970411
-       { "latextype",                  LT_LATEXTYPE },
-       { "layout",                     LT_LAYOUT },
-       { "left",                       LT_LEFT },
-       { "leftmargin",                 LT_LEFTMARGIN },
-       { "linuxdoc",                   LT_OTLINUXDOC },
-       { "list_environment",           LT_LIST_ENVIRONMENT },
-       { "literate",                   LT_OTLITERATE },
-       { "manual",                     LT_MANUAL },
-       { "margin",                     LT_MARGIN },
-       { "maxcounter",                 LT_MAXCOUNTER },
-       { "needprotect",                LT_NEED_PROTECT },
-       { "newline",                    LT_NEWLINE },
-       { "nextnoindent",               LT_NEXTNOINDENT },
-       { "no_label",                   LT_NO_LABEL },
-       { "nostyle",                    LT_NOSTYLE },
-       { "obsoletedby",                LT_OBSOLETEDBY },
-       { "onehalf",                    LT_SPACING_ONEHALF },
-       { "other",                      LT_OTHER },
-       { "outputtype",                 LT_OUTPUTTYPE },
-       { "pagestyle",                  LT_PAGESTYLE },
-       { "paragraph",                  LT_PARAGRAPH },
-       { "parindent",                  LT_PARINDENT },
-       { "parsep",                     LT_PARSEP },
-       { "parskip",                    LT_PARSKIP },
-       { "plain",                      LT_PLAIN },
-       { "preamble",                   LT_PREAMBLE },
-       { "providesamsmath",            LT_PROVIDESAMSMATH },
-       { "providesmakeidx",            LT_PROVIDESMAKEIDX },
-       { "providesurl",                LT_PROVIDESURL },
-       { "right",                      LT_RIGHT },
-       { "right_address_box",          LT_RIGHT_ADDRESS_BOX },
-       { "rightmargin",                LT_RIGHTMARGIN },
-       { "secnumdepth",                LT_SECNUMDEPTH },
-       { "sensitive",                  LT_SENSITIVE },
-       { "sides",                      LT_SIDES },
-       { "single",                     LT_SPACING_SINGLE },
-       { "spacing",                    LT_SPACING },
-       { "static",                     LT_STATIC },
-       { "style",                      LT_STYLE },
-       { "textfont",                   LT_TEXTFONT },
-       { "tocdepth",                   LT_TOCDEPTH },
-       { "top_environment",            LT_TOP_ENVIRONMENT },
-       { "topsep",                     LT_TOPSEP }
-};
-
-
-/* ******************************************************************* */
+/////////////////////
 
 // Constructor for layout
 LyXLayout::LyXLayout ()
@@ -216,6 +126,7 @@ LyXLayout::LyXLayout ()
        align = LYX_ALIGN_BLOCK;
        alignpossible = LYX_ALIGN_BLOCK;
        labeltype = LABEL_NO_LABEL;
+       endlabeltype = END_LABEL_NO_LABEL;
        // Should or should not. That is the question.
        // spacing.set(Spacing::OneHalf);
        fill_top = false;
@@ -225,97 +136,94 @@ LyXLayout::LyXLayout ()
 }
 
 
-LyXLayout::~LyXLayout ()
-{
-}
-
-
-void LyXLayout::Copy (LyXLayout const &l)
+// Reads a layout definition from file
+bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass)
 {
-       name = l.name;
-       obsoleted_by = l.obsoleted_by;
-       margintype = l.margintype;
-       latextype = l.latextype;
-       intitle = l.intitle;
-       needprotect = l.needprotect;
-       keepempty = l.keepempty;
-       latexname = l.latexname;
-       latexparam = l.latexparam;   //arrae970411
-       preamble = l.preamble;
-       font = l.font;
-       labelfont = l.labelfont;
-       resfont = l.resfont;
-       reslabelfont = l.reslabelfont;
-       nextnoindent = l.nextnoindent;
-       leftmargin = l.leftmargin;
-       rightmargin = l.rightmargin;
-       labelsep = l.labelsep;
-       labelindent = l.labelindent;
-       parindent = l.parindent;
-       parskip = l.parskip;
-       itemsep = l.itemsep;
-       topsep = l.topsep;
-       bottomsep = l.bottomsep;
-       labelbottomsep = l.labelbottomsep;
-       parsep = l.parsep;
-       align = l.align;
-       alignpossible = l.alignpossible;
-       labeltype = l.labeltype;
-       spacing = l.spacing;
-       labelstring = l.labelstring;
-       labelstring_appendix = l.labelstring_appendix;
-       fill_top = l.fill_top;
-       fill_bottom = l.fill_bottom;
-       newline_allowed = l.newline_allowed;
-       free_spacing = l.free_spacing;
-}
-
+       // This table is sorted alphabetically [asierra 30March96]
+       keyword_item layoutTags[] = {
+               { "align",                      LT_ALIGN },
+               { "alignpossible",              LT_ALIGNPOSSIBLE },
+               { "bottomsep",                  LT_BOTTOMSEP },
+               { "copystyle",                  LT_COPYSTYLE },
+               { "end",                        LT_END },
+               { "endlabelstring",             LT_ENDLABELSTRING },
+               { "endlabeltype",               LT_ENDLABELTYPE },
+               { "fill_bottom",                LT_FILL_BOTTOM },
+               { "fill_top",                   LT_FILL_TOP },
+               { "font",                       LT_FONT },
+               { "freespacing",                LT_FREE_SPACING },
+               { "intitle",                    LT_INTITLE },
+               { "itemsep",                    LT_ITEMSEP },
+               { "keepempty",                  LT_KEEPEMPTY },
+               { "labelbottomsep",             LT_LABEL_BOTTOMSEP },
+               { "labelfont",                  LT_LABELFONT },
+               { "labelindent",                LT_LABELINDENT },
+               { "labelsep",                   LT_LABELSEP },
+               { "labelstring",                LT_LABELSTRING },
+               { "labelstringappendix",        LT_LABELSTRING_APPENDIX },
+               { "labeltype",                  LT_LABELTYPE },
+               { "latexname",                  LT_LATEXNAME },
+               { "latexparam",                 LT_LATEXPARAM },
+               { "latextype",                  LT_LATEXTYPE },
+               { "leftmargin",                 LT_LEFTMARGIN },
+               { "margin",                     LT_MARGIN },
+               { "needprotect",                LT_NEED_PROTECT },
+               { "newline",                    LT_NEWLINE },
+               { "nextnoindent",               LT_NEXTNOINDENT },
+               { "obsoletedby",                LT_OBSOLETEDBY },
+               { "parindent",                  LT_PARINDENT },
+               { "parsep",                     LT_PARSEP },
+               { "parskip",                    LT_PARSKIP },
+               { "preamble",                   LT_PREAMBLE },
+               { "rightmargin",                LT_RIGHTMARGIN },
+               { "spacing",                    LT_SPACING },
+               { "textfont",                   LT_TEXTFONT },
+               { "topsep",                     LT_TOPSEP }
+       };
 
-/* Reads a layout definition from file */
-bool LyXLayout::Read (LyXLex & lexrc, LyXLayoutList * list)
-{
        bool error = false;
        bool finished = false;
-       
-       /* parse style section */
+       lexrc.pushTable(layoutTags, LT_INTITLE);
+       // parse style section
        while (!finished && lexrc.IsOK() && !error) {
-               switch(lexrc.lex()) {
-
-               case -2:
-                       break;
+               int le = lexrc.lex();
+               // See comment in lyxrc.C.
+               switch(le) {
+               case LyXLex::LEX_FEOF:
+                       continue; 
 
-               case -1:                /* parse error */
-                       lexrc.printError("Unknown tag `$$Token'");
+               case LyXLex::LEX_UNDEF:         // parse error
+                       lexrc.printError("Unknown layout tag `$$Token'");
                        error = true;
-                       break;
-
-               case LT_END:            /* end of structure */
+                       continue; 
+               default: break;
+               }
+               switch(static_cast<LayoutTags>(le)) {
+               case LT_END:            // end of structure
                        finished = true;
                        break;
 
                case LT_COPYSTYLE:     // initialize with a known style
                        if (lexrc.next()) {
-                               LyXLayout * layout = list->GetLayout(lexrc.GetString());
-                               if (layout) {
-                                       string tmpname = name;
-                                       Copy(*layout);
-                                       name = tmpname;
+                               if (tclass.hasLayout(lexrc.GetString())) {
+                                       string tmpname = name_;
+                                       this->operator= (tclass.GetLayout(lexrc.GetString()));
+                                       name_ = tmpname;
                                } else {
-                                       lexrc.printError("Cannot copy unknown "
-                                                 "style `$$Token'");
+                                       lexrc.printError("Cannot copy known "
+                                                        "style `$$Token'");
                                }
                        }
                        break;
 
                case LT_OBSOLETEDBY:     // replace with a known style
                        if (lexrc.next()) {
-                               LyXLayout * layout = list->GetLayout(lexrc.GetString());
-                               if (layout) {
-                                       string tmpname = name;
-                                       Copy(*layout);
-                                       name = tmpname;
-                                       if (obsoleted_by.empty())
-                                               obsoleted_by = lexrc.GetString();
+                               if (tclass.hasLayout(lexrc.GetString())) {
+                                       string tmpname = name_;
+                                       this->operator= (tclass.GetLayout(lexrc.GetString()));
+                                       name_ = tmpname;
+                                       if (obsoleted_by().empty())
+                                         obsoleted_by_ = lexrc.GetString();
                                } else {
                                        lexrc.printError("Cannot replace with" 
                                                         " unknown style "
@@ -324,51 +232,12 @@ bool LyXLayout::Read (LyXLex & lexrc, LyXLayoutList * list)
                        }
                        break;
 
-               case LT_MARGIN:         /* margin style definition */
-                      
-                       switch(lexrc.lex()) {
-                       case LT_STATIC:
-                               margintype = MARGIN_STATIC;
-                               break;
-                       case LT_MANUAL:
-                               margintype = MARGIN_MANUAL;
-                               break;
-                       case LT_DYNAMIC:
-                               margintype = MARGIN_DYNAMIC;
-                               break;
-                       case LT_FIRST_DYNAMIC:
-                               margintype = MARGIN_FIRST_DYNAMIC;
-                               break;
-                       case LT_RIGHT_ADDRESS_BOX:
-                               margintype = MARGIN_RIGHT_ADDRESS_BOX;
-                               break;
-                       default:
-                               lexrc.printError("Unknown margin type `$$Token'");
-                               break;
-                       }
+               case LT_MARGIN:         // Margin style definition.
+                       readMargin(lexrc);
                        break;
 
-               case LT_LATEXTYPE:      /* latex style definition */
-                       switch (lexrc.lex()) {
-                       case LT_PARAGRAPH:
-                               latextype=LATEX_PARAGRAPH;
-                               break;
-                       case LT_COMMAND:
-                               latextype=LATEX_COMMAND;
-                               break;
-                       case LT_ENVIRONMENT:
-                               latextype=LATEX_ENVIRONMENT;
-                               break;
-                       case LT_ITEM_ENVIRONMENT:
-                               latextype=LATEX_ITEM_ENVIRONMENT;
-                               break;
-                       case LT_LIST_ENVIRONMENT:
-                               latextype=LATEX_LIST_ENVIRONMENT;
-                               break;
-                       default:
-                               lexrc.printError("Unknown latextype `$$Token'");
-                               break;
-                       }
+               case LT_LATEXTYPE:      // Latex style definition.
+                       readLatexType(lexrc);
                        break;
 
                case LT_INTITLE:
@@ -385,7 +254,7 @@ bool LyXLayout::Read (LyXLex & lexrc, LyXLayoutList * list)
 
                case LT_FONT:
                        font.lyxRead(lexrc);
-                       labelfont=font;
+                       labelfont= font;
                        break;
 
                case LT_TEXTFONT:
@@ -396,482 +265,598 @@ bool LyXLayout::Read (LyXLex & lexrc, LyXLayoutList * list)
                        labelfont.lyxRead(lexrc);
                        break;
 
-               case LT_NEXTNOINDENT:   /* indent next paragraph ? */
+               case LT_NEXTNOINDENT:   // Indent next paragraph?
                        if (lexrc.next() && lexrc.GetInteger())
                                nextnoindent = true;
                        else
                                nextnoindent = false;
                        break;
 
-               case LT_LATEXNAME:      /* latex name */
+               case LT_LATEXNAME:
                        if (lexrc.next())
-                               latexname = lexrc.GetString();
+                               latexname_ = lexrc.GetString();
                        break;
                         
-                //arrae970411
-               case LT_LATEXPARAM:     /* latex parameter */
+               case LT_LATEXPARAM:
                        if (lexrc.next())
-                               latexparam = lexrc.GetString();
+                               latexparam_ = lexrc.GetString();
                        break;
 
                case LT_PREAMBLE:
-                       preamble = lexrc.getLongString("EndPreamble");
+                       preamble_ = lexrc.getLongString("EndPreamble");
                        break;
 
-               case LT_LABELTYPE:      /* label type */
-                       switch (lexrc.lex()) {
-                       case LT_NO_LABEL:
-                               labeltype = LABEL_NO_LABEL;
-                               break;
-                       case LT_MANUAL:
-                               labeltype = LABEL_MANUAL;
-                               break;
-                       case LT_TOP_ENVIRONMENT:
-                               labeltype = LABEL_TOP_ENVIRONMENT;
-                               break;
-                       case LT_CENTERED_TOP_ENVIRONMENT:
-                               labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
-                               break;
-                       case LT_STATIC:
-                               labeltype = LABEL_STATIC;
-                               break;
-                       case LT_SENSITIVE:
-                               labeltype = LABEL_SENSITIVE;
-                               break;
-                       case LT_COUNTER_CHAPTER:
-                               labeltype = LABEL_COUNTER_CHAPTER;
-                               break;
-                       case LT_COUNTER_SECTION:
-                               labeltype = LABEL_COUNTER_SECTION;
-                               break;
-                       case LT_COUNTER_SUBSECTION:
-                               labeltype = LABEL_COUNTER_SUBSECTION;
-                               break;
-                       case LT_COUNTER_SUBSUBSECTION:
-                               labeltype = LABEL_COUNTER_SUBSUBSECTION;
-                               break;
-                       case LT_COUNTER_PARAGRAPH:
-                               labeltype = LABEL_COUNTER_PARAGRAPH;
-                               break;
-                       case LT_COUNTER_SUBPARAGRAPH:
-                               labeltype = LABEL_COUNTER_SUBPARAGRAPH;
-                               break;
-                       case LT_COUNTER_ENUMI:
-                               labeltype = LABEL_COUNTER_ENUMI;
-                               break;
-                       case LT_COUNTER_ENUMII:
-                               labeltype = LABEL_COUNTER_ENUMII;
-                               break;
-                       case LT_COUNTER_ENUMIII:
-                               labeltype = LABEL_COUNTER_ENUMIII;
-                               break;
-                       case LT_COUNTER_ENUMIV:
-                               labeltype = LABEL_COUNTER_ENUMIV;
-                               break;
-                       case LT_BIBLIO:
-                               labeltype = LABEL_BIBLIO;
-                               break;
-                       default:
-                               lexrc.printError("Unknown labeltype `$$Token'");
-                       }
+               case LT_LABELTYPE:
+                       readLabelType(lexrc);
                        break;
 
-               case LT_LEFTMARGIN:     /* left margin type */
+               case LT_ENDLABELTYPE:
+                       readEndLabelType(lexrc);
+                       break;
+                       
+               case LT_LEFTMARGIN:     // left margin type
                        if (lexrc.next())
                                leftmargin = lexrc.GetString();
                        break;                  
 
-               case LT_RIGHTMARGIN:    /* right margin type */
+               case LT_RIGHTMARGIN:    // right margin type
                        if (lexrc.next())
                                rightmargin = lexrc.GetString();
                        break;
 
-               case LT_LABELINDENT:    /* label indenting flag */
+               case LT_LABELINDENT:    // label indenting flag
                        if (lexrc.next())
                                labelindent = lexrc.GetString();
                        break;
 
-               case LT_PARINDENT:      /* paragraph indent. flag */
+               case LT_PARINDENT:      // paragraph indent. flag
                        if (lexrc.next())
                                parindent = lexrc.GetString();
                        break;
 
-               case LT_PARSKIP:        /* paragraph skip size */
+               case LT_PARSKIP:        // paragraph skip size
                        if (lexrc.next())
                                parskip = lexrc.GetFloat();
                        break;
 
-               case LT_ITEMSEP:        /* item separation size */
+               case LT_ITEMSEP:        // item separation size
                        if (lexrc.next())
                                itemsep = lexrc.GetFloat();
                        break;
 
-               case LT_TOPSEP:         /* top separation size */
+               case LT_TOPSEP:         // top separation size
                        if (lexrc.next())
                                topsep = lexrc.GetFloat();
                        break;
 
-               case LT_BOTTOMSEP:      /* bottom separation size */
+               case LT_BOTTOMSEP:      // bottom separation size
                        if (lexrc.next())
                                bottomsep = lexrc.GetFloat();
                        break;
 
-               case LT_LABEL_BOTTOMSEP:/* label bottom separation size */
+               case LT_LABEL_BOTTOMSEP: // label bottom separation size
                        if (lexrc.next())
                                labelbottomsep = lexrc.GetFloat();
                        break;
 
-               case LT_LABELSEP:       /* label separator */
+               case LT_LABELSEP:       // label separator
                        if (lexrc.next()) {
-                               labelsep = lexrc.GetString();
-                               subst(labelsep, 'x', ' ');
+                               labelsep = subst(lexrc.GetString(), 'x', ' ');
                        }
                        break;
 
-               case LT_PARSEP:         /* par. separation size */
+               case LT_PARSEP:         // par. separation size
                        if (lexrc.next())
                                parsep = lexrc.GetFloat();
                        break;
 
-               case LT_FILL_TOP:       /* fill top flag */
+               case LT_FILL_TOP:       // fill top flag
                        if (lexrc.next())
                                fill_top = lexrc.GetInteger();
                        break;
 
-               case LT_FILL_BOTTOM:    /* fill bottom flag */
+               case LT_FILL_BOTTOM:    // fill bottom flag
                        if (lexrc.next())
                                fill_bottom = lexrc.GetInteger();
                        break;
 
-               case LT_NEWLINE:        /* newlines allowed ? */
+               case LT_NEWLINE:        // newlines allowed?
                        if (lexrc.next())
                                newline_allowed = lexrc.GetInteger();
                        break;
 
-               case LT_ALIGN:          /* paragraph align */
-                       switch (lexrc.lex()) {
-                       case LT_BLOCK:
-                               align = LYX_ALIGN_BLOCK;
-                               break;
-                       case LT_LEFT:
-                               align = LYX_ALIGN_LEFT;
-                               break;
-                       case LT_RIGHT:
-                               align = LYX_ALIGN_RIGHT;
-                               break;
-                       case LT_CENTER:
-                               align = LYX_ALIGN_CENTER;
-                               break;
-                       case LT_LAYOUT:
-                               align = LYX_ALIGN_LAYOUT;
-                               break;
-                       default:
-                               lexrc.printError("Unknown alignment `$$Token'");
-                       }
+               case LT_ALIGN:          // paragraph align
+                       readAlign(lexrc);
+                       break;
+               case LT_ALIGNPOSSIBLE:  // paragraph allowed align
+                       readAlignPossible(lexrc);
                        break;
 
-               case LT_ALIGNPOSSIBLE:  /* paragraph allowed align */
-               {       alignpossible = 0;
-                     
-               int lineno = lexrc.GetLineNo();
-               do {
-                       switch (lexrc.lex()) {
-                       case LT_BLOCK:
-                               alignpossible |= LYX_ALIGN_BLOCK;
-                               break;
-                       case LT_LEFT:
-                               alignpossible |= LYX_ALIGN_LEFT;
-                               break;
-                       case LT_RIGHT:
-                               alignpossible |= LYX_ALIGN_RIGHT;
-                               break;
-                       case LT_CENTER:
-                               alignpossible |= LYX_ALIGN_CENTER;
-                               break;
-                       case LT_LAYOUT:
-                               alignpossible |= LYX_ALIGN_LAYOUT;
-                               break;
-                       default:
-                               lexrc.printError("Unknown alignment `$$Token'");
-
-                       }
-               } while (lineno==lexrc.GetLineNo());
-               break;
-               }
+               case LT_LABELSTRING:    // label string definition
+                       if (lexrc.next())
+                               labelstring_ = lexrc.GetString();
+                       break;
 
-               case LT_LABELSTRING:    /* label string definition */
+               case LT_ENDLABELSTRING: // endlabel string definition
                        if (lexrc.next())
-                               labelstring = lexrc.GetString();
+                               endlabelstring_ = lexrc.GetString();
                        break;
 
-               case LT_LABELSTRING_APPENDIX:   /* label string appendix definition */
+               case LT_LABELSTRING_APPENDIX: // label string appendix definition
                        if (lexrc.next())
-                               labelstring_appendix = lexrc.GetString();
+                               labelstring_appendix_ = lexrc.GetString();
                        break;
 
-               case LT_FREE_SPACING:   /* Allow for free spacing. */
+               case LT_FREE_SPACING:   // Allow for free spacing.
                        if (lexrc.next())
                                free_spacing = lexrc.GetInteger();
                        break;
 
                case LT_SPACING: // setspace.sty
-                       switch(lexrc.lex()) {
-                       case LT_SPACING_SINGLE:
-                               spacing.set(Spacing::Single);
-                               //spacing_value = 1.0;
-                               break;
-                       case LT_SPACING_ONEHALF:
-                               spacing.set(Spacing::Onehalf);
-                               //spacing_value = 1.25;
-                               break;
-                       case LT_SPACING_DOUBLE:
-                               spacing.set(Spacing::Double);
-                               //spacing_value = 1.667;
-                               break;
-                       case LT_OTHER:
-                               lexrc.next();
-                               spacing.set(Spacing::Other, lexrc.GetFloat());
-                               break;
-                       default:
-                               lexrc.printError("Unknown spacing `$$Token'");
-                       }
-                       break;
-               default:                /* context error */
-                       lexrc.printError("Tag `$$Token' is not "
-                                        "allowed in layout");
-                       error = true;
+                       readSpacing(lexrc);
                        break;
                }
        }
-
+       lexrc.popTable();
        return error;
 }
 
-/* ******************************************************************* */
 
-LyXLayoutList::LyXLayoutList()
-{
-       l = 0;
-       eol = 0;
-       num_layouts = 0;
-}
+enum AlignTags {
+       AT_BLOCK = 1,
+       AT_LEFT,
+       AT_RIGHT,
+       AT_CENTER,
+       AT_LAYOUT
+};
 
 
-LyXLayoutList::~LyXLayoutList()
+void LyXLayout::readAlign(LyXLex & lexrc)
 {
-       //don't do anything. the layouts will be extracted by ToAr.
-       //destruction is done by Clean in emergencies
+       keyword_item alignTags[] = {
+               { "block",  AT_BLOCK },
+               { "center", AT_CENTER },
+               { "layout", AT_LAYOUT },
+               { "left",   AT_LEFT },
+               { "right",  AT_RIGHT }
+       };
+
+       pushpophelper pph(lexrc, alignTags, AT_LAYOUT);
+       int le = lexrc.lex();
+       switch (le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown alignment `$$Token'");
+               return; 
+       default: break;
+       };
+       switch(static_cast<AlignTags>(le)) {
+       case AT_BLOCK:
+               align = LYX_ALIGN_BLOCK;
+               break;
+       case AT_LEFT:
+               align = LYX_ALIGN_LEFT;
+               break;
+       case AT_RIGHT:
+               align = LYX_ALIGN_RIGHT;
+               break;
+       case AT_CENTER:
+               align = LYX_ALIGN_CENTER;
+               break;
+       case AT_LAYOUT:
+               align = LYX_ALIGN_LAYOUT;
+               break;
+       }
 }
 
 
-int LyXLayoutList::GetNum ()
+void LyXLayout::readAlignPossible(LyXLex & lexrc)
 {
-       return num_layouts;
+       keyword_item alignTags[] = {
+               { "block",  AT_BLOCK },
+               { "center", AT_CENTER },
+               { "layout", AT_LAYOUT },
+               { "left",   AT_LEFT },
+               { "right",  AT_RIGHT }
+       };
+
+       lexrc.pushTable(alignTags, AT_LAYOUT);
+       alignpossible = LYX_ALIGN_NONE;
+       int lineno = lexrc.GetLineNo();
+       do {
+               int le = lexrc.lex();
+               switch (le) {
+               case LyXLex::LEX_UNDEF:
+                       lexrc.printError("Unknown alignment `$$Token'");
+                       continue; 
+               default: break;
+               };
+               switch (static_cast<AlignTags>(le)) {
+               case AT_BLOCK:
+                       alignpossible |= LYX_ALIGN_BLOCK;
+                       break;
+               case AT_LEFT:
+                       alignpossible |= LYX_ALIGN_LEFT;
+                       break;
+               case AT_RIGHT:
+                       alignpossible |= LYX_ALIGN_RIGHT;
+                       break;
+               case AT_CENTER:
+                       alignpossible |= LYX_ALIGN_CENTER;
+                       break;
+               case AT_LAYOUT:
+                       alignpossible |= LYX_ALIGN_LAYOUT;
+                       break;
+               }
+       } while (lineno == lexrc.GetLineNo());
+       lexrc.popTable();
 }
 
 
-void LyXLayoutList::Add (LyXLayout *lay)
+enum LabelTypeTags {
+       LA_NO_LABEL = 1,
+       LA_MANUAL,
+       LA_TOP_ENVIRONMENT,
+       LA_CENTERED_TOP_ENVIRONMENT,
+       LA_STATIC,
+       LA_SENSITIVE,
+       LA_COUNTER_CHAPTER,
+       LA_COUNTER_SECTION,
+       LA_COUNTER_SUBSECTION,
+       LA_COUNTER_SUBSUBSECTION,
+       LA_COUNTER_PARAGRAPH,
+       LA_COUNTER_SUBPARAGRAPH,
+       LA_COUNTER_ENUMI,
+       LA_COUNTER_ENUMII,
+       LA_COUNTER_ENUMIII,
+       LA_COUNTER_ENUMIV,
+       LA_BIBLIO
+};
+
+
+void LyXLayout::readLabelType(LyXLex & lexrc)
 {
-       LyXLayoutL * tmp = new LyXLayoutL;
-       tmp->layout = lay;
-       tmp->next = 0;
-       if (!eol) l = tmp; 
-       else eol->next = tmp;
-       eol = tmp;
-       num_layouts++;
+       keyword_item labelTypeTags[] = {
+       { "bibliography",             LA_BIBLIO },
+       { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT },
+       { "counter_chapter",          LA_COUNTER_CHAPTER },
+       { "counter_enumi",            LA_COUNTER_ENUMI },
+       { "counter_enumii",           LA_COUNTER_ENUMII },
+       { "counter_enumiii",          LA_COUNTER_ENUMIII },
+       { "counter_enumiv",           LA_COUNTER_ENUMIV },
+       { "counter_paragraph",        LA_COUNTER_PARAGRAPH },
+       { "counter_section",          LA_COUNTER_SECTION },
+       { "counter_subparagraph",     LA_COUNTER_SUBPARAGRAPH },
+       { "counter_subsection",       LA_COUNTER_SUBSECTION },
+       { "counter_subsubsection",    LA_COUNTER_SUBSUBSECTION },
+       { "manual",                   LA_MANUAL },
+       { "no_label",                 LA_NO_LABEL },
+       { "sensitive",                LA_SENSITIVE },
+       { "static",                   LA_STATIC },
+       { "top_environment",          LA_TOP_ENVIRONMENT }
+};
+
+       pushpophelper pph(lexrc, labelTypeTags, LA_BIBLIO);
+       int le = lexrc.lex();
+       switch (le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown labeltype tag `$$Token'");
+               return; 
+       default: break;
+       }
+       switch (static_cast<LabelTypeTags>(le)) {
+       case LA_NO_LABEL:
+               labeltype = LABEL_NO_LABEL;
+               break;
+       case LA_MANUAL:
+               labeltype = LABEL_MANUAL;
+               break;
+       case LA_TOP_ENVIRONMENT:
+               labeltype = LABEL_TOP_ENVIRONMENT;
+               break;
+       case LA_CENTERED_TOP_ENVIRONMENT:
+               labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
+               break;
+       case LA_STATIC:
+               labeltype = LABEL_STATIC;
+               break;
+       case LA_SENSITIVE:
+               labeltype = LABEL_SENSITIVE;
+               break;
+       case LA_COUNTER_CHAPTER:
+               labeltype = LABEL_COUNTER_CHAPTER;
+               break;
+       case LA_COUNTER_SECTION:
+               labeltype = LABEL_COUNTER_SECTION;
+               break;
+       case LA_COUNTER_SUBSECTION:
+               labeltype = LABEL_COUNTER_SUBSECTION;
+               break;
+       case LA_COUNTER_SUBSUBSECTION:
+               labeltype = LABEL_COUNTER_SUBSUBSECTION;
+               break;
+       case LA_COUNTER_PARAGRAPH:
+               labeltype = LABEL_COUNTER_PARAGRAPH;
+               break;
+       case LA_COUNTER_SUBPARAGRAPH:
+               labeltype = LABEL_COUNTER_SUBPARAGRAPH;
+               break;
+       case LA_COUNTER_ENUMI:
+               labeltype = LABEL_COUNTER_ENUMI;
+               break;
+       case LA_COUNTER_ENUMII:
+               labeltype = LABEL_COUNTER_ENUMII;
+               break;
+       case LA_COUNTER_ENUMIII:
+               labeltype = LABEL_COUNTER_ENUMIII;
+               break;
+       case LA_COUNTER_ENUMIV:
+               labeltype = LABEL_COUNTER_ENUMIV;
+               break;
+       case LA_BIBLIO:
+               labeltype = LABEL_BIBLIO;
+               break;
+       }
 }
 
+static keyword_item endlabelTypeTags[] = {
+       { "box",        END_LABEL_BOX },
+       { "filled_box", END_LABEL_FILLED_BOX },
+       { "no_label",   END_LABEL_NO_LABEL },
+       { "static",     END_LABEL_STATIC }
+};
 
-bool LyXLayoutList::Delete (string const &name)
+void LyXLayout::readEndLabelType(LyXLex & lexrc)
 {
-       LyXLayoutL * layoutl = l;
-       while(layoutl) {
-               if (layoutl->layout && layoutl->layout->name == name) {
-                       delete layoutl->layout;
-                       layoutl->layout = 0; // not sure it is necessary
-                       num_layouts--;
-                       return true;
-               }
-               layoutl = layoutl->next;
+       pushpophelper pph(lexrc, endlabelTypeTags,
+                         END_LABEL_ENUM_LAST-END_LABEL_ENUM_FIRST+1);
+       int le = lexrc.lex();
+       switch(le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown labeltype tag `$$Token'");
+               break;
+       case END_LABEL_STATIC:
+       case END_LABEL_BOX:
+       case END_LABEL_FILLED_BOX:
+       case END_LABEL_NO_LABEL:
+               endlabeltype = static_cast<LYX_END_LABEL_TYPES>(le);
+               break;
+       default:
+               lyxerr << "Unhandled value " << le
+                      << " in LyXLayout::readEndLabelType." << endl;
+               break;
        }
-       return false;
 }
 
 
-LyXLayout * LyXLayoutList::GetLayout (string const &name)
+void LyXLayout::readMargin(LyXLex & lexrc)
 {
-       LyXLayoutL * layoutl = l;
-       while(layoutl) {
-               if (layoutl->layout && layoutl->layout->name == name) 
-                       return layoutl->layout;
-               layoutl = layoutl->next;
+       keyword_item marginTags[] = {
+               { "dynamic",           MARGIN_DYNAMIC },
+               { "first_dynamic",     MARGIN_FIRST_DYNAMIC },
+               { "manual",            MARGIN_MANUAL },
+               { "right_address_box", MARGIN_RIGHT_ADDRESS_BOX },
+               { "static",            MARGIN_STATIC }
+       };
+
+       pushpophelper pph(lexrc, marginTags, MARGIN_RIGHT_ADDRESS_BOX);
+
+       int le = lexrc.lex();
+       switch(le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown margin type tag `$$Token'");
+               return;
+       case MARGIN_STATIC:
+       case MARGIN_MANUAL:
+       case MARGIN_DYNAMIC:
+       case MARGIN_FIRST_DYNAMIC:
+       case MARGIN_RIGHT_ADDRESS_BOX:
+               margintype = static_cast<LYX_MARGIN_TYPE>(le);
+               break;
+       default:
+               lyxerr << "Unhandled value " << le
+                      << " in LyXLayout::readMargin." << endl;
+               break;
        }
-       return 0;
 }
 
 
-LyXLayout * LyXLayoutList::ToAr ()
+void LyXLayout::readLatexType(LyXLex & lexrc)
 {
-       LyXLayoutL * lp, * op;
-       int idx = 0;
-       LyXLayout* ar = new LyXLayout [num_layouts];
-       lp = l;
-       while (lp) {
-               if (lp->layout) {
-                       ar[idx].Copy (*lp->layout);
-                       idx++;
-                       delete lp->layout;
-               }
-               op = lp;
-               lp = lp->next;
-               delete op;
+       keyword_item latexTypeTags[] = {
+               { "command",          LATEX_COMMAND },
+               { "environment",      LATEX_ENVIRONMENT },
+               { "item_environment", LATEX_ITEM_ENVIRONMENT },
+               { "list_environment", LATEX_LIST_ENVIRONMENT },
+               { "paragraph",        LATEX_PARAGRAPH }
+       };
+
+       pushpophelper pph(lexrc, latexTypeTags, LATEX_LIST_ENVIRONMENT);
+       int le = lexrc.lex();
+       switch (le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown latextype tag `$$Token'");
+               return;
+       case LATEX_PARAGRAPH:
+       case LATEX_COMMAND:
+       case LATEX_ENVIRONMENT:
+       case LATEX_ITEM_ENVIRONMENT:
+       case LATEX_LIST_ENVIRONMENT:
+               latextype = static_cast<LYX_LATEX_TYPES>(le);
+               break;
+       default:
+               lyxerr << "Unhandled value " << le
+                      << " in LyXLayout::readLatexType." << endl;
+               break;
        }
-       return ar;
 }
 
 
-//wipe up any dead layouts
-void LyXLayoutList::Clean ()
+enum SpacingTags {
+       ST_SPACING_SINGLE = 1,
+       ST_SPACING_ONEHALF,
+       ST_SPACING_DOUBLE,
+       ST_OTHER
+};
+
+
+void LyXLayout::readSpacing(LyXLex & lexrc)
 {
-       LyXLayoutL * lp, * op;
-       lp = l;
-       while (lp) {
-               delete lp->layout;
-               op = lp;
-               lp = lp->next;
-               delete op;
+       keyword_item spacingTags[] = {
+               {"double",  ST_SPACING_DOUBLE },
+               {"onehalf", ST_SPACING_ONEHALF },
+               {"other",   ST_OTHER },
+               {"single",  ST_SPACING_SINGLE }
+       };
+
+       pushpophelper pph(lexrc, spacingTags, ST_OTHER);
+       int le = lexrc.lex();
+       switch(le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown spacing token `$$Token'");
+               return;
+       default: break;
+       }
+       switch(static_cast<SpacingTags>(le)) {
+       case ST_SPACING_SINGLE:
+               spacing.set(Spacing::Single);
+               break;
+       case ST_SPACING_ONEHALF:
+               spacing.set(Spacing::Onehalf);
+               break;
+       case ST_SPACING_DOUBLE:
+               spacing.set(Spacing::Double);
+               break;
+       case ST_OTHER:
+               lexrc.next();
+               spacing.set(Spacing::Other, lexrc.GetFloat());
+               break;
        }
 }
 
+
 /* ******************************************************************* */
 
-LyXTextClass::LyXTextClass(string const &fn, string const &cln,
-                          string const &desc)
+LyXTextClass::LyXTextClass(string const & fn, string const & cln,
+                          string const & desc)
+       : name_(fn), latexname_(cln), description_(desc)
 {
-       name = fn;
-       latexname = cln;
-       description = desc;
-       output_type = LATEX;
-       style = 0;
-       columns = 1;
-       sides = 1;
-       secnumdepth = 3;
-       tocdepth = 3;
-       pagestyle = "default";
-       maxcounter = LABEL_COUNTER_CHAPTER;
-       defaultfont = LyXFont(LyXFont::ALL_SANE);
-       number_of_defined_layouts = 0;
-       opt_fontsize = "10|11|12";
-       opt_pagestyle = "empty|plain|headings|fancy";
-       provides_amsmath = false;
-       provides_makeidx = false;
-       provides_url = false;
+       outputType_ = LATEX;
+       columns_ = 1;
+       sides_ = OneSide;
+       secnumdepth_ = 3;
+       tocdepth_ = 3;
+       pagestyle_ = "default";
+       maxcounter_ = LABEL_COUNTER_CHAPTER;
+       defaultfont_ = LyXFont(LyXFont::ALL_SANE);
+       opt_fontsize_ = "10|11|12";
+       opt_pagestyle_ = "empty|plain|headings|fancy";
+       provides_ = nothing;
        loaded = false;
 }
 
 
-// This is not a proper copy.
-// It just references the style rather than copying it!
-void LyXTextClass::Copy (LyXTextClass const &l)
+bool LyXTextClass::do_readStyle(LyXLex & lexrc, LyXLayout & lay)
 {
-       name = l.name;
-       latexname = l.latexname;
-       description = l.description;
-       output_type = l.output_type;
-       preamble = l.preamble;
-       options = l.options;
-       if (style) delete style;
-       style = l.style; //just aliases NO COPY
-       number_of_defined_layouts = l.number_of_defined_layouts;
-       columns = l.columns;
-       sides = l.sides;
-       secnumdepth = l.secnumdepth;
-       tocdepth = l.tocdepth;
-       pagestyle = l.pagestyle;
-       maxcounter = l.maxcounter;
-       defaultfont = l.defaultfont;
-        opt_fontsize = l.opt_fontsize;
-        opt_pagestyle = l.opt_pagestyle;
-       provides_amsmath = l.provides_amsmath;
-       provides_makeidx = l.provides_makeidx;
-       provides_url = l.provides_url;
-        loaded = l.loaded;
-
-       leftmargin = l.leftmargin;
-       rightmargin = l.rightmargin;
-         
+       lyxerr[Debug::TCLASS] << "Reading style " << lay.name() << endl;
+       if (!lay.Read(lexrc, *this)) {
+               // Reslove fonts
+               lay.resfont = lay.font;
+               lay.resfont.realize(defaultfont());
+               lay.reslabelfont = lay.labelfont;
+               lay.reslabelfont.realize(defaultfont());
+               return false; // no errors
+       } 
+       lyxerr << "Error parsing style `" << lay.name() << "'" << endl;
+       return true;
 }
 
 
-LyXTextClass::~LyXTextClass()
-{
-       //we can't delete the style here because otherwise 
-       //our list classes wouldn't work
-}
+enum TextClassTags {
+       TC_OUTPUTTYPE = 1,
+       TC_INPUT,
+       TC_STYLE,
+       TC_NOSTYLE,
+       TC_COLUMNS,
+       TC_SIDES,
+       TC_PAGESTYLE,
+       TC_DEFAULTFONT,
+       TC_MAXCOUNTER,
+       TC_SECNUMDEPTH,
+       TC_TOCDEPTH,
+       TC_CLASSOPTIONS,
+       TC_PREAMBLE,
+       TC_PROVIDESAMSMATH,
+       TC_PROVIDESMAKEIDX,
+       TC_PROVIDESURL,
+       TC_LEFTMARGIN,
+       TC_RIGHTMARGIN
+};
 
 
-/* Reads a textclass structure from file */
-int LyXTextClass::Read (string const &filename, LyXLayoutList *list)
+// Reads a textclass structure from file.
+bool LyXTextClass::Read(string const & filename, bool merge)
 {
-       if (!list)
-               lyxerr.debug("Reading textclass "
-                            + MakeDisplayPath(filename), Error::TCLASS);
-       else 
-               lyxerr.debug("Reading input file "
-                            + MakeDisplayPath(filename), Error::TCLASS);
-
-       LyXLex lexrc(layoutTags, sizeof(layoutTags)/sizeof(keyword_item));
+       keyword_item textClassTags[] = {
+               { "classoptions",    TC_CLASSOPTIONS },
+               { "columns",         TC_COLUMNS },
+               { "defaultfont",     TC_DEFAULTFONT },
+               { "input",           TC_INPUT },
+               { "leftmargin",      TC_LEFTMARGIN },
+               { "maxcounter",      TC_MAXCOUNTER },
+               { "nostyle",         TC_NOSTYLE },
+               { "outputtype",      TC_OUTPUTTYPE },
+               { "pagestyle",       TC_PAGESTYLE },
+               { "preamble",        TC_PREAMBLE },
+               { "providesamsmath", TC_PROVIDESAMSMATH },
+               { "providesmakeidx", TC_PROVIDESMAKEIDX },
+               { "providesurl",     TC_PROVIDESURL },
+               { "rightmargin",     TC_RIGHTMARGIN },
+               { "secnumdepth",     TC_SECNUMDEPTH },
+               { "sides",           TC_SIDES },
+               { "style",           TC_STYLE },
+               { "tocdepth",        TC_TOCDEPTH }
+       };
+
+       if (!merge)
+               lyxerr[Debug::TCLASS] << "Reading textclass "
+                                     << MakeDisplayPath(filename)
+                                     << endl;
+       else
+               lyxerr[Debug::TCLASS] << "Reading input file "
+                                    << MakeDisplayPath(filename)
+                                    << endl;
+       
+       LyXLex lexrc(textClassTags, TC_RIGHTMARGIN);
        bool error = false;
 
         lexrc.setFile(filename);
-       if (!lexrc.IsOK()) return -2; 
-
-       LyXLayoutList * l;
-       LyXLayout * tmpl;
+       if (!lexrc.IsOK()) error = true; 
 
-       if (list) 
-               l = list;
-       else 
-               l = new LyXLayoutList;
-
-       /* parsing */
+       // parsing
        while (lexrc.IsOK() && !error) {
-               switch(lexrc.lex()) {
-               case -2:
-                       break;
+               int le = lexrc.lex();
+               switch(le) {
+               case LyXLex::LEX_FEOF:
+                       continue; 
 
-               case -1:                                 
-                       lexrc.printError("Unknown tag `$$Token'");
+               case LyXLex::LEX_UNDEF:                                 
+                       lexrc.printError("Unknown TextClass tag `$$Token'");
                        error = true;
-                       break;
-
-               case LT_OUTPUTTYPE:   // output type definition
-                       switch(lexrc.lex()) {
-                       case LT_OTLATEX:
-                               output_type=LATEX;
-                               break;
-                       case LT_OTLINUXDOC:
-                               output_type=LINUXDOC;
-                               break;
-                       case LT_OTDOCBOOK:
-                               output_type=DOCBOOK;
-                               break;
-                       case LT_OTLITERATE:
-                               output_type=LITERATE;
-                               break;
-                       default:
-                               lexrc.printError("Unknown output type `$$Token'");
-                               break;
-                       }
+                       continue; 
+               default: break;
+               }
+               switch(static_cast<TextClassTags>(le)) {
+               case TC_OUTPUTTYPE:   // output type definition
+                       readOutputType(lexrc);
                        break;
                        
-               case LT_INPUT: // Include file
+               case TC_INPUT: // Include file
                        if (lexrc.next()) {
                                string tmp = LibFileSearch("layouts",
                                                            lexrc.GetString(), 
                                                            "layout");
                                
-                               if (Read(tmp, l)) {
+                               if (Read(tmp, true)) {
                                        lexrc.printError("Error reading input"
                                                         "file: "+tmp);
                                        error = true;
@@ -879,41 +864,18 @@ int LyXTextClass::Read (string const &filename, LyXLayoutList *list)
                        }
                        break;
 
-               case LT_STYLE:
+               case TC_STYLE:
                        if (lexrc.next()) {
-                               string name = lexrc.GetString();
-                               bool is_new = false;
-
-                               subst(name, '_',' ');
-                               tmpl = l->GetLayout(name);
-                               if (!tmpl) {
-                                       is_new = true;
-                                       tmpl = new LyXLayout;
-                                       tmpl->name = name;
-                               }
-
-                               lyxerr.debug("  Reading style "+tmpl->name, Error::TCLASS);
-
-                               if (!tmpl->Read(lexrc, l)) {
-                                       // Resolve fonts
-                                       tmpl->resfont = tmpl->font;
-                                       tmpl->resfont.realize(defaultfont);
-                                       tmpl->reslabelfont = tmpl->labelfont;
-                                       tmpl->reslabelfont.realize(defaultfont);
-                                       if (is_new) {
-                                               l->Add (tmpl);
-                                               // NB! we don't delete because 
-                                               // we just pass it in.... 
-                                       }
+                               string name = subst(lexrc.GetString(),
+                                                   '_', ' ');
+                               if (hasLayout(name)) {
+                                       LyXLayout & lay = GetLayout(name);
+                                       error = do_readStyle(lexrc, lay);
                                } else {
-                                       lexrc.printError(
-                                                      "Error parsing style `"
-                                                      +tmpl->name+'\'');
-                                       error = true;
-                                       if (is_new) {
-                                               delete tmpl;  
-                                               //we delete dead ones here
-                                       }
+                                       LyXLayout lay;
+                                       lay.setName(name);
+                                       if (!(error = do_readStyle(lexrc, lay)))
+                                               layoutlist.push_back(lay);
                                }
                        }
                        else {
@@ -922,351 +884,447 @@ int LyXTextClass::Read (string const &filename, LyXLayoutList *list)
                        }
                        break;
 
-               case LT_NOSTYLE:
+               case TC_NOSTYLE:
                        if (lexrc.next()) {
-                               string style = lexrc.GetString();
-                               if (!l->Delete(subst(style, '_', ' ')))
-                                       lexrc.printError("Cannot delete style `$$Token'");
+                               string style = subst(lexrc.GetString(),
+                                                    '_', ' ');
+                               if (!delete_layout(style))
+                                       lexrc.printError("Cannot delete style"
+                                                        " `$$Token'");
                        }
                        break;
 
-               case LT_COLUMNS:
+               case TC_COLUMNS:
                        if (lexrc.next())
-                               columns = lexrc.GetInteger();
+                               columns_ = lexrc.GetInteger();
                        break;
                        
-               case LT_SIDES:
-                       if (lexrc.next())
-                               sides = lexrc.GetInteger();
+               case TC_SIDES:
+                       if (lexrc.next()) {
+                               switch(lexrc.GetInteger()) {
+                               case 1: sides_ = OneSide; break;
+                               case 2: sides_ = TwoSides; break;
+                               default:
+                                       lyxerr << "Impossible number of page"
+                                               " sides, setting to one."
+                                              << endl;
+                                       sides_ = OneSide;
+                                       break;
+                               }
+                       }
                        break;
                        
-               case LT_PAGESTYLE:
+               case TC_PAGESTYLE:
                        lexrc.next();
-                       pagestyle = strip(lexrc.GetString());
+                       pagestyle_ = strip(lexrc.GetString());
                        break;
                        
-               case LT_DEFAULTFONT:
-                       defaultfont.lyxRead(lexrc);
-                       if (!defaultfont.resolved()) {
+               case TC_DEFAULTFONT:
+                       defaultfont_.lyxRead(lexrc);
+                       if (!defaultfont_.resolved()) {
                                lexrc.printError("Warning: defaultfont should "
                                                 "be fully instantiated!");
-                               defaultfont.realize(LyXFont::ALL_SANE);
+                               defaultfont_.realize(LyXFont(LyXFont::ALL_SANE));
                        }
                        break;
 
-               case LT_MAXCOUNTER:
-                       switch (lexrc.lex()) {
-                       case LT_COUNTER_CHAPTER:
-                               maxcounter = LABEL_COUNTER_CHAPTER;
-                               break;
-                       case LT_COUNTER_SECTION:
-                               maxcounter = LABEL_COUNTER_SECTION;
-                               break;
-                       case LT_COUNTER_SUBSECTION:
-                               maxcounter = LABEL_COUNTER_SUBSECTION;
-                               break;
-                       case LT_COUNTER_SUBSUBSECTION:
-                               maxcounter = LABEL_COUNTER_SUBSUBSECTION;
-                               break;
-                       case LT_COUNTER_PARAGRAPH:
-                               maxcounter = LABEL_COUNTER_PARAGRAPH;
-                               break;
-                       case LT_COUNTER_SUBPARAGRAPH:
-                               maxcounter = LABEL_COUNTER_SUBPARAGRAPH;
-                               break;
-                       case LT_COUNTER_ENUMI:
-                               maxcounter = LABEL_COUNTER_ENUMI;
-                               break;
-                       case LT_COUNTER_ENUMII:
-                               maxcounter = LABEL_COUNTER_ENUMII;
-                               break;
-                       case LT_COUNTER_ENUMIII:
-                               maxcounter = LABEL_COUNTER_ENUMIII;
-                               break;
-                       case LT_COUNTER_ENUMIV:
-                               maxcounter = LABEL_COUNTER_ENUMIV;
-                               break;
-                       }
+               case TC_MAXCOUNTER:
+                       readMaxCounter(lexrc);
                        break;
 
-               case LT_SECNUMDEPTH:
+               case TC_SECNUMDEPTH:
                        lexrc.next();
-                       secnumdepth = lexrc.GetInteger();
+                       secnumdepth_ = lexrc.GetInteger();
                        break;
 
-               case LT_TOCDEPTH:
+               case TC_TOCDEPTH:
                        lexrc.next();
-                       tocdepth = lexrc.GetInteger();
+                       tocdepth_ = lexrc.GetInteger();
                        break;
 
-        // First step to support options 
-               case LT_CLASSOPTIONS:
-               {
-                       bool getout = true;
-                       while (getout && lexrc.IsOK()) { 
-                               switch (lexrc.lex()) {
-                               case LT_FONTSIZE:
-                                       lexrc.next();
-                                       opt_fontsize = strip(lexrc.GetString());
-                                       break;
-                               case LT_PAGESTYLE:
-                                       lexrc.next();
-                                       opt_pagestyle = strip(lexrc.GetString()); 
-                                       break;
-                               case LT_OTHER:
-                                       lexrc.next();
-                                       options = lexrc.GetString();
-                                       break;
-                               case LT_END: getout = false; break;
-                               default:
-                                       lexrc.printError("Out of context tag `$$Token'");
-                                       break;
-                               }
-                       }
+                       // First step to support options 
+               case TC_CLASSOPTIONS:
+                       readClassOptions(lexrc);
                        break;
-               }
 
-               case LT_PREAMBLE:
-                       preamble = lexrc.getLongString("EndPreamble");
+               case TC_PREAMBLE:
+                       preamble_ = lexrc.getLongString("EndPreamble");
                        break;
 
-               case LT_PROVIDESAMSMATH:
-                       if (lexrc.next())
-                               provides_amsmath = lexrc.GetInteger();
+               case TC_PROVIDESAMSMATH:
+                       if (lexrc.next() && lexrc.GetInteger())
+                               provides_ |= amsmath;
                        break;
 
-               case LT_PROVIDESMAKEIDX:
-                       if (lexrc.next())
-                               provides_makeidx = lexrc.GetInteger();
+               case TC_PROVIDESMAKEIDX:
+                       if (lexrc.next() && lexrc.GetInteger())
+                               provides_ |= makeidx;
                        break;
 
-               case LT_PROVIDESURL:
-                       if (lexrc.next())
-                               provides_url = lexrc.GetInteger();
+               case TC_PROVIDESURL:
+                       if (lexrc.next() && lexrc.GetInteger())
+                               provides_ = url;
                        break;
 
-               case LT_LEFTMARGIN:     /* left margin type */
+               case TC_LEFTMARGIN:     // left margin type
                        if (lexrc.next())
-                               leftmargin = lexrc.GetString();
+                               leftmargin_ = lexrc.GetString();
                        break;                  
 
-               case LT_RIGHTMARGIN:    /* right margin type */
+               case TC_RIGHTMARGIN:    // right margin type
                        if (lexrc.next())
-                               rightmargin = lexrc.GetString();
-                       break;
-
-               default:
-                       lexrc.printError("Out of context tag `$$Token'");
+                               rightmargin_ = lexrc.GetString();
                        break;
                }
        }       
 
-       if (!list) { // we are at top level here.
-               if (error) {
-                       number_of_defined_layouts = 0;
-                       l->Clean(); //wipe any we may have found
-                       delete l;
-               }
-               else {
-                       style = l->ToAr();
-                       number_of_defined_layouts = l->GetNum();
-                       delete l;
-               }
-               lyxerr.debug("Finished reading textclass " 
-                            + MakeDisplayPath(filename), Error::TCLASS);
-       }
-       else
-               lyxerr.debug("Finished reading input file " 
-                            + MakeDisplayPath(filename), Error::TCLASS);
+       if (!merge) { // we are at top level here.
+               lyxerr[Debug::TCLASS] << "Finished reading textclass " 
+                                     << MakeDisplayPath(filename)
+                                     << endl;
+       } else
+               lyxerr[Debug::TCLASS] << "Finished reading input file " 
+                                     << MakeDisplayPath(filename)
+                                     << endl;
 
        return error;
 }
 
 
-// Load textclass info if not loaded yet
-void LyXTextClass::load()
+void LyXTextClass::readOutputType(LyXLex & lexrc)
 {
-       if (loaded)
+       keyword_item outputTypeTags[] = {
+               { "docbook", DOCBOOK },
+               { "latex", LATEX },
+               { "linuxdoc", LINUXDOC },
+               { "literate", LITERATE }
+       };
+
+       pushpophelper pph(lexrc, outputTypeTags, LITERATE);
+
+       int le = lexrc.lex();
+       switch(le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown output type `$$Token'");
                return;
+       case LATEX:
+       case LINUXDOC:
+       case DOCBOOK:
+       case LITERATE:
+               outputType_ = static_cast<OutputType>(le);
+               break;
+       default:
+               lyxerr << "Unhandled value " << le
+                      << " in LyXTextClass::readOutputType." << endl;
 
-       // Read style-file
-       string real_file = LibFileSearch("layouts", name, "layout");
+               break;
+       }
+}
 
-       if (Read(real_file)) {
-               lyxerr.print("Error reading `"
-                            + MakeDisplayPath(real_file) + '\'');
-               lyxerr.print("(Check `" + name + "')");
-               lyxerr.print("Check your installation and "
-                            "try Options/Reconfigure...");
+
+enum MaxCounterTags {
+       MC_COUNTER_CHAPTER = 1,
+       MC_COUNTER_SECTION,
+       MC_COUNTER_SUBSECTION,
+       MC_COUNTER_SUBSUBSECTION,
+       MC_COUNTER_PARAGRAPH,
+       MC_COUNTER_SUBPARAGRAPH,
+       MC_COUNTER_ENUMI,
+       MC_COUNTER_ENUMII,
+       MC_COUNTER_ENUMIII,
+       MC_COUNTER_ENUMIV
+};
+
+
+void LyXTextClass::readMaxCounter(LyXLex & lexrc)
+{
+       keyword_item maxCounterTags[] = {
+               {"counter_chapter", MC_COUNTER_CHAPTER },
+               {"counter_enumi", MC_COUNTER_ENUMI },
+               {"counter_enumii", MC_COUNTER_ENUMII },
+               {"counter_enumiii", MC_COUNTER_ENUMIII },
+               {"counter_enumiv", MC_COUNTER_ENUMIV },
+               {"counter_paragraph", MC_COUNTER_PARAGRAPH },
+               {"counter_section", MC_COUNTER_SECTION },
+               {"counter_subparagraph", MC_COUNTER_SUBPARAGRAPH },
+               {"counter_subsection", MC_COUNTER_SUBSECTION },
+               {"counter_subsubsection", MC_COUNTER_SUBSUBSECTION }
+       };
+
+       pushpophelper pph(lexrc, maxCounterTags, MC_COUNTER_ENUMIV);
+       int le = lexrc.lex();
+       switch(le) {
+       case LyXLex::LEX_UNDEF:
+               lexrc.printError("Unknown MaxCounter tag `$$Token'");
+               return; 
+       default: break;
+       }
+       switch (static_cast<MaxCounterTags>(le)) {
+       case MC_COUNTER_CHAPTER:
+               maxcounter_ = LABEL_COUNTER_CHAPTER;
+               break;
+       case MC_COUNTER_SECTION:
+               maxcounter_ = LABEL_COUNTER_SECTION;
+               break;
+       case MC_COUNTER_SUBSECTION:
+               maxcounter_ = LABEL_COUNTER_SUBSECTION;
+               break;
+       case MC_COUNTER_SUBSUBSECTION:
+               maxcounter_ = LABEL_COUNTER_SUBSUBSECTION;
+               break;
+       case MC_COUNTER_PARAGRAPH:
+               maxcounter_ = LABEL_COUNTER_PARAGRAPH;
+               break;
+       case MC_COUNTER_SUBPARAGRAPH:
+               maxcounter_ = LABEL_COUNTER_SUBPARAGRAPH;
+               break;
+       case MC_COUNTER_ENUMI:
+               maxcounter_ = LABEL_COUNTER_ENUMI;
+               break;
+       case MC_COUNTER_ENUMII:
+               maxcounter_ = LABEL_COUNTER_ENUMII;
+               break;
+       case MC_COUNTER_ENUMIII:
+               maxcounter_ = LABEL_COUNTER_ENUMIII;
+               break;
+       case MC_COUNTER_ENUMIV:
+               maxcounter_ = LABEL_COUNTER_ENUMIV;
+               break;
        }
-       loaded = true;
 }
 
-/* ******************************************************************* */
 
-LyXTextClassList::LyXTextClassList()
+enum ClassOptionsTags {
+       CO_FONTSIZE = 1,
+       CO_PAGESTYLE,
+       CO_OTHER,
+       CO_END
+};
+
+
+void LyXTextClass::readClassOptions(LyXLex & lexrc)
 {
-       l = 0;
-       ar = 0;
-       num_textclass = 0;
+       keyword_item classOptionsTags[] = {
+               {"end", CO_END },
+               {"fontsize", CO_FONTSIZE },
+               {"other", CO_OTHER },
+               {"pagestyle", CO_PAGESTYLE }
+       };
+
+       lexrc.pushTable(classOptionsTags, CO_END);
+       bool getout = false;
+       while (!getout && lexrc.IsOK()) {
+               int le = lexrc.lex();
+               switch (le) {
+               case LyXLex::LEX_UNDEF:
+                       lexrc.printError("Unknown ClassOption tag `$$Token'");
+                       continue; 
+               default: break;
+               }
+               switch (static_cast<ClassOptionsTags>(le)) {
+               case CO_FONTSIZE:
+                       lexrc.next();
+                       opt_fontsize_ = strip(lexrc.GetString());
+                       break;
+               case CO_PAGESTYLE:
+                       lexrc.next();
+                       opt_pagestyle_ = strip(lexrc.GetString()); 
+                       break;
+               case CO_OTHER:
+                       lexrc.next();
+                       options_ = lexrc.GetString();
+                       break;
+               case CO_END:
+                       getout = true;
+                       break;
+               }
+       }
+       lexrc.popTable();
+}
+
+
+bool LyXTextClass::hasLayout(string const & name) const
+{
+       return find_if(layoutlist.begin(), layoutlist.end(),
+                      compare_memfun(&LyXLayout::name, name))
+               != layoutlist.end();
+}
+
+
+LyXLayout const & LyXTextClass::GetLayout (string const & name) const
+{
+       LayoutList::const_iterator cit =
+               find_if(layoutlist.begin(),
+                       layoutlist.end(),
+                       compare_memfun(&LyXLayout::name, name));
+       Assert(cit != layoutlist.end()); // we require the name to exist
+       return (*cit);
 }
 
 
-LyXTextClassList::~LyXTextClassList()
+LyXLayout & LyXTextClass::GetLayout(string const & name)
 {
-       // The textclass list is in ar.
-       if (ar) {
-               delete [] ar;
+       LayoutList::iterator it =
+               find_if(layoutlist.begin(),
+                       layoutlist.end(),
+                       compare_memfun(&LyXLayout::name, name));
+       Assert(it != layoutlist.end()); // we require the name to exist
+       return (*it);
+}
+
+
+bool LyXTextClass::delete_layout(string const & name)
+{
+       LayoutList::iterator it =
+               remove_if(layoutlist.begin(), layoutlist.end(),
+                         compare_memfun(&LyXLayout::name, name));
+       LayoutList::iterator end = layoutlist.end();
+       bool const ret = (it != end);
+       layoutlist.erase(it, end);
+       return ret;
+}
+
+
+// Load textclass info if not loaded yet
+void LyXTextClass::load()
+{
+       if (loaded) return;
+
+       // Read style-file
+       string const real_file = LibFileSearch("layouts", name_, "layout");
+
+       if (Read(real_file)) {
+               lyxerr << "Error reading `"
+                      << MakeDisplayPath(real_file)
+                      << "'\n(Check `" << name_
+                      << "')\nCheck your installation and "
+                       "try Options/Reconfigure..." << endl;
        }
+       loaded = true;
 }
 
 
+//////////////////////////////////////////
+
 // Gets textclass number from name
-signed char LyXTextClassList::NumberOfClass(string const &textclass) 
+pair<bool, LyXTextClassList::size_type> const
+LyXTextClassList::NumberOfClass(string const & textclass) const
 {
-       int i = 0;
-   
-       while (i < num_textclass && textclass != ar[i].name)
-               i++;
-   
-       if (i >= num_textclass)
-               i = -1;
-
-       return i;
+       ClassList::const_iterator cit =
+               find_if(classlist.begin(), classlist.end(),
+                       compare_memfun(&LyXTextClass::name, textclass));
+       return cit != classlist.end() ?
+               make_pair(true, size_type(cit - classlist.begin())) :
+               make_pair(false, size_type(0));
 }
 
 
 // Gets layout structure from style number and textclass number
-LyXLayout *LyXTextClassList::Style(char textclass, char layout) 
+LyXLayout const &
+LyXTextClassList::Style(LyXTextClassList::size_type textclass,
+                       LyXTextClass::size_type layout) const
 {
-       ar[textclass].load();
-
-       if (layout < ar[textclass].number_of_defined_layouts)
-               return &ar[textclass].style[layout];
-       else {
-               return &ar[textclass].style[0];
-       };
+       classlist[textclass].load();
+       if (layout < classlist[textclass].numLayouts())
+               return classlist[textclass][layout];
+       return classlist[textclass][0];
 }
 
 
 // Gets layout number from name and textclass number
-char LyXTextClassList::NumberOfLayout(char textclass, string const &name) 
+pair<bool, LyXTextClass::size_type> const
+LyXTextClassList::NumberOfLayout(LyXTextClassList::size_type textclass,
+                                string const & name) const
 {
-       ar[textclass].load();
-
-       int i = 0;
-       while (i < ar[textclass].number_of_defined_layouts 
-              && name != ar[textclass].style[i].name)
-               i++;
-
-       if (i >= ar[textclass].number_of_defined_layouts) {
-               if (name == "dummy")
-                       i = LYX_DUMMY_LAYOUT;
-               else
-                       // so that we can detect if the layout doesn't exist.
-                       i = -1; // not found
-       } 
-       return i;
+       classlist[textclass].load();
+       for(unsigned int i = 0; i < classlist[textclass].numLayouts(); ++i) {
+               if (classlist[textclass][i].name() == name)
+                       return make_pair(true, i);
+       }
+       if (name == "dummy")
+               return make_pair(true, LyXTextClassList::size_type(LYX_DUMMY_LAYOUT));
+       return make_pair(false, LyXTextClass::size_type(0)); // not found
 }
 
 
 // Gets a layout (style) name from layout number and textclass number
-string LyXTextClassList::NameOfLayout(char textclass, char layout) 
+string const &
+LyXTextClassList::NameOfLayout(LyXTextClassList::size_type textclass,
+                              LyXTextClass::size_type layout) const
 {
-       ar[textclass].load();
-
-       if (layout < ar[textclass].number_of_defined_layouts)
-               return ar[textclass].style[layout].name;
-       else if (layout == LYX_DUMMY_LAYOUT)
-               return "dummy";
-       else
-               return "@@end@@";
+       static string dummy("dummy");
+       classlist[textclass].load();
+       if (layout < classlist[textclass].numLayouts())
+               return classlist[textclass][layout].name();
+       return dummy;
 }
 
 
 // Gets a textclass name from number
-string LyXTextClassList::NameOfClass(char number) 
+string const &
+LyXTextClassList::NameOfClass(LyXTextClassList::size_type number) const
 {
-       if (num_textclass == 0) { 
-               if (number == 0) return "dummy";
-               else return "@@end@@";
+       static string dummy("dummy");
+       if (classlist.size() == 0) {
+               return dummy;
        }
-       if (number < num_textclass)
-               return ar[number].name;
-       else
-               return "@@end@@";
+       Assert(number < classlist.size());
+       return classlist[number].name();
 }
 
+
 // Gets a textclass latexname from number
-string LyXTextClassList::LatexnameOfClass(char number) 
+string const &
+LyXTextClassList::LatexnameOfClass(LyXTextClassList::size_type number) const
 {
-       ar[number].load();
-
-       if (num_textclass == 0) { 
-               if (number == 0) return "dummy";
-               else return "@@end@@";
+       static string dummy("dummy");
+       classlist[number].load();
+       if (classlist.size() == 0) {
+               return dummy;
        }
-       if (number < num_textclass)
-               return ar[number].latexname;
-       else
-               return "@@end@@";
+       Assert(number < classlist.size());
+       return classlist[number].latexname();
 }
 
+
 // Gets a textclass description from number
-string LyXTextClassList::DescOfClass(char number) 
+string const &
+LyXTextClassList::DescOfClass(LyXTextClassList::size_type number) const
 {
-       if (num_textclass == 0) { 
-               if (number == 0) return "dummy";
-               else return "@@end@@";
+       static string dummy("dummy");
+       if (classlist.size() == 0) {
+               return dummy;
        }
-       if (number < num_textclass)
-               return ar[number].description;
-       else
-               return "@@end@@";
+       Assert(number < classlist.size());
+       return classlist[number].description();
 }
 
 
 // Gets a textclass structure from number
-LyXTextClass * LyXTextClassList::TextClass(char textclass) 
+LyXTextClass const &
+LyXTextClassList::TextClass(LyXTextClassList::size_type textclass) const
 {
-       ar[textclass].load();
-       if (textclass < num_textclass)
-               return &ar[textclass];
+       classlist[textclass].load();
+       if (textclass < classlist.size())
+               return classlist[textclass];
        else
-               return &ar[0];
+               return classlist[0];
 }
 
 
-void LyXTextClassList::Add (LyXTextClass *t)
+void LyXTextClassList::Add(LyXTextClass const & t)
 {
-       LyXTextClassL ** h = &l;
-       string const desc = t->description;
-       while (*h && compare_no_case((*h)->textclass->description, desc) < 0)
-               h = &((*h)->next);
-       LyXTextClassL * tmp = new LyXTextClassL;
-       tmp->textclass = t;
-       tmp->next = *h;
-       *h = tmp;
-       num_textclass++;
+       classlist.push_back(t);
 }
 
 
-void LyXTextClassList::ToAr ()
-{
-       LyXTextClassL * lp, *op;
-       int idx = 0;
-       ar = new LyXTextClass [num_textclass];
-       lp = l;
-       while (lp) {
-               ar[idx].Copy (*lp->textclass);
-               idx++;
-               delete lp->textclass; // note we don't delete layouts
-                                     // here at all 
-               op = lp;
-               lp = lp->next;
-               delete op;
+// used when sorting the textclass list.
+class less_textclass_desc {
+public:
+       int operator()(LyXTextClass const & tc1, LyXTextClass const & tc2) {
+               return tc1.description() < tc2.description();
        }
-}
+};
 
 
 // Reads LyX textclass definitions according to textclass config file
@@ -1274,12 +1332,13 @@ bool LyXTextClassList::Read ()
 {
        LyXLex lex(0, 0);
        string real_file = LibFileSearch("", "textclass.lst");
-       lyxerr.debug("Reading textclasses from "+real_file,Error::TCLASS);
+       lyxerr[Debug::TCLASS] << "Reading textclasses from `"
+                             << real_file << "'" << endl;
 
        if (real_file.empty()) {
-               lyxerr.print("LyXTextClassList::Read: unable to find "
-                             "textclass file  `" +
-                             MakeDisplayPath(real_file, 1000) + "'. Exiting.");
+               lyxerr << "LyXTextClassList::Read: unable to find "
+                       "textclass file  `" << MakeDisplayPath(real_file, 1000)
+                      << "'. Exiting." << endl;
 
                WriteAlert(_("LyX wasn't able to find its layout descriptions!"),
                           _("Check that the file \"textclass.lst\""),
@@ -1288,79 +1347,103 @@ bool LyXTextClassList::Read ()
                // This causes LyX to end... Not a desirable behaviour. Lgb
                // What do you propose? That the user gets a file dialog
                // and is allowed to hunt for the file? (Asger)
+               // more that we have a layout for minimal.cls statically
+               // compiled in... (Lgb)
        }
 
-       lex.setFile(real_file);
+       if (!lex.setFile(real_file)) {
+               lyxerr << "LyXTextClassList::Read: "
+                       "lyxlex was not able to set file: "
+                      << real_file << endl;
+       }
        
        if (!lex.IsOK()) {
-               lyxerr.print("LyXTextClassList::Read: unable to open "
-                             "textclass file  `" +
-                             MakeDisplayPath(real_file, 1000) + '\'');
-               lyxerr.print("Check your installation. LyX can't continue.");
+               lyxerr << "LyXTextClassList::Read: unable to open "
+                       "textclass file  `" << MakeDisplayPath(real_file, 1000)
+                      << "'\nCheck your installation. LyX can't continue."
+                      << endl;
                return false;
        }
        bool finished = false;
        string fname, clname, desc;
-       LyXTextClass * tmpl;
-
        // Parse config-file
+       lyxerr[Debug::TCLASS] << "Starting parsing of textclass.lst" << endl;
        while (lex.IsOK() && !finished) {
+               lyxerr[Debug::TCLASS] << "\tline by line" << endl;
                switch (lex.lex()) {
                case LyXLex::LEX_FEOF:
                        finished = true;
                        break;
                default:
                        fname = lex.GetString();
-                       lyxerr.debug("Fname: " + fname, Error::TCLASS);
+                       lyxerr[Debug::TCLASS] << "Fname: " << fname << endl;
                        if (lex.next()) {
                                clname = lex.GetString();
-                               lyxerr.debug("Clname: " + clname,
-                                            Error::TCLASS);
+                               lyxerr[Debug::TCLASS]
+                                       << "Clname: " << clname << endl;
                                if (lex.next()) {
                                              desc = lex.GetString();
-                                             lyxerr.debug("Desc: " + desc,
-                                                          Error::TCLASS);
+                                             lyxerr[Debug::TCLASS]
+                                                     << "Desc: " << desc << endl;
                                              // This code is run when we have
                                              // fname, clname and desc
-                                             tmpl =new LyXTextClass(fname,
-                                                                    clname,
-                                                                    desc);
-                                             Add (tmpl);
+                                             LyXTextClass tmpl(fname,
+                                                               clname,
+                                                               desc);
                                              if (lyxerr.
-                                                 debugging(Error::TCLASS)) {
-                                                   tmpl->load();
+                                                 debugging(Debug::TCLASS)) {
+                                                     tmpl.load();
                                              }
+                                             Add (tmpl);
                                }
                        }
                }
        }
-       
-       if (num_textclass == 0) {
-               lyxerr.print("LyXTextClassList::Read: no textclass found!");
+       lyxerr[Debug::TCLASS] << "End of parsing of textclass.lst" << endl;
+
+       if (classlist.size() == 0) {
+               lyxerr << "LyXTextClassList::Read: no textclasses found!"
+                      << endl;
                WriteAlert(_("LyX wasn't able to find any layout description!"),
                           _("Check the contents of  the file \"textclass.lst\""),
                           _("Sorry, has to exit :-("));
                return false;
        }
-       else { 
-               ToAr();
-               return true;
-       }
+       // Ok everything loaded ok, now sort the list.
+       sort(classlist.begin(), classlist.end(), less_textclass_desc());
+       return true;
 }
 
-// Load textclass
-/* Returns false if this fails */
-bool LyXTextClassList::Load (char const number)
-{
-       bool result = 1;
        
-       if (number < num_textclass) {
-               ar[number].load();
-               if (!ar[number].number_of_defined_layouts) {
-                       result = 0;
+/* Load textclass
+   Returns false if this fails
+*/
+bool
+LyXTextClassList::Load (LyXTextClassList::size_type number) const
+{
+       bool result = true;
+       if (number < classlist.size()) {
+               classlist[number].load();
+               if (classlist[number].numLayouts() == 0) {
+                       result = false;
                }
        } else {
-               result = 0;
+               result = false;
        }
        return result;
 }
+
+
+std::ostream & operator<<(std::ostream & os, LyXTextClass::PageSides p)
+{
+       switch (p) {
+       case LyXTextClass::OneSide:
+               os << "1";
+               break;
+       case LyXTextClass::TwoSides:
+               os << "2";
+               break;
+       }
+       return os;
+}
+