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