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