]> git.lyx.org Git - lyx.git/blob - src/lyxlayout.C
don't copy if a reference is fine
[lyx.git] / src / lyxlayout.C
1
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1995 Matthias Ettrich
8  *          Copyright 1995-2001 The LyX Team.
9  *
10  * ======================================================
11  */
12
13 #include <config.h>
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
19 #include "lyxlayout.h"
20 #include "lyxtextclass.h"
21 #include "lyxlex.h"
22 #include "debug.h"
23
24 #include "support/lstrings.h"
25
26 using std::endl;
27
28 //  The order of the LayoutTags enum is no more important. [asierra300396]
29 // Tags indexes.
30 enum LayoutTags {
31         LT_ALIGN = 1, 
32         LT_ALIGNPOSSIBLE, 
33         LT_MARGIN, 
34         LT_BOTTOMSEP, 
35         LT_COPYSTYLE, 
36         LT_OBSOLETEDBY, 
37         //LT_EMPTY,
38         LT_END, 
39         //LT_ENVIRONMENT_DEFAULT, 
40         //LT_FANCYHDR,
41         LT_FILL_BOTTOM, 
42         LT_FILL_TOP, 
43         //LT_FIRST_COUNTER,
44         LT_FONT, 
45         LT_FREE_SPACING, 
46         LT_PASS_THRU,
47         //LT_HEADINGS,
48         LT_ITEMSEP, 
49         LT_KEEPEMPTY, 
50         LT_LABEL_BOTTOMSEP, 
51         LT_LABELFONT, 
52         LT_TEXTFONT,
53         LT_LABELINDENT, 
54         LT_LABELSEP, 
55         LT_LABELSTRING, 
56         LT_LABELSTRING_APPENDIX, 
57         LT_LABELTYPE,
58         LT_ENDLABELSTRING,
59         LT_ENDLABELTYPE,
60         LT_LATEXNAME, 
61         LT_LATEXPARAM, 
62         LT_LATEXTYPE, 
63         LT_LEFTMARGIN, 
64         LT_NEED_PROTECT, 
65         LT_NEWLINE, 
66         LT_NEXTNOINDENT, 
67         LT_PARINDENT, 
68         LT_PARSEP, 
69         LT_PARSKIP, 
70         //LT_PLAIN,
71         LT_PREAMBLE, 
72         LT_RIGHTMARGIN, 
73         LT_SPACING, 
74         LT_TOPSEP, 
75         LT_INTITLE 
76 };
77
78 /////////////////////
79
80 // Constructor for layout
81 LyXLayout::LyXLayout ()
82 {
83         margintype = MARGIN_STATIC;
84         latextype = LATEX_PARAGRAPH;
85         intitle = false;
86         needprotect = false;
87         keepempty = false;
88         font = LyXFont(LyXFont::ALL_INHERIT);
89         labelfont = LyXFont(LyXFont::ALL_INHERIT);
90         resfont = LyXFont(LyXFont::ALL_SANE);
91         reslabelfont = LyXFont(LyXFont::ALL_SANE);
92         nextnoindent = false;
93         parskip = 0.0;
94         itemsep = 0;
95         topsep = 0.0;
96         bottomsep = 0.0;
97         labelbottomsep = 0.0;
98         parsep = 0;
99         align = LYX_ALIGN_BLOCK;
100         alignpossible = LYX_ALIGN_BLOCK;
101         labeltype = LABEL_NO_LABEL;
102         endlabeltype = END_LABEL_NO_LABEL;
103         // Should or should not. That is the question.
104         // spacing.set(Spacing::OneHalf);
105         fill_top = false;
106         fill_bottom = false;
107         newline_allowed = true;
108         free_spacing = false;
109         pass_thru = false;
110 }
111
112
113 // Reads a layout definition from file
114 bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass)
115 {
116         // This table is sorted alphabetically [asierra 30March96]
117         keyword_item layoutTags[] = {
118                 { "align",                      LT_ALIGN },
119                 { "alignpossible",              LT_ALIGNPOSSIBLE },
120                 { "bottomsep",                  LT_BOTTOMSEP },
121                 { "copystyle",                  LT_COPYSTYLE },
122                 { "end",                        LT_END },
123                 { "endlabelstring",             LT_ENDLABELSTRING },
124                 { "endlabeltype",               LT_ENDLABELTYPE },
125                 { "fill_bottom",                LT_FILL_BOTTOM },
126                 { "fill_top",                   LT_FILL_TOP },
127                 { "font",                       LT_FONT },
128                 { "freespacing",                LT_FREE_SPACING },
129                 { "intitle",                    LT_INTITLE },
130                 { "itemsep",                    LT_ITEMSEP },
131                 { "keepempty",                  LT_KEEPEMPTY },
132                 { "labelbottomsep",             LT_LABEL_BOTTOMSEP },
133                 { "labelfont",                  LT_LABELFONT },
134                 { "labelindent",                LT_LABELINDENT },
135                 { "labelsep",                   LT_LABELSEP },
136                 { "labelstring",                LT_LABELSTRING },
137                 { "labelstringappendix",        LT_LABELSTRING_APPENDIX },
138                 { "labeltype",                  LT_LABELTYPE },
139                 { "latexname",                  LT_LATEXNAME },
140                 { "latexparam",                 LT_LATEXPARAM },
141                 { "latextype",                  LT_LATEXTYPE },
142                 { "leftmargin",                 LT_LEFTMARGIN },
143                 { "margin",                     LT_MARGIN },
144                 { "needprotect",                LT_NEED_PROTECT },
145                 { "newline",                    LT_NEWLINE },
146                 { "nextnoindent",               LT_NEXTNOINDENT },
147                 { "obsoletedby",                LT_OBSOLETEDBY },
148                 { "parindent",                  LT_PARINDENT },
149                 { "parsep",                     LT_PARSEP },
150                 { "parskip",                    LT_PARSKIP },
151                 { "passthru",                   LT_PASS_THRU },
152                 { "preamble",                   LT_PREAMBLE },
153                 { "rightmargin",                LT_RIGHTMARGIN },
154                 { "spacing",                    LT_SPACING },
155                 { "textfont",                   LT_TEXTFONT },
156                 { "topsep",                     LT_TOPSEP }
157         };
158
159         bool error = false;
160         bool finished = false;
161         lexrc.pushTable(layoutTags, LT_INTITLE);
162         // parse style section
163         while (!finished && lexrc.isOK() && !error) {
164                 int le = lexrc.lex();
165                 // See comment in lyxrc.C.
166                 switch (le) {
167                 case LyXLex::LEX_FEOF:
168                         continue; 
169
170                 case LyXLex::LEX_UNDEF:         // parse error
171                         lexrc.printError("Unknown layout tag `$$Token'");
172                         error = true;
173                         continue; 
174                 default: break;
175                 }
176                 switch (static_cast<LayoutTags>(le)) {
177                 case LT_END:            // end of structure
178                         finished = true;
179                         break;
180
181                 case LT_COPYSTYLE:     // initialize with a known style
182                         if (lexrc.next()) {
183                                 if (tclass.hasLayout(lexrc.getString())) {
184                                         string const tmpname = name_;
185                                         this->operator= (tclass.GetLayout(lexrc.getString()));
186                                         name_ = tmpname;
187                                 } else {
188                                         lexrc.printError("Cannot copy known "
189                                                          "style `$$Token'");
190                                 }
191                         }
192                         break;
193
194                 case LT_OBSOLETEDBY:     // replace with a known style
195                         if (lexrc.next()) {
196                                 if (tclass.hasLayout(lexrc.getString())) {
197                                         string const tmpname = name_;
198                                         this->operator= (tclass.GetLayout(lexrc.getString()));
199                                         name_ = tmpname;
200                                         if (obsoleted_by().empty())
201                                                 obsoleted_by_ = lexrc.getString();
202                                 } else {
203                                         lexrc.printError("Cannot replace with" 
204                                                          " unknown style "
205                                                          "`$$Token'");
206                                 }
207                         }
208                         break;
209
210                 case LT_MARGIN:         // Margin style definition.
211                         readMargin(lexrc);
212                         break;
213
214                 case LT_LATEXTYPE:      // Latex style definition.
215                         readLatexType(lexrc);
216                         break;
217
218                 case LT_INTITLE:
219                         intitle = lexrc.next() && lexrc.getInteger();
220                         break;
221                         
222                 case LT_NEED_PROTECT:
223                         needprotect = lexrc.next() && lexrc.getInteger();
224                         break;
225                         
226                 case LT_KEEPEMPTY:
227                         keepempty = lexrc.next() && lexrc.getInteger();
228                         break;
229
230                 case LT_FONT:
231                         font.lyxRead(lexrc);
232                         labelfont= font;
233                         break;
234
235                 case LT_TEXTFONT:
236                         font.lyxRead(lexrc);
237                         break;
238
239                 case LT_LABELFONT:
240                         labelfont.lyxRead(lexrc);
241                         break;
242
243                 case LT_NEXTNOINDENT:   // Indent next paragraph?
244                         if (lexrc.next() && lexrc.getInteger())
245                                 nextnoindent = true;
246                         else
247                                 nextnoindent = false;
248                         break;
249
250                 case LT_LATEXNAME:
251                         if (lexrc.next())
252                                 latexname_ = lexrc.getString();
253                         break;
254                         
255                 case LT_LATEXPARAM:
256                         if (lexrc.next())
257                                 latexparam_ = lexrc.getString();
258                         break;
259
260                 case LT_PREAMBLE:
261                         preamble_ = lexrc.getLongString("EndPreamble");
262                         break;
263
264                 case LT_LABELTYPE:
265                         readLabelType(lexrc);
266                         break;
267
268                 case LT_ENDLABELTYPE:
269                         readEndLabelType(lexrc);
270                         break;
271                         
272                 case LT_LEFTMARGIN:     // left margin type
273                         if (lexrc.next())
274                                 leftmargin = lexrc.getString();
275                         break;                  
276
277                 case LT_RIGHTMARGIN:    // right margin type
278                         if (lexrc.next())
279                                 rightmargin = lexrc.getString();
280                         break;
281
282                 case LT_LABELINDENT:    // label indenting flag
283                         if (lexrc.next())
284                                 labelindent = lexrc.getString();
285                         break;
286
287                 case LT_PARINDENT:      // paragraph indent. flag
288                         if (lexrc.next())
289                                 parindent = lexrc.getString();
290                         break;
291
292                 case LT_PARSKIP:        // paragraph skip size
293                         if (lexrc.next())
294                                 parskip = lexrc.getFloat();
295                         break;
296
297                 case LT_ITEMSEP:        // item separation size
298                         if (lexrc.next())
299                                 itemsep = lexrc.getFloat();
300                         break;
301
302                 case LT_TOPSEP:         // top separation size
303                         if (lexrc.next())
304                                 topsep = lexrc.getFloat();
305                         break;
306
307                 case LT_BOTTOMSEP:      // bottom separation size
308                         if (lexrc.next())
309                                 bottomsep = lexrc.getFloat();
310                         break;
311
312                 case LT_LABEL_BOTTOMSEP: // label bottom separation size
313                         if (lexrc.next())
314                                 labelbottomsep = lexrc.getFloat();
315                         break;
316
317                 case LT_LABELSEP:       // label separator
318                         if (lexrc.next()) {
319                                 labelsep = subst(lexrc.getString(), 'x', ' ');
320                         }
321                         break;
322
323                 case LT_PARSEP:         // par. separation size
324                         if (lexrc.next())
325                                 parsep = lexrc.getFloat();
326                         break;
327
328                 case LT_FILL_TOP:       // fill top flag
329                         if (lexrc.next())
330                                 fill_top = lexrc.getInteger();
331                         break;
332
333                 case LT_FILL_BOTTOM:    // fill bottom flag
334                         if (lexrc.next())
335                                 fill_bottom = lexrc.getInteger();
336                         break;
337
338                 case LT_NEWLINE:        // newlines allowed?
339                         if (lexrc.next())
340                                 newline_allowed = lexrc.getInteger();
341                         break;
342
343                 case LT_ALIGN:          // paragraph align
344                         readAlign(lexrc);
345                         break;
346                 case LT_ALIGNPOSSIBLE:  // paragraph allowed align
347                         readAlignPossible(lexrc);
348                         break;
349
350                 case LT_LABELSTRING:    // label string definition
351                         if (lexrc.next())
352                                 labelstring_ = lexrc.getString();
353                         break;
354
355                 case LT_ENDLABELSTRING: // endlabel string definition
356                         if (lexrc.next())
357                                 endlabelstring_ = lexrc.getString();
358                         break;
359
360                 case LT_LABELSTRING_APPENDIX: // label string appendix definition
361                         if (lexrc.next())
362                                 labelstring_appendix_ = lexrc.getString();
363                         break;
364
365                 case LT_FREE_SPACING:   // Allow for free spacing.
366                         if (lexrc.next())
367                                 free_spacing = lexrc.getInteger();
368                         break;
369
370                 case LT_PASS_THRU:      // Allow for pass thru.
371                         if (lexrc.next())
372                                 pass_thru = lexrc.getInteger();
373                         break;
374
375                 case LT_SPACING: // setspace.sty
376                         readSpacing(lexrc);
377                         break;
378                 }
379         }
380         lexrc.popTable();
381         return error;
382 }
383
384
385 enum AlignTags {
386         AT_BLOCK = 1,
387         AT_LEFT,
388         AT_RIGHT,
389         AT_CENTER,
390         AT_LAYOUT
391 };
392
393
394 void LyXLayout::readAlign(LyXLex & lexrc)
395 {
396         keyword_item alignTags[] = {
397                 { "block",  AT_BLOCK },
398                 { "center", AT_CENTER },
399                 { "layout", AT_LAYOUT },
400                 { "left",   AT_LEFT },
401                 { "right",  AT_RIGHT }
402         };
403
404         pushpophelper pph(lexrc, alignTags, AT_LAYOUT);
405         int le = lexrc.lex();
406         switch (le) {
407         case LyXLex::LEX_UNDEF:
408                 lexrc.printError("Unknown alignment `$$Token'");
409                 return; 
410         default: break;
411         };
412         switch (static_cast<AlignTags>(le)) {
413         case AT_BLOCK:
414                 align = LYX_ALIGN_BLOCK;
415                 break;
416         case AT_LEFT:
417                 align = LYX_ALIGN_LEFT;
418                 break;
419         case AT_RIGHT:
420                 align = LYX_ALIGN_RIGHT;
421                 break;
422         case AT_CENTER:
423                 align = LYX_ALIGN_CENTER;
424                 break;
425         case AT_LAYOUT:
426                 align = LYX_ALIGN_LAYOUT;
427                 break;
428         }
429 }
430
431
432 void LyXLayout::readAlignPossible(LyXLex & lexrc)
433 {
434         keyword_item alignTags[] = {
435                 { "block",  AT_BLOCK },
436                 { "center", AT_CENTER },
437                 { "layout", AT_LAYOUT },
438                 { "left",   AT_LEFT },
439                 { "right",  AT_RIGHT }
440         };
441
442         lexrc.pushTable(alignTags, AT_LAYOUT);
443         alignpossible = LYX_ALIGN_NONE;
444         int lineno = lexrc.getLineNo();
445         do {
446                 int le = lexrc.lex();
447                 switch (le) {
448                 case LyXLex::LEX_UNDEF:
449                         lexrc.printError("Unknown alignment `$$Token'");
450                         continue; 
451                 default: break;
452                 };
453                 switch (static_cast<AlignTags>(le)) {
454                 case AT_BLOCK:
455                         alignpossible |= LYX_ALIGN_BLOCK;
456                         break;
457                 case AT_LEFT:
458                         alignpossible |= LYX_ALIGN_LEFT;
459                         break;
460                 case AT_RIGHT:
461                         alignpossible |= LYX_ALIGN_RIGHT;
462                         break;
463                 case AT_CENTER:
464                         alignpossible |= LYX_ALIGN_CENTER;
465                         break;
466                 case AT_LAYOUT:
467                         alignpossible |= LYX_ALIGN_LAYOUT;
468                         break;
469                 }
470         } while (lineno == lexrc.getLineNo());
471         lexrc.popTable();
472 }
473
474
475 enum LabelTypeTags {
476         LA_NO_LABEL = 1,
477         LA_MANUAL,
478         LA_TOP_ENVIRONMENT,
479         LA_CENTERED_TOP_ENVIRONMENT,
480         LA_STATIC,
481         LA_SENSITIVE,
482         LA_COUNTER_CHAPTER,
483         LA_COUNTER_SECTION,
484         LA_COUNTER_SUBSECTION,
485         LA_COUNTER_SUBSUBSECTION,
486         LA_COUNTER_PARAGRAPH,
487         LA_COUNTER_SUBPARAGRAPH,
488         LA_COUNTER_ENUMI,
489         LA_COUNTER_ENUMII,
490         LA_COUNTER_ENUMIII,
491         LA_COUNTER_ENUMIV,
492         LA_BIBLIO
493 };
494
495
496 void LyXLayout::readLabelType(LyXLex & lexrc)
497 {
498         keyword_item labelTypeTags[] = {
499         { "bibliography",             LA_BIBLIO },
500         { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT },
501         { "counter_chapter",          LA_COUNTER_CHAPTER },
502         { "counter_enumi",            LA_COUNTER_ENUMI },
503         { "counter_enumii",           LA_COUNTER_ENUMII },
504         { "counter_enumiii",          LA_COUNTER_ENUMIII },
505         { "counter_enumiv",           LA_COUNTER_ENUMIV },
506         { "counter_paragraph",        LA_COUNTER_PARAGRAPH },
507         { "counter_section",          LA_COUNTER_SECTION },
508         { "counter_subparagraph",     LA_COUNTER_SUBPARAGRAPH },
509         { "counter_subsection",       LA_COUNTER_SUBSECTION },
510         { "counter_subsubsection",    LA_COUNTER_SUBSUBSECTION },
511         { "manual",                   LA_MANUAL },
512         { "no_label",                 LA_NO_LABEL },
513         { "sensitive",                LA_SENSITIVE },
514         { "static",                   LA_STATIC },
515         { "top_environment",          LA_TOP_ENVIRONMENT }
516 };
517
518         pushpophelper pph(lexrc, labelTypeTags, LA_BIBLIO);
519         int le = lexrc.lex();
520         switch (le) {
521         case LyXLex::LEX_UNDEF:
522                 lexrc.printError("Unknown labeltype tag `$$Token'");
523                 return; 
524         default: break;
525         }
526         switch (static_cast<LabelTypeTags>(le)) {
527         case LA_NO_LABEL:
528                 labeltype = LABEL_NO_LABEL;
529                 break;
530         case LA_MANUAL:
531                 labeltype = LABEL_MANUAL;
532                 break;
533         case LA_TOP_ENVIRONMENT:
534                 labeltype = LABEL_TOP_ENVIRONMENT;
535                 break;
536         case LA_CENTERED_TOP_ENVIRONMENT:
537                 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
538                 break;
539         case LA_STATIC:
540                 labeltype = LABEL_STATIC;
541                 break;
542         case LA_SENSITIVE:
543                 labeltype = LABEL_SENSITIVE;
544                 break;
545         case LA_COUNTER_CHAPTER:
546                 labeltype = LABEL_COUNTER_CHAPTER;
547                 break;
548         case LA_COUNTER_SECTION:
549                 labeltype = LABEL_COUNTER_SECTION;
550                 break;
551         case LA_COUNTER_SUBSECTION:
552                 labeltype = LABEL_COUNTER_SUBSECTION;
553                 break;
554         case LA_COUNTER_SUBSUBSECTION:
555                 labeltype = LABEL_COUNTER_SUBSUBSECTION;
556                 break;
557         case LA_COUNTER_PARAGRAPH:
558                 labeltype = LABEL_COUNTER_PARAGRAPH;
559                 break;
560         case LA_COUNTER_SUBPARAGRAPH:
561                 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
562                 break;
563         case LA_COUNTER_ENUMI:
564                 labeltype = LABEL_COUNTER_ENUMI;
565                 break;
566         case LA_COUNTER_ENUMII:
567                 labeltype = LABEL_COUNTER_ENUMII;
568                 break;
569         case LA_COUNTER_ENUMIII:
570                 labeltype = LABEL_COUNTER_ENUMIII;
571                 break;
572         case LA_COUNTER_ENUMIV:
573                 labeltype = LABEL_COUNTER_ENUMIV;
574                 break;
575         case LA_BIBLIO:
576                 labeltype = LABEL_BIBLIO;
577                 break;
578         }
579 }
580
581
582 namespace {
583
584 keyword_item endlabelTypeTags[] = {
585         { "box",        END_LABEL_BOX },
586         { "filled_box", END_LABEL_FILLED_BOX },
587         { "no_label",   END_LABEL_NO_LABEL },
588         { "static",     END_LABEL_STATIC }
589 };
590
591 } // namespace anon
592
593
594 void LyXLayout::readEndLabelType(LyXLex & lexrc)
595 {
596         pushpophelper pph(lexrc, endlabelTypeTags,
597                           END_LABEL_ENUM_LAST-END_LABEL_ENUM_FIRST+1);
598         int le = lexrc.lex();
599         switch (le) {
600         case LyXLex::LEX_UNDEF:
601                 lexrc.printError("Unknown labeltype tag `$$Token'");
602                 break;
603         case END_LABEL_STATIC:
604         case END_LABEL_BOX:
605         case END_LABEL_FILLED_BOX:
606         case END_LABEL_NO_LABEL:
607                 endlabeltype = static_cast<LYX_END_LABEL_TYPES>(le);
608                 break;
609         default:
610                 lyxerr << "Unhandled value " << le
611                        << " in LyXLayout::readEndLabelType." << endl;
612                 break;
613         }
614 }
615
616
617 void LyXLayout::readMargin(LyXLex & lexrc)
618 {
619         keyword_item marginTags[] = {
620                 { "dynamic",           MARGIN_DYNAMIC },
621                 { "first_dynamic",     MARGIN_FIRST_DYNAMIC },
622                 { "manual",            MARGIN_MANUAL },
623                 { "right_address_box", MARGIN_RIGHT_ADDRESS_BOX },
624                 { "static",            MARGIN_STATIC }
625         };
626
627         pushpophelper pph(lexrc, marginTags, MARGIN_RIGHT_ADDRESS_BOX);
628
629         int le = lexrc.lex();
630         switch (le) {
631         case LyXLex::LEX_UNDEF:
632                 lexrc.printError("Unknown margin type tag `$$Token'");
633                 return;
634         case MARGIN_STATIC:
635         case MARGIN_MANUAL:
636         case MARGIN_DYNAMIC:
637         case MARGIN_FIRST_DYNAMIC:
638         case MARGIN_RIGHT_ADDRESS_BOX:
639                 margintype = static_cast<LYX_MARGIN_TYPE>(le);
640                 break;
641         default:
642                 lyxerr << "Unhandled value " << le
643                        << " in LyXLayout::readMargin." << endl;
644                 break;
645         }
646 }
647
648
649 void LyXLayout::readLatexType(LyXLex & lexrc)
650 {
651         keyword_item latexTypeTags[] = {
652                 { "command",          LATEX_COMMAND },
653                 { "environment",      LATEX_ENVIRONMENT },
654                 { "item_environment", LATEX_ITEM_ENVIRONMENT },
655                 { "list_environment", LATEX_LIST_ENVIRONMENT },
656                 { "paragraph",        LATEX_PARAGRAPH }
657         };
658
659         pushpophelper pph(lexrc, latexTypeTags, LATEX_LIST_ENVIRONMENT);
660         int le = lexrc.lex();
661         switch (le) {
662         case LyXLex::LEX_UNDEF:
663                 lexrc.printError("Unknown latextype tag `$$Token'");
664                 return;
665         case LATEX_PARAGRAPH:
666         case LATEX_COMMAND:
667         case LATEX_ENVIRONMENT:
668         case LATEX_ITEM_ENVIRONMENT:
669         case LATEX_LIST_ENVIRONMENT:
670                 latextype = static_cast<LYX_LATEX_TYPES>(le);
671                 break;
672         default:
673                 lyxerr << "Unhandled value " << le
674                        << " in LyXLayout::readLatexType." << endl;
675                 break;
676         }
677 }
678
679
680 enum SpacingTags {
681         ST_SPACING_SINGLE = 1,
682         ST_SPACING_ONEHALF,
683         ST_SPACING_DOUBLE,
684         ST_OTHER
685 };
686
687
688 void LyXLayout::readSpacing(LyXLex & lexrc)
689 {
690         keyword_item spacingTags[] = {
691                 {"double",  ST_SPACING_DOUBLE },
692                 {"onehalf", ST_SPACING_ONEHALF },
693                 {"other",   ST_OTHER },
694                 {"single",  ST_SPACING_SINGLE }
695         };
696
697         pushpophelper pph(lexrc, spacingTags, ST_OTHER);
698         int le = lexrc.lex();
699         switch (le) {
700         case LyXLex::LEX_UNDEF:
701                 lexrc.printError("Unknown spacing token `$$Token'");
702                 return;
703         default: break;
704         }
705         switch (static_cast<SpacingTags>(le)) {
706         case ST_SPACING_SINGLE:
707                 spacing.set(Spacing::Single);
708                 break;
709         case ST_SPACING_ONEHALF:
710                 spacing.set(Spacing::Onehalf);
711                 break;
712         case ST_SPACING_DOUBLE:
713                 spacing.set(Spacing::Double);
714                 break;
715         case ST_OTHER:
716                 lexrc.next();
717                 spacing.set(Spacing::Other, lexrc.getFloat());
718                 break;
719         }
720 }