X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLayout.cpp;h=a2c98ac4610fb3d6dd94322b85837816a9462f0f;hb=2660df9b99b8059856b931c22f53ee8f714a1d8e;hp=d92345eed1ebb8e914e8672000c5094dbf089425;hpb=08467b3ddc5d7f01a89daa5edf1b6a8e97421eb8;p=lyx.git diff --git a/src/Layout.cpp b/src/Layout.cpp index d92345eed1..50a4d05ac6 100644 --- a/src/Layout.cpp +++ b/src/Layout.cpp @@ -13,24 +13,23 @@ #include #include "Layout.h" -#include "Language.h" +#include "output_xhtml.h" #include "TextClass.h" -#include "Lexer.h" -#include "Font.h" -#include "support/Messages.h" #include "support/debug.h" +#include "support/docstream.h" #include "support/lassert.h" +#include "support/Lexer.h" #include "support/lstrings.h" +#include "support/textutils.h" -#include using namespace std; using namespace lyx::support; namespace lyx { -/// Special value of toclevel for layouts that to not belong in a TOC +/// Special value of toclevel for layouts that do not belong to a TOC const int Layout::NOT_IN_TOC = -1000; // The order of the LayoutTags enum is no more important. [asierra300396] @@ -38,6 +37,9 @@ const int Layout::NOT_IN_TOC = -1000; enum LayoutTags { LT_ALIGN = 1, LT_ALIGNPOSSIBLE, + LT_ARGUMENT, + LT_AUTONESTS, + LT_AUTONESTEDBY, LT_MARGIN, LT_BOTTOMSEP, LT_CATEGORY, @@ -45,17 +47,13 @@ enum LayoutTags { LT_COPYSTYLE, LT_DEPENDSON, LT_OBSOLETEDBY, - //LT_EMPTY, LT_END, - //LT_ENVIRONMENT_DEFAULT, - //LT_FANCYHDR, - LT_FILL_BOTTOM, - LT_FILL_TOP, - //LT_FIRST_COUNTER, LT_FONT, LT_FREE_SPACING, LT_PASS_THRU, - //LT_HEADINGS, + LT_PASS_THRU_CHARS, + LT_PARBREAK_IS_NEWLINE, + LT_ITEMCOMMAND, LT_ITEMSEP, LT_KEEPEMPTY, LT_LABEL_BOTTOMSEP, @@ -71,16 +69,18 @@ enum LayoutTags { LT_ENDLABELTYPE, LT_LATEXNAME, LT_LATEXPARAM, - LT_OPTARGS, LT_LATEXTYPE, + LT_LEFTDELIM, LT_LEFTMARGIN, + LT_NEED_CPROTECT, + LT_NEED_MBOXPROTECT, LT_NEED_PROTECT, LT_NEWLINE, LT_NEXTNOINDENT, + LT_PAR_GROUP, LT_PARINDENT, LT_PARSEP, LT_PARSKIP, - //LT_PLAIN, LT_PREAMBLE, LT_LANGPREAMBLE, LT_BABELPREAMBLE, @@ -92,19 +92,77 @@ enum LayoutTags { LT_INNERTAG, LT_LABELTAG, LT_ITEMTAG, + LT_HTMLTAG, + LT_HTMLATTR, + LT_HTMLCLASS, + LT_HTMLITEM, + LT_HTMLITEMATTR, + LT_HTMLLABEL, + LT_HTMLLABELATTR, + LT_HTMLLABELFIRST, + LT_HTMLPREAMBLE, + LT_HTMLSTYLE, + LT_HTMLFORCECSS, + LT_DOCBOOKTAG, + LT_DOCBOOKATTR, + LT_DOCBOOKTAGTYPE, + LT_DOCBOOKINNERATTR, + LT_DOCBOOKINNERTAG, + LT_DOCBOOKINNERTAGTYPE, + LT_DOCBOOKININFO, + LT_DOCBOOKABSTRACT, + LT_DOCBOOKGENERATETITLE, + LT_DOCBOOKWRAPPERTAG, + LT_DOCBOOKWRAPPERATTR, + LT_DOCBOOKWRAPPERTAGTYPE, + LT_DOCBOOKWRAPPERMERGEWITHPREVIOUS, + LT_DOCBOOKSECTION, + LT_DOCBOOKSECTIONTAG, + LT_DOCBOOKITEMWRAPPERTAG, + LT_DOCBOOKITEMWRAPPERATTR, + LT_DOCBOOKITEMWRAPPERTAGTYPE, + LT_DOCBOOKITEMTAG, + LT_DOCBOOKITEMATTR, + LT_DOCBOOKITEMTAGTYPE, + LT_DOCBOOKITEMLABELTAG, + LT_DOCBOOKITEMLABELATTR, + LT_DOCBOOKITEMLABELTAGTYPE, + LT_DOCBOOKITEMINNERTAG, + LT_DOCBOOKITEMINNERATTR, + LT_DOCBOOKITEMINNERTAGTYPE, + LT_DOCBOOKFORCEABSTRACTTAG, + LT_DOCBOOKNOFONTINSIDE, + LT_INPREAMBLE, + LT_HTMLTITLE, + LT_SPELLCHECK, + LT_REFPREFIX, + LT_RESETARGS, + LT_RESUMECOUNTER, + LT_STEPPARENTCOUNTER, + LT_RIGHTDELIM, + LT_FORCELOCAL, + LT_TOGGLE_INDENT, + LT_ADDTOTOC, + LT_ISTOCCAPTION, + LT_HTMLINTOC, LT_INTITLE // keep this last! }; ///////////////////// Layout::Layout() + : add_to_toc_(false), is_toc_caption_(true) { unknown_ = false; margintype = MARGIN_STATIC; latextype = LATEX_PARAGRAPH; + resumecounter = false; + stepparentcounter = false; intitle = false; - optionalargs = 0; + inpreamble = false; needprotect = false; + needcprotect = false; + needmboxprotect = false; keepempty = false; font = inherit_font; labelfont = inherit_font; @@ -123,37 +181,117 @@ Layout::Layout() endlabeltype = END_LABEL_NO_LABEL; // Should or should not. That is the question. // spacing.set(Spacing::OneHalf); - fill_top = false; - fill_bottom = false; newline_allowed = true; free_spacing = false; pass_thru = false; + parbreak_is_newline = false; toclevel = NOT_IN_TOC; commanddepth = 0; + htmllabelfirst_ = false; + htmlforcecss_ = false; + htmltitle_ = false; + htmlintoc_ = true; + docbookabstract_ = false; + docbookwrappermergewithprevious_ = false; + docbooksection_ = false; + spellcheck = true; + forcelocal = 0; + itemcommand_ = "item"; + toggle_indent = ITOGGLE_DOCUMENT_DEFAULT; + par_group_ = false; } -bool Layout::read(Lexer & lex, TextClass const & tclass) +bool Layout::read(Lexer & lex, TextClass const & tclass, bool validating) +{ + // If this is an empty layout, or if no force local version is set, + // we know that we will not discard the stuff to read + if (forcelocal == 0) + return readIgnoreForcelocal(lex, tclass, validating); + Layout tmp(*this); + tmp.forcelocal = 0; + bool const ret = tmp.readIgnoreForcelocal(lex, tclass, validating); + // Keep the stuff if + // - the read version is higher + // - both versions are infinity (arbitrary decision) + // - the file did not contain any local version (needed for not + // skipping user defined local layouts) + if (tmp.forcelocal <= 0 || tmp.forcelocal > forcelocal) + *this = tmp; + return ret; +} + + +bool Layout::readIgnoreForcelocal(Lexer & lex, TextClass const & tclass, + bool validating) { // This table is sorted alphabetically [asierra 30March96] LexerKeyword layoutTags[] = { + { "addtotoc", LT_ADDTOTOC }, { "align", LT_ALIGN }, { "alignpossible", LT_ALIGNPOSSIBLE }, + { "argument", LT_ARGUMENT }, + { "autonests", LT_AUTONESTS }, { "babelpreamble", LT_BABELPREAMBLE }, { "bottomsep", LT_BOTTOMSEP }, { "category", LT_CATEGORY }, { "commanddepth", LT_COMMANDDEPTH }, { "copystyle", LT_COPYSTYLE }, { "dependson", LT_DEPENDSON }, + { "docbookabstract", LT_DOCBOOKABSTRACT }, + { "docbookattr", LT_DOCBOOKATTR }, + { "docbookforceabstracttag", LT_DOCBOOKFORCEABSTRACTTAG }, + { "docbookgeneratetitle", LT_DOCBOOKGENERATETITLE }, + { "docbookininfo", LT_DOCBOOKININFO }, + { "docbookinnerattr", LT_DOCBOOKINNERATTR }, + { "docbookinnertag", LT_DOCBOOKINNERTAG }, + { "docbookinnertagtype", LT_DOCBOOKINNERTAGTYPE }, + { "docbookitemattr", LT_DOCBOOKITEMATTR }, + { "docbookiteminnerattr", LT_DOCBOOKITEMINNERATTR }, + { "docbookiteminnertag", LT_DOCBOOKITEMINNERTAG }, + { "docbookiteminnertagtype", LT_DOCBOOKITEMINNERTAGTYPE }, + { "docbookitemlabelattr", LT_DOCBOOKITEMLABELATTR }, + { "docbookitemlabeltag", LT_DOCBOOKITEMLABELTAG }, + { "docbookitemlabeltagtype", LT_DOCBOOKITEMLABELTAGTYPE }, + { "docbookitemtag", LT_DOCBOOKITEMTAG }, + { "docbookitemtagtype", LT_DOCBOOKITEMTAGTYPE }, + { "docbookitemwrapperattr", LT_DOCBOOKITEMWRAPPERATTR }, + { "docbookitemwrappertag", LT_DOCBOOKITEMWRAPPERTAG }, + { "docbookitemwrappertagtype", LT_DOCBOOKITEMWRAPPERTAGTYPE }, + { "docbooknofontinside", LT_DOCBOOKNOFONTINSIDE, }, + { "docbooksection", LT_DOCBOOKSECTION }, + { "docbooksectiontag", LT_DOCBOOKSECTIONTAG }, + { "docbooktag", LT_DOCBOOKTAG }, + { "docbooktagtype", LT_DOCBOOKTAGTYPE }, + { "docbookwrapperattr", LT_DOCBOOKWRAPPERATTR }, + { "docbookwrappermergewithprevious", LT_DOCBOOKWRAPPERMERGEWITHPREVIOUS }, + { "docbookwrappertag", LT_DOCBOOKWRAPPERTAG }, + { "docbookwrappertagtype", LT_DOCBOOKWRAPPERTAGTYPE }, { "end", LT_END }, { "endlabelstring", LT_ENDLABELSTRING }, { "endlabeltype", LT_ENDLABELTYPE }, - { "fill_bottom", LT_FILL_BOTTOM }, - { "fill_top", LT_FILL_TOP }, { "font", LT_FONT }, + { "forcelocal", LT_FORCELOCAL }, { "freespacing", LT_FREE_SPACING }, + { "htmlattr", LT_HTMLATTR }, + { "htmlclass", LT_HTMLCLASS }, + { "htmlforcecss", LT_HTMLFORCECSS }, + { "htmlintoc", LT_HTMLINTOC }, + { "htmlitem", LT_HTMLITEM }, + { "htmlitemattr", LT_HTMLITEMATTR }, + { "htmllabel", LT_HTMLLABEL }, + { "htmllabelattr", LT_HTMLLABELATTR }, + { "htmllabelfirst", LT_HTMLLABELFIRST }, + { "htmlpreamble", LT_HTMLPREAMBLE }, + { "htmlstyle", LT_HTMLSTYLE }, + { "htmltag", LT_HTMLTAG }, + { "htmltitle", LT_HTMLTITLE }, { "innertag", LT_INNERTAG }, + { "inpreamble", LT_INPREAMBLE }, { "intitle", LT_INTITLE }, + { "isautonestedby", LT_AUTONESTEDBY }, + { "istoccaption", LT_ISTOCCAPTION }, + { "itemcommand", LT_ITEMCOMMAND }, { "itemsep", LT_ITEMSEP }, { "itemtag", LT_ITEMTAG }, { "keepempty", LT_KEEPEMPTY }, @@ -170,29 +308,42 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) { "latexname", LT_LATEXNAME }, { "latexparam", LT_LATEXPARAM }, { "latextype", LT_LATEXTYPE }, + { "leftdelim", LT_LEFTDELIM }, { "leftmargin", LT_LEFTMARGIN }, { "margin", LT_MARGIN }, + { "needcprotect", LT_NEED_CPROTECT }, + { "needmboxprotect", LT_NEED_MBOXPROTECT }, { "needprotect", LT_NEED_PROTECT }, { "newline", LT_NEWLINE }, { "nextnoindent", LT_NEXTNOINDENT }, { "obsoletedby", LT_OBSOLETEDBY }, - { "optionalargs", LT_OPTARGS }, + { "paragraphgroup", LT_PAR_GROUP }, + { "parbreakisnewline", LT_PARBREAK_IS_NEWLINE }, { "parindent", LT_PARINDENT }, { "parsep", LT_PARSEP }, { "parskip", LT_PARSKIP }, { "passthru", LT_PASS_THRU }, + { "passthruchars", LT_PASS_THRU_CHARS }, { "preamble", LT_PREAMBLE }, + { "refprefix", LT_REFPREFIX }, { "requires", LT_REQUIRES }, + { "resetargs", LT_RESETARGS }, + { "resumecounter", LT_RESUMECOUNTER }, + { "rightdelim", LT_RIGHTDELIM }, { "rightmargin", LT_RIGHTMARGIN }, { "spacing", LT_SPACING }, + { "spellcheck", LT_SPELLCHECK }, + { "stepparentcounter", LT_STEPPARENTCOUNTER }, { "textfont", LT_TEXTFONT }, { "toclevel", LT_TOCLEVEL }, + { "toggleindent", LT_TOGGLE_INDENT }, { "topsep", LT_TOPSEP } }; bool error = false; bool finished = false; lex.pushTable(layoutTags); + // parse style section while (!finished && lex.isOK() && !error) { int le = lex.lex(); @@ -201,16 +352,17 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) case Lexer::LEX_FEOF: continue; - case Lexer::LEX_UNDEF: // parse error + case Lexer::LEX_UNDEF: + // parse error lex.printError("Unknown layout tag `$$Token'"); error = true; continue; - default: + default: break; } switch (static_cast(le)) { - case LT_END: // end of structure + case LT_END: finished = true; break; @@ -218,7 +370,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) lex >> category_; break; - case LT_COPYSTYLE: { // initialize with a known style + case LT_COPYSTYLE: { docstring style; lex >> style; style = subst(style, '_', ' '); @@ -239,7 +391,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) break; } - case LT_OBSOLETEDBY: { // replace with a known style + case LT_OBSOLETEDBY: { docstring style; lex >> style; style = subst(style, '_', ' '); @@ -251,7 +403,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) if (obsoleted_by().empty()) obsoleted_by_ = style; } else { - LYXERR0("Cannot replace with unknown style `" + LYXERR0("Cannot replace with unknown style `" << style << '\''); //lex.printError("Cannot replace with" @@ -266,11 +418,11 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) depends_on_ = subst(depends_on_, '_', ' '); break; - case LT_MARGIN: // margin style definition. + case LT_MARGIN: readMargin(lex); break; - case LT_LATEXTYPE: // LaTeX style definition. + case LT_LATEXTYPE: readLatexType(lex); break; @@ -278,18 +430,49 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) lex >> intitle; break; + case LT_INPREAMBLE: + lex >> inpreamble; + break; + case LT_TOCLEVEL: lex >> toclevel; break; - case LT_OPTARGS: - lex >> optionalargs ; + case LT_RESETARGS: + bool reset; + lex >> reset; + if (reset) { + latexargs_.clear(); + itemargs_.clear(); + postcommandargs_.clear(); + listpreamble_.clear(); + } + break; + + case LT_RESUMECOUNTER: + lex >> resumecounter; + break; + + case LT_STEPPARENTCOUNTER: + lex >> stepparentcounter; + break; + + case LT_ARGUMENT: + readArgument(lex, validating); break; case LT_NEED_PROTECT: lex >> needprotect; break; + case LT_NEED_CPROTECT: + lex >> needcprotect; + break; + + case LT_NEED_MBOXPROTECT: + lex >> needmboxprotect; + break; + case LT_KEEPEMPTY: lex >> keepempty; break; @@ -307,10 +490,23 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) labelfont = lyxRead(lex, labelfont); break; - case LT_NEXTNOINDENT: // Indent next paragraph? + case LT_NEXTNOINDENT: lex >> nextnoindent; break; + case LT_TOGGLE_INDENT: { + string tog; + lex >> tog; + tog = support::ascii_lowercase(tog); + if (tog == "always") + toggle_indent = ITOGGLE_ALWAYS; + else if (tog == "never") + toggle_indent = ITOGGLE_NEVER; + else + toggle_indent = ITOGGLE_DOCUMENT_DEFAULT; + break; + } + case LT_COMMANDDEPTH: lex >> commanddepth; break; @@ -321,7 +517,19 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) case LT_LATEXPARAM: lex >> latexparam_; - latexparam_ = subst(latexparam_, """, "\""); + latexparam_ = subst(latexparam_, """, "\""); + break; + + case LT_LEFTDELIM: + lex >> leftdelim_; + leftdelim_ = support::subst(leftdelim_, from_ascii("
"), + from_ascii("\n")); + break; + + case LT_RIGHTDELIM: + lex >> rightdelim_; + rightdelim_ = support::subst(rightdelim_, from_ascii("
"), + from_ascii("\n")); break; case LT_INNERTAG: @@ -336,16 +544,20 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) lex >> itemtag_; break; + case LT_ITEMCOMMAND: + lex >> itemcommand_; + break; + case LT_PREAMBLE: - preamble_ = from_utf8(lex.getLongString("EndPreamble")); + preamble_ = lex.getLongString(from_ascii("EndPreamble")); break; case LT_LANGPREAMBLE: - langpreamble_ = from_utf8(lex.getLongString("EndLangPreamble")); + langpreamble_ = lex.getLongString(from_ascii("EndLangPreamble")); break; case LT_BABELPREAMBLE: - babelpreamble_ = from_utf8(lex.getLongString("EndBabelPreamble")); + babelpreamble_ = lex.getLongString(from_ascii("EndBabelPreamble")); break; case LT_LABELTYPE: @@ -356,117 +568,344 @@ bool Layout::read(Lexer & lex, TextClass const & tclass) readEndLabelType(lex); break; - case LT_LEFTMARGIN: // left margin type + case LT_LEFTMARGIN: lex >> leftmargin; break; - case LT_RIGHTMARGIN: // right margin type + case LT_RIGHTMARGIN: lex >> rightmargin; break; - case LT_LABELINDENT: // label indenting flag + case LT_LABELINDENT: lex >> labelindent; break; - case LT_PARINDENT: // paragraph indent. flag + case LT_PARINDENT: lex >> parindent; break; - case LT_PARSKIP: // paragraph skip size + case LT_PARSKIP: lex >> parskip; break; - case LT_ITEMSEP: // item separation size + case LT_ITEMSEP: lex >> itemsep; break; - case LT_TOPSEP: // top separation size + case LT_TOPSEP: lex >> topsep; break; - case LT_BOTTOMSEP: // bottom separation size + case LT_BOTTOMSEP: lex >> bottomsep; break; - case LT_LABEL_BOTTOMSEP: // label bottom separation size + case LT_LABEL_BOTTOMSEP: lex >> labelbottomsep; break; - case LT_LABELSEP: // label separator + case LT_LABELSEP: lex >> labelsep; labelsep = subst(labelsep, 'x', ' '); break; - case LT_PARSEP: // par. separation size + case LT_PARSEP: lex >> parsep; break; - case LT_FILL_TOP: // fill top flag - lex >> fill_top; - break; - - case LT_FILL_BOTTOM: // fill bottom flag - lex >> fill_bottom; - break; - - case LT_NEWLINE: // newlines allowed? + case LT_NEWLINE: lex >> newline_allowed; break; - case LT_ALIGN: // paragraph align + case LT_ALIGN: readAlign(lex); break; - case LT_ALIGNPOSSIBLE: // paragraph allowed align + + case LT_ALIGNPOSSIBLE: readAlignPossible(lex); break; - case LT_LABELSTRING: // label string definition - // FIXME: this means LT_ENDLABELSTRING may only + case LT_LABELSTRING: + // FIXME: this means LT_LABELSTRING_APPENDIX may only // occur after LT_LABELSTRING lex >> labelstring_; - labelstring_ = trim(labelstring_); labelstring_appendix_ = labelstring_; break; - case LT_ENDLABELSTRING: // endlabel string definition - lex >> endlabelstring_; - endlabelstring_ = trim(endlabelstring_); + case LT_ENDLABELSTRING: + lex >> endlabelstring_; + break; + + case LT_LABELSTRING_APPENDIX: + lex >> labelstring_appendix_; break; - case LT_LABELSTRING_APPENDIX: // label string appendix definition - lex >> labelstring_appendix_; - labelstring_appendix_ = trim(labelstring_appendix_); + case LT_LABELCOUNTER: + lex >> counter; break; - case LT_LABELCOUNTER: // name of counter to use - lex >> counter; - counter = trim(counter); + case LT_PAR_GROUP: + lex >> par_group_; break; - case LT_FREE_SPACING: // Allow for free spacing. + case LT_FREE_SPACING: lex >> free_spacing; break; - case LT_PASS_THRU: // Allow for pass thru. + case LT_PASS_THRU: lex >> pass_thru; break; - case LT_SPACING: // setspace.sty + case LT_PASS_THRU_CHARS: + lex >> pass_thru_chars; + break; + + case LT_PARBREAK_IS_NEWLINE: + lex >> parbreak_is_newline; + break; + + case LT_SPACING: readSpacing(lex); break; - case LT_REQUIRES: + case LT_REQUIRES: { lex.eatLine(); - vector const req = - getVectorFromString(lex.getString()); - requires_.insert(req.begin(), req.end()); + vector const req = + getVectorFromString(lex.getString(true)); + required_.insert(req.begin(), req.end()); + break; + } + + case LT_AUTONESTS: { + docstring autonest = lex.getLongString(from_ascii("EndAutoNests")); + autonest = subst(autonest, from_ascii("\n"), docstring()); + autonest = subst(autonest, from_ascii("\t"), docstring()); + autonest = subst(autonest, from_ascii("\""), docstring()); + autonest = subst(autonest, '_', ' '); + vector const autonests = + getVectorFromString(autonest, from_ascii(","), false, true); + autonests_.insert(autonests.begin(), autonests.end()); + break; + } + + case LT_AUTONESTEDBY: { + docstring autonest = lex.getLongString(from_ascii("EndIsAutoNestedBy")); + autonest = subst(autonest, from_ascii("\n"), docstring()); + autonest = subst(autonest, from_ascii("\t"), docstring()); + autonest = subst(autonest, from_ascii("\""), docstring()); + autonest = subst(autonest, '_', ' '); + vector const autonests = + getVectorFromString(autonest, from_ascii(","), false, true); + autonested_by_.insert(autonests.begin(), autonests.end()); + break; + } + + case LT_REFPREFIX: { + docstring arg; + lex >> arg; + if (arg == "OFF") + refprefix.clear(); + else + refprefix = arg; + break; + } + + case LT_HTMLINTOC: + lex >> htmlintoc_; + break; + + case LT_HTMLTAG: + lex >> htmltag_; + break; + + case LT_HTMLATTR: + lex >> htmlattr_; + break; + + case LT_HTMLCLASS: + lex >> htmlclass_; + break; + + case LT_HTMLITEM: + lex >> htmlitemtag_; + break; + + case LT_HTMLITEMATTR: + lex >> htmlitemattr_; + break; + + case LT_HTMLLABEL: + lex >> htmllabeltag_; + break; + + case LT_HTMLLABELATTR: + lex >> htmllabelattr_; + break; + + case LT_HTMLLABELFIRST: + lex >> htmllabelfirst_; + break; + + case LT_HTMLSTYLE: + htmlstyle_ = lex.getLongString(from_ascii("EndHTMLStyle")); + break; + + case LT_HTMLFORCECSS: + lex >> htmlforcecss_; + break; + + case LT_HTMLPREAMBLE: + htmlpreamble_ = lex.getLongString(from_ascii("EndPreamble")); + break; + + case LT_HTMLTITLE: + lex >> htmltitle_; + break; + + case LT_DOCBOOKTAG: + lex >> docbooktag_; + break; + + case LT_DOCBOOKATTR: + lex >> docbookattr_; + break; + + case LT_DOCBOOKTAGTYPE: + lex >> docbooktagtype_; + break; + + case LT_DOCBOOKINNERTAG: + lex >> docbookinnertag_; + break; + + case LT_DOCBOOKINNERATTR: + lex >> docbookinnerattr_; + break; + + case LT_DOCBOOKINNERTAGTYPE: + lex >> docbookinnertagtype_; + break; + + case LT_DOCBOOKFORCEABSTRACTTAG: + lex >> docbookforceabstracttag_; + break; + + case LT_DOCBOOKININFO: + lex >> docbookininfo_; + break; + + case LT_DOCBOOKABSTRACT: + lex >> docbookabstract_; + break; + + case LT_DOCBOOKWRAPPERTAG: + lex >> docbookwrappertag_; + break; + + case LT_DOCBOOKWRAPPERATTR: + lex >> docbookwrapperattr_; + break; + + case LT_DOCBOOKWRAPPERTAGTYPE: + lex >> docbookwrappertagtype_; + break; + + case LT_DOCBOOKWRAPPERMERGEWITHPREVIOUS: + lex >> docbookwrappermergewithprevious_; + break; + + case LT_DOCBOOKSECTION: + lex >> docbooksection_; + break; + + case LT_DOCBOOKSECTIONTAG: + lex >> docbooksectiontag_; + break; + + case LT_DOCBOOKITEMWRAPPERTAG: + lex >> docbookitemwrappertag_; + break; + + case LT_DOCBOOKITEMWRAPPERATTR: + lex >> docbookitemwrapperattr_; + break; + + case LT_DOCBOOKITEMWRAPPERTAGTYPE: + lex >> docbookitemwrappertagtype_; + break; + + case LT_DOCBOOKITEMTAG: + lex >> docbookitemtag_; + break; + + case LT_DOCBOOKITEMATTR: + lex >> docbookitemattr_; + break; + + case LT_DOCBOOKITEMTAGTYPE: + lex >> docbookitemtagtype_; + break; + + case LT_DOCBOOKITEMLABELTAG: + lex >> docbookitemlabeltag_; + break; + + case LT_DOCBOOKITEMLABELATTR: + lex >> docbookitemlabelattr_; + break; + + case LT_DOCBOOKITEMLABELTAGTYPE: + lex >> docbookitemlabeltagtype_; + break; + + case LT_DOCBOOKITEMINNERTAG: + lex >> docbookiteminnertag_; + break; + + case LT_DOCBOOKITEMINNERATTR: + lex >> docbookiteminnerattr_; + break; + + case LT_DOCBOOKITEMINNERTAGTYPE: + lex >> docbookiteminnertagtype_; + break; + + case LT_DOCBOOKNOFONTINSIDE: + lex >> docbooknofontinside_; + break; + + case LT_DOCBOOKGENERATETITLE: + lex >> docbookgeneratetitle_; + break; + + case LT_SPELLCHECK: + lex >> spellcheck; + break; + + case LT_FORCELOCAL: + lex >> forcelocal; + break; + + case LT_ADDTOTOC: + lex >> toc_type_; + add_to_toc_ = !toc_type_.empty(); + break; + + case LT_ISTOCCAPTION: + lex >> is_toc_caption_; break; } } lex.popTable(); + // make sure we only have inpreamble = true for commands + if (inpreamble && latextype != LATEX_COMMAND && latextype != LATEX_PARAGRAPH) { + LYXERR0("InPreamble not permitted except with command and paragraph layouts."); + LYXERR0("Layout name: " << name()); + inpreamble = false; + } - return !error; + return finished && !error; } @@ -558,11 +997,10 @@ void Layout::readLabelType(Lexer & lex) enum { LA_NO_LABEL = 1, LA_MANUAL, - LA_TOP_ENVIRONMENT, - LA_CENTERED_TOP_ENVIRONMENT, + LA_ABOVE, + LA_CENTERED, LA_STATIC, LA_SENSITIVE, - LA_COUNTER, LA_ENUMERATE, LA_ITEMIZE, LA_BIBLIO @@ -570,16 +1008,15 @@ void Layout::readLabelType(Lexer & lex) LexerKeyword labelTypeTags[] = { - { "bibliography", LA_BIBLIO }, - { "centered_top_environment", LA_CENTERED_TOP_ENVIRONMENT }, - { "counter", LA_COUNTER }, - { "enumerate", LA_ENUMERATE }, - { "itemize", LA_ITEMIZE }, - { "manual", LA_MANUAL }, - { "no_label", LA_NO_LABEL }, - { "sensitive", LA_SENSITIVE }, - { "static", LA_STATIC }, - { "top_environment", LA_TOP_ENVIRONMENT } + { "above", LA_ABOVE }, + { "bibliography", LA_BIBLIO }, + { "centered", LA_CENTERED }, + { "enumerate", LA_ENUMERATE }, + { "itemize", LA_ITEMIZE }, + { "manual", LA_MANUAL }, + { "no_label", LA_NO_LABEL }, + { "sensitive", LA_SENSITIVE }, + { "static", LA_STATIC } }; PushPopHelper pph(lex, labelTypeTags); @@ -597,11 +1034,11 @@ void Layout::readLabelType(Lexer & lex) case LA_MANUAL: labeltype = LABEL_MANUAL; break; - case LA_TOP_ENVIRONMENT: - labeltype = LABEL_TOP_ENVIRONMENT; + case LA_ABOVE: + labeltype = LABEL_ABOVE; break; - case LA_CENTERED_TOP_ENVIRONMENT: - labeltype = LABEL_CENTERED_TOP_ENVIRONMENT; + case LA_CENTERED: + labeltype = LABEL_CENTERED; break; case LA_STATIC: labeltype = LABEL_STATIC; @@ -609,9 +1046,6 @@ void Layout::readLabelType(Lexer & lex) case LA_SENSITIVE: labeltype = LABEL_SENSITIVE; break; - case LA_COUNTER: - labeltype = LABEL_COUNTER; - break; case LA_ENUMERATE: labeltype = LABEL_ENUMERATE; break; @@ -627,6 +1061,8 @@ void Layout::readLabelType(Lexer & lex) void Layout::readEndLabelType(Lexer & lex) { + // this should be const, but can't be because + // of PushPopHelper. static LexerKeyword endlabelTypeTags[] = { { "box", END_LABEL_BOX }, { "filled_box", END_LABEL_FILLED_BOX }, @@ -703,12 +1139,15 @@ void Layout::readLatexType(Lexer & lex) return; case LATEX_PARAGRAPH: case LATEX_COMMAND: - case LATEX_ENVIRONMENT: case LATEX_ITEM_ENVIRONMENT: - case LATEX_BIB_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: latextype = static_cast(le); break; + case LATEX_ENVIRONMENT: + case LATEX_BIB_ENVIRONMENT: + latextype = static_cast(le); + par_group_ = true; + break; default: LYXERR0("Unhandled value " << le); break; @@ -758,76 +1197,989 @@ void Layout::readSpacing(Lexer & lex) } -docstring const & Layout::name() const +void Layout::readArgument(Lexer & lex, bool validating) +{ + if (!lex.next()) { + LYXERR0("Unable to read argument ID!"); + return; + } + string const id = lex.getString(); + + bool const itemarg = prefixIs(id, "item:"); + bool const postcmd = prefixIs(id, "post:"); + bool const listpreamble = prefixIs(id, "listpreamble:"); + + LaTeXArgMap & lam = itemarg ? itemargs_ : + (postcmd ? postcommandargs_ : + (listpreamble ? listpreamble_ : + latexargs_)); + latexarg & arg = lam[id]; + + if (listpreamble) + // list preamble has no delimiters by default + arg.nodelims = true; + + bool error = false; + bool finished = false; + while (!finished && lex.isOK() && !error) { + lex.next(); + string const tok = ascii_lowercase(lex.getString()); + + if (tok.empty()) { + continue; + } else if (tok == "endargument") { + finished = true; + } else if (tok == "labelstring") { + lex.next(); + arg.labelstring = lex.getDocString(); + } else if (tok == "menustring") { + lex.next(); + arg.menustring = lex.getDocString(); + } else if (tok == "mandatory") { + lex.next(); + arg.mandatory = lex.getBool(); + } else if (tok == "autoinsert") { + lex.next(); + arg.autoinsert = lex.getBool(); + } else if (tok == "insertcotext") { + lex.next(); + arg.insertcotext = lex.getBool(); + } else if (tok == "leftdelim") { + lex.next(); + arg.ldelim = lex.getDocString(); + arg.ldelim = support::subst(arg.ldelim, from_ascii("
"), + from_ascii("\n")); + } else if (tok == "rightdelim") { + lex.next(); + arg.rdelim = lex.getDocString(); + arg.rdelim = support::subst(arg.rdelim, from_ascii("
"), + from_ascii("\n")); + } else if (tok == "defaultarg") { + lex.next(); + arg.defaultarg = lex.getDocString(); + } else if (tok == "presetarg") { + lex.next(); + arg.presetarg = lex.getDocString(); + } else if (tok == "tooltip") { + lex.next(); + arg.tooltip = lex.getDocString(); + } else if (tok == "requires") { + lex.eatLine(); + arg.required = lex.getString(); + } else if (tok == "decoration") { + lex.next(); + arg.decoration = lex.getString(); + } else if (tok == "newlinecmd") { + lex.next(); + arg.newlinecmd = lex.getString(); + } else if (tok == "font") { + arg.font = lyxRead(lex, arg.font); + } else if (tok == "labelfont") { + arg.labelfont = lyxRead(lex, arg.labelfont); + } else if (tok == "passthruchars") { + lex.next(); + arg.pass_thru_chars = lex.getDocString(); + } else if (tok == "passthru") { + lex.next(); + docstring value = lex.getDocString(); + if (value == "true" || value == "1") + arg.passthru = PT_TRUE; + else if (value == "false" || value == "0") + arg.passthru = PT_FALSE; + else + arg.passthru = PT_INHERITED; + } else if (tok == "istoccaption") { + lex.next(); + arg.is_toc_caption = lex.getBool(); + } else if (tok == "freespacing") { + lex.next(); + arg.free_spacing = lex.getBool(); + } else if (tok == "docbooktag") { + lex.next(); + arg.docbooktag = lex.getDocString(); + } else if (tok == "docbookattr") { + lex.next(); + arg.docbookattr = lex.getDocString(); + } else if (tok == "docbooktagtype") { + lex.next(); + arg.docbooktagtype = lex.getDocString(); + } else if (tok == "docbookargumentaftermaintag") { + lex.next(); + arg.docbookargumentaftermaintag = lex.getBool(); + } else if (tok == "docbookargumentbeforemaintag") { + lex.next(); + arg.docbookargumentbeforemaintag = lex.getBool(); + } else { + lex.printError("Unknown tag"); + error = true; + } + } + if (!validating && arg.labelstring.empty()) { + LYXERR0("Incomplete Argument definition!"); + // remove invalid definition + lam.erase(id); + } +} + + +void writeArgument(ostream & os, string const & id, Layout::latexarg const & arg) +{ + os << "\tArgument " << id << '\n'; + if (!arg.labelstring.empty()) + os << "\t\tLabelString \"" << to_utf8(arg.labelstring) << "\"\n"; + if (!arg.menustring.empty()) + os << "\t\tMenuString \"" << to_utf8(arg.menustring) << "\"\n"; + if (arg.mandatory) + os << "\t\tMandatory " << arg.mandatory << '\n'; + if (arg.autoinsert) + os << "\t\tAutoinsert " << arg.autoinsert << '\n'; + if (arg.insertcotext) + os << "\t\tInsertCotext " << arg.insertcotext << '\n'; + if (!arg.ldelim.empty()) + os << "\t\tLeftDelim \"" + << to_utf8(subst(arg.ldelim, from_ascii("\n"), from_ascii("
"))) + << "\"\n"; + if (!arg.rdelim.empty()) + os << "\t\tRightDelim \"" + << to_utf8(subst(arg.rdelim, from_ascii("\n"), from_ascii("
"))) + << "\"\n"; + if (!arg.defaultarg.empty()) + os << "\t\tDefaultArg \"" << to_utf8(arg.defaultarg) << "\"\n"; + if (!arg.presetarg.empty()) + os << "\t\tPresetArg \"" << to_utf8(arg.presetarg) << "\"\n"; + if (!arg.tooltip.empty()) + os << "\t\tToolTip \"" << to_utf8(arg.tooltip) << "\"\n"; + if (!arg.required.empty()) + os << "\t\tRequires " << arg.required << "\n"; + if (!arg.decoration.empty()) + os << "\t\tDecoration \"" << arg.decoration << "\"\n"; + if (!arg.newlinecmd.empty()) + os << "\t\tNewlineCmd \"" << arg.newlinecmd << "\"\n"; + if (arg.font != inherit_font) + lyxWrite(os, arg.font, "Font", 2); + if (arg.labelfont != inherit_font) + lyxWrite(os, arg.labelfont, "LabelFont", 2); + switch (arg.passthru) { + case PT_TRUE: + os << "\t\tPassThru true\n"; + break; + case PT_FALSE: + os << "\t\tPassThru false\n"; + break; + case PT_INHERITED: + os << "\t\tPassThru inherited\n"; + break; + } + if (!arg.pass_thru_chars.empty()) + os << "\t\tPassThruChars \"" << to_utf8(arg.pass_thru_chars) << "\"\n"; + if (arg.free_spacing) + os << "\t\tFreeSpacing " << arg.free_spacing << "\n"; + os << "\tEndArgument\n"; +} + + +void Layout::write(ostream & os) const +{ + os << "Style \"" << to_utf8(name_) << "\"\n"; + if (!category_.empty() && obsoleted_by_.empty()) + os << "\tCategory \"" << to_utf8(category_) << "\"\n"; + // Can't deduce Copystyle here :-( + if (!obsoleted_by_.empty()) { + os << "\tObsoletedBy \"" << to_utf8(obsoleted_by_) + << "\"\nEnd\n"; + return; + } + if (!depends_on_.empty()) + os << "\tDependsOn " << to_utf8(depends_on_) << '\n'; + switch (margintype) { + case MARGIN_DYNAMIC: + os << "\tMargin Dynamic\n"; + break; + case MARGIN_FIRST_DYNAMIC: + os << "\tMargin First_Dynamic\n"; + break; + case MARGIN_MANUAL: + os << "\tMargin Manual\n"; + break; + case MARGIN_RIGHT_ADDRESS_BOX: + os << "\tMargin Right_Address_Box\n"; + break; + case MARGIN_STATIC: + os << "\tMargin Static\n"; + break; + } + switch (latextype) { + case LATEX_BIB_ENVIRONMENT: + os << "\tLatexType Bib_Environment\n"; + break; + case LATEX_COMMAND: + os << "\tLatexType Command\n"; + break; + case LATEX_ENVIRONMENT: + os << "\tLatexType Environment\n"; + break; + case LATEX_ITEM_ENVIRONMENT: + os << "\tLatexType Item_Environment\n"; + break; + case LATEX_LIST_ENVIRONMENT: + os << "\tLatexType List_Environment\n"; + break; + case LATEX_PARAGRAPH: + os << "\tLatexType Paragraph\n"; + break; + } + os << "\tInTitle " << intitle << "\n" + "\tInPreamble " << inpreamble << "\n" + "\tTocLevel " << toclevel << "\n" + "\tResumeCounter " << resumecounter << "\n" + "\tStepParentCounter " << stepparentcounter << '\n'; + // ResetArgs does not make sense here + for (LaTeXArgMap::const_iterator it = latexargs_.begin(); + it != latexargs_.end(); ++it) + writeArgument(os, it->first, it->second); + for (LaTeXArgMap::const_iterator it = itemargs_.begin(); + it != itemargs_.end(); ++it) + writeArgument(os, it->first, it->second); + for (LaTeXArgMap::const_iterator it = postcommandargs_.begin(); + it != postcommandargs_.end(); ++it) + writeArgument(os, it->first, it->second); + for (LaTeXArgMap::const_iterator it = listpreamble_.begin(); + it != listpreamble_.end(); ++it) + writeArgument(os, it->first, it->second); + os << "\tNeedProtect " << needprotect << "\n" + "\tNeedCProtect " << needcprotect << "\n" + "\tNeedMBoxProtect " << needmboxprotect << "\n" + "\tKeepEmpty " << keepempty << '\n'; + if (labelfont == font) + lyxWrite(os, font, "Font", 1); + else { + lyxWrite(os, font, "TextFont", 1); + lyxWrite(os, labelfont, "LabelFont", 1); + } + os << "\tNextNoIndent " << nextnoindent << "\n" + "\tCommandDepth " << commanddepth << '\n'; + if (!latexname_.empty()) + os << "\tLatexName \"" << latexname_ << "\"\n"; + if (!latexparam_.empty()) + os << "\tLatexParam \"" << subst(latexparam_, "\"", """) + << "\"\n"; + if (!leftdelim_.empty()) + os << "\tLeftDelim " + << to_utf8(subst(leftdelim_, from_ascii("\n"), from_ascii("
"))) + << '\n'; + if (!rightdelim_.empty()) + os << "\tRightDelim " + << to_utf8(subst(rightdelim_, from_ascii("\n"), from_ascii("
"))) + << '\n'; + if (!innertag_.empty()) + os << "\tInnerTag \"" << innertag_ << "\"\n"; + if (!labeltag_.empty()) + os << "\tLabelTag \"" << labeltag_ << "\"\n"; + if (!itemtag_.empty()) + os << "\tItemTag \"" << itemtag_ << "\"\n"; + if (!itemcommand_.empty()) + os << "\tItemCommand " << itemcommand_ << '\n'; + if (!preamble_.empty()) + os << "\tPreamble\n\t" + << to_utf8(subst(rtrim(preamble_, "\n"), + from_ascii("\n"), from_ascii("\n\t"))) + << "\n\tEndPreamble\n"; + if (!langpreamble_.empty()) + os << "\tLangPreamble\n\t" + << to_utf8(subst(rtrim(langpreamble_, "\n"), + from_ascii("\n"), from_ascii("\n\t"))) + << "\n\tEndLangPreamble\n"; + if (!babelpreamble_.empty()) + os << "\tBabelPreamble\n\t" + << to_utf8(subst(rtrim(babelpreamble_, "\n"), + from_ascii("\n"), from_ascii("\n\t"))) + << "\n\tEndBabelPreamble\n"; + switch (labeltype) { + case LABEL_ABOVE: + os << "\tLabelType Above\n"; + break; + case LABEL_BIBLIO: + os << "\tLabelType Bibliography\n"; + break; + case LABEL_CENTERED: + os << "\tLabelType Centered\n"; + break; + case LABEL_ENUMERATE: + os << "\tLabelType Enumerate\n"; + break; + case LABEL_ITEMIZE: + os << "\tLabelType Itemize\n"; + break; + case LABEL_MANUAL: + os << "\tLabelType Manual\n"; + break; + case LABEL_NO_LABEL: + os << "\tLabelType No_Label\n"; + break; + case LABEL_SENSITIVE: + os << "\tLabelType Sensitive\n"; + break; + case LABEL_STATIC: + os << "\tLabelType Static\n"; + break; + } + switch (endlabeltype) { + case END_LABEL_BOX: + os << "\tEndLabelType Box\n"; + break; + case END_LABEL_FILLED_BOX: + os << "\tEndLabelType Filled_Box\n"; + break; + case END_LABEL_NO_LABEL: + os << "\tEndLabelType No_Label\n"; + break; + case END_LABEL_STATIC: + os << "\tEndLabelType Static\n"; + break; + } + os << "\tParagraphGroup \"" << par_group_ << "\"\n"; + if (!leftmargin.empty()) + os << "\tLeftMargin \"" << to_utf8(leftmargin) << "\"\n"; + if (!rightmargin.empty()) + os << "\tRightMargin \"" << to_utf8(rightmargin) << "\"\n"; + if (!labelindent.empty()) + os << "\tLabelIndent " << to_utf8(labelindent) << '\n'; + if (!parindent.empty()) + os << "\tParIndent " << to_utf8(parindent) << '\n'; + os << "\tParSkip " << parskip << "\n" + "\tItemSep " << itemsep << "\n" + "\tTopSep " << topsep << "\n" + "\tBottomSep " << bottomsep << "\n" + "\tLabelBottomSep " << labelbottomsep << '\n'; + if (!labelsep.empty()) + os << "\tLabelSep " << to_utf8(subst(labelsep, ' ', 'x')) + << '\n'; + os << "\tParSep " << parsep << "\n" + "\tNewLine " << newline_allowed << '\n'; + switch (align) { + case LYX_ALIGN_BLOCK: + os << "\tAlign Block\n"; + break; + case LYX_ALIGN_CENTER: + os << "\tAlign Center\n"; + break; + case LYX_ALIGN_LAYOUT: + os << "\tAlign Layout\n"; + break; + case LYX_ALIGN_LEFT: + os << "\tAlign Left\n"; + break; + case LYX_ALIGN_RIGHT: + os << "\tAlign Right\n"; + break; + case LYX_ALIGN_DECIMAL: + case LYX_ALIGN_SPECIAL: + case LYX_ALIGN_NONE: + break; + } + if (alignpossible & (LYX_ALIGN_BLOCK | LYX_ALIGN_CENTER | + LYX_ALIGN_LAYOUT | LYX_ALIGN_LEFT | LYX_ALIGN_RIGHT)) { + bool first = true; + os << "\tAlignPossible"; + if (alignpossible & LYX_ALIGN_BLOCK) { + os << " Block"; + first = false; + } + if (alignpossible & LYX_ALIGN_CENTER) { + if (!first) + os << ','; + os << " Center"; + first = false; + } + if (alignpossible & LYX_ALIGN_LAYOUT) { + if (!first) + os << ','; + os << " Layout"; + first = false; + } + if (alignpossible & LYX_ALIGN_LEFT) { + if (!first) + os << ','; + os << " Left"; + first = false; + } + if (alignpossible & LYX_ALIGN_RIGHT) { + if (!first) + os << ','; + os << " Right"; + first = false; + } + os << '\n'; + } + // LabelString must come before LabelStringAppendix + if (!labelstring_.empty()) + os << "\tLabelString \"" << to_utf8(labelstring_) << "\"\n"; + if (!endlabelstring_.empty()) + os << "\tEndLabelString \"" << to_utf8(endlabelstring_) << "\"\n"; + if (!labelstring_appendix_.empty() && labelstring_appendix_ != labelstring_) + os << "\tLabelStringAppendix \"" + << to_utf8(labelstring_appendix_) << "\"\n"; + if (!counter.empty()) + os << "\tLabelCounter \"" << to_utf8(counter) << "\"\n"; + os << "\tFreeSpacing " << free_spacing << '\n'; + os << "\tPassThru " << pass_thru << '\n'; + if (!pass_thru_chars.empty()) + os << "\tPassThruChars " << to_utf8(pass_thru_chars) << '\n'; + os << "\tParbreakIsNewline " << parbreak_is_newline << '\n'; + switch (spacing.getSpace()) { + case Spacing::Double: + os << "\tSpacing Double\n"; + break; + case Spacing::Onehalf: + os << "\tSpacing Onehalf\n"; + break; + case Spacing::Other: + os << "\tSpacing Other " << spacing.getValueAsString() << '\n'; + break; + case Spacing::Single: + os << "\tSpacing Single\n"; + break; + case Spacing::Default: + break; + } + if (!required_.empty()) { + os << "\tRequires "; + for (set::const_iterator it = required_.begin(); + it != required_.end(); ++it) { + if (it != required_.begin()) + os << ','; + os << *it; + } + os << '\n'; + } + if (!autonests_.empty()) { + os << "\tAutoNests\n\t"; + for (set::const_iterator it = autonests_.begin(); + it != autonests_.end(); ++it) { + if (it != autonests_.begin()) + os << ','; + os << to_utf8(*it); + } + os << "\n\tEndAutoNests\n"; + } + if (!autonested_by_.empty()) { + os << "\tIsAutoNestedBy\n\t\t"; + for (set::const_iterator it = autonested_by_.begin(); + it != autonested_by_.end(); ++it) { + if (it != autonested_by_.begin()) + os << ','; + os << to_utf8(*it); + } + os << "\n\tEndIsAutoNestedBy\n"; + } + if (refprefix.empty()) + os << "\tRefPrefix OFF\n"; + else + os << "\tRefPrefix " << to_utf8(refprefix) << '\n'; + if (!htmltag_.empty()) + os << "\tHTMLTag " << htmltag_ << '\n'; + if (!htmlattr_.empty()) + os << "\tHTMLAttr " << htmlattr_ << '\n'; + if (!htmlclass_.empty()) + os << "\tHTMLClass " << htmlclass_ << '\n'; + if (!htmlintoc_) + os << "\tHTMLInToc " << htmlintoc_ << '\n'; + if (!htmlitemtag_.empty()) + os << "\tHTMLItem " << htmlitemtag_ << '\n'; + if (!htmlitemattr_.empty()) + os << "\tHTMLItemAttr " << htmlitemattr_ << '\n'; + if (!htmllabeltag_.empty()) + os << "\tHTMLLabel " << htmllabeltag_ << '\n'; + if (!htmllabelattr_.empty()) + os << "\tHTMLLabelAttr " << htmllabelattr_ << '\n'; + os << "\tHTMLLabelFirst " << htmllabelfirst_ << '\n'; + if (!htmlstyle_.empty()) + os << "\tHTMLStyle\n" + << to_utf8(rtrim(htmlstyle_, "\n")) + << "\n\tEndHTMLStyle\n"; + os << "\tHTMLForceCSS " << htmlforcecss_ << '\n'; + if (!htmlpreamble_.empty()) + os << "\tHTMLPreamble\n" + << to_utf8(rtrim(htmlpreamble_, "\n")) + << "\n\tEndPreamble\n"; + os << "\tHTMLTitle " << htmltitle_ << "\n"; + if (!docbooktag_.empty()) + os << "\tDocBookTag " << docbooktag_ << '\n'; + if (!docbookattr_.empty()) + os << "\tDocBookAttr \"" << docbookattr_ << "\"\n"; + if (!docbooktagtype_.empty()) + os << "\tDocBookTagType " << docbooktagtype_ << '\n'; + if (!docbookinnertag_.empty()) + os << "\tDocBookInnerTag " << docbookinnertag_ << '\n'; + if (!docbookinnerattr_.empty()) + os << "\tDocBookInnerAttr \"" << docbookinnerattr_ << "\"\n"; + if (!docbookinnertagtype_.empty()) + os << "\tDocBookInnerTagType " << docbookinnertagtype_ << '\n'; + if (!docbookininfo_.empty()) + os << "\tDocBookInInfo " << docbookininfo_ << '\n'; + os << "\tDocBookAbstract " << docbookabstract_ << '\n'; + if (!docbookwrappertag_.empty()) + os << "\tDocBookWrapperTag " << docbookwrappertag_ << '\n'; + if (!docbookwrapperattr_.empty()) + os << "\tDocBookWrapperAttr " << docbookwrapperattr_ << '\n'; + if (!docbookwrappertagtype_.empty()) + os << "\tDocBookWrapperTagType " << docbookwrappertagtype_ << '\n'; + os << "\tDocBookSection " << docbooksection_ << '\n'; + if (!docbooksectiontag_.empty()) + os << "\tDocBookSectionTag " << docbooksectiontag_ << '\n'; + if (!docbookitemtag_.empty()) + os << "\tDocBookItemTag " << docbookitemtag_ << '\n'; + if (!docbookitemattr_.empty()) + os << "\tDocBookItemAttr " << docbookitemattr_ << '\n'; + if (!docbookitemtagtype_.empty()) + os << "\tDocBookItemTagType " << docbookitemtagtype_ << '\n'; + if (!docbookitemwrappertag_.empty()) + os << "\tDocBookItemWrapperTag " << docbookitemwrappertag_ << '\n'; + if (!docbookitemwrapperattr_.empty()) + os << "\tDocBookItemWrapperAttr " << docbookitemwrapperattr_ << '\n'; + if (!docbookitemwrappertagtype_.empty()) + os << "\tDocBookItemWrapperTagType " << docbookitemwrappertagtype_ << '\n'; + os << "\tDocBookWrapperMergeWithPrevious " << docbookwrappermergewithprevious_ << '\n'; + if (!docbookitemlabeltag_.empty()) + os << "\tDocBookItemLabelTag " << docbookitemlabeltag_ << '\n'; + if (!docbookitemlabelattr_.empty()) + os << "\tDocBookItemLabelAttr " << docbookitemlabelattr_ << '\n'; + if (!docbookitemlabeltagtype_.empty()) + os << "\tDocBookItemLabelTagType " << docbookitemlabeltagtype_ << '\n'; + if (!docbookiteminnertag_.empty()) + os << "\tDocBookItemInnerTag " << docbookiteminnertag_ << '\n'; + if (!docbookiteminnerattr_.empty()) + os << "\tDocBookItemInnerAttr " << docbookiteminnerattr_ << '\n'; + if (!docbookiteminnertagtype_.empty()) + os << "\tDocBookItemInnerTagType " << docbookiteminnertagtype_ << '\n'; + if (!docbookforceabstracttag_.empty()) + os << "\tDocBookForceAbstractTag " << docbookforceabstracttag_ << '\n'; + os << "\tDocBookNoFontInside " << docbooknofontinside_ << "\n" + "\tSpellcheck " << spellcheck << "\n" + "\tForceLocal " << forcelocal << "\n" + "End\n"; +} + + +bool Layout::hasArgs() const { - return name_; + return !latexargs_.empty() || !postcommandargs_.empty() || + !itemargs_.empty() || !listpreamble_.empty(); } -void Layout::setName(docstring const & name) +Layout::LaTeXArgMap Layout::args() const { - name_ = name; + LaTeXArgMap args = latexargs_; + if (!postcommandargs_.empty()) + args.insert(postcommandargs_.begin(), postcommandargs_.end()); + if (!listpreamble_.empty()) + args.insert(listpreamble_.begin(), listpreamble_.end()); + if (!itemargs_.empty()) + args.insert(itemargs_.begin(), itemargs_.end()); + return args; } -docstring const & Layout::obsoleted_by() const +int Layout::optArgs() const { - return obsoleted_by_; + int nr = 0; + LaTeXArgMap::const_iterator it = latexargs_.begin(); + for (; it != latexargs_.end(); ++it) { + if (!(*it).second.mandatory) + ++nr; + } + LaTeXArgMap::const_iterator iit = postcommandargs_.begin(); + for (; iit != postcommandargs_.end(); ++iit) { + if (!(*iit).second.mandatory) + ++nr; + } + return nr; } -docstring const & Layout::depends_on() const +int Layout::requiredArgs() const { - return depends_on_; + int nr = 0; + LaTeXArgMap::const_iterator it = latexargs_.begin(); + for (; it != latexargs_.end(); ++it) { + if ((*it).second.mandatory) + ++nr; + } + LaTeXArgMap::const_iterator iit = postcommandargs_.begin(); + for (; iit != postcommandargs_.end(); ++iit) { + if (!(*iit).second.mandatory) + ++nr; + } + return nr; } -namespace { +string const & Layout::htmltag() const +{ + if (htmltag_.empty()) + htmltag_ = "div"; + return htmltag_; +} -docstring const i18npreamble(Language const * lang, docstring const & templ) -{ - if (templ.empty()) - return templ; - - string preamble = subst(to_utf8(templ), "$$lang", lang->babel()); - -#ifdef TEX2LYX - // tex2lyx does not have getMessages() - LASSERT(false, /**/); -#else - // FIXME UNICODE - // boost::regex is not unicode-safe. - // Should use QRegExp or (boost::u32regex, but that requires ICU) - static boost::regex const reg("_\\(([^\\)]+)\\)"); - boost::smatch sub; - while (boost::regex_search(preamble, sub, reg)) { - string const key = sub.str(1); - string translated; - if (isAscii(key)) - translated = to_utf8(getMessages(lang->code()).get(key)); - else { - lyxerr << "Warning: not translating `" << key - << "' because it is not pure ASCII." << endl; - translated = key; - } - preamble = subst(preamble, sub.str(), translated); + +string const & Layout::htmlclass() const +{ + // If it's an enumeration or itemize list, then we recalculate the class each + // time through (unless it has been given explicitly). So we do nothing here. + if (htmlclass_.empty() && labeltype != LABEL_ENUMERATE && labeltype != LABEL_ITEMIZE) + htmlclass_ = defaultCSSClass(); + return htmlclass_; +} + + +string const & Layout::htmlGetAttrString() const { + if (!htmlfullattrs_.empty()) + return htmlfullattrs_; + htmlfullattrs_ = htmlclass(); + if (!htmlfullattrs_.empty()) + htmlfullattrs_ = "class='" + htmlfullattrs_ + "'"; + if (!htmlattr_.empty()) + htmlfullattrs_ += " " + htmlattr_; + return htmlfullattrs_; +} + + +string const & Layout::htmlitemtag() const +{ + if (htmlitemtag_.empty()) + htmlitemtag_ = "div"; + return htmlitemtag_; +} + + +string const & Layout::htmlitemattr() const +{ + if (htmlitemattr_.empty()) + htmlitemattr_ = "class=\"" + defaultCSSItemClass() + "\""; + return htmlitemattr_; +} + + +string const & Layout::htmllabeltag() const +{ + if (htmllabeltag_.empty()) + htmllabeltag_ = "span"; + return htmllabeltag_; +} + + +string const & Layout::htmllabelattr() const +{ + if (htmllabelattr_.empty()) + htmllabelattr_ = "class=\"" + defaultCSSLabelClass() + "\""; + return htmllabelattr_; +} + + +docstring Layout::htmlstyle() const +{ + if (!htmlstyle_.empty() && !htmlforcecss_) + return htmlstyle_; + if (htmldefaultstyle_.empty()) + makeDefaultCSS(); + docstring retval = htmldefaultstyle_; + if (!htmlstyle_.empty()) + retval += '\n' + htmlstyle_; + return retval; +} + + +string Layout::defaultCSSClass() const +{ + if (!defaultcssclass_.empty()) + return defaultcssclass_; + docstring d; + docstring::const_iterator it = name().begin(); + docstring::const_iterator en = name().end(); + for (; it != en; ++it) { + char_type const c = *it; + if (!isAlphaASCII(c)) { + if (d.empty()) + // make sure we don't start with an underscore, + // as that sometimes causes problems. + d = from_ascii("lyx_"); + else + d += '_'; + } else if (isLower(c)) + d += c; + else + // this is slow, so do it only if necessary + d += lowercase(c); + } + defaultcssclass_ = to_utf8(d); + return defaultcssclass_; +} + + +string const & Layout::docbooktag() const +{ + if (docbooktag_.empty()) { + if (to_ascii(name_) == "Plain Layout") + docbooktag_ = "para"; + else // No sensible default value, unhappily... + docbooktag_ = to_utf8(name_); } -#endif - return from_utf8(preamble); + return docbooktag_; +} + + +string const & Layout::docbookattr() const +{ + // Perfectly OK to return no attributes, so docbookattr_ does not need to be filled. + return docbookattr_; +} + + +bool isValidTagType(std::string const & type) +{ + return !(type.empty() || (type != "block" && type != "paragraph" && type != "inline")); } + +string const & Layout::docbooktagtype() const +{ + if (!isValidTagType(docbooktagtype_)) + docbooktagtype_ = "block"; + return docbooktagtype_; +} + + +string const & Layout::docbookinnertag() const +{ + if (docbookinnertag_.empty()) + docbookinnertag_ = "NONE"; + return docbookinnertag_; } -docstring const Layout::langpreamble(Language const * lang) const +string const & Layout::docbookinnerattr() const { - return i18npreamble(lang, langpreamble_); + return docbookinnerattr_; } -docstring const Layout::babelpreamble(Language const * lang) const +string const & Layout::docbookinnertagtype() const { - return i18npreamble(lang, babelpreamble_); + if (!isValidTagType(docbookinnertagtype_)) + docbookinnertagtype_ = "block"; + return docbookinnertagtype_; +} + + +string const & Layout::docbookininfo() const +{ + // Indeed, a trilean. Only titles should be "maybe": otherwise, metadata is "always", content is "never". + if (docbookininfo_.empty() || (docbookininfo_ != "never" && docbookininfo_ != "always" && docbookininfo_ != "maybe")) + docbookininfo_ = "never"; + return docbookininfo_; +} + + +string const & Layout::docbookwrappertag() const +{ + if (docbookwrappertag_.empty()) + docbookwrappertag_ = "NONE"; + return docbookwrappertag_; +} + + +string const & Layout::docbookwrapperattr() const +{ + return docbookwrapperattr_; +} + + +string const & Layout::docbookwrappertagtype() const +{ + if (!isValidTagType(docbookwrappertagtype_)) + docbookwrappertagtype_ = "block"; + return docbookwrappertagtype_; +} + + +string const & Layout::docbooksectiontag() const +{ + if (docbooksectiontag_.empty()) + docbooksectiontag_ = "section"; + return docbooksectiontag_; +} + + +string const & Layout::docbookitemwrappertag() const +{ + if (docbookitemwrappertag_.empty()) + docbookitemwrappertag_ = "NONE"; + return docbookitemwrappertag_; +} + + +string const & Layout::docbookitemwrapperattr() const +{ + return docbookitemwrapperattr_; +} + + +string const & Layout::docbookitemwrappertagtype() const +{ + if (!isValidTagType(docbookitemwrappertagtype_)) + docbookitemwrappertagtype_ = "block"; + return docbookitemwrappertagtype_; +} + + +string const & Layout::docbookitemtag() const +{ + if (docbookitemtag_.empty()) + docbookitemtag_ = "NONE"; + return docbookitemtag_; +} + + +string const & Layout::docbookitemattr() const +{ + return docbookitemattr_; +} + + +string const & Layout::docbookitemtagtype() const +{ + if (!isValidTagType(docbookitemtagtype_)) + docbookitemtagtype_ = "block"; + return docbookitemtagtype_; +} + + +string const & Layout::docbookitemlabeltag() const +{ + if (docbookitemlabeltag_.empty()) + docbookitemlabeltag_ = "NONE"; + return docbookitemlabeltag_; +} + + +string const & Layout::docbookitemlabelattr() const +{ + return docbookitemlabelattr_; +} + + +string const & Layout::docbookitemlabeltagtype() const +{ + if (!isValidTagType(docbookitemlabeltagtype_)) + docbookitemlabeltagtype_ = "block"; + return docbookitemlabeltagtype_; +} + + +string const & Layout::docbookiteminnertag() const +{ + if (docbookiteminnertag_.empty()) + docbookiteminnertag_ = "NONE"; + return docbookiteminnertag_; +} + + +string const & Layout::docbookiteminnerattr() const +{ + return docbookiteminnerattr_; +} + + +string const & Layout::docbookiteminnertagtype() const +{ + if (!isValidTagType(docbookiteminnertagtype_)) + docbookiteminnertagtype_ = "block"; + return docbookiteminnertagtype_; +} + + +std::string const & Layout::docbookforceabstracttag() const +{ + if (docbookforceabstracttag_.empty()) + docbookforceabstracttag_ = "NONE"; + return docbookforceabstracttag_; +} + + + +namespace { + +string makeMarginValue(char const * side, double d) +{ + ostringstream os; + os << "margin-" << side << ": " << d << "ex;\n"; + return os.str(); +} + +} // namespace + + +void Layout::makeDefaultCSS() const +{ + // this never needs to be redone, since reloading layouts will + // wipe out what we did before. + if (!htmldefaultstyle_.empty()) + return; + + // main font + htmldefaultstyle_ = font.asCSS(); + + // bottom margins + string tmp; + if (topsep > 0) + tmp += makeMarginValue("top", topsep); + if (bottomsep > 0) + tmp += makeMarginValue("bottom", bottomsep); + if (!leftmargin.empty()) { + // we can't really do what LyX does with the margin, so + // we'll just figure out how many characters it is + int const len = leftmargin.length(); + tmp += makeMarginValue("left", len); + } + if (!rightmargin.empty()) { + int const len = rightmargin.length(); + tmp += makeMarginValue("right", len); + } + + if (!tmp.empty()) { + if (!htmldefaultstyle_.empty()) + htmldefaultstyle_ += from_ascii("\n"); + htmldefaultstyle_ += from_ascii(tmp); + } + + // alignment + string where = alignmentToCSS(align); + if (!where.empty()) { + htmldefaultstyle_ += from_ascii("text-align: " + where + ";\n"); + } + + // wrap up what we have, if anything + if (!htmldefaultstyle_.empty()) + htmldefaultstyle_ = + from_ascii(htmltag() + "." + defaultCSSClass() + " {\n") + + htmldefaultstyle_ + from_ascii("\n}\n"); + + if (labeltype == LABEL_NO_LABEL || htmllabeltag() == "NONE") + return; + + docstring labelCSS; + + // label font + if (labelfont != font) + labelCSS = labelfont.asCSS() + from_ascii("\n"); + if (labeltype == LABEL_CENTERED) + labelCSS += from_ascii("text-align: center;\n"); + + if (!labelCSS.empty()) + htmldefaultstyle_ += + from_ascii(htmllabeltag() + "." + defaultCSSLabelClass() + " {\n") + + labelCSS + from_ascii("\n}\n"); }