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