1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright (C) 1995 Matthias Ettrich
7 * Copyright (C) 1995-1998 The LyX Team.
9 *======================================================*/
13 * 14/11/1995, Pascal André <andre@via.ecp.fr>
14 * Modified for external style definition.
16 * 15/11/1995, Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
17 * Modified to use binary search and a small pseudo lexical analyzer.
19 * 29/03/1996, Dirk Niggeman
20 * Created classes LyXTextClass & LyXLayout.
23 * Created class LyxLex and improved the lexical analyzer.
29 #pragma implementation
32 #include "definitions.h"
36 #include "filetools.h"
37 #include "lyx_gui_misc.h"
41 // $Id: layout.C,v 1.1 1999/09/27 18:44:37 larsbj Exp $
43 #if !defined(lint) && !defined(WITH_WARNINGS)
44 static char vcid[] = "$Id: layout.C,v 1.1 1999/09/27 18:44:37 larsbj Exp $";
47 /* Global variable: textclass table */
48 LyXTextClassList lyxstyle;
50 // Reads the style files
53 lyxerr.debug("LyXSetStyle: parsing configuration...");
55 if (!lyxstyle.Read()) {
56 lyxerr.print("LyXSetStyle: an error occured during parsing.");
57 lyxerr.print(" Exiting.");
61 lyxerr.debug("LyXSetStyle: configuration parsed.");
65 // The order of the LayoutTags enum is no more important. [asierra300396]
68 LT_ALIGN, LT_ALIGNPOSSIBLE,
70 LT_BOTTOMSEP, LT_CENTER, LT_CENTERED_TOP_ENVIRONMENT, LT_COLUMNS,
71 LT_COPYSTYLE, LT_OBSOLETEDBY,
72 LT_COMMAND, LT_COUNTER_CHAPTER, LT_COUNTER_ENUMI, LT_COUNTER_ENUMII,
73 LT_COUNTER_ENUMIII, LT_COUNTER_ENUMIV, LT_COUNTER_PARAGRAPH,
74 LT_COUNTER_SECTION, LT_COUNTER_SUBPARAGRAPH, LT_COUNTER_SUBSECTION,
75 LT_COUNTER_SUBSUBSECTION, LT_DEFAULTFONT, LT_DYNAMIC, LT_EMPTY,
76 LT_END, LT_ENVIRONMENT, LT_ENVIRONMENT_DEFAULT,
77 LT_FANCYHDR, LT_FILL_BOTTOM, LT_FILL_TOP, LT_FIRST_COUNTER,
78 LT_FIRST_DYNAMIC, LT_FONT, LT_FREE_SPACING, LT_HEADINGS, LT_INPUT,
79 LT_ITEM_ENVIRONMENT, LT_ITEMSEP, LT_KEEPEMPTY,
80 LT_LABEL_BOTTOMSEP, LT_LABELFONT, LT_TEXTFONT,
81 LT_LABELINDENT, LT_LABELSEP, LT_LABELSTRING,
82 LT_LABELSTRING_APPENDIX, LT_LABELTYPE,
83 LT_LATEXNAME, LT_LATEXPARAM, LT_LATEXTYPE, LT_LAYOUT, LT_LEFT,
85 LT_LIST_ENVIRONMENT , LT_MANUAL, LT_MAXCOUNTER,
86 LT_NEED_PROTECT, LT_NEWLINE,
87 LT_NEXTNOINDENT, LT_NO_LABEL, LT_NOSTYLE,
88 LT_PAGESTYLE, LT_PARAGRAPH,
89 LT_PARINDENT, LT_PARSEP, LT_PARSKIP, LT_PLAIN, LT_PREAMBLE,
90 LT_PROVIDESAMSMATH, LT_PROVIDESMAKEIDX, LT_PROVIDESURL, LT_RIGHT,
91 LT_RIGHT_ADDRESS_BOX, LT_RIGHTMARGIN, LT_SENSITIVE, LT_SIDES,
92 LT_SPACING, LT_SPACING_SINGLE, LT_SPACING_ONEHALF,
93 LT_SPACING_DOUBLE, LT_OTHER, LT_CLASSOPTIONS, LT_FONTSIZE,
94 LT_STATIC, LT_STYLE, LT_TOP_ENVIRONMENT, LT_TOPSEP, LT_BIBLIO,
95 LT_INTITLE, LT_SECNUMDEPTH, LT_TOCDEPTH,
96 LT_OUTPUTTYPE, LT_OTLATEX, LT_OTLINUXDOC, LT_OTDOCBOOK, LT_OTLITERATE
100 // This table is sorted alphabetically [asierra 30March96]
101 static keyword_item layoutTags[] = {
102 { "align", LT_ALIGN },
103 { "alignpossible", LT_ALIGNPOSSIBLE },
104 { "bibliography", LT_BIBLIO },
105 { "block", LT_BLOCK },
106 { "bottomsep", LT_BOTTOMSEP },
107 { "center", LT_CENTER },
108 { "centered_top_environment", LT_CENTERED_TOP_ENVIRONMENT },
109 { "classoptions", LT_CLASSOPTIONS },
110 { "columns", LT_COLUMNS },
111 { "command", LT_COMMAND },
112 { "copystyle", LT_COPYSTYLE },
113 { "counter_chapter", LT_COUNTER_CHAPTER },
114 { "counter_enumi", LT_COUNTER_ENUMI },
115 { "counter_enumii", LT_COUNTER_ENUMII },
116 { "counter_enumiii", LT_COUNTER_ENUMIII },
117 { "counter_enumiv", LT_COUNTER_ENUMIV },
118 { "counter_paragraph", LT_COUNTER_PARAGRAPH },
119 { "counter_section", LT_COUNTER_SECTION },
120 { "counter_subparagraph", LT_COUNTER_SUBPARAGRAPH },
121 { "counter_subsection", LT_COUNTER_SUBSECTION },
122 { "counter_subsubsection", LT_COUNTER_SUBSUBSECTION },
123 { "defaultfont", LT_DEFAULTFONT },
124 { "docbook", LT_OTDOCBOOK },
125 { "double", LT_SPACING_DOUBLE },
126 { "dynamic", LT_DYNAMIC },
127 { "empty", LT_EMPTY },
129 { "environment", LT_ENVIRONMENT },
130 { "environment_default", LT_ENVIRONMENT_DEFAULT },
131 { "fancyhdr", LT_FANCYHDR },
132 { "fill_bottom", LT_FILL_BOTTOM },
133 { "fill_top", LT_FILL_TOP },
134 { "first_counter", LT_FIRST_COUNTER },
135 { "first_dynamic", LT_FIRST_DYNAMIC },
137 { "fontsize", LT_FONTSIZE },
138 { "freespacing", LT_FREE_SPACING },
139 { "headings", LT_HEADINGS },
140 { "input", LT_INPUT },
141 { "intitle", LT_INTITLE },
142 { "item_environment", LT_ITEM_ENVIRONMENT },
143 { "itemsep", LT_ITEMSEP },
144 { "keepempty", LT_KEEPEMPTY },
145 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
146 { "labelfont", LT_LABELFONT },
147 { "labelindent", LT_LABELINDENT },
148 { "labelsep", LT_LABELSEP },
149 { "labelstring", LT_LABELSTRING },
150 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
151 { "labeltype", LT_LABELTYPE },
152 { "latex", LT_OTLATEX },
153 { "latexname", LT_LATEXNAME },
154 { "latexparam", LT_LATEXPARAM }, //arrae970411
155 { "latextype", LT_LATEXTYPE },
156 { "layout", LT_LAYOUT },
158 { "leftmargin", LT_LEFTMARGIN },
159 { "linuxdoc", LT_OTLINUXDOC },
160 { "list_environment", LT_LIST_ENVIRONMENT },
161 { "literate", LT_OTLITERATE },
162 { "manual", LT_MANUAL },
163 { "margin", LT_MARGIN },
164 { "maxcounter", LT_MAXCOUNTER },
165 { "needprotect", LT_NEED_PROTECT },
166 { "newline", LT_NEWLINE },
167 { "nextnoindent", LT_NEXTNOINDENT },
168 { "no_label", LT_NO_LABEL },
169 { "nostyle", LT_NOSTYLE },
170 { "obsoletedby", LT_OBSOLETEDBY },
171 { "onehalf", LT_SPACING_ONEHALF },
172 { "other", LT_OTHER },
173 { "outputtype", LT_OUTPUTTYPE },
174 { "pagestyle", LT_PAGESTYLE },
175 { "paragraph", LT_PARAGRAPH },
176 { "parindent", LT_PARINDENT },
177 { "parsep", LT_PARSEP },
178 { "parskip", LT_PARSKIP },
179 { "plain", LT_PLAIN },
180 { "preamble", LT_PREAMBLE },
181 { "providesamsmath", LT_PROVIDESAMSMATH },
182 { "providesmakeidx", LT_PROVIDESMAKEIDX },
183 { "providesurl", LT_PROVIDESURL },
184 { "right", LT_RIGHT },
185 { "right_address_box", LT_RIGHT_ADDRESS_BOX },
186 { "rightmargin", LT_RIGHTMARGIN },
187 { "secnumdepth", LT_SECNUMDEPTH },
188 { "sensitive", LT_SENSITIVE },
189 { "sides", LT_SIDES },
190 { "single", LT_SPACING_SINGLE },
191 { "spacing", LT_SPACING },
192 { "static", LT_STATIC },
193 { "style", LT_STYLE },
194 { "textfont", LT_TEXTFONT },
195 { "tocdepth", LT_TOCDEPTH },
196 { "top_environment", LT_TOP_ENVIRONMENT },
197 { "topsep", LT_TOPSEP }
201 /* ******************************************************************* */
203 // Constructor for layout
204 LyXLayout::LyXLayout ()
206 margintype = MARGIN_STATIC;
207 latextype = LATEX_PARAGRAPH;
211 font = LyXFont(LyXFont::ALL_INHERIT);
212 labelfont = LyXFont(LyXFont::ALL_INHERIT);
213 resfont = LyXFont(LyXFont::ALL_SANE);
214 reslabelfont = LyXFont(LyXFont::ALL_SANE);
215 nextnoindent = false;
220 labelbottomsep = 0.0;
222 align = LYX_ALIGN_BLOCK;
223 alignpossible = LYX_ALIGN_BLOCK;
224 labeltype = LABEL_NO_LABEL;
225 // Should or should not. That is the question.
226 // spacing.set(Spacing::OneHalf);
229 newline_allowed = true;
230 free_spacing = false;
234 LyXLayout::~LyXLayout ()
239 void LyXLayout::Copy (LyXLayout const &l)
242 obsoleted_by = l.obsoleted_by;
243 margintype = l.margintype;
244 latextype = l.latextype;
246 needprotect = l.needprotect;
247 keepempty = l.keepempty;
248 latexname = l.latexname;
249 latexparam = l.latexparam; //arrae970411
250 preamble = l.preamble;
252 labelfont = l.labelfont;
254 reslabelfont = l.reslabelfont;
255 nextnoindent = l.nextnoindent;
256 leftmargin = l.leftmargin;
257 rightmargin = l.rightmargin;
258 labelsep = l.labelsep;
259 labelindent = l.labelindent;
260 parindent = l.parindent;
264 bottomsep = l.bottomsep;
265 labelbottomsep = l.labelbottomsep;
268 alignpossible = l.alignpossible;
269 labeltype = l.labeltype;
271 labelstring = l.labelstring;
272 labelstring_appendix = l.labelstring_appendix;
273 fill_top = l.fill_top;
274 fill_bottom = l.fill_bottom;
275 newline_allowed = l.newline_allowed;
276 free_spacing = l.free_spacing;
280 /* Reads a layout definition from file */
281 bool LyXLayout::Read (LyXLex & lexrc, LyXLayoutList * list)
284 bool finished = false;
286 /* parse style section */
287 while (!finished && lexrc.IsOK() && !error) {
288 switch(lexrc.lex()) {
293 case -1: /* parse error */
294 lexrc.printError("Unknown tag `$$Token'");
298 case LT_END: /* end of structure */
302 case LT_COPYSTYLE: // initialize with a known style
304 LyXLayout * layout = list->GetLayout(lexrc.GetString());
306 LString tmpname = name;
310 lexrc.printError("Cannot copy unknown "
316 case LT_OBSOLETEDBY: // replace with a known style
318 LyXLayout * layout = list->GetLayout(lexrc.GetString());
320 LString tmpname = name;
323 if (obsoleted_by.empty())
324 obsoleted_by = lexrc.GetString();
326 lexrc.printError("Cannot replace with"
333 case LT_MARGIN: /* margin style definition */
335 switch(lexrc.lex()) {
337 margintype = MARGIN_STATIC;
340 margintype = MARGIN_MANUAL;
343 margintype = MARGIN_DYNAMIC;
345 case LT_FIRST_DYNAMIC:
346 margintype = MARGIN_FIRST_DYNAMIC;
348 case LT_RIGHT_ADDRESS_BOX:
349 margintype = MARGIN_RIGHT_ADDRESS_BOX;
352 lexrc.printError("Unknown margin type `$$Token'");
357 case LT_LATEXTYPE: /* latex style definition */
358 switch (lexrc.lex()) {
360 latextype=LATEX_PARAGRAPH;
363 latextype=LATEX_COMMAND;
366 latextype=LATEX_ENVIRONMENT;
368 case LT_ITEM_ENVIRONMENT:
369 latextype=LATEX_ITEM_ENVIRONMENT;
371 case LT_LIST_ENVIRONMENT:
372 latextype=LATEX_LIST_ENVIRONMENT;
375 lexrc.printError("Unknown latextype `$$Token'");
381 intitle = lexrc.next() && lexrc.GetInteger();
384 case LT_NEED_PROTECT:
385 needprotect = lexrc.next() && lexrc.GetInteger();
389 keepempty = lexrc.next() && lexrc.GetInteger();
402 labelfont.lyxRead(lexrc);
405 case LT_NEXTNOINDENT: /* indent next paragraph ? */
406 if (lexrc.next() && lexrc.GetInteger())
409 nextnoindent = false;
412 case LT_LATEXNAME: /* latex name */
414 latexname = lexrc.GetString();
418 case LT_LATEXPARAM: /* latex parameter */
420 latexparam = lexrc.GetString();
424 preamble = lexrc.getLongString("EndPreamble");
427 case LT_LABELTYPE: /* label type */
428 switch (lexrc.lex()) {
430 labeltype = LABEL_NO_LABEL;
433 labeltype = LABEL_MANUAL;
435 case LT_TOP_ENVIRONMENT:
436 labeltype = LABEL_TOP_ENVIRONMENT;
438 case LT_CENTERED_TOP_ENVIRONMENT:
439 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
442 labeltype = LABEL_STATIC;
445 labeltype = LABEL_SENSITIVE;
447 case LT_COUNTER_CHAPTER:
448 labeltype = LABEL_COUNTER_CHAPTER;
450 case LT_COUNTER_SECTION:
451 labeltype = LABEL_COUNTER_SECTION;
453 case LT_COUNTER_SUBSECTION:
454 labeltype = LABEL_COUNTER_SUBSECTION;
456 case LT_COUNTER_SUBSUBSECTION:
457 labeltype = LABEL_COUNTER_SUBSUBSECTION;
459 case LT_COUNTER_PARAGRAPH:
460 labeltype = LABEL_COUNTER_PARAGRAPH;
462 case LT_COUNTER_SUBPARAGRAPH:
463 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
465 case LT_COUNTER_ENUMI:
466 labeltype = LABEL_COUNTER_ENUMI;
468 case LT_COUNTER_ENUMII:
469 labeltype = LABEL_COUNTER_ENUMII;
471 case LT_COUNTER_ENUMIII:
472 labeltype = LABEL_COUNTER_ENUMIII;
474 case LT_COUNTER_ENUMIV:
475 labeltype = LABEL_COUNTER_ENUMIV;
478 labeltype = LABEL_BIBLIO;
481 lexrc.printError("Unknown labeltype `$$Token'");
485 case LT_LEFTMARGIN: /* left margin type */
487 leftmargin = lexrc.GetString();
490 case LT_RIGHTMARGIN: /* right margin type */
492 rightmargin = lexrc.GetString();
495 case LT_LABELINDENT: /* label indenting flag */
497 labelindent = lexrc.GetString();
500 case LT_PARINDENT: /* paragraph indent. flag */
502 parindent = lexrc.GetString();
505 case LT_PARSKIP: /* paragraph skip size */
507 parskip = lexrc.GetFloat();
510 case LT_ITEMSEP: /* item separation size */
512 itemsep = lexrc.GetFloat();
515 case LT_TOPSEP: /* top separation size */
517 topsep = lexrc.GetFloat();
520 case LT_BOTTOMSEP: /* bottom separation size */
522 bottomsep = lexrc.GetFloat();
525 case LT_LABEL_BOTTOMSEP:/* label bottom separation size */
527 labelbottomsep = lexrc.GetFloat();
530 case LT_LABELSEP: /* label separator */
532 labelsep = lexrc.GetString();
533 labelsep.subst('x', ' ');
537 case LT_PARSEP: /* par. separation size */
539 parsep = lexrc.GetFloat();
542 case LT_FILL_TOP: /* fill top flag */
544 fill_top = lexrc.GetInteger();
547 case LT_FILL_BOTTOM: /* fill bottom flag */
549 fill_bottom = lexrc.GetInteger();
552 case LT_NEWLINE: /* newlines allowed ? */
554 newline_allowed = lexrc.GetInteger();
557 case LT_ALIGN: /* paragraph align */
558 switch (lexrc.lex()) {
560 align = LYX_ALIGN_BLOCK;
563 align = LYX_ALIGN_LEFT;
566 align = LYX_ALIGN_RIGHT;
569 align = LYX_ALIGN_CENTER;
572 align = LYX_ALIGN_LAYOUT;
575 lexrc.printError("Unknown alignment `$$Token'");
579 case LT_ALIGNPOSSIBLE: /* paragraph allowed align */
582 int lineno = lexrc.GetLineNo();
584 switch (lexrc.lex()) {
586 alignpossible |= LYX_ALIGN_BLOCK;
589 alignpossible |= LYX_ALIGN_LEFT;
592 alignpossible |= LYX_ALIGN_RIGHT;
595 alignpossible |= LYX_ALIGN_CENTER;
598 alignpossible |= LYX_ALIGN_LAYOUT;
601 lexrc.printError("Unknown alignment `$$Token'");
604 } while (lineno==lexrc.GetLineNo());
608 case LT_LABELSTRING: /* label string definition */
610 labelstring = lexrc.GetString();
613 case LT_LABELSTRING_APPENDIX: /* label string appendix definition */
615 labelstring_appendix = lexrc.GetString();
618 case LT_FREE_SPACING: /* Allow for free spacing. */
620 free_spacing = lexrc.GetInteger();
623 case LT_SPACING: // setspace.sty
624 switch(lexrc.lex()) {
625 case LT_SPACING_SINGLE:
626 spacing.set(Spacing::Single);
627 //spacing_value = 1.0;
629 case LT_SPACING_ONEHALF:
630 spacing.set(Spacing::Onehalf);
631 //spacing_value = 1.25;
633 case LT_SPACING_DOUBLE:
634 spacing.set(Spacing::Double);
635 //spacing_value = 1.667;
639 spacing.set(Spacing::Other, lexrc.GetFloat());
642 lexrc.printError("Unknown spacing `$$Token'");
645 default: /* context error */
646 lexrc.printError("Tag `$$Token' is not "
647 "allowed in layout");
656 /* ******************************************************************* */
658 LyXLayoutList::LyXLayoutList()
666 LyXLayoutList::~LyXLayoutList()
668 //don't do anything. the layouts will be extracted by ToAr.
669 //destruction is done by Clean in emergencies
673 int LyXLayoutList::GetNum ()
679 void LyXLayoutList::Add (LyXLayout *lay)
681 LyXLayoutL * tmp = new LyXLayoutL;
685 else eol->next = tmp;
691 bool LyXLayoutList::Delete (LString const &name)
693 LyXLayoutL * layoutl = l;
695 if (layoutl->layout && layoutl->layout->name == name) {
696 delete layoutl->layout;
697 layoutl->layout = NULL; // not sure it is necessary
701 layoutl = layoutl->next;
707 LyXLayout * LyXLayoutList::GetLayout (LString const &name)
709 LyXLayoutL * layoutl = l;
711 if (layoutl->layout && layoutl->layout->name == name)
712 return layoutl->layout;
713 layoutl = layoutl->next;
719 LyXLayout * LyXLayoutList::ToAr ()
721 LyXLayoutL * lp, * op;
723 LyXLayout* ar = new LyXLayout [num_layouts];
727 ar[idx].Copy (*lp->layout);
739 //wipe up any dead layouts
740 void LyXLayoutList::Clean ()
742 LyXLayoutL * lp, * op;
752 /* ******************************************************************* */
754 LyXTextClass::LyXTextClass(LString const &fn, LString const &cln,
766 pagestyle = "default";
767 maxcounter = LABEL_COUNTER_CHAPTER;
768 defaultfont = LyXFont(LyXFont::ALL_SANE);
769 number_of_defined_layouts = 0;
770 opt_fontsize = "10|11|12";
771 opt_pagestyle = "empty|plain|headings|fancy";
772 provides_amsmath = false;
773 provides_makeidx = false;
774 provides_url = false;
779 // This is not a proper copy.
780 // It just references the style rather than copying it!
781 void LyXTextClass::Copy (LyXTextClass const &l)
784 latexname = l.latexname;
785 description = l.description;
786 output_type = l.output_type;
787 preamble = l.preamble;
789 if (style) delete style;
790 style = l.style; //just aliases NO COPY
791 number_of_defined_layouts = l.number_of_defined_layouts;
794 secnumdepth = l.secnumdepth;
795 tocdepth = l.tocdepth;
796 pagestyle = l.pagestyle;
797 maxcounter = l.maxcounter;
798 defaultfont = l.defaultfont;
799 opt_fontsize = l.opt_fontsize;
800 opt_pagestyle = l.opt_pagestyle;
801 provides_amsmath = l.provides_amsmath;
802 provides_makeidx = l.provides_makeidx;
803 provides_url = l.provides_url;
806 leftmargin = l.leftmargin;
807 rightmargin = l.rightmargin;
812 LyXTextClass::~LyXTextClass()
814 //we can't delete the style here because otherwise
815 //our list classes wouldn't work
819 /* Reads a textclass structure from file */
820 int LyXTextClass::Read (LString const &filename, LyXLayoutList *list)
823 lyxerr.debug("Reading textclass "
824 + MakeDisplayPath(filename), Error::TCLASS);
826 lyxerr.debug("Reading input file "
827 + MakeDisplayPath(filename), Error::TCLASS);
829 LyXLex lexrc(layoutTags, sizeof(layoutTags)/sizeof(keyword_item));
832 lexrc.setFile(filename);
833 if (!lexrc.IsOK()) return -2;
841 l = new LyXLayoutList;
844 while (lexrc.IsOK() && !error) {
845 switch(lexrc.lex()) {
850 lexrc.printError("Unknown tag `$$Token'");
854 case LT_OUTPUTTYPE: // output type definition
855 switch(lexrc.lex()) {
860 output_type=LINUXDOC;
866 output_type=LITERATE;
869 lexrc.printError("Unknown output type `$$Token'");
874 case LT_INPUT: // Include file
876 LString tmp = LibFileSearch("layouts",
881 lexrc.printError("Error reading input"
890 LString name = lexrc.GetString();
894 tmpl = l->GetLayout(name);
897 tmpl = new LyXLayout;
901 lyxerr.debug(" Reading style "+tmpl->name, Error::TCLASS);
903 if (!tmpl->Read(lexrc, l)) {
905 tmpl->resfont = tmpl->font;
906 tmpl->resfont.realize(defaultfont);
907 tmpl->reslabelfont = tmpl->labelfont;
908 tmpl->reslabelfont.realize(defaultfont);
911 // NB! we don't delete because
912 // we just pass it in....
916 "Error parsing style `"
921 //we delete dead ones here
926 lexrc.printError("No name given for style: `$$Token'.");
933 LString style = lexrc.GetString();
934 if (!l->Delete(style.subst('_', ' ')))
935 lexrc.printError("Cannot delete style `$$Token'");
941 columns = lexrc.GetInteger();
946 sides = lexrc.GetInteger();
951 pagestyle = lexrc.GetString();
956 defaultfont.lyxRead(lexrc);
957 if (!defaultfont.resolved()) {
958 lexrc.printError("Warning: defaultfont should "
959 "be fully instantiated!");
960 defaultfont.realize(LyXFont::ALL_SANE);
965 switch (lexrc.lex()) {
966 case LT_COUNTER_CHAPTER:
967 maxcounter = LABEL_COUNTER_CHAPTER;
969 case LT_COUNTER_SECTION:
970 maxcounter = LABEL_COUNTER_SECTION;
972 case LT_COUNTER_SUBSECTION:
973 maxcounter = LABEL_COUNTER_SUBSECTION;
975 case LT_COUNTER_SUBSUBSECTION:
976 maxcounter = LABEL_COUNTER_SUBSUBSECTION;
978 case LT_COUNTER_PARAGRAPH:
979 maxcounter = LABEL_COUNTER_PARAGRAPH;
981 case LT_COUNTER_SUBPARAGRAPH:
982 maxcounter = LABEL_COUNTER_SUBPARAGRAPH;
984 case LT_COUNTER_ENUMI:
985 maxcounter = LABEL_COUNTER_ENUMI;
987 case LT_COUNTER_ENUMII:
988 maxcounter = LABEL_COUNTER_ENUMII;
990 case LT_COUNTER_ENUMIII:
991 maxcounter = LABEL_COUNTER_ENUMIII;
993 case LT_COUNTER_ENUMIV:
994 maxcounter = LABEL_COUNTER_ENUMIV;
1001 secnumdepth = lexrc.GetInteger();
1006 tocdepth = lexrc.GetInteger();
1009 // First step to support options
1010 case LT_CLASSOPTIONS:
1013 while (getout && lexrc.IsOK()) {
1014 switch (lexrc.lex()) {
1017 opt_fontsize = lexrc.GetString();
1018 opt_fontsize.strip();
1022 opt_pagestyle = lexrc.GetString();
1023 opt_pagestyle.strip();
1027 options = lexrc.GetString();
1029 case LT_END: getout = false; break;
1031 lexrc.printError("Out of context tag `$$Token'");
1039 preamble = lexrc.getLongString("EndPreamble");
1042 case LT_PROVIDESAMSMATH:
1044 provides_amsmath = lexrc.GetInteger();
1047 case LT_PROVIDESMAKEIDX:
1049 provides_makeidx = lexrc.GetInteger();
1052 case LT_PROVIDESURL:
1054 provides_url = lexrc.GetInteger();
1057 case LT_LEFTMARGIN: /* left margin type */
1059 leftmargin = lexrc.GetString();
1062 case LT_RIGHTMARGIN: /* right margin type */
1064 rightmargin = lexrc.GetString();
1068 lexrc.printError("Out of context tag `$$Token'");
1073 if (!list) { // we are at top level here.
1075 number_of_defined_layouts = 0;
1076 l->Clean(); //wipe any we may have found
1081 number_of_defined_layouts = l->GetNum();
1084 lyxerr.debug("Finished reading textclass "
1085 + MakeDisplayPath(filename), Error::TCLASS);
1088 lyxerr.debug("Finished reading input file "
1089 + MakeDisplayPath(filename), Error::TCLASS);
1095 // Load textclass info if not loaded yet
1096 void LyXTextClass::load()
1102 LString real_file = LibFileSearch("layouts", name, "layout");
1104 if (Read(real_file)) {
1105 lyxerr.print("Error reading `"
1106 + MakeDisplayPath(real_file) + '\'');
1107 lyxerr.print("(Check `" + name + "')");
1108 lyxerr.print("Check your installation and "
1109 "try Options/Reconfigure...");
1114 /* ******************************************************************* */
1116 LyXTextClassList::LyXTextClassList()
1124 LyXTextClassList::~LyXTextClassList()
1126 // The textclass list is in ar.
1133 // Gets textclass number from name
1134 signed char LyXTextClassList::NumberOfClass(LString const &textclass)
1138 while (i < num_textclass && textclass != ar[i].name)
1141 if (i >= num_textclass)
1148 // Gets layout structure from style number and textclass number
1149 LyXLayout *LyXTextClassList::Style(char textclass, char layout)
1151 ar[textclass].load();
1153 if (layout < ar[textclass].number_of_defined_layouts)
1154 return &ar[textclass].style[layout];
1156 return &ar[textclass].style[0];
1161 // Gets layout number from name and textclass number
1162 char LyXTextClassList::NumberOfLayout(char textclass, LString const &name)
1164 ar[textclass].load();
1167 while (i < ar[textclass].number_of_defined_layouts
1168 && name != ar[textclass].style[i].name)
1171 if (i >= ar[textclass].number_of_defined_layouts) {
1172 if (name == "dummy")
1173 i = LYX_DUMMY_LAYOUT;
1175 // so that we can detect if the layout doesn't exist.
1176 i = -1; // not found
1182 // Gets a layout (style) name from layout number and textclass number
1183 LString LyXTextClassList::NameOfLayout(char textclass, char layout)
1185 ar[textclass].load();
1187 if (layout < ar[textclass].number_of_defined_layouts)
1188 return ar[textclass].style[layout].name;
1189 else if (layout == LYX_DUMMY_LAYOUT)
1196 // Gets a textclass name from number
1197 LString LyXTextClassList::NameOfClass(char number)
1199 if (num_textclass == 0) {
1200 if (number == 0) return "dummy";
1201 else return "@@end@@";
1203 if (number < num_textclass)
1204 return ar[number].name;
1209 // Gets a textclass latexname from number
1210 LString LyXTextClassList::LatexnameOfClass(char number)
1214 if (num_textclass == 0) {
1215 if (number == 0) return "dummy";
1216 else return "@@end@@";
1218 if (number < num_textclass)
1219 return ar[number].latexname;
1224 // Gets a textclass description from number
1225 LString LyXTextClassList::DescOfClass(char number)
1227 if (num_textclass == 0) {
1228 if (number == 0) return "dummy";
1229 else return "@@end@@";
1231 if (number < num_textclass)
1232 return ar[number].description;
1238 // Gets a textclass structure from number
1239 LyXTextClass * LyXTextClassList::TextClass(char textclass)
1241 ar[textclass].load();
1242 if (textclass < num_textclass)
1243 return &ar[textclass];
1249 void LyXTextClassList::Add (LyXTextClass *t)
1251 LyXTextClassL ** h = &l;
1252 char const *desc = t->description.c_str();
1253 while (*h && strcasecmp((*h)->textclass->description.c_str(),desc)<0)
1255 LyXTextClassL * tmp = new LyXTextClassL;
1263 void LyXTextClassList::ToAr ()
1265 LyXTextClassL * lp, *op;
1267 ar = new LyXTextClass [num_textclass];
1270 ar[idx].Copy (*lp->textclass);
1272 delete lp->textclass; // note we don't delete layouts
1281 // Reads LyX textclass definitions according to textclass config file
1282 bool LyXTextClassList::Read ()
1284 LyXLex lex(NULL, 0);
1285 LString real_file = LibFileSearch("", "textclass.lst");
1286 lyxerr.debug("Reading textclasses from "+real_file,Error::TCLASS);
1288 if (real_file.empty()) {
1289 lyxerr.print("LyXTextClassList::Read: unable to find "
1290 "textclass file `" +
1291 MakeDisplayPath(real_file, 1000) + "'. Exiting.");
1293 WriteAlert(_("LyX wasn't able to find its layout descriptions!"),
1294 _("Check that the file \"textclass.lst\""),
1295 _("is installed correctly. Sorry, has to exit :-("));
1297 // This causes LyX to end... Not a desirable behaviour. Lgb
1298 // What do you propose? That the user gets a file dialog
1299 // and is allowed to hunt for the file? (Asger)
1302 lex.setFile(real_file);
1305 lyxerr.print("LyXTextClassList::Read: unable to open "
1306 "textclass file `" +
1307 MakeDisplayPath(real_file, 1000) + '\'');
1308 lyxerr.print("Check your installation. LyX can't continue.");
1311 bool finished = false;
1312 LString fname, clname, desc;
1313 LyXTextClass * tmpl;
1315 // Parse config-file
1316 while (lex.IsOK() && !finished) {
1317 switch (lex.lex()) {
1318 case LyXLex::LEX_FEOF:
1322 fname = lex.GetString();
1323 lyxerr.debug("Fname: " + fname, Error::TCLASS);
1325 clname = lex.GetString();
1326 lyxerr.debug("Clname: " + clname,
1329 desc = lex.GetString();
1330 lyxerr.debug("Desc: " + desc,
1332 // This code is run when we have
1333 // fname, clname and desc
1334 tmpl =new LyXTextClass(fname,
1339 debugging(Error::TCLASS)) {
1347 if (num_textclass == 0) {
1348 lyxerr.print("LyXTextClassList::Read: no textclass found!");
1349 WriteAlert(_("LyX wasn't able to find any layout description!"),
1350 _("Check the contents of the file \"textclass.lst\""),
1351 _("Sorry, has to exit :-("));
1361 /* Returns false if this fails */
1362 bool LyXTextClassList::Load (char const number)
1366 if (number < num_textclass) {
1368 if (!ar[number].number_of_defined_layouts) {