]> git.lyx.org Git - lyx.git/blob - src/lyxlayout.C
fix crash when collapsing ert with cursor inside
[lyx.git] / src / lyxlayout.C
1 /**
2  * \file lyxlayout.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Jean-Marc Lasgouttes
8  * \author André Pönitz
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "lyxlayout.h"
16 #include "lyxtextclass.h"
17 #include "lyxlex.h"
18 #include "debug.h"
19
20 #include "support/lstrings.h"
21
22 using lyx::support::subst;
23 using lyx::support::trim;
24
25 using std::endl;
26 using std::string;
27
28
29 //  The order of the LayoutTags enum is no more important. [asierra300396]
30 // Tags indexes.
31 enum LayoutTags {
32         LT_ALIGN = 1,
33         LT_ALIGNPOSSIBLE,
34         LT_MARGIN,
35         LT_BOTTOMSEP,
36         LT_COMMANDDEPTH,
37         LT_COPYSTYLE,
38         LT_DEPENDSON,
39         LT_OBSOLETEDBY,
40         //LT_EMPTY,
41         LT_END,
42         //LT_ENVIRONMENT_DEFAULT,
43         //LT_FANCYHDR,
44         LT_FILL_BOTTOM,
45         LT_FILL_TOP,
46         //LT_FIRST_COUNTER,
47         LT_FONT,
48         LT_FREE_SPACING,
49         LT_PASS_THRU,
50         //LT_HEADINGS,
51         LT_ITEMSEP,
52         LT_KEEPEMPTY,
53         LT_LABEL_BOTTOMSEP,
54         LT_LABELFONT,
55         LT_TEXTFONT,
56         LT_LABELINDENT,
57         LT_LABELSEP,
58         LT_LABELSTRING,
59         LT_LABELSTRING_APPENDIX,
60         LT_LABELCOUNTER,
61         LT_LABELTYPE,
62         LT_ENDLABELSTRING,
63         LT_ENDLABELTYPE,
64         LT_LATEXNAME,
65         LT_LATEXPARAM,
66         LT_OPTARGS,
67         LT_LATEXTYPE,
68         LT_LATEXHEADER,
69         LT_LATEXFOOTER,
70         LT_LATEXPARAGRAPH,
71         LT_LEFTMARGIN,
72         LT_NEED_PROTECT,
73         LT_NEWLINE,
74         LT_NEXTNOINDENT,
75         LT_PARINDENT,
76         LT_PARSEP,
77         LT_PARSKIP,
78         //LT_PLAIN,
79         LT_PREAMBLE,
80         LT_RIGHTMARGIN,
81         LT_SPACING,
82         LT_TOPSEP,
83         LT_TOCLEVEL,
84         LT_INNERTAG,
85         LT_LABELTAG,
86         LT_ITEMTAG,
87         LT_INTITLE // keep this last!
88 };
89
90 /////////////////////
91
92 // Constructor for layout
93 LyXLayout::LyXLayout ()
94 {
95         margintype = MARGIN_STATIC;
96         latextype = LATEX_PARAGRAPH;
97         intitle = false;
98         optionalargs = 0;
99         needprotect = false;
100         keepempty = false;
101         font = LyXFont(LyXFont::ALL_INHERIT);
102         labelfont = LyXFont(LyXFont::ALL_INHERIT);
103         resfont = LyXFont(LyXFont::ALL_SANE);
104         reslabelfont = LyXFont(LyXFont::ALL_SANE);
105         nextnoindent = false;
106         parskip = 0.0;
107         itemsep = 0;
108         topsep = 0.0;
109         bottomsep = 0.0;
110         labelbottomsep = 0.0;
111         parsep = 0;
112         align = LYX_ALIGN_BLOCK;
113         alignpossible = LYX_ALIGN_BLOCK;
114         labeltype = LABEL_NO_LABEL;
115         endlabeltype = END_LABEL_NO_LABEL;
116         // Should or should not. That is the question.
117         // spacing.set(Spacing::OneHalf);
118         fill_top = false;
119         fill_bottom = false;
120         newline_allowed = true;
121         free_spacing = false;
122         pass_thru = false;
123         is_environment = false;
124         toclevel = -2;
125         commanddepth = 0;
126 }
127
128
129 // Reads a layout definition from file
130 bool LyXLayout::Read(LyXLex & lexrc, LyXTextClass const & tclass)
131 {
132         // This table is sorted alphabetically [asierra 30March96]
133         keyword_item layoutTags[] = {
134                 { "align",          LT_ALIGN },
135                 { "alignpossible",  LT_ALIGNPOSSIBLE },
136                 { "bottomsep",      LT_BOTTOMSEP },
137                 { "commanddepth",   LT_COMMANDDEPTH },
138                 { "copystyle",      LT_COPYSTYLE },
139                 { "dependson",      LT_DEPENDSON },
140                 { "end",            LT_END },
141                 { "endlabelstring", LT_ENDLABELSTRING },
142                 { "endlabeltype",   LT_ENDLABELTYPE },
143                 { "fill_bottom",    LT_FILL_BOTTOM },
144                 { "fill_top",       LT_FILL_TOP },
145                 { "font",           LT_FONT },
146                 { "freespacing",    LT_FREE_SPACING },
147                 { "innertag",       LT_INNERTAG },
148                 { "intitle",        LT_INTITLE },
149                 { "itemsep",        LT_ITEMSEP },
150                 { "itemtag",        LT_ITEMTAG },
151                 { "keepempty",      LT_KEEPEMPTY },
152                 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
153                 { "labelcounter",   LT_LABELCOUNTER },
154                 { "labelfont",      LT_LABELFONT },
155                 { "labelindent",    LT_LABELINDENT },
156                 { "labelsep",       LT_LABELSEP },
157                 { "labelstring",    LT_LABELSTRING },
158                 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
159                 { "labeltag",       LT_LABELTAG },
160                 { "labeltype",      LT_LABELTYPE },
161                 { "latexfooter",    LT_LATEXFOOTER },
162                 { "latexheader",    LT_LATEXHEADER },
163                 { "latexname",      LT_LATEXNAME },
164                 { "latexparagraph", LT_LATEXPARAGRAPH },
165                 { "latexparam",     LT_LATEXPARAM },
166                 { "latextype",      LT_LATEXTYPE },
167                 { "leftmargin",     LT_LEFTMARGIN },
168                 { "margin",         LT_MARGIN },
169                 { "needprotect",    LT_NEED_PROTECT },
170                 { "newline",        LT_NEWLINE },
171                 { "nextnoindent",   LT_NEXTNOINDENT },
172                 { "obsoletedby",    LT_OBSOLETEDBY },
173                 { "optionalargs",   LT_OPTARGS },
174                 { "parindent",      LT_PARINDENT },
175                 { "parsep",         LT_PARSEP },
176                 { "parskip",        LT_PARSKIP },
177                 { "passthru",       LT_PASS_THRU },
178                 { "preamble",       LT_PREAMBLE },
179                 { "rightmargin",    LT_RIGHTMARGIN },
180                 { "spacing",        LT_SPACING },
181                 { "textfont",       LT_TEXTFONT },
182                 { "toclevel",       LT_TOCLEVEL },
183                 { "topsep",         LT_TOPSEP }
184         };
185
186         bool error = false;
187         bool finished = false;
188         lexrc.pushTable(layoutTags, LT_INTITLE);
189         // parse style section
190         while (!finished && lexrc.isOK() && !error) {
191                 int le = lexrc.lex();
192                 // See comment in lyxrc.C.
193                 switch (le) {
194                 case LyXLex::LEX_FEOF:
195                         continue;
196
197                 case LyXLex::LEX_UNDEF:         // parse error
198                         lexrc.printError("Unknown layout tag `$$Token'");
199                         error = true;
200                         continue;
201                 default: break;
202                 }
203                 switch (static_cast<LayoutTags>(le)) {
204                 case LT_END:            // end of structure
205                         finished = true;
206                         break;
207
208                 case LT_COPYSTYLE:     // initialize with a known style
209                         if (lexrc.next()) {
210                                 string const style = subst(lexrc.getString(),
211                                                                 '_', ' ');
212
213                                 if (tclass.hasLayout(style)) {
214                                         string const tmpname = name_;
215                                         this->operator=(*tclass[style]);
216                                         name_ = tmpname;
217                                 } else {
218                                         lyxerr << "Cannot copy unknown style `"
219                                                << style << "'\n"
220                                                << "All layouts so far:"
221                                                << endl;
222                                         LyXTextClass::const_iterator it =
223                                                 tclass.begin();
224                                         LyXTextClass::const_iterator end =
225                                                 tclass.end();
226                                         for (; it != end; ++it) {
227                                                 lyxerr << (*it)->name()
228                                                        << endl;
229                                         }
230
231                                         //lexrc.printError("Cannot copy known "
232                                         //               "style `$$Token'");
233                                 }
234                         }
235                         break;
236
237                 case LT_OBSOLETEDBY:     // replace with a known style
238                         if (lexrc.next()) {
239                                 string const style = lexrc.getString();
240
241                                 if (tclass.hasLayout(style)) {
242                                         string const tmpname = name_;
243                                         this->operator=(*tclass[style]);
244                                         name_ = tmpname;
245                                         if (obsoleted_by().empty())
246                                                 obsoleted_by_ = style;
247                                 } else {
248                                         lyxerr << "Cannot replace with unknown style `" << style << '\'' << endl;
249
250                                         //lexrc.printError("Cannot replace with"
251                                         //               " unknown style "
252                                         //               "`$$Token'");
253                                 }
254                         }
255                         break;
256
257                 case LT_DEPENDSON:
258                         if (lexrc.next())
259                                 depends_on_ = lexrc.getString();
260                         break;
261
262                 case LT_MARGIN:         // margin style definition.
263                         readMargin(lexrc);
264                         break;
265
266                 case LT_LATEXTYPE:      // LaTeX style definition.
267                         readLatexType(lexrc);
268                         break;
269
270                 case LT_LATEXHEADER:    // header for environments
271                         lexrc.next();
272                         latexheader = lexrc.getString();
273                         break;
274
275                 case LT_LATEXFOOTER:    // footer for environments
276                         lexrc.next();
277                         latexfooter = lexrc.getString();
278                         break;
279
280                 case LT_LATEXPARAGRAPH:
281                         lexrc.next();
282                         latexparagraph = lexrc.getString();
283                         break;
284
285                 case LT_INTITLE:
286                         intitle = lexrc.next() && lexrc.getInteger();
287                         break;
288
289                 case LT_TOCLEVEL:
290                         lexrc.next();
291                         toclevel = lexrc.getInteger();
292                         break;
293
294                 case LT_OPTARGS:
295                         if (lexrc.next())
296                                 optionalargs = lexrc.getInteger();
297                         break;
298
299                 case LT_NEED_PROTECT:
300                         needprotect = lexrc.next() && lexrc.getInteger();
301                         break;
302
303                 case LT_KEEPEMPTY:
304                         keepempty = lexrc.next() && lexrc.getInteger();
305                         break;
306
307                 case LT_FONT:
308                         font.lyxRead(lexrc);
309                         labelfont= font;
310                         break;
311
312                 case LT_TEXTFONT:
313                         font.lyxRead(lexrc);
314                         break;
315
316                 case LT_LABELFONT:
317                         labelfont.lyxRead(lexrc);
318                         break;
319
320                 case LT_NEXTNOINDENT:   // Indent next paragraph?
321                         if (lexrc.next() && lexrc.getInteger())
322                                 nextnoindent = true;
323                         else
324                                 nextnoindent = false;
325                         break;
326
327                 case LT_COMMANDDEPTH:
328                         lexrc.next();
329                         commanddepth = lexrc.getInteger();
330                         break;
331
332                 case LT_LATEXNAME:
333                         if (lexrc.next())
334                                 latexname_ = lexrc.getString();
335                         break;
336
337                 case LT_LATEXPARAM:
338                         if (lexrc.next())
339                                 latexparam_ = subst(lexrc.getString(), "&quot;", "\"");
340                         break;
341
342                 case LT_INNERTAG:
343                         if (lexrc.next())
344                                 innertag_ = lexrc.getString();
345                         break;
346
347                 case LT_LABELTAG:
348                         if (lexrc.next())
349                                 labeltag_ = lexrc.getString();
350                         break;
351
352                 case LT_ITEMTAG:
353                         if (lexrc.next())
354                                 itemtag_ = lexrc.getString();
355                         break;
356
357                 case LT_PREAMBLE:
358                         preamble_ = lexrc.getLongString("EndPreamble");
359                         break;
360
361                 case LT_LABELTYPE:
362                         readLabelType(lexrc);
363                         break;
364
365                 case LT_ENDLABELTYPE:
366                         readEndLabelType(lexrc);
367                         break;
368
369                 case LT_LEFTMARGIN:     // left margin type
370                         if (lexrc.next())
371                                 leftmargin = lexrc.getString();
372                         break;
373
374                 case LT_RIGHTMARGIN:    // right margin type
375                         if (lexrc.next())
376                                 rightmargin = lexrc.getString();
377                         break;
378
379                 case LT_LABELINDENT:    // label indenting flag
380                         if (lexrc.next())
381                                 labelindent = lexrc.getString();
382                         break;
383
384                 case LT_PARINDENT:      // paragraph indent. flag
385                         if (lexrc.next())
386                                 parindent = lexrc.getString();
387                         break;
388
389                 case LT_PARSKIP:        // paragraph skip size
390                         if (lexrc.next())
391                                 parskip = lexrc.getFloat();
392                         break;
393
394                 case LT_ITEMSEP:        // item separation size
395                         if (lexrc.next())
396                                 itemsep = lexrc.getFloat();
397                         break;
398
399                 case LT_TOPSEP:         // top separation size
400                         if (lexrc.next())
401                                 topsep = lexrc.getFloat();
402                         break;
403
404                 case LT_BOTTOMSEP:      // bottom separation size
405                         if (lexrc.next())
406                                 bottomsep = lexrc.getFloat();
407                         break;
408
409                 case LT_LABEL_BOTTOMSEP: // label bottom separation size
410                         if (lexrc.next())
411                                 labelbottomsep = lexrc.getFloat();
412                         break;
413
414                 case LT_LABELSEP:       // label separator
415                         if (lexrc.next()) {
416                                 labelsep = subst(lexrc.getString(), 'x', ' ');
417                         }
418                         break;
419
420                 case LT_PARSEP:         // par. separation size
421                         if (lexrc.next())
422                                 parsep = lexrc.getFloat();
423                         break;
424
425                 case LT_FILL_TOP:       // fill top flag
426                         if (lexrc.next())
427                                 fill_top = lexrc.getInteger();
428                         break;
429
430                 case LT_FILL_BOTTOM:    // fill bottom flag
431                         if (lexrc.next())
432                                 fill_bottom = lexrc.getInteger();
433                         break;
434
435                 case LT_NEWLINE:        // newlines allowed?
436                         if (lexrc.next())
437                                 newline_allowed = lexrc.getInteger();
438                         break;
439
440                 case LT_ALIGN:          // paragraph align
441                         readAlign(lexrc);
442                         break;
443                 case LT_ALIGNPOSSIBLE:  // paragraph allowed align
444                         readAlignPossible(lexrc);
445                         break;
446
447                 case LT_LABELSTRING:    // label string definition
448                         if (lexrc.next())
449                                 labelstring_ = trim(lexrc.getString());
450                         break;
451
452                 case LT_ENDLABELSTRING: // endlabel string definition
453                         if (lexrc.next())
454                                 endlabelstring_ = trim(lexrc.getString());
455                         break;
456
457                 case LT_LABELSTRING_APPENDIX: // label string appendix definition
458                         if (lexrc.next())
459                                 labelstring_appendix_ = trim(lexrc.getString());
460                         break;
461
462                 case LT_LABELCOUNTER: // name of counter to use
463                         if (lexrc.next())
464                                 counter = trim(lexrc.getString());
465                         break;
466
467                 case LT_FREE_SPACING:   // Allow for free spacing.
468                         if (lexrc.next())
469                                 free_spacing = lexrc.getInteger();
470                         break;
471
472                 case LT_PASS_THRU:      // Allow for pass thru.
473                         if (lexrc.next())
474                                 pass_thru = lexrc.getInteger();
475                         break;
476
477                 case LT_SPACING: // setspace.sty
478                         readSpacing(lexrc);
479                         break;
480                 }
481         }
482         lexrc.popTable();
483
484         if (labelstring_appendix_.empty())
485                 labelstring_appendix_ = labelstring_;
486         return error;
487 }
488
489
490 enum AlignTags {
491         AT_BLOCK = 1,
492         AT_LEFT,
493         AT_RIGHT,
494         AT_CENTER,
495         AT_LAYOUT
496 };
497
498
499 void LyXLayout::readAlign(LyXLex & lexrc)
500 {
501         keyword_item alignTags[] = {
502                 { "block",  AT_BLOCK },
503                 { "center", AT_CENTER },
504                 { "layout", AT_LAYOUT },
505                 { "left",   AT_LEFT },
506                 { "right",  AT_RIGHT }
507         };
508
509         pushpophelper pph(lexrc, alignTags, AT_LAYOUT);
510         int le = lexrc.lex();
511         switch (le) {
512         case LyXLex::LEX_UNDEF:
513                 lexrc.printError("Unknown alignment `$$Token'");
514                 return;
515         default: break;
516         };
517         switch (static_cast<AlignTags>(le)) {
518         case AT_BLOCK:
519                 align = LYX_ALIGN_BLOCK;
520                 break;
521         case AT_LEFT:
522                 align = LYX_ALIGN_LEFT;
523                 break;
524         case AT_RIGHT:
525                 align = LYX_ALIGN_RIGHT;
526                 break;
527         case AT_CENTER:
528                 align = LYX_ALIGN_CENTER;
529                 break;
530         case AT_LAYOUT:
531                 align = LYX_ALIGN_LAYOUT;
532                 break;
533         }
534 }
535
536
537 void LyXLayout::readAlignPossible(LyXLex & lexrc)
538 {
539         keyword_item alignTags[] = {
540                 { "block",  AT_BLOCK },
541                 { "center", AT_CENTER },
542                 { "layout", AT_LAYOUT },
543                 { "left",   AT_LEFT },
544                 { "right",  AT_RIGHT }
545         };
546
547         lexrc.pushTable(alignTags, AT_LAYOUT);
548         alignpossible = LYX_ALIGN_NONE;
549         int lineno = lexrc.getLineNo();
550         do {
551                 int le = lexrc.lex();
552                 switch (le) {
553                 case LyXLex::LEX_UNDEF:
554                         lexrc.printError("Unknown alignment `$$Token'");
555                         continue;
556                 default: break;
557                 };
558                 switch (static_cast<AlignTags>(le)) {
559                 case AT_BLOCK:
560                         alignpossible |= LYX_ALIGN_BLOCK;
561                         break;
562                 case AT_LEFT:
563                         alignpossible |= LYX_ALIGN_LEFT;
564                         break;
565                 case AT_RIGHT:
566                         alignpossible |= LYX_ALIGN_RIGHT;
567                         break;
568                 case AT_CENTER:
569                         alignpossible |= LYX_ALIGN_CENTER;
570                         break;
571                 case AT_LAYOUT:
572                         alignpossible |= LYX_ALIGN_LAYOUT;
573                         break;
574                 }
575         } while (lineno == lexrc.getLineNo());
576         lexrc.popTable();
577 }
578
579
580 enum LabelTypeTags {
581         LA_NO_LABEL = 1,
582         LA_MANUAL,
583         LA_TOP_ENVIRONMENT,
584         LA_CENTERED_TOP_ENVIRONMENT,
585         LA_STATIC,
586         LA_SENSITIVE,
587         LA_COUNTER,
588         LA_ENUMERATE,
589         LA_ITEMIZE,
590         LA_BIBLIO
591 };
592
593
594 void LyXLayout::readLabelType(LyXLex & lexrc)
595 {
596         keyword_item labelTypeTags[] = {
597         { "bibliography",             LA_BIBLIO },
598         { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT },
599         { "counter",                  LA_COUNTER },
600         { "enumerate",                LA_ENUMERATE },
601         { "itemize",                  LA_ITEMIZE },
602         { "manual",                   LA_MANUAL },
603         { "no_label",                 LA_NO_LABEL },
604         { "sensitive",                LA_SENSITIVE },
605         { "static",                   LA_STATIC },
606         { "top_environment",          LA_TOP_ENVIRONMENT }
607         };
608
609         pushpophelper pph(lexrc, labelTypeTags, LA_BIBLIO);
610         int le = lexrc.lex();
611         switch (le) {
612         case LyXLex::LEX_UNDEF:
613                 lexrc.printError("Unknown labeltype tag `$$Token'");
614                 return;
615         default: break;
616         }
617         switch (static_cast<LabelTypeTags>(le)) {
618         case LA_NO_LABEL:
619                 labeltype = LABEL_NO_LABEL;
620                 break;
621         case LA_MANUAL:
622                 labeltype = LABEL_MANUAL;
623                 break;
624         case LA_TOP_ENVIRONMENT:
625                 labeltype = LABEL_TOP_ENVIRONMENT;
626                 break;
627         case LA_CENTERED_TOP_ENVIRONMENT:
628                 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
629                 break;
630         case LA_STATIC:
631                 labeltype = LABEL_STATIC;
632                 break;
633         case LA_SENSITIVE:
634                 labeltype = LABEL_SENSITIVE;
635                 break;
636         case LA_COUNTER:
637                 labeltype = LABEL_COUNTER;
638                 break;
639         case LA_ENUMERATE:
640                 labeltype = LABEL_ENUMERATE;
641                 break;
642         case LA_ITEMIZE:
643                 labeltype = LABEL_ITEMIZE;
644                 break;
645         case LA_BIBLIO:
646                 labeltype = LABEL_BIBLIO;
647                 break;
648         }
649 }
650
651
652 namespace {
653
654 keyword_item endlabelTypeTags[] = {
655         { "box",        END_LABEL_BOX },
656         { "filled_box", END_LABEL_FILLED_BOX },
657         { "no_label",   END_LABEL_NO_LABEL },
658         { "static",     END_LABEL_STATIC }
659 };
660
661 } // namespace anon
662
663
664 void LyXLayout::readEndLabelType(LyXLex & lexrc)
665 {
666         pushpophelper pph(lexrc, endlabelTypeTags,
667                           END_LABEL_ENUM_LAST-END_LABEL_ENUM_FIRST+1);
668         int le = lexrc.lex();
669         switch (le) {
670         case LyXLex::LEX_UNDEF:
671                 lexrc.printError("Unknown labeltype tag `$$Token'");
672                 break;
673         case END_LABEL_STATIC:
674         case END_LABEL_BOX:
675         case END_LABEL_FILLED_BOX:
676         case END_LABEL_NO_LABEL:
677                 endlabeltype = static_cast<LYX_END_LABEL_TYPES>(le);
678                 break;
679         default:
680                 lyxerr << "Unhandled value " << le
681                        << " in LyXLayout::readEndLabelType." << endl;
682                 break;
683         }
684 }
685
686
687 void LyXLayout::readMargin(LyXLex & lexrc)
688 {
689         keyword_item marginTags[] = {
690                 { "dynamic",           MARGIN_DYNAMIC },
691                 { "first_dynamic",     MARGIN_FIRST_DYNAMIC },
692                 { "manual",            MARGIN_MANUAL },
693                 { "right_address_box", MARGIN_RIGHT_ADDRESS_BOX },
694                 { "static",            MARGIN_STATIC }
695         };
696
697         pushpophelper pph(lexrc, marginTags, MARGIN_RIGHT_ADDRESS_BOX);
698
699         int le = lexrc.lex();
700         switch (le) {
701         case LyXLex::LEX_UNDEF:
702                 lexrc.printError("Unknown margin type tag `$$Token'");
703                 return;
704         case MARGIN_STATIC:
705         case MARGIN_MANUAL:
706         case MARGIN_DYNAMIC:
707         case MARGIN_FIRST_DYNAMIC:
708         case MARGIN_RIGHT_ADDRESS_BOX:
709                 margintype = static_cast<LYX_MARGIN_TYPE>(le);
710                 break;
711         default:
712                 lyxerr << "Unhandled value " << le
713                        << " in LyXLayout::readMargin." << endl;
714                 break;
715         }
716 }
717
718
719 void LyXLayout::readLatexType(LyXLex & lexrc)
720 {
721         keyword_item latexTypeTags[] = {
722                 { "bib_environment",  LATEX_BIB_ENVIRONMENT },
723                 { "command",          LATEX_COMMAND },
724                 { "environment",      LATEX_ENVIRONMENT },
725                 { "item_environment", LATEX_ITEM_ENVIRONMENT },
726                 { "list_environment", LATEX_LIST_ENVIRONMENT },
727                 { "paragraph",        LATEX_PARAGRAPH }
728         };
729
730         pushpophelper pph(lexrc, latexTypeTags, LATEX_LIST_ENVIRONMENT);
731         int le = lexrc.lex();
732         switch (le) {
733         case LyXLex::LEX_UNDEF:
734                 lexrc.printError("Unknown latextype tag `$$Token'");
735                 return;
736         case LATEX_PARAGRAPH:
737         case LATEX_COMMAND:
738         case LATEX_ENVIRONMENT:
739         case LATEX_ITEM_ENVIRONMENT:
740         case LATEX_BIB_ENVIRONMENT:
741         case LATEX_LIST_ENVIRONMENT:
742                 latextype = static_cast<LYX_LATEX_TYPES>(le);
743                 break;
744         default:
745                 lyxerr << "Unhandled value " << le
746                        << " in LyXLayout::readLatexType." << endl;
747                 break;
748         }
749 }
750
751
752 enum SpacingTags {
753         ST_SPACING_SINGLE = 1,
754         ST_SPACING_ONEHALF,
755         ST_SPACING_DOUBLE,
756         ST_OTHER
757 };
758
759
760 void LyXLayout::readSpacing(LyXLex & lexrc)
761 {
762         keyword_item spacingTags[] = {
763                 {"double",  ST_SPACING_DOUBLE },
764                 {"onehalf", ST_SPACING_ONEHALF },
765                 {"other",   ST_OTHER },
766                 {"single",  ST_SPACING_SINGLE }
767         };
768
769         pushpophelper pph(lexrc, spacingTags, ST_OTHER);
770         int le = lexrc.lex();
771         switch (le) {
772         case LyXLex::LEX_UNDEF:
773                 lexrc.printError("Unknown spacing token `$$Token'");
774                 return;
775         default: break;
776         }
777         switch (static_cast<SpacingTags>(le)) {
778         case ST_SPACING_SINGLE:
779                 spacing.set(Spacing::Single);
780                 break;
781         case ST_SPACING_ONEHALF:
782                 spacing.set(Spacing::Onehalf);
783                 break;
784         case ST_SPACING_DOUBLE:
785                 spacing.set(Spacing::Double);
786                 break;
787         case ST_OTHER:
788                 lexrc.next();
789                 spacing.set(Spacing::Other, lexrc.getString());
790                 break;
791         }
792 }
793
794
795 string const & LyXLayout::name() const
796 {
797         return name_;
798 }
799
800
801 void LyXLayout::setName(string const & n)
802 {
803         name_ = n;
804 }
805
806
807 string const & LyXLayout::obsoleted_by() const
808 {
809         return obsoleted_by_;
810 }
811
812
813 string const & LyXLayout::depends_on() const
814 {
815         return depends_on_;
816 }