1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
14 #pragma implementation
23 #include "support/filetools.h"
24 #include "lyx_gui_misc.h"
27 #include "support/LAssert.h"
29 // Global variable: textclass table.
30 LyXTextClassList textclasslist;
32 // Reads the style files
35 lyxerr[Debug::TCLASS] << "LyXSetStyle: parsing configuration...\n";
37 if (!textclasslist.Read()) {
38 lyxerr[Debug::TCLASS] << "LyXSetStyle: an error occured "
39 "during parsing.\n Exiting." << endl;
43 lyxerr[Debug::TCLASS] << "LyXSetStyle: configuration parsed." << endl;
47 // The order of the LayoutTags enum is no more important. [asierra300396]
58 //LT_ENVIRONMENT_DEFAULT,
74 LT_LABELSTRING_APPENDIX,
95 // This table is sorted alphabetically [asierra 30March96]
96 static keyword_item layoutTags[] = {
97 { "align", LT_ALIGN },
98 { "alignpossible", LT_ALIGNPOSSIBLE },
99 { "bottomsep", LT_BOTTOMSEP },
100 { "copystyle", LT_COPYSTYLE },
102 { "fill_bottom", LT_FILL_BOTTOM },
103 { "fill_top", LT_FILL_TOP },
105 { "freespacing", LT_FREE_SPACING },
106 { "intitle", LT_INTITLE },
107 { "itemsep", LT_ITEMSEP },
108 { "keepempty", LT_KEEPEMPTY },
109 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
110 { "labelfont", LT_LABELFONT },
111 { "labelindent", LT_LABELINDENT },
112 { "labelsep", LT_LABELSEP },
113 { "labelstring", LT_LABELSTRING },
114 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
115 { "labeltype", LT_LABELTYPE },
116 { "latexname", LT_LATEXNAME },
117 { "latexparam", LT_LATEXPARAM },
118 { "latextype", LT_LATEXTYPE },
119 { "leftmargin", LT_LEFTMARGIN },
120 { "margin", LT_MARGIN },
121 { "needprotect", LT_NEED_PROTECT },
122 { "newline", LT_NEWLINE },
123 { "nextnoindent", LT_NEXTNOINDENT },
124 { "obsoletedby", LT_OBSOLETEDBY },
125 { "parindent", LT_PARINDENT },
126 { "parsep", LT_PARSEP },
127 { "parskip", LT_PARSKIP },
128 { "preamble", LT_PREAMBLE },
129 { "rightmargin", LT_RIGHTMARGIN },
130 { "spacing", LT_SPACING },
131 { "textfont", LT_TEXTFONT },
132 { "topsep", LT_TOPSEP }
136 /////////////////////
138 // Constructor for layout
139 LyXLayout::LyXLayout ()
141 margintype = MARGIN_STATIC;
142 latextype = LATEX_PARAGRAPH;
146 font = LyXFont(LyXFont::ALL_INHERIT);
147 labelfont = LyXFont(LyXFont::ALL_INHERIT);
148 resfont = LyXFont(LyXFont::ALL_SANE);
149 reslabelfont = LyXFont(LyXFont::ALL_SANE);
150 nextnoindent = false;
155 labelbottomsep = 0.0;
157 align = LYX_ALIGN_BLOCK;
158 alignpossible = LYX_ALIGN_BLOCK;
159 labeltype = LABEL_NO_LABEL;
160 // Should or should not. That is the question.
161 // spacing.set(Spacing::OneHalf);
164 newline_allowed = true;
165 free_spacing = false;
169 // Reads a layout definition from file
170 bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass)
173 bool finished = false;
174 lexrc.pushTable(layoutTags, LT_INTITLE);
175 // parse style section
176 while (!finished && lexrc.IsOK() && !error) {
177 int le = lexrc.lex();
178 // See comment in lyxrc.C.
180 case LyXLex::LEX_FEOF:
183 case LyXLex::LEX_UNDEF: // parse error
184 lexrc.printError("Unknown layout tag `$$Token'");
189 switch(static_cast<LayoutTags>(le)) {
190 case LT_END: // end of structure
194 case LT_COPYSTYLE: // initialize with a known style
196 if (tclass.hasLayout(lexrc.GetString())) {
197 string tmpname = name_;
198 this->operator= (tclass.GetLayout(lexrc.GetString()));
201 lexrc.printError("Cannot copy known "
207 case LT_OBSOLETEDBY: // replace with a known style
209 if (tclass.hasLayout(lexrc.GetString())) {
210 string tmpname = name_;
211 this->operator= (tclass.GetLayout(lexrc.GetString()));
213 if (obsoleted_by().empty())
214 obsoleted_by_ = lexrc.GetString();
216 lexrc.printError("Cannot replace with"
223 case LT_MARGIN: // Margin style definition.
227 case LT_LATEXTYPE: // Latex style definition.
228 readLatexType(lexrc);
232 intitle = lexrc.next() && lexrc.GetInteger();
235 case LT_NEED_PROTECT:
236 needprotect = lexrc.next() && lexrc.GetInteger();
240 keepempty = lexrc.next() && lexrc.GetInteger();
253 labelfont.lyxRead(lexrc);
256 case LT_NEXTNOINDENT: // Indent next paragraph?
257 if (lexrc.next() && lexrc.GetInteger())
260 nextnoindent = false;
265 latexname_ = lexrc.GetString();
270 latexparam_ = lexrc.GetString();
274 preamble_ = lexrc.getLongString("EndPreamble");
278 readLabelType(lexrc);
281 case LT_LEFTMARGIN: // left margin type
283 leftmargin = lexrc.GetString();
286 case LT_RIGHTMARGIN: // right margin type
288 rightmargin = lexrc.GetString();
291 case LT_LABELINDENT: // label indenting flag
293 labelindent = lexrc.GetString();
296 case LT_PARINDENT: // paragraph indent. flag
298 parindent = lexrc.GetString();
301 case LT_PARSKIP: // paragraph skip size
303 parskip = lexrc.GetFloat();
306 case LT_ITEMSEP: // item separation size
308 itemsep = lexrc.GetFloat();
311 case LT_TOPSEP: // top separation size
313 topsep = lexrc.GetFloat();
316 case LT_BOTTOMSEP: // bottom separation size
318 bottomsep = lexrc.GetFloat();
321 case LT_LABEL_BOTTOMSEP: // label bottom separation size
323 labelbottomsep = lexrc.GetFloat();
326 case LT_LABELSEP: // label separator
328 labelsep = subst(lexrc.GetString(), 'x', ' ');
332 case LT_PARSEP: // par. separation size
334 parsep = lexrc.GetFloat();
337 case LT_FILL_TOP: // fill top flag
339 fill_top = lexrc.GetInteger();
342 case LT_FILL_BOTTOM: // fill bottom flag
344 fill_bottom = lexrc.GetInteger();
347 case LT_NEWLINE: // newlines allowed?
349 newline_allowed = lexrc.GetInteger();
352 case LT_ALIGN: // paragraph align
355 case LT_ALIGNPOSSIBLE: // paragraph allowed align
356 readAlignPossible(lexrc);
359 case LT_LABELSTRING: // label string definition
361 labelstring_ = lexrc.GetString();
364 case LT_LABELSTRING_APPENDIX: // label string appendix definition
366 labelstring_appendix_ = lexrc.GetString();
369 case LT_FREE_SPACING: // Allow for free spacing.
371 free_spacing = lexrc.GetInteger();
374 case LT_SPACING: // setspace.sty
391 static keyword_item alignTags[] = {
392 { "block", AT_BLOCK },
393 { "center", AT_CENTER },
394 { "layout", AT_LAYOUT },
396 { "right", AT_RIGHT }
400 void LyXLayout::readAlign(LyXLex & lexrc)
402 pushpophelper pph(lexrc, alignTags, AT_LAYOUT);
403 int le = lexrc.lex();
405 case LyXLex::LEX_UNDEF:
406 lexrc.printError("Unknown alignment `$$Token'");
410 switch(static_cast<AlignTags>(le)) {
412 align = LYX_ALIGN_BLOCK;
415 align = LYX_ALIGN_LEFT;
418 align = LYX_ALIGN_RIGHT;
421 align = LYX_ALIGN_CENTER;
424 align = LYX_ALIGN_LAYOUT;
430 void LyXLayout::readAlignPossible(LyXLex & lexrc)
432 lexrc.pushTable(alignTags, AT_LAYOUT);
433 alignpossible = LYX_ALIGN_NONE;
434 int lineno = lexrc.GetLineNo();
436 int le = lexrc.lex();
438 case LyXLex::LEX_UNDEF:
439 lexrc.printError("Unknown alignment `$$Token'");
443 switch (static_cast<AlignTags>(le)) {
445 alignpossible |= LYX_ALIGN_BLOCK;
448 alignpossible |= LYX_ALIGN_LEFT;
451 alignpossible |= LYX_ALIGN_RIGHT;
454 alignpossible |= LYX_ALIGN_CENTER;
457 alignpossible |= LYX_ALIGN_LAYOUT;
460 } while (lineno == lexrc.GetLineNo());
468 LA_CENTERED_TOP_ENVIRONMENT,
473 LA_COUNTER_SUBSECTION,
474 LA_COUNTER_SUBSUBSECTION,
475 LA_COUNTER_PARAGRAPH,
476 LA_COUNTER_SUBPARAGRAPH,
484 static keyword_item labelTypeTags[] = {
485 { "bibliography", LA_BIBLIO },
486 { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT },
487 { "counter_chapter", LA_COUNTER_CHAPTER },
488 { "counter_enumi", LA_COUNTER_ENUMI },
489 { "counter_enumii", LA_COUNTER_ENUMII },
490 { "counter_enumiii", LA_COUNTER_ENUMIII },
491 { "counter_enumiv", LA_COUNTER_ENUMIV },
492 { "counter_paragraph", LA_COUNTER_PARAGRAPH },
493 { "counter_section", LA_COUNTER_SECTION },
494 { "counter_subparagraph", LA_COUNTER_SUBPARAGRAPH },
495 { "counter_subsection", LA_COUNTER_SUBSECTION },
496 { "counter_subsubsection", LA_COUNTER_SUBSUBSECTION },
497 { "manual", LA_MANUAL },
498 { "no_label", LA_NO_LABEL },
499 { "sensitive", LA_SENSITIVE },
500 { "static", LA_STATIC },
501 { "top_environment", LA_TOP_ENVIRONMENT }
504 void LyXLayout::readLabelType(LyXLex & lexrc)
506 pushpophelper pph(lexrc, labelTypeTags, LA_BIBLIO);
507 int le = lexrc.lex();
509 case LyXLex::LEX_UNDEF:
510 lexrc.printError("Unknown labeltype tag `$$Token'");
514 switch (static_cast<LabelTypeTags>(le)) {
516 labeltype = LABEL_NO_LABEL;
519 labeltype = LABEL_MANUAL;
521 case LA_TOP_ENVIRONMENT:
522 labeltype = LABEL_TOP_ENVIRONMENT;
524 case LA_CENTERED_TOP_ENVIRONMENT:
525 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
528 labeltype = LABEL_STATIC;
531 labeltype = LABEL_SENSITIVE;
533 case LA_COUNTER_CHAPTER:
534 labeltype = LABEL_COUNTER_CHAPTER;
536 case LA_COUNTER_SECTION:
537 labeltype = LABEL_COUNTER_SECTION;
539 case LA_COUNTER_SUBSECTION:
540 labeltype = LABEL_COUNTER_SUBSECTION;
542 case LA_COUNTER_SUBSUBSECTION:
543 labeltype = LABEL_COUNTER_SUBSUBSECTION;
545 case LA_COUNTER_PARAGRAPH:
546 labeltype = LABEL_COUNTER_PARAGRAPH;
548 case LA_COUNTER_SUBPARAGRAPH:
549 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
551 case LA_COUNTER_ENUMI:
552 labeltype = LABEL_COUNTER_ENUMI;
554 case LA_COUNTER_ENUMII:
555 labeltype = LABEL_COUNTER_ENUMII;
557 case LA_COUNTER_ENUMIII:
558 labeltype = LABEL_COUNTER_ENUMIII;
560 case LA_COUNTER_ENUMIV:
561 labeltype = LABEL_COUNTER_ENUMIV;
564 labeltype = LABEL_BIBLIO;
577 static keyword_item marginTags[] = {
578 { "dynamic", MT_DYNAMIC },
579 { "first_dynamic", MT_FIRST_DYNAMIC },
580 { "manual", MT_MANUAL },
581 { "right_address_box", MT_RIGHT_ADDRESS_BOX },
582 { "static", MT_STATIC }
585 void LyXLayout::readMargin(LyXLex & lexrc)
587 pushpophelper pph(lexrc, marginTags, MT_RIGHT_ADDRESS_BOX);
588 int le = lexrc.lex();
590 case LyXLex::LEX_UNDEF:
591 lexrc.printError("Unknown margin type tag `$$Token'");
595 switch(static_cast<MarginTags>(le)) {
597 margintype = MARGIN_STATIC;
600 margintype = MARGIN_MANUAL;
603 margintype = MARGIN_DYNAMIC;
605 case MT_FIRST_DYNAMIC:
606 margintype = MARGIN_FIRST_DYNAMIC;
608 case MT_RIGHT_ADDRESS_BOX:
609 margintype = MARGIN_RIGHT_ADDRESS_BOX;
622 static keyword_item latexTypeTags[] = {
623 { "command", LX_COMMAND },
624 { "environment", LX_ENVIRONMENT },
625 { "item_environment", LX_ITEM_ENVIRONMENT },
626 { "list_environment", LX_LIST_ENVIRONMENT },
627 { "paragraph", LX_PARAGRAPH }
630 void LyXLayout::readLatexType(LyXLex & lexrc)
632 pushpophelper pph(lexrc, latexTypeTags, LX_LIST_ENVIRONMENT);
633 int le = lexrc.lex();
635 case LyXLex::LEX_UNDEF:
636 lexrc.printError("Unknown latextype tag `$$Token'");
640 switch (static_cast<LatexTypeTags>(le)) {
642 latextype= LATEX_PARAGRAPH;
645 latextype= LATEX_COMMAND;
648 latextype= LATEX_ENVIRONMENT;
650 case LX_ITEM_ENVIRONMENT:
651 latextype= LATEX_ITEM_ENVIRONMENT;
653 case LX_LIST_ENVIRONMENT:
654 latextype= LATEX_LIST_ENVIRONMENT;
660 ST_SPACING_SINGLE = 1,
666 static keyword_item spacingTags[] = {
667 {"double", ST_SPACING_DOUBLE },
668 {"onehalf", ST_SPACING_ONEHALF },
669 {"other", ST_OTHER },
670 {"single", ST_SPACING_SINGLE }
673 void LyXLayout::readSpacing(LyXLex & lexrc)
675 pushpophelper pph(lexrc, spacingTags, ST_OTHER);
676 int le = lexrc.lex();
678 case LyXLex::LEX_UNDEF:
679 lexrc.printError("Unknown spacing token `$$Token'");
683 switch(static_cast<SpacingTags>(le)) {
684 case ST_SPACING_SINGLE:
685 spacing.set(Spacing::Single);
687 case ST_SPACING_ONEHALF:
688 spacing.set(Spacing::Onehalf);
690 case ST_SPACING_DOUBLE:
691 spacing.set(Spacing::Double);
695 spacing.set(Spacing::Other, lexrc.GetFloat());
700 /* ******************************************************************* */
702 LyXTextClass::LyXTextClass(string const & fn, string const & cln,
704 : name_(fn), latexname_(cln), description_(desc)
711 pagestyle_ = "default";
712 maxcounter_ = LABEL_COUNTER_CHAPTER;
713 defaultfont_ = LyXFont(LyXFont::ALL_SANE);
714 opt_fontsize_ = "10|11|12";
715 opt_pagestyle_ = "empty|plain|headings|fancy";
721 bool LyXTextClass::do_readStyle(LyXLex & lexrc, LyXLayout & lay)
723 lyxerr[Debug::TCLASS] << "Reading style " << lay.name() << endl;
724 if (!lay.Read(lexrc, *this)) {
726 lay.resfont = lay.font;
727 lay.resfont.realize(defaultfont());
728 lay.reslabelfont = lay.labelfont;
729 lay.reslabelfont.realize(defaultfont());
730 return false; // no errors
732 lyxerr << "Error parsing style `" << lay.name() << "'" << endl;
758 static keyword_item textClassTags[] = {
759 { "classoptions", TC_CLASSOPTIONS },
760 { "columns", TC_COLUMNS },
761 { "defaultfont", TC_DEFAULTFONT },
762 { "input", TC_INPUT },
763 { "leftmargin", TC_LEFTMARGIN },
764 { "maxcounter", TC_MAXCOUNTER },
765 { "nostyle", TC_NOSTYLE },
766 { "outputtype", TC_OUTPUTTYPE },
767 { "pagestyle", TC_PAGESTYLE },
768 { "preamble", TC_PREAMBLE },
769 { "providesamsmath", TC_PROVIDESAMSMATH },
770 { "providesmakeidx", TC_PROVIDESMAKEIDX },
771 { "providesurl", TC_PROVIDESURL },
772 { "rightmargin", TC_RIGHTMARGIN },
773 { "secnumdepth", TC_SECNUMDEPTH },
774 { "sides", TC_SIDES },
775 { "style", TC_STYLE },
776 { "tocdepth", TC_TOCDEPTH }
779 // Reads a textclass structure from file.
780 bool LyXTextClass::Read(string const & filename, bool merge)
783 lyxerr[Debug::TCLASS] << "Reading textclass "
784 << MakeDisplayPath(filename)
787 lyxerr[Debug::TCLASS] << "Reading input file "
788 << MakeDisplayPath(filename)
791 LyXLex lexrc(textClassTags, TC_RIGHTMARGIN);
794 lexrc.setFile(filename);
795 if (!lexrc.IsOK()) error = true;
798 while (lexrc.IsOK() && !error) {
799 int le = lexrc.lex();
801 case LyXLex::LEX_FEOF:
804 case LyXLex::LEX_UNDEF:
805 lexrc.printError("Unknown TextClass tag `$$Token'");
810 switch(static_cast<TextClassTags>(le)) {
811 case TC_OUTPUTTYPE: // output type definition
812 readOutputType(lexrc);
815 case TC_INPUT: // Include file
817 string tmp = LibFileSearch("layouts",
821 if (Read(tmp, true)) {
822 lexrc.printError("Error reading input"
831 string name = subst(lexrc.GetString(),
833 if (hasLayout(name)) {
834 LyXLayout & lay = GetLayout(name);
835 error = do_readStyle(lexrc, lay);
839 if (!(error = do_readStyle(lexrc, lay)))
840 layoutlist.push_back(lay);
844 lexrc.printError("No name given for style: `$$Token'.");
851 string style = subst(lexrc.GetString(),
853 if (!delete_layout(style))
854 lexrc.printError("Cannot delete style"
861 columns_ = lexrc.GetInteger();
866 switch(lexrc.GetInteger()) {
867 case 1: sides_ = OneSide; break;
868 case 2: sides_ = TwoSides; break;
870 lyxerr << "Impossible number of page"
871 " sides, setting to one."
881 pagestyle_ = strip(lexrc.GetString());
885 defaultfont_.lyxRead(lexrc);
886 if (!defaultfont_.resolved()) {
887 lexrc.printError("Warning: defaultfont should "
888 "be fully instantiated!");
889 defaultfont_.realize(LyXFont::ALL_SANE);
894 readMaxCounter(lexrc);
899 secnumdepth_ = lexrc.GetInteger();
904 tocdepth_ = lexrc.GetInteger();
907 // First step to support options
908 case TC_CLASSOPTIONS:
909 readClassOptions(lexrc);
913 preamble_ = lexrc.getLongString("EndPreamble");
916 case TC_PROVIDESAMSMATH:
917 if (lexrc.next() && lexrc.GetInteger())
918 provides_ |= amsmath;
921 case TC_PROVIDESMAKEIDX:
922 if (lexrc.next() && lexrc.GetInteger())
923 provides_ |= makeidx;
927 if (lexrc.next() && lexrc.GetInteger())
931 case TC_LEFTMARGIN: // left margin type
933 leftmargin_ = lexrc.GetString();
936 case TC_RIGHTMARGIN: // right margin type
938 rightmargin_ = lexrc.GetString();
943 if (!merge) { // we are at top level here.
944 lyxerr[Debug::TCLASS] << "Finished reading textclass "
945 << MakeDisplayPath(filename)
948 lyxerr[Debug::TCLASS] << "Finished reading input file "
949 << MakeDisplayPath(filename)
955 enum OutputTypeTags {
962 static keyword_item outputTypeTags[] = {
963 { "docbook", OT_OTDOCBOOK },
964 { "latex", OT_OTLATEX },
965 { "linuxdoc", OT_OTLINUXDOC },
966 { "literate", OT_OTLITERATE }
969 void LyXTextClass::readOutputType(LyXLex & lexrc)
971 pushpophelper pph(lexrc, outputTypeTags, OT_OTLITERATE);
972 int le = lexrc.lex();
974 case LyXLex::LEX_UNDEF:
975 lexrc.printError("Unknown output type `$$Token'");
979 switch(static_cast<OutputTypeTags>(le)) {
984 outputType_ = LINUXDOC;
987 outputType_ = DOCBOOK;
990 outputType_ = LITERATE;
995 enum MaxCounterTags {
996 MC_COUNTER_CHAPTER = 1,
998 MC_COUNTER_SUBSECTION,
999 MC_COUNTER_SUBSUBSECTION,
1000 MC_COUNTER_PARAGRAPH,
1001 MC_COUNTER_SUBPARAGRAPH,
1008 static keyword_item maxCounterTags[] = {
1009 {"counter_chapter", MC_COUNTER_CHAPTER },
1010 {"counter_enumi", MC_COUNTER_ENUMI },
1011 {"counter_enumii", MC_COUNTER_ENUMII },
1012 {"counter_enumiii", MC_COUNTER_ENUMIII },
1013 {"counter_enumiv", MC_COUNTER_ENUMIV },
1014 {"counter_paragraph", MC_COUNTER_PARAGRAPH },
1015 {"counter_section", MC_COUNTER_SECTION },
1016 {"counter_subparagraph", MC_COUNTER_SUBPARAGRAPH },
1017 {"counter_subsection", MC_COUNTER_SUBSECTION },
1018 {"counter_subsubsection", MC_COUNTER_SUBSUBSECTION }
1021 void LyXTextClass::readMaxCounter(LyXLex & lexrc)
1023 pushpophelper pph(lexrc, maxCounterTags, MC_COUNTER_ENUMIV);
1024 int le = lexrc.lex();
1026 case LyXLex::LEX_UNDEF:
1027 lexrc.printError("Unknown MaxCounter tag `$$Token'");
1031 switch (static_cast<MaxCounterTags>(le)) {
1032 case MC_COUNTER_CHAPTER:
1033 maxcounter_ = LABEL_COUNTER_CHAPTER;
1035 case MC_COUNTER_SECTION:
1036 maxcounter_ = LABEL_COUNTER_SECTION;
1038 case MC_COUNTER_SUBSECTION:
1039 maxcounter_ = LABEL_COUNTER_SUBSECTION;
1041 case MC_COUNTER_SUBSUBSECTION:
1042 maxcounter_ = LABEL_COUNTER_SUBSUBSECTION;
1044 case MC_COUNTER_PARAGRAPH:
1045 maxcounter_ = LABEL_COUNTER_PARAGRAPH;
1047 case MC_COUNTER_SUBPARAGRAPH:
1048 maxcounter_ = LABEL_COUNTER_SUBPARAGRAPH;
1050 case MC_COUNTER_ENUMI:
1051 maxcounter_ = LABEL_COUNTER_ENUMI;
1053 case MC_COUNTER_ENUMII:
1054 maxcounter_ = LABEL_COUNTER_ENUMII;
1056 case MC_COUNTER_ENUMIII:
1057 maxcounter_ = LABEL_COUNTER_ENUMIII;
1059 case MC_COUNTER_ENUMIV:
1060 maxcounter_ = LABEL_COUNTER_ENUMIV;
1065 enum ClassOptionsTags {
1072 static keyword_item classOptionsTags[] = {
1074 {"fontsize", CO_FONTSIZE },
1075 {"other", CO_OTHER },
1076 {"pagestyle", CO_PAGESTYLE }
1079 void LyXTextClass::readClassOptions(LyXLex & lexrc)
1081 lexrc.pushTable(classOptionsTags, CO_END);
1082 bool getout = false;
1083 while (!getout && lexrc.IsOK()) {
1084 int le = lexrc.lex();
1086 case LyXLex::LEX_UNDEF:
1087 lexrc.printError("Unknown ClassOption tag `$$Token'");
1091 switch (static_cast<ClassOptionsTags>(le)) {
1094 opt_fontsize_ = strip(lexrc.GetString());
1098 opt_pagestyle_ = strip(lexrc.GetString());
1102 options_ = lexrc.GetString();
1113 bool LyXTextClass::hasLayout(string const & name) const
1115 for (LayoutList::const_iterator cit = layoutlist.begin();
1116 cit != layoutlist.end(); ++cit) {
1117 if ((*cit).name() == name)
1124 LyXLayout const & LyXTextClass::GetLayout (string const & name) const
1126 for (LayoutList::const_iterator cit = layoutlist.begin();
1127 cit != layoutlist.end(); ++cit) {
1128 if ((*cit).name() == name)
1131 Assert(false); // we actually require the name to exist.
1132 return layoutlist.front();
1136 LyXLayout & LyXTextClass::GetLayout(string const & name)
1138 for (LayoutList::iterator it = layoutlist.begin();
1139 it != layoutlist.end(); ++it) {
1140 if ((*it).name() == name)
1143 Assert(false); // we actually require the name to exist.
1144 return layoutlist.front();
1148 bool LyXTextClass::delete_layout (string const & name)
1150 for(LayoutList::iterator it = layoutlist.begin();
1151 it != layoutlist.end(); ++it) {
1152 if ((*it).name() == name) {
1153 layoutlist.erase(it);
1161 // Load textclass info if not loaded yet
1162 void LyXTextClass::load()
1167 string real_file = LibFileSearch("layouts", name_, "layout");
1169 if (Read(real_file)) {
1170 lyxerr << "Error reading `"
1171 << MakeDisplayPath(real_file)
1172 << "'\n(Check `" << name_
1173 << "')\nCheck your installation and "
1174 "try Options/Reconfigure..." << endl;
1180 //////////////////////////////////////////
1182 // Gets textclass number from name
1183 pair<bool, LyXTextClassList::ClassList::size_type>
1184 LyXTextClassList::NumberOfClass(string const & textclass) const
1186 for (ClassList::const_iterator cit = classlist.begin();
1187 cit != classlist.end(); ++cit) {
1188 if ((*cit).name() == textclass)
1189 return make_pair(true, cit - classlist.begin());
1191 return make_pair(false, 0);
1195 // Gets layout structure from style number and textclass number
1197 LyXTextClassList::Style(LyXTextClassList::ClassList::size_type textclass,
1198 LyXTextClass::LayoutList::size_type layout) const
1200 classlist[textclass].load();
1201 if (layout < classlist[textclass].numLayouts())
1202 return classlist[textclass][layout];
1203 return classlist[textclass][0];
1207 // Gets layout number from name and textclass number
1208 pair<bool, LyXTextClass::LayoutList::size_type>
1209 LyXTextClassList::NumberOfLayout(LyXTextClassList::ClassList::size_type textclass, string const & name) const
1211 classlist[textclass].load();
1212 for(unsigned int i = 0; i < classlist[textclass].numLayouts(); ++i) {
1213 if (classlist[textclass][i].name() == name)
1214 return make_pair(true, i);
1216 if (name == "dummy")
1217 return make_pair(true, LYX_DUMMY_LAYOUT);
1218 return make_pair(false, 0); // not found
1222 // Gets a layout (style) name from layout number and textclass number
1224 LyXTextClassList::NameOfLayout(LyXTextClassList::ClassList::size_type textclass,
1225 LyXTextClass::LayoutList::size_type layout) const
1227 static string dummy("dummy");
1228 static string end("@@end@@");
1229 classlist[textclass].load();
1230 if (layout < classlist[textclass].numLayouts())
1231 return classlist[textclass][layout].name();
1232 else if (layout == LYX_DUMMY_LAYOUT)
1239 // Gets a textclass name from number
1241 LyXTextClassList::NameOfClass(LyXTextClassList::ClassList::size_type number) const
1243 static string dummy("dummy");
1244 static string end("@@end@@");
1245 if (classlist.size() == 0) {
1246 if (number == 0) return dummy;
1249 if (number < classlist.size())
1250 return classlist[number].name();
1256 // Gets a textclass latexname from number
1258 LyXTextClassList::LatexnameOfClass(LyXTextClassList::ClassList::size_type number) const
1260 static string dummy("dummy");
1261 static string end("@@end@@");
1262 classlist[number].load();
1263 if (classlist.size() == 0) {
1264 if (number == 0) return dummy;
1267 if (number < classlist.size())
1268 return classlist[number].latexname();
1274 // Gets a textclass description from number
1276 LyXTextClassList::DescOfClass(LyXTextClassList::ClassList::size_type number) const
1278 static string dummy("dummy");
1279 static string end("@@end@@");
1280 if (classlist.size() == 0) {
1281 if (number == 0) return dummy;
1284 if (number < classlist.size())
1285 return classlist[number].description();
1291 // Gets a textclass structure from number
1292 LyXTextClass const &
1293 LyXTextClassList::TextClass(LyXTextClassList::ClassList::size_type textclass) const
1295 classlist[textclass].load();
1296 if (textclass < classlist.size())
1297 return classlist[textclass];
1299 return classlist[0];
1303 void LyXTextClassList::Add(LyXTextClass const & t)
1305 classlist.push_back(t);
1309 // used when sorting the textclass list.
1310 class less_textclass_desc {
1312 int operator()(LyXTextClass const & tc1, LyXTextClass const & tc2) {
1313 return tc1.description() < tc2.description();
1318 // Reads LyX textclass definitions according to textclass config file
1319 bool LyXTextClassList::Read ()
1322 string real_file = LibFileSearch("", "textclass.lst");
1323 lyxerr[Debug::TCLASS] << "Reading textclasses from "
1324 << real_file << endl;
1326 if (real_file.empty()) {
1327 lyxerr << "LyXTextClassList::Read: unable to find "
1328 "textclass file `" << MakeDisplayPath(real_file, 1000)
1329 << "'. Exiting." << endl;
1331 WriteAlert(_("LyX wasn't able to find its layout descriptions!"),
1332 _("Check that the file \"textclass.lst\""),
1333 _("is installed correctly. Sorry, has to exit :-("));
1335 // This causes LyX to end... Not a desirable behaviour. Lgb
1336 // What do you propose? That the user gets a file dialog
1337 // and is allowed to hunt for the file? (Asger)
1340 lex.setFile(real_file);
1343 lyxerr << "LyXTextClassList::Read: unable to open "
1344 "textclass file `" << MakeDisplayPath(real_file, 1000)
1345 << "'\nCheck your installation. LyX can't continue."
1349 bool finished = false;
1350 string fname, clname, desc;
1351 // Parse config-file
1352 while (lex.IsOK() && !finished) {
1353 switch (lex.lex()) {
1354 case LyXLex::LEX_FEOF:
1358 fname = lex.GetString();
1359 lyxerr[Debug::TCLASS] << "Fname: " << fname << endl;
1361 clname = lex.GetString();
1362 lyxerr[Debug::TCLASS]
1363 << "Clname: " << clname << endl;
1365 desc = lex.GetString();
1366 lyxerr[Debug::TCLASS]
1367 << "Desc: " << desc << endl;
1368 // This code is run when we have
1369 // fname, clname and desc
1370 LyXTextClass tmpl(fname,
1374 debugging(Debug::TCLASS)) {
1383 if (classlist.size() == 0) {
1384 lyxerr << "LyXTextClassList::Read: no textclass found!"
1386 WriteAlert(_("LyX wasn't able to find any layout description!"),
1387 _("Check the contents of the file \"textclass.lst\""),
1388 _("Sorry, has to exit :-("));
1391 // Ok everything loaded ok, now sort the list.
1392 sort(classlist.begin(), classlist.end(), less_textclass_desc());
1398 Returns false if this fails
1401 LyXTextClassList::Load (LyXTextClassList::ClassList::size_type number) const
1404 if (number < classlist.size()) {
1405 classlist[number].load();
1406 if (classlist[number].numLayouts() == 0) {