X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flayout.C;h=58fd7f1bb93ec9b31cc1b7a8965196533bbf3521;hb=9f7498dbdf16f61cd5c9ee82e0cb6576d2bf620f;hp=9de9933f24940f206a537cf9011e0e6280e3341d;hpb=35584afc1162dec2cf9fff79305e95cb3b75aefb;p=lyx.git diff --git a/src/layout.C b/src/layout.C index 9de9933f24..58fd7f1bb9 100644 --- a/src/layout.C +++ b/src/layout.C @@ -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é - * Modified for external style definition. - * - * 15/11/1995, Alejandro Aguilar Sierra - * 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 @@ -29,170 +15,94 @@ #pragma implementation #endif -#include "definitions.h" -#include +#include + #include "layout.h" #include "lyxlex.h" #include "support/filetools.h" #include "lyx_gui_misc.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..." << endl; + lyxerr[Debug::TCLASS] << "LyXSetStyle: parsing configuration...\n"; - if (!lyxstyle.Read()) { - lyxerr << "LyXSetStyle: an error occured during parsing.\n" - << " Exiting." << endl; + if (!textclasslist.Read()) { + lyxerr[Debug::TCLASS] << "LyXSetStyle: an error occured " + "during parsing.\n Exiting." << endl; exit(1); } - lyxerr.debug() << "LyXSetStyle: configuration parsed." << endl; + 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 () +// Reads a layout definition from file +bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass) { -} - - -void LyXLayout::Copy (LyXLayout const &l) -{ - 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(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,483 +265,604 @@ 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(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(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(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; + } } -bool LyXLayoutList::Delete (string const &name) +namespace { + +keyword_item endlabelTypeTags[] = { + { "box", END_LABEL_BOX }, + { "filled_box", END_LABEL_FILLED_BOX }, + { "no_label", END_LABEL_NO_LABEL }, + { "static", END_LABEL_STATIC } +}; + +} // namespace anon + + +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(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(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(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(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) + 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 + else lyxerr[Debug::TCLASS] << "Reading input file " - << MakeDisplayPath(filename) << endl; - - LyXLex lexrc(layoutTags, sizeof(layoutTags)/sizeof(keyword_item)); + << 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(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; @@ -880,43 +870,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::TCLASS] << " Reading style " - << tmpl->name - << endl; - - 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 { @@ -925,161 +890,105 @@ 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; - } + if (!merge) { // we are at top level here. lyxerr[Debug::TCLASS] << "Finished reading textclass " << MakeDisplayPath(filename) << endl; - } - else + } else lyxerr[Debug::TCLASS] << "Finished reading input file " << MakeDisplayPath(filename) << endl; @@ -1088,190 +997,340 @@ int LyXTextClass::Read (string const &filename, LyXLayoutList *list) } -// 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(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 << "Error reading `" - << MakeDisplayPath(real_file) - << "'\n(Check `" << name - << "')\nCheck your installation and " - "try Options/Reconfigure..." << endl; + +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(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) +{ + 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(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 { - l = 0; - ar = 0; - num_textclass = 0; + 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 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 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 @@ -1279,8 +1338,8 @@ bool LyXTextClassList::Read () { LyXLex lex(0, 0); string real_file = LibFileSearch("", "textclass.lst"); - lyxerr[Debug::TCLASS] << "Reading textclasses from " - << real_file << endl; + lyxerr[Debug::TCLASS] << "Reading textclasses from `" + << real_file << "'" << endl; if (real_file.empty()) { lyxerr << "LyXTextClassList::Read: unable to find " @@ -1294,23 +1353,29 @@ 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 << "LyXTextClassList::Read: unable to open " "textclass file `" << MakeDisplayPath(real_file, 1000) - << "\'\nCheck your installation. LyX can't continue." + << "'\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; @@ -1328,45 +1393,63 @@ bool LyXTextClassList::Read () << "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(Debug::TCLASS)) { - tmpl->load(); + tmpl.load(); } + Add (tmpl); } } } } - - if (num_textclass == 0) { - lyxerr << "LyXTextClassList::Read: no textclass found!" << endl; + 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; +} +