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