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
19 #include "definitions.h"
22 #include "support/filetools.h"
23 #include "lyx_gui_misc.h"
26 #include "support/LAssert.h"
28 // Global variable: textclass table.
29 LyXTextClassList textclasslist;
31 // Reads the style files
34 lyxerr[Debug::TCLASS] << "LyXSetStyle: parsing configuration...\n";
36 if (!textclasslist.Read()) {
37 lyxerr[Debug::TCLASS] << "LyXSetStyle: an error occured "
38 "during parsing.\n Exiting." << endl;
42 lyxerr[Debug::TCLASS] << "LyXSetStyle: configuration parsed." << endl;
46 // The order of the LayoutTags enum is no more important. [asierra300396]
49 LT_ALIGN, LT_ALIGNPOSSIBLE,
51 LT_BOTTOMSEP, LT_CENTER, LT_CENTERED_TOP_ENVIRONMENT, LT_COLUMNS,
52 LT_COPYSTYLE, LT_OBSOLETEDBY,
53 LT_COMMAND, LT_COUNTER_CHAPTER, LT_COUNTER_ENUMI, LT_COUNTER_ENUMII,
54 LT_COUNTER_ENUMIII, LT_COUNTER_ENUMIV, LT_COUNTER_PARAGRAPH,
55 LT_COUNTER_SECTION, LT_COUNTER_SUBPARAGRAPH, LT_COUNTER_SUBSECTION,
56 LT_COUNTER_SUBSUBSECTION, LT_DEFAULTFONT, LT_DYNAMIC, LT_EMPTY,
57 LT_END, LT_ENVIRONMENT, LT_ENVIRONMENT_DEFAULT,
58 LT_FANCYHDR, LT_FILL_BOTTOM, LT_FILL_TOP, LT_FIRST_COUNTER,
59 LT_FIRST_DYNAMIC, LT_FONT, LT_FREE_SPACING, LT_HEADINGS, LT_INPUT,
60 LT_ITEM_ENVIRONMENT, LT_ITEMSEP, LT_KEEPEMPTY,
61 LT_LABEL_BOTTOMSEP, LT_LABELFONT, LT_TEXTFONT,
62 LT_LABELINDENT, LT_LABELSEP, LT_LABELSTRING,
63 LT_LABELSTRING_APPENDIX, LT_LABELTYPE,
64 LT_LATEXNAME, LT_LATEXPARAM, LT_LATEXTYPE, LT_LAYOUT, LT_LEFT,
66 LT_LIST_ENVIRONMENT , LT_MANUAL, LT_MAXCOUNTER,
67 LT_NEED_PROTECT, LT_NEWLINE,
68 LT_NEXTNOINDENT, LT_NO_LABEL, LT_NOSTYLE,
69 LT_PAGESTYLE, LT_PARAGRAPH,
70 LT_PARINDENT, LT_PARSEP, LT_PARSKIP, LT_PLAIN, LT_PREAMBLE,
71 LT_PROVIDESAMSMATH, LT_PROVIDESMAKEIDX, LT_PROVIDESURL, LT_RIGHT,
72 LT_RIGHT_ADDRESS_BOX, LT_RIGHTMARGIN, LT_SENSITIVE, LT_SIDES,
73 LT_SPACING, LT_SPACING_SINGLE, LT_SPACING_ONEHALF,
74 LT_SPACING_DOUBLE, LT_OTHER, LT_CLASSOPTIONS, LT_FONTSIZE,
75 LT_STATIC, LT_STYLE, LT_TOP_ENVIRONMENT, LT_TOPSEP, LT_BIBLIO,
76 LT_INTITLE, LT_SECNUMDEPTH, LT_TOCDEPTH,
77 LT_OUTPUTTYPE, LT_OTLATEX, LT_OTLINUXDOC, LT_OTDOCBOOK, LT_OTLITERATE
81 // This table is sorted alphabetically [asierra 30March96]
82 static keyword_item layoutTags[] = {
83 { "align", LT_ALIGN },
84 { "alignpossible", LT_ALIGNPOSSIBLE },
85 { "bibliography", LT_BIBLIO },
86 { "block", LT_BLOCK },
87 { "bottomsep", LT_BOTTOMSEP },
88 { "center", LT_CENTER },
89 { "centered_top_environment", LT_CENTERED_TOP_ENVIRONMENT },
90 { "classoptions", LT_CLASSOPTIONS },
91 { "columns", LT_COLUMNS },
92 { "command", LT_COMMAND },
93 { "copystyle", LT_COPYSTYLE },
94 { "counter_chapter", LT_COUNTER_CHAPTER },
95 { "counter_enumi", LT_COUNTER_ENUMI },
96 { "counter_enumii", LT_COUNTER_ENUMII },
97 { "counter_enumiii", LT_COUNTER_ENUMIII },
98 { "counter_enumiv", LT_COUNTER_ENUMIV },
99 { "counter_paragraph", LT_COUNTER_PARAGRAPH },
100 { "counter_section", LT_COUNTER_SECTION },
101 { "counter_subparagraph", LT_COUNTER_SUBPARAGRAPH },
102 { "counter_subsection", LT_COUNTER_SUBSECTION },
103 { "counter_subsubsection", LT_COUNTER_SUBSUBSECTION },
104 { "defaultfont", LT_DEFAULTFONT },
105 { "docbook", LT_OTDOCBOOK },
106 { "double", LT_SPACING_DOUBLE },
107 { "dynamic", LT_DYNAMIC },
108 { "empty", LT_EMPTY },
110 { "environment", LT_ENVIRONMENT },
111 { "environment_default", LT_ENVIRONMENT_DEFAULT },
112 { "fancyhdr", LT_FANCYHDR },
113 { "fill_bottom", LT_FILL_BOTTOM },
114 { "fill_top", LT_FILL_TOP },
115 { "first_counter", LT_FIRST_COUNTER },
116 { "first_dynamic", LT_FIRST_DYNAMIC },
118 { "fontsize", LT_FONTSIZE },
119 { "freespacing", LT_FREE_SPACING },
120 { "headings", LT_HEADINGS },
121 { "input", LT_INPUT },
122 { "intitle", LT_INTITLE },
123 { "item_environment", LT_ITEM_ENVIRONMENT },
124 { "itemsep", LT_ITEMSEP },
125 { "keepempty", LT_KEEPEMPTY },
126 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
127 { "labelfont", LT_LABELFONT },
128 { "labelindent", LT_LABELINDENT },
129 { "labelsep", LT_LABELSEP },
130 { "labelstring", LT_LABELSTRING },
131 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
132 { "labeltype", LT_LABELTYPE },
133 { "latex", LT_OTLATEX },
134 { "latexname", LT_LATEXNAME },
135 { "latexparam", LT_LATEXPARAM }, //arrae970411
136 { "latextype", LT_LATEXTYPE },
137 { "layout", LT_LAYOUT },
139 { "leftmargin", LT_LEFTMARGIN },
140 { "linuxdoc", LT_OTLINUXDOC },
141 { "list_environment", LT_LIST_ENVIRONMENT },
142 { "literate", LT_OTLITERATE },
143 { "manual", LT_MANUAL },
144 { "margin", LT_MARGIN },
145 { "maxcounter", LT_MAXCOUNTER },
146 { "needprotect", LT_NEED_PROTECT },
147 { "newline", LT_NEWLINE },
148 { "nextnoindent", LT_NEXTNOINDENT },
149 { "no_label", LT_NO_LABEL },
150 { "nostyle", LT_NOSTYLE },
151 { "obsoletedby", LT_OBSOLETEDBY },
152 { "onehalf", LT_SPACING_ONEHALF },
153 { "other", LT_OTHER },
154 { "outputtype", LT_OUTPUTTYPE },
155 { "pagestyle", LT_PAGESTYLE },
156 { "paragraph", LT_PARAGRAPH },
157 { "parindent", LT_PARINDENT },
158 { "parsep", LT_PARSEP },
159 { "parskip", LT_PARSKIP },
160 { "plain", LT_PLAIN },
161 { "preamble", LT_PREAMBLE },
162 { "providesamsmath", LT_PROVIDESAMSMATH },
163 { "providesmakeidx", LT_PROVIDESMAKEIDX },
164 { "providesurl", LT_PROVIDESURL },
165 { "right", LT_RIGHT },
166 { "right_address_box", LT_RIGHT_ADDRESS_BOX },
167 { "rightmargin", LT_RIGHTMARGIN },
168 { "secnumdepth", LT_SECNUMDEPTH },
169 { "sensitive", LT_SENSITIVE },
170 { "sides", LT_SIDES },
171 { "single", LT_SPACING_SINGLE },
172 { "spacing", LT_SPACING },
173 { "static", LT_STATIC },
174 { "style", LT_STYLE },
175 { "textfont", LT_TEXTFONT },
176 { "tocdepth", LT_TOCDEPTH },
177 { "top_environment", LT_TOP_ENVIRONMENT },
178 { "topsep", LT_TOPSEP }
182 /////////////////////
184 // Constructor for layout
185 LyXLayout::LyXLayout ()
187 margintype = MARGIN_STATIC;
188 latextype = LATEX_PARAGRAPH;
192 font = LyXFont(LyXFont::ALL_INHERIT);
193 labelfont = LyXFont(LyXFont::ALL_INHERIT);
194 resfont = LyXFont(LyXFont::ALL_SANE);
195 reslabelfont = LyXFont(LyXFont::ALL_SANE);
196 nextnoindent = false;
201 labelbottomsep = 0.0;
203 align = LYX_ALIGN_BLOCK;
204 alignpossible = LYX_ALIGN_BLOCK;
205 labeltype = LABEL_NO_LABEL;
206 // Should or should not. That is the question.
207 // spacing.set(Spacing::OneHalf);
210 newline_allowed = true;
211 free_spacing = false;
215 // Reads a layout definition from file
216 bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass)
219 bool finished = false;
221 // parse style section
222 while (!finished && lexrc.IsOK() && !error) {
223 switch(lexrc.lex()) {
228 case -1: // parse error
229 lexrc.printError("Unknown tag `$$Token'");
233 case LT_END: // end of structure
237 case LT_COPYSTYLE: // initialize with a known style
239 if (tclass.hasLayout(lexrc.GetString())) {
240 string tmpname = name_;
241 this->operator=(tclass.GetLayout(lexrc.GetString()));
244 lexrc.printError("Cannot copy known "
250 case LT_OBSOLETEDBY: // replace with a known style
252 if (tclass.hasLayout(lexrc.GetString())) {
253 string tmpname = name_;
254 this->operator=(tclass.GetLayout(lexrc.GetString()));
256 if (obsoleted_by().empty())
257 obsoleted_by_ = lexrc.GetString();
259 lexrc.printError("Cannot replace with"
266 case LT_MARGIN: // Margin style definition.
268 switch(lexrc.lex()) {
270 margintype = MARGIN_STATIC;
273 margintype = MARGIN_MANUAL;
276 margintype = MARGIN_DYNAMIC;
278 case LT_FIRST_DYNAMIC:
279 margintype = MARGIN_FIRST_DYNAMIC;
281 case LT_RIGHT_ADDRESS_BOX:
282 margintype = MARGIN_RIGHT_ADDRESS_BOX;
285 lexrc.printError("Unknown margin type `$$Token'");
290 case LT_LATEXTYPE: // Latex style definition.
291 switch (lexrc.lex()) {
293 latextype=LATEX_PARAGRAPH;
296 latextype=LATEX_COMMAND;
299 latextype=LATEX_ENVIRONMENT;
301 case LT_ITEM_ENVIRONMENT:
302 latextype=LATEX_ITEM_ENVIRONMENT;
304 case LT_LIST_ENVIRONMENT:
305 latextype=LATEX_LIST_ENVIRONMENT;
308 lexrc.printError("Unknown latextype `$$Token'");
314 intitle = lexrc.next() && lexrc.GetInteger();
317 case LT_NEED_PROTECT:
318 needprotect = lexrc.next() && lexrc.GetInteger();
322 keepempty = lexrc.next() && lexrc.GetInteger();
335 labelfont.lyxRead(lexrc);
338 case LT_NEXTNOINDENT: // Indent next paragraph?
339 if (lexrc.next() && lexrc.GetInteger())
342 nextnoindent = false;
347 latexname_ = lexrc.GetString();
352 latexparam_ = lexrc.GetString();
356 preamble_ = lexrc.getLongString("EndPreamble");
360 switch (lexrc.lex()) {
362 labeltype = LABEL_NO_LABEL;
365 labeltype = LABEL_MANUAL;
367 case LT_TOP_ENVIRONMENT:
368 labeltype = LABEL_TOP_ENVIRONMENT;
370 case LT_CENTERED_TOP_ENVIRONMENT:
371 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
374 labeltype = LABEL_STATIC;
377 labeltype = LABEL_SENSITIVE;
379 case LT_COUNTER_CHAPTER:
380 labeltype = LABEL_COUNTER_CHAPTER;
382 case LT_COUNTER_SECTION:
383 labeltype = LABEL_COUNTER_SECTION;
385 case LT_COUNTER_SUBSECTION:
386 labeltype = LABEL_COUNTER_SUBSECTION;
388 case LT_COUNTER_SUBSUBSECTION:
389 labeltype = LABEL_COUNTER_SUBSUBSECTION;
391 case LT_COUNTER_PARAGRAPH:
392 labeltype = LABEL_COUNTER_PARAGRAPH;
394 case LT_COUNTER_SUBPARAGRAPH:
395 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
397 case LT_COUNTER_ENUMI:
398 labeltype = LABEL_COUNTER_ENUMI;
400 case LT_COUNTER_ENUMII:
401 labeltype = LABEL_COUNTER_ENUMII;
403 case LT_COUNTER_ENUMIII:
404 labeltype = LABEL_COUNTER_ENUMIII;
406 case LT_COUNTER_ENUMIV:
407 labeltype = LABEL_COUNTER_ENUMIV;
410 labeltype = LABEL_BIBLIO;
413 lexrc.printError("Unknown labeltype `$$Token'");
417 case LT_LEFTMARGIN: // left margin type
419 leftmargin = lexrc.GetString();
422 case LT_RIGHTMARGIN: // right margin type
424 rightmargin = lexrc.GetString();
427 case LT_LABELINDENT: // label indenting flag
429 labelindent = lexrc.GetString();
432 case LT_PARINDENT: // paragraph indent. flag
434 parindent = lexrc.GetString();
437 case LT_PARSKIP: // paragraph skip size
439 parskip = lexrc.GetFloat();
442 case LT_ITEMSEP: // item separation size
444 itemsep = lexrc.GetFloat();
447 case LT_TOPSEP: // top separation size
449 topsep = lexrc.GetFloat();
452 case LT_BOTTOMSEP: // bottom separation size
454 bottomsep = lexrc.GetFloat();
457 case LT_LABEL_BOTTOMSEP: // label bottom separation size
459 labelbottomsep = lexrc.GetFloat();
462 case LT_LABELSEP: // label separator
464 labelsep = subst(lexrc.GetString(), 'x', ' ');
468 case LT_PARSEP: // par. separation size
470 parsep = lexrc.GetFloat();
473 case LT_FILL_TOP: // fill top flag
475 fill_top = lexrc.GetInteger();
478 case LT_FILL_BOTTOM: // fill bottom flag
480 fill_bottom = lexrc.GetInteger();
483 case LT_NEWLINE: // newlines allowed?
485 newline_allowed = lexrc.GetInteger();
488 case LT_ALIGN: // paragraph align
489 switch (lexrc.lex()) {
491 align = LYX_ALIGN_BLOCK;
494 align = LYX_ALIGN_LEFT;
497 align = LYX_ALIGN_RIGHT;
500 align = LYX_ALIGN_CENTER;
503 align = LYX_ALIGN_LAYOUT;
506 lexrc.printError("Unknown alignment `$$Token'");
510 case LT_ALIGNPOSSIBLE: // paragraph allowed align
511 { alignpossible = LYX_ALIGN_NONE;
513 int lineno = lexrc.GetLineNo();
515 switch (lexrc.lex()) {
517 alignpossible |= LYX_ALIGN_BLOCK;
520 alignpossible |= LYX_ALIGN_LEFT;
523 alignpossible |= LYX_ALIGN_RIGHT;
526 alignpossible |= LYX_ALIGN_CENTER;
529 alignpossible |= LYX_ALIGN_LAYOUT;
532 lexrc.printError("Unknown alignment `$$Token'");
535 } while (lineno == lexrc.GetLineNo());
539 case LT_LABELSTRING: // label string definition
541 labelstring_ = lexrc.GetString();
544 case LT_LABELSTRING_APPENDIX: // label string appendix definition
546 labelstring_appendix_ = lexrc.GetString();
549 case LT_FREE_SPACING: // Allow for free spacing.
551 free_spacing = lexrc.GetInteger();
554 case LT_SPACING: // setspace.sty
555 switch(lexrc.lex()) {
556 case LT_SPACING_SINGLE:
557 spacing.set(Spacing::Single);
559 case LT_SPACING_ONEHALF:
560 spacing.set(Spacing::Onehalf);
562 case LT_SPACING_DOUBLE:
563 spacing.set(Spacing::Double);
567 spacing.set(Spacing::Other, lexrc.GetFloat());
570 lexrc.printError("Unknown spacing `$$Token'");
573 default: /* context error */
574 lexrc.printError("Tag `$$Token' is not "
575 "allowed in layout");
585 /* ******************************************************************* */
587 LyXTextClass::LyXTextClass(string const & fn, string const & cln,
589 : name_(fn), latexname_(cln), description_(desc)
596 pagestyle_ = "default";
597 maxcounter_ = LABEL_COUNTER_CHAPTER;
598 defaultfont_ = LyXFont(LyXFont::ALL_SANE);
599 opt_fontsize_ = "10|11|12";
600 opt_pagestyle_ = "empty|plain|headings|fancy";
606 bool LyXTextClass::do_readStyle(LyXLex & lexrc, LyXLayout & lay)
608 lyxerr[Debug::TCLASS] << "Reading style " << lay.name() << endl;
609 if (!lay.Read(lexrc, *this)) {
611 lay.resfont = lay.font;
612 lay.resfont.realize(defaultfont());
613 lay.reslabelfont = lay.labelfont;
614 lay.reslabelfont.realize(defaultfont());
615 return false; // no errors
617 lyxerr << "Error parsing style `" << lay.name() << "'" << endl;
622 // Reads a textclass structure from file.
623 bool LyXTextClass::Read(string const & filename, bool merge)
626 lyxerr[Debug::TCLASS] << "Reading textclass "
627 << MakeDisplayPath(filename)
630 lyxerr[Debug::TCLASS] << "Reading input file "
631 << MakeDisplayPath(filename)
634 LyXLex lexrc(layoutTags, sizeof(layoutTags)/sizeof(keyword_item));
637 lexrc.setFile(filename);
638 if (!lexrc.IsOK()) error = true;
641 while (lexrc.IsOK() && !error) {
642 switch(lexrc.lex()) {
647 lexrc.printError("Unknown tag `$$Token'");
651 case LT_OUTPUTTYPE: // output type definition
652 switch(lexrc.lex()) {
657 outputType_ = LINUXDOC;
660 outputType_ = DOCBOOK;
663 outputType_ = LITERATE;
666 lexrc.printError("Unknown output type `$$Token'");
671 case LT_INPUT: // Include file
673 string tmp = LibFileSearch("layouts",
677 if (Read(tmp, true)) {
678 lexrc.printError("Error reading input"
687 string name = subst(lexrc.GetString(),
689 if (hasLayout(name)) {
690 LyXLayout & lay = GetLayout(name);
691 error = do_readStyle(lexrc, lay);
695 if (!(error =do_readStyle(lexrc, lay)))
696 layoutlist.push_back(lay);
700 lexrc.printError("No name given for style: `$$Token'.");
707 string style = subst(lexrc.GetString(),
709 if (!delete_layout(style))
710 lexrc.printError("Cannot delete style"
717 columns_ = lexrc.GetInteger();
722 switch(lexrc.GetInteger()) {
723 case 1: sides_ = OneSide; break;
724 case 2: sides_ = TwoSides; break;
726 lyxerr << "Impossible number of page"
727 " sides, setting to one."
737 pagestyle_ = strip(lexrc.GetString());
741 defaultfont_.lyxRead(lexrc);
742 if (!defaultfont_.resolved()) {
743 lexrc.printError("Warning: defaultfont should "
744 "be fully instantiated!");
745 defaultfont_.realize(LyXFont::ALL_SANE);
750 switch (lexrc.lex()) {
751 case LT_COUNTER_CHAPTER:
752 maxcounter_ = LABEL_COUNTER_CHAPTER;
754 case LT_COUNTER_SECTION:
755 maxcounter_ = LABEL_COUNTER_SECTION;
757 case LT_COUNTER_SUBSECTION:
758 maxcounter_ = LABEL_COUNTER_SUBSECTION;
760 case LT_COUNTER_SUBSUBSECTION:
761 maxcounter_ = LABEL_COUNTER_SUBSUBSECTION;
763 case LT_COUNTER_PARAGRAPH:
764 maxcounter_ = LABEL_COUNTER_PARAGRAPH;
766 case LT_COUNTER_SUBPARAGRAPH:
767 maxcounter_ = LABEL_COUNTER_SUBPARAGRAPH;
769 case LT_COUNTER_ENUMI:
770 maxcounter_ = LABEL_COUNTER_ENUMI;
772 case LT_COUNTER_ENUMII:
773 maxcounter_ = LABEL_COUNTER_ENUMII;
775 case LT_COUNTER_ENUMIII:
776 maxcounter_ = LABEL_COUNTER_ENUMIII;
778 case LT_COUNTER_ENUMIV:
779 maxcounter_ = LABEL_COUNTER_ENUMIV;
786 secnumdepth_ = lexrc.GetInteger();
791 tocdepth_ = lexrc.GetInteger();
794 // First step to support options
795 case LT_CLASSOPTIONS:
798 while (getout && lexrc.IsOK()) {
799 switch (lexrc.lex()) {
802 opt_fontsize_ = strip(lexrc.GetString());
806 opt_pagestyle_ = strip(lexrc.GetString());
810 options_ = lexrc.GetString();
812 case LT_END: getout = false; break;
814 lexrc.printError("Out of context tag `$$Token'");
822 preamble_ = lexrc.getLongString("EndPreamble");
825 case LT_PROVIDESAMSMATH:
826 if (lexrc.next() && lexrc.GetInteger())
827 provides_ |= amsmath;
830 case LT_PROVIDESMAKEIDX:
831 if (lexrc.next() && lexrc.GetInteger())
832 provides_ |= makeidx;
836 if (lexrc.next() && lexrc.GetInteger())
840 case LT_LEFTMARGIN: // left margin type
842 leftmargin_ = lexrc.GetString();
845 case LT_RIGHTMARGIN: // right margin type
847 rightmargin_ = lexrc.GetString();
851 lexrc.printError("Out of context tag `$$Token'");
856 if (!merge) { // we are at top level here.
857 lyxerr[Debug::TCLASS] << "Finished reading textclass "
858 << MakeDisplayPath(filename)
861 lyxerr[Debug::TCLASS] << "Finished reading input file "
862 << MakeDisplayPath(filename)
869 bool LyXTextClass::hasLayout(string const & name) const
871 for (LayoutList::const_iterator cit = layoutlist.begin();
872 cit != layoutlist.end(); ++cit) {
873 if ((*cit).name() == name)
880 LyXLayout const & LyXTextClass::GetLayout (string const & name) const
882 for (LayoutList::const_iterator cit = layoutlist.begin();
883 cit != layoutlist.end(); ++cit) {
884 if ((*cit).name() == name)
887 Assert(false); // we actually require the name to exist.
888 return layoutlist.front();
892 LyXLayout & LyXTextClass::GetLayout(string const & name)
894 for (LayoutList::iterator it = layoutlist.begin();
895 it != layoutlist.end(); ++it) {
896 if ((*it).name() == name)
899 Assert(false); // we actually require the name to exist.
900 return layoutlist.front();
904 bool LyXTextClass::delete_layout (string const & name)
906 for(LayoutList::iterator it = layoutlist.begin();
907 it != layoutlist.end(); ++it) {
908 if ((*it).name() == name) {
909 layoutlist.erase(it);
917 // Load textclass info if not loaded yet
918 void LyXTextClass::load()
923 string real_file = LibFileSearch("layouts", name_, "layout");
925 if (Read(real_file)) {
926 lyxerr << "Error reading `"
927 << MakeDisplayPath(real_file)
928 << "'\n(Check `" << name_
929 << "')\nCheck your installation and "
930 "try Options/Reconfigure..." << endl;
936 //////////////////////////////////////////
938 // Gets textclass number from name
939 pair<bool, LyXTextClassList::ClassList::size_type>
940 LyXTextClassList::NumberOfClass(string const & textclass) const
942 for (ClassList::const_iterator cit = classlist.begin();
943 cit != classlist.end(); ++cit) {
944 if ((*cit).name() == textclass)
945 return make_pair(true, cit - classlist.begin());
947 return make_pair(false, 0);
951 // Gets layout structure from style number and textclass number
953 LyXTextClassList::Style(LyXTextClassList::ClassList::size_type textclass,
954 LyXTextClass::LayoutList::size_type layout) const
956 classlist[textclass].load();
957 if (layout < classlist[textclass].numLayouts())
958 return classlist[textclass][layout];
959 return classlist[textclass][0];
963 // Gets layout number from name and textclass number
964 pair<bool, LyXTextClass::LayoutList::size_type>
965 LyXTextClassList::NumberOfLayout(LyXTextClassList::ClassList::size_type textclass, string const & name) const
967 classlist[textclass].load();
968 for(unsigned int i = 0; i < classlist[textclass].numLayouts(); ++i) {
969 if (classlist[textclass][i].name() == name)
970 return make_pair(true, i);
973 return make_pair(true, LYX_DUMMY_LAYOUT);
974 return make_pair(false, 0); // not found
978 // Gets a layout (style) name from layout number and textclass number
980 LyXTextClassList::NameOfLayout(LyXTextClassList::ClassList::size_type textclass,
981 LyXTextClass::LayoutList::size_type layout) const
983 static string dummy("dummy");
984 static string end("@@end@@");
985 classlist[textclass].load();
986 if (layout < classlist[textclass].numLayouts())
987 return classlist[textclass][layout].name();
988 else if (layout == LYX_DUMMY_LAYOUT)
995 // Gets a textclass name from number
997 LyXTextClassList::NameOfClass(LyXTextClassList::ClassList::size_type number) const
999 static string dummy("dummy");
1000 static string end("@@end@@");
1001 if (classlist.size() == 0) {
1002 if (number == 0) return dummy;
1005 if (number < classlist.size())
1006 return classlist[number].name();
1012 // Gets a textclass latexname from number
1014 LyXTextClassList::LatexnameOfClass(LyXTextClassList::ClassList::size_type number) const
1016 static string dummy("dummy");
1017 static string end("@@end@@");
1018 classlist[number].load();
1019 if (classlist.size() == 0) {
1020 if (number == 0) return dummy;
1023 if (number < classlist.size())
1024 return classlist[number].latexname();
1030 // Gets a textclass description from number
1032 LyXTextClassList::DescOfClass(LyXTextClassList::ClassList::size_type number) const
1034 static string dummy("dummy");
1035 static string end("@@end@@");
1036 if (classlist.size() == 0) {
1037 if (number == 0) return dummy;
1040 if (number < classlist.size())
1041 return classlist[number].description();
1047 // Gets a textclass structure from number
1048 LyXTextClass const &
1049 LyXTextClassList::TextClass(LyXTextClassList::ClassList::size_type textclass) const
1051 classlist[textclass].load();
1052 if (textclass < classlist.size())
1053 return classlist[textclass];
1055 return classlist[0];
1059 void LyXTextClassList::Add(LyXTextClass const & t)
1061 classlist.push_back(t);
1065 // used when sorting the textclass list.
1066 class less_textclass_desc {
1068 int operator()(LyXTextClass const & tc1, LyXTextClass const & tc2) {
1069 return tc1.description() < tc2.description();
1074 // Reads LyX textclass definitions according to textclass config file
1075 bool LyXTextClassList::Read ()
1078 string real_file = LibFileSearch("", "textclass.lst");
1079 lyxerr[Debug::TCLASS] << "Reading textclasses from "
1080 << real_file << endl;
1082 if (real_file.empty()) {
1083 lyxerr << "LyXTextClassList::Read: unable to find "
1084 "textclass file `" << MakeDisplayPath(real_file, 1000)
1085 << "'. Exiting." << endl;
1087 WriteAlert(_("LyX wasn't able to find its layout descriptions!"),
1088 _("Check that the file \"textclass.lst\""),
1089 _("is installed correctly. Sorry, has to exit :-("));
1091 // This causes LyX to end... Not a desirable behaviour. Lgb
1092 // What do you propose? That the user gets a file dialog
1093 // and is allowed to hunt for the file? (Asger)
1096 lex.setFile(real_file);
1099 lyxerr << "LyXTextClassList::Read: unable to open "
1100 "textclass file `" << MakeDisplayPath(real_file, 1000)
1101 << "\'\nCheck your installation. LyX can't continue."
1105 bool finished = false;
1106 string fname, clname, desc;
1107 // Parse config-file
1108 while (lex.IsOK() && !finished) {
1109 switch (lex.lex()) {
1110 case LyXLex::LEX_FEOF:
1114 fname = lex.GetString();
1115 lyxerr[Debug::TCLASS] << "Fname: " << fname << endl;
1117 clname = lex.GetString();
1118 lyxerr[Debug::TCLASS]
1119 << "Clname: " << clname << endl;
1121 desc = lex.GetString();
1122 lyxerr[Debug::TCLASS]
1123 << "Desc: " << desc << endl;
1124 // This code is run when we have
1125 // fname, clname and desc
1126 LyXTextClass tmpl(fname,
1130 debugging(Debug::TCLASS)) {
1139 if (classlist.size() == 0) {
1140 lyxerr << "LyXTextClassList::Read: no textclass found!"
1142 WriteAlert(_("LyX wasn't able to find any layout description!"),
1143 _("Check the contents of the file \"textclass.lst\""),
1144 _("Sorry, has to exit :-("));
1147 // Ok everything loaded ok, now sort the list.
1148 sort(classlist.begin(), classlist.end(), less_textclass_desc());
1154 Returns false if this fails
1157 LyXTextClassList::Load (LyXTextClassList::ClassList::size_type number) const
1160 if (number < classlist.size()) {
1161 classlist[number].load();
1162 if (classlist[number].numLayouts() == 0) {