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]
50 LT_ALIGN, LT_ALIGNPOSSIBLE,
52 LT_BOTTOMSEP, LT_CENTER, LT_CENTERED_TOP_ENVIRONMENT, LT_COLUMNS,
53 LT_COPYSTYLE, LT_OBSOLETEDBY,
54 LT_COMMAND, LT_COUNTER_CHAPTER, LT_COUNTER_ENUMI, LT_COUNTER_ENUMII,
55 LT_COUNTER_ENUMIII, LT_COUNTER_ENUMIV, LT_COUNTER_PARAGRAPH,
56 LT_COUNTER_SECTION, LT_COUNTER_SUBPARAGRAPH, LT_COUNTER_SUBSECTION,
57 LT_COUNTER_SUBSUBSECTION, LT_DEFAULTFONT, LT_DYNAMIC, LT_EMPTY,
58 LT_END, LT_ENVIRONMENT, LT_ENVIRONMENT_DEFAULT,
59 LT_FANCYHDR, LT_FILL_BOTTOM, LT_FILL_TOP, LT_FIRST_COUNTER,
60 LT_FIRST_DYNAMIC, LT_FONT, LT_FREE_SPACING, LT_HEADINGS, LT_INPUT,
61 LT_ITEM_ENVIRONMENT, LT_ITEMSEP, LT_KEEPEMPTY,
62 LT_LABEL_BOTTOMSEP, LT_LABELFONT, LT_TEXTFONT,
63 LT_LABELINDENT, LT_LABELSEP, LT_LABELSTRING,
64 LT_LABELSTRING_APPENDIX, LT_LABELTYPE,
65 LT_LATEXNAME, LT_LATEXPARAM, LT_LATEXTYPE, LT_LAYOUT, LT_LEFT,
67 LT_LIST_ENVIRONMENT , LT_MANUAL, LT_MAXCOUNTER,
68 LT_NEED_PROTECT, LT_NEWLINE,
69 LT_NEXTNOINDENT, LT_NO_LABEL, LT_NOSTYLE,
70 LT_PAGESTYLE, LT_PARAGRAPH,
71 LT_PARINDENT, LT_PARSEP, LT_PARSKIP, LT_PLAIN, LT_PREAMBLE,
72 LT_PROVIDESAMSMATH, LT_PROVIDESMAKEIDX, LT_PROVIDESURL, LT_RIGHT,
73 LT_RIGHT_ADDRESS_BOX, LT_RIGHTMARGIN, LT_SENSITIVE, LT_SIDES,
74 LT_SPACING, LT_SPACING_SINGLE, LT_SPACING_ONEHALF,
75 LT_SPACING_DOUBLE, LT_OTHER, LT_CLASSOPTIONS, LT_FONTSIZE,
76 LT_STATIC, LT_STYLE, LT_TOP_ENVIRONMENT, LT_TOPSEP, LT_BIBLIO,
77 LT_INTITLE, LT_SECNUMDEPTH, LT_TOCDEPTH,
78 LT_OUTPUTTYPE, LT_OTLATEX, LT_OTLINUXDOC, LT_OTDOCBOOK, LT_OTLITERATE
82 // This table is sorted alphabetically [asierra 30March96]
83 static keyword_item layoutTags[] = {
84 { "align", LT_ALIGN },
85 { "alignpossible", LT_ALIGNPOSSIBLE },
86 { "bibliography", LT_BIBLIO },
87 { "block", LT_BLOCK },
88 { "bottomsep", LT_BOTTOMSEP },
89 { "center", LT_CENTER },
90 { "centered_top_environment", LT_CENTERED_TOP_ENVIRONMENT },
91 { "classoptions", LT_CLASSOPTIONS },
92 { "columns", LT_COLUMNS },
93 { "command", LT_COMMAND },
94 { "copystyle", LT_COPYSTYLE },
95 { "counter_chapter", LT_COUNTER_CHAPTER },
96 { "counter_enumi", LT_COUNTER_ENUMI },
97 { "counter_enumii", LT_COUNTER_ENUMII },
98 { "counter_enumiii", LT_COUNTER_ENUMIII },
99 { "counter_enumiv", LT_COUNTER_ENUMIV },
100 { "counter_paragraph", LT_COUNTER_PARAGRAPH },
101 { "counter_section", LT_COUNTER_SECTION },
102 { "counter_subparagraph", LT_COUNTER_SUBPARAGRAPH },
103 { "counter_subsection", LT_COUNTER_SUBSECTION },
104 { "counter_subsubsection", LT_COUNTER_SUBSUBSECTION },
105 { "defaultfont", LT_DEFAULTFONT },
106 { "docbook", LT_OTDOCBOOK },
107 { "double", LT_SPACING_DOUBLE },
108 { "dynamic", LT_DYNAMIC },
109 { "empty", LT_EMPTY },
111 { "environment", LT_ENVIRONMENT },
112 { "environment_default", LT_ENVIRONMENT_DEFAULT },
113 { "fancyhdr", LT_FANCYHDR },
114 { "fill_bottom", LT_FILL_BOTTOM },
115 { "fill_top", LT_FILL_TOP },
116 { "first_counter", LT_FIRST_COUNTER },
117 { "first_dynamic", LT_FIRST_DYNAMIC },
119 { "fontsize", LT_FONTSIZE },
120 { "freespacing", LT_FREE_SPACING },
121 { "headings", LT_HEADINGS },
122 { "input", LT_INPUT },
123 { "intitle", LT_INTITLE },
124 { "item_environment", LT_ITEM_ENVIRONMENT },
125 { "itemsep", LT_ITEMSEP },
126 { "keepempty", LT_KEEPEMPTY },
127 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
128 { "labelfont", LT_LABELFONT },
129 { "labelindent", LT_LABELINDENT },
130 { "labelsep", LT_LABELSEP },
131 { "labelstring", LT_LABELSTRING },
132 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
133 { "labeltype", LT_LABELTYPE },
134 { "latex", LT_OTLATEX },
135 { "latexname", LT_LATEXNAME },
136 { "latexparam", LT_LATEXPARAM }, //arrae970411
137 { "latextype", LT_LATEXTYPE },
138 { "layout", LT_LAYOUT },
140 { "leftmargin", LT_LEFTMARGIN },
141 { "linuxdoc", LT_OTLINUXDOC },
142 { "list_environment", LT_LIST_ENVIRONMENT },
143 { "literate", LT_OTLITERATE },
144 { "manual", LT_MANUAL },
145 { "margin", LT_MARGIN },
146 { "maxcounter", LT_MAXCOUNTER },
147 { "needprotect", LT_NEED_PROTECT },
148 { "newline", LT_NEWLINE },
149 { "nextnoindent", LT_NEXTNOINDENT },
150 { "no_label", LT_NO_LABEL },
151 { "nostyle", LT_NOSTYLE },
152 { "obsoletedby", LT_OBSOLETEDBY },
153 { "onehalf", LT_SPACING_ONEHALF },
154 { "other", LT_OTHER },
155 { "outputtype", LT_OUTPUTTYPE },
156 { "pagestyle", LT_PAGESTYLE },
157 { "paragraph", LT_PARAGRAPH },
158 { "parindent", LT_PARINDENT },
159 { "parsep", LT_PARSEP },
160 { "parskip", LT_PARSKIP },
161 { "plain", LT_PLAIN },
162 { "preamble", LT_PREAMBLE },
163 { "providesamsmath", LT_PROVIDESAMSMATH },
164 { "providesmakeidx", LT_PROVIDESMAKEIDX },
165 { "providesurl", LT_PROVIDESURL },
166 { "right", LT_RIGHT },
167 { "right_address_box", LT_RIGHT_ADDRESS_BOX },
168 { "rightmargin", LT_RIGHTMARGIN },
169 { "secnumdepth", LT_SECNUMDEPTH },
170 { "sensitive", LT_SENSITIVE },
171 { "sides", LT_SIDES },
172 { "single", LT_SPACING_SINGLE },
173 { "spacing", LT_SPACING },
174 { "static", LT_STATIC },
175 { "style", LT_STYLE },
176 { "textfont", LT_TEXTFONT },
177 { "tocdepth", LT_TOCDEPTH },
178 { "top_environment", LT_TOP_ENVIRONMENT },
179 { "topsep", LT_TOPSEP }
183 /////////////////////
185 // Constructor for layout
186 LyXLayout::LyXLayout ()
188 margintype = MARGIN_STATIC;
189 latextype = LATEX_PARAGRAPH;
193 font = LyXFont(LyXFont::ALL_INHERIT);
194 labelfont = LyXFont(LyXFont::ALL_INHERIT);
195 resfont = LyXFont(LyXFont::ALL_SANE);
196 reslabelfont = LyXFont(LyXFont::ALL_SANE);
197 nextnoindent = false;
202 labelbottomsep = 0.0;
204 align = LYX_ALIGN_BLOCK;
205 alignpossible = LYX_ALIGN_BLOCK;
206 labeltype = LABEL_NO_LABEL;
207 // Should or should not. That is the question.
208 // spacing.set(Spacing::OneHalf);
211 newline_allowed = true;
212 free_spacing = false;
216 // Reads a layout definition from file
217 bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass)
220 bool finished = false;
222 // parse style section
223 while (!finished && lexrc.IsOK() && !error) {
224 switch(lexrc.lex()) {
229 case -1: // parse error
230 lexrc.printError("Unknown tag `$$Token'");
234 case LT_END: // end of structure
238 case LT_COPYSTYLE: // initialize with a known style
240 if (tclass.hasLayout(lexrc.GetString())) {
241 string tmpname = name_;
242 this->operator= (tclass.GetLayout(lexrc.GetString()));
245 lexrc.printError("Cannot copy known "
251 case LT_OBSOLETEDBY: // replace with a known style
253 if (tclass.hasLayout(lexrc.GetString())) {
254 string tmpname = name_;
255 this->operator= (tclass.GetLayout(lexrc.GetString()));
257 if (obsoleted_by().empty())
258 obsoleted_by_ = lexrc.GetString();
260 lexrc.printError("Cannot replace with"
267 case LT_MARGIN: // Margin style definition.
269 switch(lexrc.lex()) {
271 margintype = MARGIN_STATIC;
274 margintype = MARGIN_MANUAL;
277 margintype = MARGIN_DYNAMIC;
279 case LT_FIRST_DYNAMIC:
280 margintype = MARGIN_FIRST_DYNAMIC;
282 case LT_RIGHT_ADDRESS_BOX:
283 margintype = MARGIN_RIGHT_ADDRESS_BOX;
286 lexrc.printError("Unknown margin type `$$Token'");
291 case LT_LATEXTYPE: // Latex style definition.
292 switch (lexrc.lex()) {
294 latextype= LATEX_PARAGRAPH;
297 latextype= LATEX_COMMAND;
300 latextype= LATEX_ENVIRONMENT;
302 case LT_ITEM_ENVIRONMENT:
303 latextype= LATEX_ITEM_ENVIRONMENT;
305 case LT_LIST_ENVIRONMENT:
306 latextype= LATEX_LIST_ENVIRONMENT;
309 lexrc.printError("Unknown latextype `$$Token'");
315 intitle = lexrc.next() && lexrc.GetInteger();
318 case LT_NEED_PROTECT:
319 needprotect = lexrc.next() && lexrc.GetInteger();
323 keepempty = lexrc.next() && lexrc.GetInteger();
336 labelfont.lyxRead(lexrc);
339 case LT_NEXTNOINDENT: // Indent next paragraph?
340 if (lexrc.next() && lexrc.GetInteger())
343 nextnoindent = false;
348 latexname_ = lexrc.GetString();
353 latexparam_ = lexrc.GetString();
357 preamble_ = lexrc.getLongString("EndPreamble");
361 switch (lexrc.lex()) {
363 labeltype = LABEL_NO_LABEL;
366 labeltype = LABEL_MANUAL;
368 case LT_TOP_ENVIRONMENT:
369 labeltype = LABEL_TOP_ENVIRONMENT;
371 case LT_CENTERED_TOP_ENVIRONMENT:
372 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
375 labeltype = LABEL_STATIC;
378 labeltype = LABEL_SENSITIVE;
380 case LT_COUNTER_CHAPTER:
381 labeltype = LABEL_COUNTER_CHAPTER;
383 case LT_COUNTER_SECTION:
384 labeltype = LABEL_COUNTER_SECTION;
386 case LT_COUNTER_SUBSECTION:
387 labeltype = LABEL_COUNTER_SUBSECTION;
389 case LT_COUNTER_SUBSUBSECTION:
390 labeltype = LABEL_COUNTER_SUBSUBSECTION;
392 case LT_COUNTER_PARAGRAPH:
393 labeltype = LABEL_COUNTER_PARAGRAPH;
395 case LT_COUNTER_SUBPARAGRAPH:
396 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
398 case LT_COUNTER_ENUMI:
399 labeltype = LABEL_COUNTER_ENUMI;
401 case LT_COUNTER_ENUMII:
402 labeltype = LABEL_COUNTER_ENUMII;
404 case LT_COUNTER_ENUMIII:
405 labeltype = LABEL_COUNTER_ENUMIII;
407 case LT_COUNTER_ENUMIV:
408 labeltype = LABEL_COUNTER_ENUMIV;
411 labeltype = LABEL_BIBLIO;
414 lexrc.printError("Unknown labeltype `$$Token'");
418 case LT_LEFTMARGIN: // left margin type
420 leftmargin = lexrc.GetString();
423 case LT_RIGHTMARGIN: // right margin type
425 rightmargin = lexrc.GetString();
428 case LT_LABELINDENT: // label indenting flag
430 labelindent = lexrc.GetString();
433 case LT_PARINDENT: // paragraph indent. flag
435 parindent = lexrc.GetString();
438 case LT_PARSKIP: // paragraph skip size
440 parskip = lexrc.GetFloat();
443 case LT_ITEMSEP: // item separation size
445 itemsep = lexrc.GetFloat();
448 case LT_TOPSEP: // top separation size
450 topsep = lexrc.GetFloat();
453 case LT_BOTTOMSEP: // bottom separation size
455 bottomsep = lexrc.GetFloat();
458 case LT_LABEL_BOTTOMSEP: // label bottom separation size
460 labelbottomsep = lexrc.GetFloat();
463 case LT_LABELSEP: // label separator
465 labelsep = subst(lexrc.GetString(), 'x', ' ');
469 case LT_PARSEP: // par. separation size
471 parsep = lexrc.GetFloat();
474 case LT_FILL_TOP: // fill top flag
476 fill_top = lexrc.GetInteger();
479 case LT_FILL_BOTTOM: // fill bottom flag
481 fill_bottom = lexrc.GetInteger();
484 case LT_NEWLINE: // newlines allowed?
486 newline_allowed = lexrc.GetInteger();
489 case LT_ALIGN: // paragraph align
490 switch (lexrc.lex()) {
492 align = LYX_ALIGN_BLOCK;
495 align = LYX_ALIGN_LEFT;
498 align = LYX_ALIGN_RIGHT;
501 align = LYX_ALIGN_CENTER;
504 align = LYX_ALIGN_LAYOUT;
507 lexrc.printError("Unknown alignment `$$Token'");
511 case LT_ALIGNPOSSIBLE: // paragraph allowed align
512 { alignpossible = LYX_ALIGN_NONE;
514 int lineno = lexrc.GetLineNo();
516 switch (lexrc.lex()) {
518 alignpossible |= LYX_ALIGN_BLOCK;
521 alignpossible |= LYX_ALIGN_LEFT;
524 alignpossible |= LYX_ALIGN_RIGHT;
527 alignpossible |= LYX_ALIGN_CENTER;
530 alignpossible |= LYX_ALIGN_LAYOUT;
533 lexrc.printError("Unknown alignment `$$Token'");
536 } while (lineno == lexrc.GetLineNo());
540 case LT_LABELSTRING: // label string definition
542 labelstring_ = lexrc.GetString();
545 case LT_LABELSTRING_APPENDIX: // label string appendix definition
547 labelstring_appendix_ = lexrc.GetString();
550 case LT_FREE_SPACING: // Allow for free spacing.
552 free_spacing = lexrc.GetInteger();
555 case LT_SPACING: // setspace.sty
556 switch(lexrc.lex()) {
557 case LT_SPACING_SINGLE:
558 spacing.set(Spacing::Single);
560 case LT_SPACING_ONEHALF:
561 spacing.set(Spacing::Onehalf);
563 case LT_SPACING_DOUBLE:
564 spacing.set(Spacing::Double);
568 spacing.set(Spacing::Other, lexrc.GetFloat());
571 lexrc.printError("Unknown spacing `$$Token'");
574 default: /* context error */
575 lexrc.printError("Tag `$$Token' is not "
576 "allowed in layout");
586 /* ******************************************************************* */
588 LyXTextClass::LyXTextClass(string const & fn, string const & cln,
590 : name_(fn), latexname_(cln), description_(desc)
597 pagestyle_ = "default";
598 maxcounter_ = LABEL_COUNTER_CHAPTER;
599 defaultfont_ = LyXFont(LyXFont::ALL_SANE);
600 opt_fontsize_ = "10|11|12";
601 opt_pagestyle_ = "empty|plain|headings|fancy";
607 bool LyXTextClass::do_readStyle(LyXLex & lexrc, LyXLayout & lay)
609 lyxerr[Debug::TCLASS] << "Reading style " << lay.name() << endl;
610 if (!lay.Read(lexrc, *this)) {
612 lay.resfont = lay.font;
613 lay.resfont.realize(defaultfont());
614 lay.reslabelfont = lay.labelfont;
615 lay.reslabelfont.realize(defaultfont());
616 return false; // no errors
618 lyxerr << "Error parsing style `" << lay.name() << "'" << endl;
623 // Reads a textclass structure from file.
624 bool LyXTextClass::Read(string const & filename, bool merge)
627 lyxerr[Debug::TCLASS] << "Reading textclass "
628 << MakeDisplayPath(filename)
631 lyxerr[Debug::TCLASS] << "Reading input file "
632 << MakeDisplayPath(filename)
635 LyXLex lexrc(layoutTags, sizeof(layoutTags)/sizeof(keyword_item));
638 lexrc.setFile(filename);
639 if (!lexrc.IsOK()) error = true;
642 while (lexrc.IsOK() && !error) {
643 switch(lexrc.lex()) {
648 lexrc.printError("Unknown tag `$$Token'");
652 case LT_OUTPUTTYPE: // output type definition
653 switch(lexrc.lex()) {
658 outputType_ = LINUXDOC;
661 outputType_ = DOCBOOK;
664 outputType_ = LITERATE;
667 lexrc.printError("Unknown output type `$$Token'");
672 case LT_INPUT: // Include file
674 string tmp = LibFileSearch("layouts",
678 if (Read(tmp, true)) {
679 lexrc.printError("Error reading input"
688 string name = subst(lexrc.GetString(),
690 if (hasLayout(name)) {
691 LyXLayout & lay = GetLayout(name);
692 error = do_readStyle(lexrc, lay);
696 if (!(error = do_readStyle(lexrc, lay)))
697 layoutlist.push_back(lay);
701 lexrc.printError("No name given for style: `$$Token'.");
708 string style = subst(lexrc.GetString(),
710 if (!delete_layout(style))
711 lexrc.printError("Cannot delete style"
718 columns_ = lexrc.GetInteger();
723 switch(lexrc.GetInteger()) {
724 case 1: sides_ = OneSide; break;
725 case 2: sides_ = TwoSides; break;
727 lyxerr << "Impossible number of page"
728 " sides, setting to one."
738 pagestyle_ = strip(lexrc.GetString());
742 defaultfont_.lyxRead(lexrc);
743 if (!defaultfont_.resolved()) {
744 lexrc.printError("Warning: defaultfont should "
745 "be fully instantiated!");
746 defaultfont_.realize(LyXFont::ALL_SANE);
751 switch (lexrc.lex()) {
752 case LT_COUNTER_CHAPTER:
753 maxcounter_ = LABEL_COUNTER_CHAPTER;
755 case LT_COUNTER_SECTION:
756 maxcounter_ = LABEL_COUNTER_SECTION;
758 case LT_COUNTER_SUBSECTION:
759 maxcounter_ = LABEL_COUNTER_SUBSECTION;
761 case LT_COUNTER_SUBSUBSECTION:
762 maxcounter_ = LABEL_COUNTER_SUBSUBSECTION;
764 case LT_COUNTER_PARAGRAPH:
765 maxcounter_ = LABEL_COUNTER_PARAGRAPH;
767 case LT_COUNTER_SUBPARAGRAPH:
768 maxcounter_ = LABEL_COUNTER_SUBPARAGRAPH;
770 case LT_COUNTER_ENUMI:
771 maxcounter_ = LABEL_COUNTER_ENUMI;
773 case LT_COUNTER_ENUMII:
774 maxcounter_ = LABEL_COUNTER_ENUMII;
776 case LT_COUNTER_ENUMIII:
777 maxcounter_ = LABEL_COUNTER_ENUMIII;
779 case LT_COUNTER_ENUMIV:
780 maxcounter_ = LABEL_COUNTER_ENUMIV;
787 secnumdepth_ = lexrc.GetInteger();
792 tocdepth_ = lexrc.GetInteger();
795 // First step to support options
796 case LT_CLASSOPTIONS:
799 while (getout && lexrc.IsOK()) {
800 switch (lexrc.lex()) {
803 opt_fontsize_ = strip(lexrc.GetString());
807 opt_pagestyle_ = strip(lexrc.GetString());
811 options_ = lexrc.GetString();
813 case LT_END: getout = false; break;
815 lexrc.printError("Out of context tag `$$Token'");
823 preamble_ = lexrc.getLongString("EndPreamble");
826 case LT_PROVIDESAMSMATH:
827 if (lexrc.next() && lexrc.GetInteger())
828 provides_ |= amsmath;
831 case LT_PROVIDESMAKEIDX:
832 if (lexrc.next() && lexrc.GetInteger())
833 provides_ |= makeidx;
837 if (lexrc.next() && lexrc.GetInteger())
841 case LT_LEFTMARGIN: // left margin type
843 leftmargin_ = lexrc.GetString();
846 case LT_RIGHTMARGIN: // right margin type
848 rightmargin_ = lexrc.GetString();
852 lexrc.printError("Out of context tag `$$Token'");
857 if (!merge) { // we are at top level here.
858 lyxerr[Debug::TCLASS] << "Finished reading textclass "
859 << MakeDisplayPath(filename)
862 lyxerr[Debug::TCLASS] << "Finished reading input file "
863 << MakeDisplayPath(filename)
870 bool LyXTextClass::hasLayout(string const & name) const
872 for (LayoutList::const_iterator cit = layoutlist.begin();
873 cit != layoutlist.end(); ++cit) {
874 if ((*cit).name() == name)
881 LyXLayout const & LyXTextClass::GetLayout (string const & name) const
883 for (LayoutList::const_iterator cit = layoutlist.begin();
884 cit != layoutlist.end(); ++cit) {
885 if ((*cit).name() == name)
888 Assert(false); // we actually require the name to exist.
889 return layoutlist.front();
893 LyXLayout & LyXTextClass::GetLayout(string const & name)
895 for (LayoutList::iterator it = layoutlist.begin();
896 it != layoutlist.end(); ++it) {
897 if ((*it).name() == name)
900 Assert(false); // we actually require the name to exist.
901 return layoutlist.front();
905 bool LyXTextClass::delete_layout (string const & name)
907 for(LayoutList::iterator it = layoutlist.begin();
908 it != layoutlist.end(); ++it) {
909 if ((*it).name() == name) {
910 layoutlist.erase(it);
918 // Load textclass info if not loaded yet
919 void LyXTextClass::load()
924 string real_file = LibFileSearch("layouts", name_, "layout");
926 if (Read(real_file)) {
927 lyxerr << "Error reading `"
928 << MakeDisplayPath(real_file)
929 << "'\n(Check `" << name_
930 << "')\nCheck your installation and "
931 "try Options/Reconfigure..." << endl;
937 //////////////////////////////////////////
939 // Gets textclass number from name
940 pair<bool, LyXTextClassList::ClassList::size_type>
941 LyXTextClassList::NumberOfClass(string const & textclass) const
943 for (ClassList::const_iterator cit = classlist.begin();
944 cit != classlist.end(); ++cit) {
945 if ((*cit).name() == textclass)
946 return make_pair(true, cit - classlist.begin());
948 return make_pair(false, 0);
952 // Gets layout structure from style number and textclass number
954 LyXTextClassList::Style(LyXTextClassList::ClassList::size_type textclass,
955 LyXTextClass::LayoutList::size_type layout) const
957 classlist[textclass].load();
958 if (layout < classlist[textclass].numLayouts())
959 return classlist[textclass][layout];
960 return classlist[textclass][0];
964 // Gets layout number from name and textclass number
965 pair<bool, LyXTextClass::LayoutList::size_type>
966 LyXTextClassList::NumberOfLayout(LyXTextClassList::ClassList::size_type textclass, string const & name) const
968 classlist[textclass].load();
969 for(unsigned int i = 0; i < classlist[textclass].numLayouts(); ++i) {
970 if (classlist[textclass][i].name() == name)
971 return make_pair(true, i);
974 return make_pair(true, LYX_DUMMY_LAYOUT);
975 return make_pair(false, 0); // not found
979 // Gets a layout (style) name from layout number and textclass number
981 LyXTextClassList::NameOfLayout(LyXTextClassList::ClassList::size_type textclass,
982 LyXTextClass::LayoutList::size_type layout) const
984 static string dummy("dummy");
985 static string end("@@end@@");
986 classlist[textclass].load();
987 if (layout < classlist[textclass].numLayouts())
988 return classlist[textclass][layout].name();
989 else if (layout == LYX_DUMMY_LAYOUT)
996 // Gets a textclass name from number
998 LyXTextClassList::NameOfClass(LyXTextClassList::ClassList::size_type number) const
1000 static string dummy("dummy");
1001 static string end("@@end@@");
1002 if (classlist.size() == 0) {
1003 if (number == 0) return dummy;
1006 if (number < classlist.size())
1007 return classlist[number].name();
1013 // Gets a textclass latexname from number
1015 LyXTextClassList::LatexnameOfClass(LyXTextClassList::ClassList::size_type number) const
1017 static string dummy("dummy");
1018 static string end("@@end@@");
1019 classlist[number].load();
1020 if (classlist.size() == 0) {
1021 if (number == 0) return dummy;
1024 if (number < classlist.size())
1025 return classlist[number].latexname();
1031 // Gets a textclass description from number
1033 LyXTextClassList::DescOfClass(LyXTextClassList::ClassList::size_type number) const
1035 static string dummy("dummy");
1036 static string end("@@end@@");
1037 if (classlist.size() == 0) {
1038 if (number == 0) return dummy;
1041 if (number < classlist.size())
1042 return classlist[number].description();
1048 // Gets a textclass structure from number
1049 LyXTextClass const &
1050 LyXTextClassList::TextClass(LyXTextClassList::ClassList::size_type textclass) const
1052 classlist[textclass].load();
1053 if (textclass < classlist.size())
1054 return classlist[textclass];
1056 return classlist[0];
1060 void LyXTextClassList::Add(LyXTextClass const & t)
1062 classlist.push_back(t);
1066 // used when sorting the textclass list.
1067 class less_textclass_desc {
1069 int operator()(LyXTextClass const & tc1, LyXTextClass const & tc2) {
1070 return tc1.description() < tc2.description();
1075 // Reads LyX textclass definitions according to textclass config file
1076 bool LyXTextClassList::Read ()
1079 string real_file = LibFileSearch("", "textclass.lst");
1080 lyxerr[Debug::TCLASS] << "Reading textclasses from "
1081 << real_file << endl;
1083 if (real_file.empty()) {
1084 lyxerr << "LyXTextClassList::Read: unable to find "
1085 "textclass file `" << MakeDisplayPath(real_file, 1000)
1086 << "'. Exiting." << endl;
1088 WriteAlert(_("LyX wasn't able to find its layout descriptions!"),
1089 _("Check that the file \"textclass.lst\""),
1090 _("is installed correctly. Sorry, has to exit :-("));
1092 // This causes LyX to end... Not a desirable behaviour. Lgb
1093 // What do you propose? That the user gets a file dialog
1094 // and is allowed to hunt for the file? (Asger)
1097 lex.setFile(real_file);
1100 lyxerr << "LyXTextClassList::Read: unable to open "
1101 "textclass file `" << MakeDisplayPath(real_file, 1000)
1102 << "\'\nCheck your installation. LyX can't continue."
1106 bool finished = false;
1107 string fname, clname, desc;
1108 // Parse config-file
1109 while (lex.IsOK() && !finished) {
1110 switch (lex.lex()) {
1111 case LyXLex::LEX_FEOF:
1115 fname = lex.GetString();
1116 lyxerr[Debug::TCLASS] << "Fname: " << fname << endl;
1118 clname = lex.GetString();
1119 lyxerr[Debug::TCLASS]
1120 << "Clname: " << clname << endl;
1122 desc = lex.GetString();
1123 lyxerr[Debug::TCLASS]
1124 << "Desc: " << desc << endl;
1125 // This code is run when we have
1126 // fname, clname and desc
1127 LyXTextClass tmpl(fname,
1131 debugging(Debug::TCLASS)) {
1140 if (classlist.size() == 0) {
1141 lyxerr << "LyXTextClassList::Read: no textclass found!"
1143 WriteAlert(_("LyX wasn't able to find any layout description!"),
1144 _("Check the contents of the file \"textclass.lst\""),
1145 _("Sorry, has to exit :-("));
1148 // Ok everything loaded ok, now sort the list.
1149 sort(classlist.begin(), classlist.end(), less_textclass_desc());
1155 Returns false if this fails
1158 LyXTextClassList::Load (LyXTextClassList::ClassList::size_type number) const
1161 if (number < classlist.size()) {
1162 classlist[number].load();
1163 if (classlist[number].numLayouts() == 0) {