3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
7 * \author Jean-Marc Lasgouttes
10 * Full author contact details are available in file CREDITS.
15 #include "lyxlayout.h"
16 #include "lyxtextclass.h"
20 #include "support/lstrings.h"
22 using lyx::support::subst;
23 using lyx::support::trim;
29 // The order of the LayoutTags enum is no more important. [asierra300396]
41 //LT_ENVIRONMENT_DEFAULT,
58 LT_LABELSTRING_APPENDIX,
88 // Constructor for layout
89 LyXLayout::LyXLayout ()
91 margintype = MARGIN_STATIC;
92 latextype = LATEX_PARAGRAPH;
97 font = LyXFont(LyXFont::ALL_INHERIT);
98 labelfont = LyXFont(LyXFont::ALL_INHERIT);
99 resfont = LyXFont(LyXFont::ALL_SANE);
100 reslabelfont = LyXFont(LyXFont::ALL_SANE);
101 nextnoindent = false;
106 labelbottomsep = 0.0;
108 align = LYX_ALIGN_BLOCK;
109 alignpossible = LYX_ALIGN_BLOCK;
110 labeltype = LABEL_NO_LABEL;
111 endlabeltype = END_LABEL_NO_LABEL;
112 // Should or should not. That is the question.
113 // spacing.set(Spacing::OneHalf);
116 newline_allowed = true;
117 free_spacing = false;
119 is_environment = false;
124 // Reads a layout definition from file
125 bool LyXLayout::Read(LyXLex & lexrc, LyXTextClass const & tclass)
127 // This table is sorted alphabetically [asierra 30March96]
128 keyword_item layoutTags[] = {
129 { "align", LT_ALIGN },
130 { "alignpossible", LT_ALIGNPOSSIBLE },
131 { "bottomsep", LT_BOTTOMSEP },
132 { "copystyle", LT_COPYSTYLE },
133 { "dependson", LT_DEPENDSON },
135 { "endlabelstring", LT_ENDLABELSTRING },
136 { "endlabeltype", LT_ENDLABELTYPE },
137 { "fill_bottom", LT_FILL_BOTTOM },
138 { "fill_top", LT_FILL_TOP },
140 { "freespacing", LT_FREE_SPACING },
141 { "intitle", LT_INTITLE },
142 { "itemsep", LT_ITEMSEP },
143 { "keepempty", LT_KEEPEMPTY },
144 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
145 { "labelcounter", LT_LABELCOUNTER },
146 { "labelfont", LT_LABELFONT },
147 { "labelindent", LT_LABELINDENT },
148 { "labelsep", LT_LABELSEP },
149 { "labelstring", LT_LABELSTRING },
150 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
151 { "labeltype", LT_LABELTYPE },
152 { "latexfooter", LT_LATEXFOOTER },
153 { "latexheader", LT_LATEXHEADER },
154 { "latexname", LT_LATEXNAME },
155 { "latexparagraph", LT_LATEXPARAGRAPH },
156 { "latexparam", LT_LATEXPARAM },
157 { "latextype", LT_LATEXTYPE },
158 { "leftmargin", LT_LEFTMARGIN },
159 { "margin", LT_MARGIN },
160 { "needprotect", LT_NEED_PROTECT },
161 { "newline", LT_NEWLINE },
162 { "nextnoindent", LT_NEXTNOINDENT },
163 { "obsoletedby", LT_OBSOLETEDBY },
164 { "optionalargs", LT_OPTARGS },
165 { "parindent", LT_PARINDENT },
166 { "parsep", LT_PARSEP },
167 { "parskip", LT_PARSKIP },
168 { "passthru", LT_PASS_THRU },
169 { "preamble", LT_PREAMBLE },
170 { "rightmargin", LT_RIGHTMARGIN },
171 { "spacing", LT_SPACING },
172 { "textfont", LT_TEXTFONT },
173 { "toclevel", LT_TOCLEVEL },
174 { "topsep", LT_TOPSEP }
178 bool finished = false;
179 lexrc.pushTable(layoutTags, LT_INTITLE);
180 // parse style section
181 while (!finished && lexrc.isOK() && !error) {
182 int le = lexrc.lex();
183 // See comment in lyxrc.C.
185 case LyXLex::LEX_FEOF:
188 case LyXLex::LEX_UNDEF: // parse error
189 lexrc.printError("Unknown layout tag `$$Token'");
194 switch (static_cast<LayoutTags>(le)) {
195 case LT_END: // end of structure
199 case LT_COPYSTYLE: // initialize with a known style
201 string const style = lexrc.getString();
203 if (tclass.hasLayout(style)) {
204 string const tmpname = name_;
205 this->operator=(*tclass[style]);
208 lyxerr << "Cannot copy unknown style `"
210 << "All layouts so far:"
212 LyXTextClass::const_iterator it =
214 LyXTextClass::const_iterator end =
216 for (; it != end; ++it) {
217 lyxerr << (*it)->name()
221 //lexrc.printError("Cannot copy known "
222 // "style `$$Token'");
227 case LT_OBSOLETEDBY: // replace with a known style
229 string const style = lexrc.getString();
231 if (tclass.hasLayout(style)) {
232 string const tmpname = name_;
233 this->operator=(*tclass[style]);
235 if (obsoleted_by().empty())
236 obsoleted_by_ = style;
238 lyxerr << "Cannot replace with unknown style `" << style << '\'' << endl;
240 //lexrc.printError("Cannot replace with"
249 depends_on_ = lexrc.getString();
252 case LT_MARGIN: // margin style definition.
256 case LT_LATEXTYPE: // LaTeX style definition.
257 readLatexType(lexrc);
260 case LT_LATEXHEADER: // header for environments
262 latexheader = lexrc.getString();
265 case LT_LATEXFOOTER: // footer for environments
267 latexfooter = lexrc.getString();
270 case LT_LATEXPARAGRAPH:
272 latexparagraph = lexrc.getString();
276 intitle = lexrc.next() && lexrc.getInteger();
281 toclevel = lexrc.getInteger();
286 optionalargs = lexrc.getInteger();
289 case LT_NEED_PROTECT:
290 needprotect = lexrc.next() && lexrc.getInteger();
294 keepempty = lexrc.next() && lexrc.getInteger();
307 labelfont.lyxRead(lexrc);
310 case LT_NEXTNOINDENT: // Indent next paragraph?
311 if (lexrc.next() && lexrc.getInteger())
314 nextnoindent = false;
319 latexname_ = lexrc.getString();
324 latexparam_ = lexrc.getString();
328 preamble_ = lexrc.getLongString("EndPreamble");
332 readLabelType(lexrc);
335 case LT_ENDLABELTYPE:
336 readEndLabelType(lexrc);
339 case LT_LEFTMARGIN: // left margin type
341 leftmargin = lexrc.getString();
344 case LT_RIGHTMARGIN: // right margin type
346 rightmargin = lexrc.getString();
349 case LT_LABELINDENT: // label indenting flag
351 labelindent = lexrc.getString();
354 case LT_PARINDENT: // paragraph indent. flag
356 parindent = lexrc.getString();
359 case LT_PARSKIP: // paragraph skip size
361 parskip = lexrc.getFloat();
364 case LT_ITEMSEP: // item separation size
366 itemsep = lexrc.getFloat();
369 case LT_TOPSEP: // top separation size
371 topsep = lexrc.getFloat();
374 case LT_BOTTOMSEP: // bottom separation size
376 bottomsep = lexrc.getFloat();
379 case LT_LABEL_BOTTOMSEP: // label bottom separation size
381 labelbottomsep = lexrc.getFloat();
384 case LT_LABELSEP: // label separator
386 labelsep = subst(lexrc.getString(), 'x', ' ');
390 case LT_PARSEP: // par. separation size
392 parsep = lexrc.getFloat();
395 case LT_FILL_TOP: // fill top flag
397 fill_top = lexrc.getInteger();
400 case LT_FILL_BOTTOM: // fill bottom flag
402 fill_bottom = lexrc.getInteger();
405 case LT_NEWLINE: // newlines allowed?
407 newline_allowed = lexrc.getInteger();
410 case LT_ALIGN: // paragraph align
413 case LT_ALIGNPOSSIBLE: // paragraph allowed align
414 readAlignPossible(lexrc);
417 case LT_LABELSTRING: // label string definition
419 labelstring_ = trim(lexrc.getString());
422 case LT_ENDLABELSTRING: // endlabel string definition
424 endlabelstring_ = trim(lexrc.getString());
427 case LT_LABELSTRING_APPENDIX: // label string appendix definition
429 labelstring_appendix_ = trim(lexrc.getString());
432 case LT_LABELCOUNTER: // name of counter to use
434 counter = trim(lexrc.getString());
437 case LT_FREE_SPACING: // Allow for free spacing.
439 free_spacing = lexrc.getInteger();
442 case LT_PASS_THRU: // Allow for pass thru.
444 pass_thru = lexrc.getInteger();
447 case LT_SPACING: // setspace.sty
454 if (labelstring_appendix_.empty())
455 labelstring_appendix_ = labelstring_;
469 void LyXLayout::readAlign(LyXLex & lexrc)
471 keyword_item alignTags[] = {
472 { "block", AT_BLOCK },
473 { "center", AT_CENTER },
474 { "layout", AT_LAYOUT },
476 { "right", AT_RIGHT }
479 pushpophelper pph(lexrc, alignTags, AT_LAYOUT);
480 int le = lexrc.lex();
482 case LyXLex::LEX_UNDEF:
483 lexrc.printError("Unknown alignment `$$Token'");
487 switch (static_cast<AlignTags>(le)) {
489 align = LYX_ALIGN_BLOCK;
492 align = LYX_ALIGN_LEFT;
495 align = LYX_ALIGN_RIGHT;
498 align = LYX_ALIGN_CENTER;
501 align = LYX_ALIGN_LAYOUT;
507 void LyXLayout::readAlignPossible(LyXLex & lexrc)
509 keyword_item alignTags[] = {
510 { "block", AT_BLOCK },
511 { "center", AT_CENTER },
512 { "layout", AT_LAYOUT },
514 { "right", AT_RIGHT }
517 lexrc.pushTable(alignTags, AT_LAYOUT);
518 alignpossible = LYX_ALIGN_NONE;
519 int lineno = lexrc.getLineNo();
521 int le = lexrc.lex();
523 case LyXLex::LEX_UNDEF:
524 lexrc.printError("Unknown alignment `$$Token'");
528 switch (static_cast<AlignTags>(le)) {
530 alignpossible |= LYX_ALIGN_BLOCK;
533 alignpossible |= LYX_ALIGN_LEFT;
536 alignpossible |= LYX_ALIGN_RIGHT;
539 alignpossible |= LYX_ALIGN_CENTER;
542 alignpossible |= LYX_ALIGN_LAYOUT;
545 } while (lineno == lexrc.getLineNo());
554 LA_CENTERED_TOP_ENVIRONMENT,
564 void LyXLayout::readLabelType(LyXLex & lexrc)
566 keyword_item labelTypeTags[] = {
567 { "bibliography", LA_BIBLIO },
568 { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT },
569 { "counter", LA_COUNTER },
570 { "enumerate", LA_ENUMERATE },
571 { "itemize", LA_ITEMIZE },
572 { "manual", LA_MANUAL },
573 { "no_label", LA_NO_LABEL },
574 { "sensitive", LA_SENSITIVE },
575 { "static", LA_STATIC },
576 { "top_environment", LA_TOP_ENVIRONMENT }
579 pushpophelper pph(lexrc, labelTypeTags, LA_BIBLIO);
580 int le = lexrc.lex();
582 case LyXLex::LEX_UNDEF:
583 lexrc.printError("Unknown labeltype tag `$$Token'");
587 switch (static_cast<LabelTypeTags>(le)) {
589 labeltype = LABEL_NO_LABEL;
592 labeltype = LABEL_MANUAL;
594 case LA_TOP_ENVIRONMENT:
595 labeltype = LABEL_TOP_ENVIRONMENT;
597 case LA_CENTERED_TOP_ENVIRONMENT:
598 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
601 labeltype = LABEL_STATIC;
604 labeltype = LABEL_SENSITIVE;
607 labeltype = LABEL_COUNTER;
610 labeltype = LABEL_ENUMERATE;
613 labeltype = LABEL_ITEMIZE;
616 labeltype = LABEL_BIBLIO;
624 keyword_item endlabelTypeTags[] = {
625 { "box", END_LABEL_BOX },
626 { "filled_box", END_LABEL_FILLED_BOX },
627 { "no_label", END_LABEL_NO_LABEL },
628 { "static", END_LABEL_STATIC }
634 void LyXLayout::readEndLabelType(LyXLex & lexrc)
636 pushpophelper pph(lexrc, endlabelTypeTags,
637 END_LABEL_ENUM_LAST-END_LABEL_ENUM_FIRST+1);
638 int le = lexrc.lex();
640 case LyXLex::LEX_UNDEF:
641 lexrc.printError("Unknown labeltype tag `$$Token'");
643 case END_LABEL_STATIC:
645 case END_LABEL_FILLED_BOX:
646 case END_LABEL_NO_LABEL:
647 endlabeltype = static_cast<LYX_END_LABEL_TYPES>(le);
650 lyxerr << "Unhandled value " << le
651 << " in LyXLayout::readEndLabelType." << endl;
657 void LyXLayout::readMargin(LyXLex & lexrc)
659 keyword_item marginTags[] = {
660 { "dynamic", MARGIN_DYNAMIC },
661 { "first_dynamic", MARGIN_FIRST_DYNAMIC },
662 { "manual", MARGIN_MANUAL },
663 { "right_address_box", MARGIN_RIGHT_ADDRESS_BOX },
664 { "static", MARGIN_STATIC }
667 pushpophelper pph(lexrc, marginTags, MARGIN_RIGHT_ADDRESS_BOX);
669 int le = lexrc.lex();
671 case LyXLex::LEX_UNDEF:
672 lexrc.printError("Unknown margin type tag `$$Token'");
677 case MARGIN_FIRST_DYNAMIC:
678 case MARGIN_RIGHT_ADDRESS_BOX:
679 margintype = static_cast<LYX_MARGIN_TYPE>(le);
682 lyxerr << "Unhandled value " << le
683 << " in LyXLayout::readMargin." << endl;
689 void LyXLayout::readLatexType(LyXLex & lexrc)
691 keyword_item latexTypeTags[] = {
692 { "bib_environment", LATEX_BIB_ENVIRONMENT },
693 { "command", LATEX_COMMAND },
694 { "environment", LATEX_ENVIRONMENT },
695 { "item_environment", LATEX_ITEM_ENVIRONMENT },
696 { "list_environment", LATEX_LIST_ENVIRONMENT },
697 { "paragraph", LATEX_PARAGRAPH }
700 pushpophelper pph(lexrc, latexTypeTags, LATEX_LIST_ENVIRONMENT);
701 int le = lexrc.lex();
703 case LyXLex::LEX_UNDEF:
704 lexrc.printError("Unknown latextype tag `$$Token'");
706 case LATEX_PARAGRAPH:
708 case LATEX_ENVIRONMENT:
709 case LATEX_ITEM_ENVIRONMENT:
710 case LATEX_BIB_ENVIRONMENT:
711 case LATEX_LIST_ENVIRONMENT:
712 latextype = static_cast<LYX_LATEX_TYPES>(le);
715 lyxerr << "Unhandled value " << le
716 << " in LyXLayout::readLatexType." << endl;
723 ST_SPACING_SINGLE = 1,
730 void LyXLayout::readSpacing(LyXLex & lexrc)
732 keyword_item spacingTags[] = {
733 {"double", ST_SPACING_DOUBLE },
734 {"onehalf", ST_SPACING_ONEHALF },
735 {"other", ST_OTHER },
736 {"single", ST_SPACING_SINGLE }
739 pushpophelper pph(lexrc, spacingTags, ST_OTHER);
740 int le = lexrc.lex();
742 case LyXLex::LEX_UNDEF:
743 lexrc.printError("Unknown spacing token `$$Token'");
747 switch (static_cast<SpacingTags>(le)) {
748 case ST_SPACING_SINGLE:
749 spacing.set(Spacing::Single);
751 case ST_SPACING_ONEHALF:
752 spacing.set(Spacing::Onehalf);
754 case ST_SPACING_DOUBLE:
755 spacing.set(Spacing::Double);
759 spacing.set(Spacing::Other, lexrc.getFloat());
765 string const & LyXLayout::name() const
771 void LyXLayout::setName(string const & n)
777 string const & LyXLayout::obsoleted_by() const
779 return obsoleted_by_;
783 string const & LyXLayout::depends_on() const