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