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