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 namespace lyx::support;
26 // The order of the LayoutTags enum is no more important. [asierra300396]
38 //LT_ENVIRONMENT_DEFAULT,
55 LT_LABELSTRING_APPENDIX,
83 // Constructor for layout
84 LyXLayout::LyXLayout ()
86 margintype = MARGIN_STATIC;
87 latextype = LATEX_PARAGRAPH;
92 font = LyXFont(LyXFont::ALL_INHERIT);
93 labelfont = LyXFont(LyXFont::ALL_INHERIT);
94 resfont = LyXFont(LyXFont::ALL_SANE);
95 reslabelfont = LyXFont(LyXFont::ALL_SANE);
101 labelbottomsep = 0.0;
103 align = LYX_ALIGN_BLOCK;
104 alignpossible = LYX_ALIGN_BLOCK;
105 labeltype = LABEL_NO_LABEL;
106 endlabeltype = END_LABEL_NO_LABEL;
107 // Should or should not. That is the question.
108 // spacing.set(Spacing::OneHalf);
111 newline_allowed = true;
112 free_spacing = false;
114 is_environment = false;
118 // Reads a layout definition from file
119 bool LyXLayout::Read (LyXLex & lexrc, LyXTextClass const & tclass)
121 // This table is sorted alphabetically [asierra 30March96]
122 keyword_item layoutTags[] = {
123 { "align", LT_ALIGN },
124 { "alignpossible", LT_ALIGNPOSSIBLE },
125 { "bottomsep", LT_BOTTOMSEP },
126 { "copystyle", LT_COPYSTYLE },
127 { "dependson", LT_DEPENDSON },
129 { "endlabelstring", LT_ENDLABELSTRING },
130 { "endlabeltype", LT_ENDLABELTYPE },
131 { "fill_bottom", LT_FILL_BOTTOM },
132 { "fill_top", LT_FILL_TOP },
134 { "freespacing", LT_FREE_SPACING },
135 { "intitle", LT_INTITLE },
136 { "itemsep", LT_ITEMSEP },
137 { "keepempty", LT_KEEPEMPTY },
138 { "labelbottomsep", LT_LABEL_BOTTOMSEP },
139 { "labelfont", LT_LABELFONT },
140 { "labelindent", LT_LABELINDENT },
141 { "labelsep", LT_LABELSEP },
142 { "labelstring", LT_LABELSTRING },
143 { "labelstringappendix", LT_LABELSTRING_APPENDIX },
144 { "labeltype", LT_LABELTYPE },
145 { "latexfooter", LT_LATEXFOOTER },
146 { "latexheader", LT_LATEXHEADER },
147 { "latexname", LT_LATEXNAME },
148 { "latexparagraph", LT_LATEXPARAGRAPH },
149 { "latexparam", LT_LATEXPARAM },
150 { "latextype", LT_LATEXTYPE },
151 { "leftmargin", LT_LEFTMARGIN },
152 { "margin", LT_MARGIN },
153 { "needprotect", LT_NEED_PROTECT },
154 { "newline", LT_NEWLINE },
155 { "nextnoindent", LT_NEXTNOINDENT },
156 { "obsoletedby", LT_OBSOLETEDBY },
157 { "optionalargs", LT_OPTARGS },
158 { "parindent", LT_PARINDENT },
159 { "parsep", LT_PARSEP },
160 { "parskip", LT_PARSKIP },
161 { "passthru", LT_PASS_THRU },
162 { "preamble", LT_PREAMBLE },
163 { "rightmargin", LT_RIGHTMARGIN },
164 { "spacing", LT_SPACING },
165 { "textfont", LT_TEXTFONT },
166 { "topsep", LT_TOPSEP }
170 bool finished = false;
171 lexrc.pushTable(layoutTags, LT_INTITLE);
172 // parse style section
173 while (!finished && lexrc.isOK() && !error) {
174 int le = lexrc.lex();
175 // See comment in lyxrc.C.
177 case LyXLex::LEX_FEOF:
180 case LyXLex::LEX_UNDEF: // parse error
181 lexrc.printError("Unknown layout tag `$$Token'");
186 switch (static_cast<LayoutTags>(le)) {
187 case LT_END: // end of structure
191 case LT_COPYSTYLE: // initialize with a known style
193 string const style = lexrc.getString();
195 if (tclass.hasLayout(style)) {
196 string const tmpname = name_;
197 this->operator=(*tclass[style]);
200 lyxerr << "Cannot copy unknown style `"
202 << "All layouts so far:"
204 LyXTextClass::const_iterator it =
206 LyXTextClass::const_iterator end =
208 for (; it != end; ++it) {
209 lyxerr << (*it)->name()
213 //lexrc.printError("Cannot copy known "
214 // "style `$$Token'");
219 case LT_OBSOLETEDBY: // replace with a known style
221 string const style = lexrc.getString();
223 if (tclass.hasLayout(style)) {
224 string const tmpname = name_;
225 this->operator=(*tclass[style]);
227 if (obsoleted_by().empty())
228 obsoleted_by_ = style;
230 lyxerr << "Cannot replace with unknown style `" << style << '\'' << endl;
232 //lexrc.printError("Cannot replace with"
241 depends_on_ = lexrc.getString();
245 case LT_MARGIN: // margin style definition.
249 case LT_LATEXTYPE: // LaTeX style definition.
250 readLatexType(lexrc);
253 case LT_LATEXHEADER: // header for environments
255 latexheader = lexrc.getString();
258 case LT_LATEXFOOTER: // footer for environments
260 latexfooter = lexrc.getString();
263 case LT_LATEXPARAGRAPH:
265 latexparagraph = lexrc.getString();
269 intitle = lexrc.next() && lexrc.getInteger();
274 optionalargs = lexrc.getInteger();
278 case LT_NEED_PROTECT:
279 needprotect = lexrc.next() && lexrc.getInteger();
283 keepempty = lexrc.next() && lexrc.getInteger();
296 labelfont.lyxRead(lexrc);
299 case LT_NEXTNOINDENT: // Indent next paragraph?
300 if (lexrc.next() && lexrc.getInteger())
303 nextnoindent = false;
308 latexname_ = lexrc.getString();
313 latexparam_ = lexrc.getString();
317 preamble_ = lexrc.getLongString("EndPreamble");
321 readLabelType(lexrc);
324 case LT_ENDLABELTYPE:
325 readEndLabelType(lexrc);
328 case LT_LEFTMARGIN: // left margin type
330 leftmargin = lexrc.getString();
333 case LT_RIGHTMARGIN: // right margin type
335 rightmargin = lexrc.getString();
338 case LT_LABELINDENT: // label indenting flag
340 labelindent = lexrc.getString();
343 case LT_PARINDENT: // paragraph indent. flag
345 parindent = lexrc.getString();
348 case LT_PARSKIP: // paragraph skip size
350 parskip = lexrc.getFloat();
353 case LT_ITEMSEP: // item separation size
355 itemsep = lexrc.getFloat();
358 case LT_TOPSEP: // top separation size
360 topsep = lexrc.getFloat();
363 case LT_BOTTOMSEP: // bottom separation size
365 bottomsep = lexrc.getFloat();
368 case LT_LABEL_BOTTOMSEP: // label bottom separation size
370 labelbottomsep = lexrc.getFloat();
373 case LT_LABELSEP: // label separator
375 labelsep = subst(lexrc.getString(), 'x', ' ');
379 case LT_PARSEP: // par. separation size
381 parsep = lexrc.getFloat();
384 case LT_FILL_TOP: // fill top flag
386 fill_top = lexrc.getInteger();
389 case LT_FILL_BOTTOM: // fill bottom flag
391 fill_bottom = lexrc.getInteger();
394 case LT_NEWLINE: // newlines allowed?
396 newline_allowed = lexrc.getInteger();
399 case LT_ALIGN: // paragraph align
402 case LT_ALIGNPOSSIBLE: // paragraph allowed align
403 readAlignPossible(lexrc);
406 case LT_LABELSTRING: // label string definition
408 labelstring_ = trim(lexrc.getString());
411 case LT_ENDLABELSTRING: // endlabel string definition
413 endlabelstring_ = trim(lexrc.getString());
416 case LT_LABELSTRING_APPENDIX: // label string appendix definition
418 labelstring_appendix_ = trim(lexrc.getString());
421 case LT_FREE_SPACING: // Allow for free spacing.
423 free_spacing = lexrc.getInteger();
426 case LT_PASS_THRU: // Allow for pass thru.
428 pass_thru = lexrc.getInteger();
431 case LT_SPACING: // setspace.sty
450 void LyXLayout::readAlign(LyXLex & lexrc)
452 keyword_item alignTags[] = {
453 { "block", AT_BLOCK },
454 { "center", AT_CENTER },
455 { "layout", AT_LAYOUT },
457 { "right", AT_RIGHT }
460 pushpophelper pph(lexrc, alignTags, AT_LAYOUT);
461 int le = lexrc.lex();
463 case LyXLex::LEX_UNDEF:
464 lexrc.printError("Unknown alignment `$$Token'");
468 switch (static_cast<AlignTags>(le)) {
470 align = LYX_ALIGN_BLOCK;
473 align = LYX_ALIGN_LEFT;
476 align = LYX_ALIGN_RIGHT;
479 align = LYX_ALIGN_CENTER;
482 align = LYX_ALIGN_LAYOUT;
488 void LyXLayout::readAlignPossible(LyXLex & lexrc)
490 keyword_item alignTags[] = {
491 { "block", AT_BLOCK },
492 { "center", AT_CENTER },
493 { "layout", AT_LAYOUT },
495 { "right", AT_RIGHT }
498 lexrc.pushTable(alignTags, AT_LAYOUT);
499 alignpossible = LYX_ALIGN_NONE;
500 int lineno = lexrc.getLineNo();
502 int le = lexrc.lex();
504 case LyXLex::LEX_UNDEF:
505 lexrc.printError("Unknown alignment `$$Token'");
509 switch (static_cast<AlignTags>(le)) {
511 alignpossible |= LYX_ALIGN_BLOCK;
514 alignpossible |= LYX_ALIGN_LEFT;
517 alignpossible |= LYX_ALIGN_RIGHT;
520 alignpossible |= LYX_ALIGN_CENTER;
523 alignpossible |= LYX_ALIGN_LAYOUT;
526 } while (lineno == lexrc.getLineNo());
535 LA_CENTERED_TOP_ENVIRONMENT,
540 LA_COUNTER_SUBSECTION,
541 LA_COUNTER_SUBSUBSECTION,
542 LA_COUNTER_PARAGRAPH,
543 LA_COUNTER_SUBPARAGRAPH,
552 void LyXLayout::readLabelType(LyXLex & lexrc)
554 keyword_item labelTypeTags[] = {
555 { "bibliography", LA_BIBLIO },
556 { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT },
557 { "counter_chapter", LA_COUNTER_CHAPTER },
558 { "counter_enumi", LA_COUNTER_ENUMI },
559 { "counter_enumii", LA_COUNTER_ENUMII },
560 { "counter_enumiii", LA_COUNTER_ENUMIII },
561 { "counter_enumiv", LA_COUNTER_ENUMIV },
562 { "counter_paragraph", LA_COUNTER_PARAGRAPH },
563 { "counter_section", LA_COUNTER_SECTION },
564 { "counter_subparagraph", LA_COUNTER_SUBPARAGRAPH },
565 { "counter_subsection", LA_COUNTER_SUBSECTION },
566 { "counter_subsubsection", LA_COUNTER_SUBSUBSECTION },
567 { "manual", LA_MANUAL },
568 { "no_label", LA_NO_LABEL },
569 { "sensitive", LA_SENSITIVE },
570 { "static", LA_STATIC },
571 { "top_environment", LA_TOP_ENVIRONMENT }
574 pushpophelper pph(lexrc, labelTypeTags, LA_BIBLIO);
575 int le = lexrc.lex();
577 case LyXLex::LEX_UNDEF:
578 lexrc.printError("Unknown labeltype tag `$$Token'");
582 switch (static_cast<LabelTypeTags>(le)) {
584 labeltype = LABEL_NO_LABEL;
587 labeltype = LABEL_MANUAL;
589 case LA_TOP_ENVIRONMENT:
590 labeltype = LABEL_TOP_ENVIRONMENT;
592 case LA_CENTERED_TOP_ENVIRONMENT:
593 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
596 labeltype = LABEL_STATIC;
599 labeltype = LABEL_SENSITIVE;
601 case LA_COUNTER_CHAPTER:
602 labeltype = LABEL_COUNTER_CHAPTER;
604 case LA_COUNTER_SECTION:
605 labeltype = LABEL_COUNTER_SECTION;
607 case LA_COUNTER_SUBSECTION:
608 labeltype = LABEL_COUNTER_SUBSECTION;
610 case LA_COUNTER_SUBSUBSECTION:
611 labeltype = LABEL_COUNTER_SUBSUBSECTION;
613 case LA_COUNTER_PARAGRAPH:
614 labeltype = LABEL_COUNTER_PARAGRAPH;
616 case LA_COUNTER_SUBPARAGRAPH:
617 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
619 case LA_COUNTER_ENUMI:
620 labeltype = LABEL_COUNTER_ENUMI;
622 case LA_COUNTER_ENUMII:
623 labeltype = LABEL_COUNTER_ENUMII;
625 case LA_COUNTER_ENUMIII:
626 labeltype = LABEL_COUNTER_ENUMIII;
628 case LA_COUNTER_ENUMIV:
629 labeltype = LABEL_COUNTER_ENUMIV;
632 labeltype = LABEL_BIBLIO;
640 keyword_item endlabelTypeTags[] = {
641 { "box", END_LABEL_BOX },
642 { "filled_box", END_LABEL_FILLED_BOX },
643 { "no_label", END_LABEL_NO_LABEL },
644 { "static", END_LABEL_STATIC }
650 void LyXLayout::readEndLabelType(LyXLex & lexrc)
652 pushpophelper pph(lexrc, endlabelTypeTags,
653 END_LABEL_ENUM_LAST-END_LABEL_ENUM_FIRST+1);
654 int le = lexrc.lex();
656 case LyXLex::LEX_UNDEF:
657 lexrc.printError("Unknown labeltype tag `$$Token'");
659 case END_LABEL_STATIC:
661 case END_LABEL_FILLED_BOX:
662 case END_LABEL_NO_LABEL:
663 endlabeltype = static_cast<LYX_END_LABEL_TYPES>(le);
666 lyxerr << "Unhandled value " << le
667 << " in LyXLayout::readEndLabelType." << endl;
673 void LyXLayout::readMargin(LyXLex & lexrc)
675 keyword_item marginTags[] = {
676 { "dynamic", MARGIN_DYNAMIC },
677 { "first_dynamic", MARGIN_FIRST_DYNAMIC },
678 { "manual", MARGIN_MANUAL },
679 { "right_address_box", MARGIN_RIGHT_ADDRESS_BOX },
680 { "static", MARGIN_STATIC }
683 pushpophelper pph(lexrc, marginTags, MARGIN_RIGHT_ADDRESS_BOX);
685 int le = lexrc.lex();
687 case LyXLex::LEX_UNDEF:
688 lexrc.printError("Unknown margin type tag `$$Token'");
693 case MARGIN_FIRST_DYNAMIC:
694 case MARGIN_RIGHT_ADDRESS_BOX:
695 margintype = static_cast<LYX_MARGIN_TYPE>(le);
698 lyxerr << "Unhandled value " << le
699 << " in LyXLayout::readMargin." << endl;
705 void LyXLayout::readLatexType(LyXLex & lexrc)
707 keyword_item latexTypeTags[] = {
708 { "bib_environment", LATEX_BIB_ENVIRONMENT },
709 { "command", LATEX_COMMAND },
710 { "environment", LATEX_ENVIRONMENT },
711 { "item_environment", LATEX_ITEM_ENVIRONMENT },
712 { "list_environment", LATEX_LIST_ENVIRONMENT },
713 { "paragraph", LATEX_PARAGRAPH }
716 pushpophelper pph(lexrc, latexTypeTags, LATEX_LIST_ENVIRONMENT);
717 int le = lexrc.lex();
719 case LyXLex::LEX_UNDEF:
720 lexrc.printError("Unknown latextype tag `$$Token'");
722 case LATEX_PARAGRAPH:
724 case LATEX_ENVIRONMENT:
725 case LATEX_ITEM_ENVIRONMENT:
726 case LATEX_BIB_ENVIRONMENT:
727 case LATEX_LIST_ENVIRONMENT:
728 latextype = static_cast<LYX_LATEX_TYPES>(le);
731 lyxerr << "Unhandled value " << le
732 << " in LyXLayout::readLatexType." << endl;
739 ST_SPACING_SINGLE = 1,
746 void LyXLayout::readSpacing(LyXLex & lexrc)
748 keyword_item spacingTags[] = {
749 {"double", ST_SPACING_DOUBLE },
750 {"onehalf", ST_SPACING_ONEHALF },
751 {"other", ST_OTHER },
752 {"single", ST_SPACING_SINGLE }
755 pushpophelper pph(lexrc, spacingTags, ST_OTHER);
756 int le = lexrc.lex();
758 case LyXLex::LEX_UNDEF:
759 lexrc.printError("Unknown spacing token `$$Token'");
763 switch (static_cast<SpacingTags>(le)) {
764 case ST_SPACING_SINGLE:
765 spacing.set(Spacing::Single);
767 case ST_SPACING_ONEHALF:
768 spacing.set(Spacing::Onehalf);
770 case ST_SPACING_DOUBLE:
771 spacing.set(Spacing::Double);
775 spacing.set(Spacing::Other, lexrc.getFloat());
781 string const & LyXLayout::name() const
787 void LyXLayout::setName(string const & n)
793 string const & LyXLayout::obsoleted_by() const
795 return obsoleted_by_;
799 string const & LyXLayout::depends_on() const