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