+ os << "\\documentclass";
+
+ LyXTextClass const & tclass = getLyXTextClass();
+
+ ostringstream clsoptions; // the document class options.
+
+ if (tokenPos(tclass.opt_fontsize(),
+ '|', fontsize) >= 0) {
+ // only write if existing in list (and not default)
+ clsoptions << fontsize << "pt,";
+ }
+
+ // custom, A3, B3 and B4 paper sizes need geometry
+ bool nonstandard_papersize = (papersize == PAPER_B3) ||
+ (papersize == PAPER_B4) ||
+ (papersize == PAPER_A3) ||
+ (papersize == PAPER_CUSTOM);
+
+ if (!use_geometry) {
+ switch (papersize) {
+ case PAPER_A4:
+ clsoptions << "a4paper,";
+ break;
+ case PAPER_USLETTER:
+ clsoptions << "letterpaper,";
+ break;
+ case PAPER_A5:
+ clsoptions << "a5paper,";
+ break;
+ case PAPER_B5:
+ clsoptions << "b5paper,";
+ break;
+ case PAPER_USEXECUTIVE:
+ clsoptions << "executivepaper,";
+ break;
+ case PAPER_USLEGAL:
+ clsoptions << "legalpaper,";
+ break;
+ case PAPER_DEFAULT:
+ case PAPER_A3:
+ case PAPER_B3:
+ case PAPER_B4:
+ case PAPER_CUSTOM:
+ break;
+ }
+ }
+
+ // if needed
+ if (sides != tclass.sides()) {
+ switch (sides) {
+ case LyXTextClass::OneSide:
+ clsoptions << "oneside,";
+ break;
+ case LyXTextClass::TwoSides:
+ clsoptions << "twoside,";
+ break;
+ }
+ }
+
+ // if needed
+ if (columns != tclass.columns()) {
+ if (columns == 2)
+ clsoptions << "twocolumn,";
+ else
+ clsoptions << "onecolumn,";
+ }
+
+ if (!use_geometry
+ && orientation == ORIENTATION_LANDSCAPE)
+ clsoptions << "landscape,";
+
+ // language should be a parameter to \documentclass
+ if (language->babel() == "hebrew"
+ && default_language->babel() != "hebrew")
+ // This seems necessary
+ features.useLanguage(default_language);
+
+ ostringstream language_options;
+ bool const use_babel = features.useBabel();
+ if (use_babel) {
+ language_options << features.getLanguages();
+ language_options << language->babel();
+ if (lyxrc.language_global_options)
+ clsoptions << language_options.str() << ',';
+ }
+
+ // the user-defined options
+ if (!options.empty()) {
+ clsoptions << options << ',';
+ }
+
+ string strOptions(clsoptions.str());
+ if (!strOptions.empty()) {
+ strOptions = rtrim(strOptions, ",");
+ os << '[' << strOptions << ']';
+ }
+
+ os << '{' << tclass.latexname() << "}\n";
+ texrow.newline();
+ // end of \documentclass defs
+
+ // font selection must be done before loading fontenc.sty
+ // The ae package is not needed when using OT1 font encoding.
+ if (fonts != "default" &&
+ (fonts != "ae" || lyxrc.fontenc != "default")) {
+ os << "\\usepackage{" << fonts << "}\n";
+ texrow.newline();
+ if (fonts == "ae") {
+ os << "\\usepackage{aecompl}\n";
+ texrow.newline();
+ }
+ }
+ // this one is not per buffer
+ if (lyxrc.fontenc != "default") {
+ os << "\\usepackage[" << lyxrc.fontenc
+ << "]{fontenc}\n";
+ texrow.newline();
+ }
+
+ if (inputenc == "auto") {
+ string const doc_encoding =
+ language->encoding()->LatexName();
+
+ // Create a list with all the input encodings used
+ // in the document
+ std::set<string> encodings =
+ features.getEncodingSet(doc_encoding);
+
+ os << "\\usepackage[";
+ std::copy(encodings.begin(), encodings.end(),
+ std::ostream_iterator<string>(os, ","));
+ os << doc_encoding << "]{inputenc}\n";
+ texrow.newline();
+ } else if (inputenc != "default") {
+ os << "\\usepackage[" << inputenc
+ << "]{inputenc}\n";
+ texrow.newline();
+ }
+
+ if (use_geometry || nonstandard_papersize) {
+ os << "\\usepackage{geometry}\n";
+ texrow.newline();
+ os << "\\geometry{verbose";
+ if (orientation == ORIENTATION_LANDSCAPE)
+ os << ",landscape";
+ switch (papersize) {
+ case PAPER_CUSTOM:
+ if (!paperwidth.empty())
+ os << ",paperwidth="
+ << paperwidth;
+ if (!paperheight.empty())
+ os << ",paperheight="
+ << paperheight;
+ break;
+ case PAPER_USLETTER:
+ os << ",letterpaper";
+ break;
+ case PAPER_USLEGAL:
+ os << ",legalpaper";
+ break;
+ case PAPER_USEXECUTIVE:
+ os << ",executivepaper";
+ break;
+ case PAPER_A3:
+ os << ",a3paper";
+ break;
+ case PAPER_A4:
+ os << ",a4paper";
+ break;
+ case PAPER_A5:
+ os << ",a5paper";
+ break;
+ case PAPER_B3:
+ os << ",b3paper";
+ break;
+ case PAPER_B4:
+ os << ",b4paper";
+ break;
+ case PAPER_B5:
+ os << ",b5paper";
+ break;
+ default:
+ // default papersize ie PAPER_DEFAULT
+ switch (lyxrc.default_papersize) {
+ case PAPER_DEFAULT: // keep compiler happy
+ case PAPER_USLETTER:
+ os << ",letterpaper";
+ break;
+ case PAPER_USLEGAL:
+ os << ",legalpaper";
+ break;
+ case PAPER_USEXECUTIVE:
+ os << ",executivepaper";
+ break;
+ case PAPER_A3:
+ os << ",a3paper";
+ break;
+ case PAPER_A4:
+ os << ",a4paper";
+ break;
+ case PAPER_A5:
+ os << ",a5paper";
+ break;
+ case PAPER_B5:
+ os << ",b5paper";
+ break;
+ case PAPER_B3:
+ case PAPER_B4:
+ case PAPER_CUSTOM:
+ break;
+ }
+ }
+ if (!topmargin.empty())
+ os << ",tmargin=" << topmargin;
+ if (!bottommargin.empty())
+ os << ",bmargin=" << bottommargin;
+ if (!leftmargin.empty())
+ os << ",lmargin=" << leftmargin;
+ if (!rightmargin.empty())
+ os << ",rmargin=" << rightmargin;
+ if (!headheight.empty())
+ os << ",headheight=" << headheight;
+ if (!headsep.empty())
+ os << ",headsep=" << headsep;
+ if (!footskip.empty())
+ os << ",footskip=" << footskip;
+ os << "}\n";
+ texrow.newline();
+ }
+
+ if (tokenPos(tclass.opt_pagestyle(),
+ '|', pagestyle) >= 0) {
+ if (pagestyle == "fancy") {
+ os << "\\usepackage{fancyhdr}\n";
+ texrow.newline();
+ }
+ os << "\\pagestyle{" << pagestyle << "}\n";
+ texrow.newline();
+ }
+
+ if (secnumdepth != tclass.secnumdepth()) {
+ os << "\\setcounter{secnumdepth}{"
+ << secnumdepth
+ << "}\n";
+ texrow.newline();
+ }
+ if (tocdepth != tclass.tocdepth()) {
+ os << "\\setcounter{tocdepth}{"
+ << tocdepth
+ << "}\n";
+ texrow.newline();
+ }
+
+ if (paragraph_separation) {
+ switch (getDefSkip().kind()) {
+ case VSpace::SMALLSKIP:
+ os << "\\setlength\\parskip{\\smallskipamount}\n";
+ break;
+ case VSpace::MEDSKIP:
+ os << "\\setlength\\parskip{\\medskipamount}\n";
+ break;
+ case VSpace::BIGSKIP:
+ os << "\\setlength\\parskip{\\bigskipamount}\n";
+ break;
+ case VSpace::LENGTH:
+ os << "\\setlength\\parskip{"
+ << getDefSkip().length().asLatexString()
+ << "}\n";
+ break;
+ default: // should never happen // Then delete it.
+ os << "\\setlength\\parskip{\\medskipamount}\n";
+ break;
+ }
+ texrow.newline();
+
+ os << "\\setlength\\parindent{0pt}\n";
+ texrow.newline();
+ }
+
+ // If we use jurabib, we have to call babel here.
+ if (use_babel && features.isRequired("jurabib")) {
+ os << babelCall(language_options.str())
+ << '\n'
+ << features.getBabelOptions();
+ texrow.newline();
+ }
+
+ // Now insert the LyX specific LaTeX commands...
+
+ // The optional packages;
+ string lyxpreamble(features.getPackages());
+
+ // this might be useful...
+ lyxpreamble += "\n\\makeatletter\n";
+
+ // Some macros LyX will need
+ string tmppreamble(features.getMacros());
+
+ if (!tmppreamble.empty()) {
+ lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
+ "LyX specific LaTeX commands.\n"
+ + tmppreamble + '\n';
+ }
+
+ // the text class specific preamble
+ tmppreamble = features.getTClassPreamble();
+ if (!tmppreamble.empty()) {
+ lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
+ "Textclass specific LaTeX commands.\n"
+ + tmppreamble + '\n';
+ }
+
+ /* the user-defined preamble */
+ if (!preamble.empty()) {
+ lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
+ "User specified LaTeX commands.\n"
+ + preamble + '\n';
+ }
+
+ // Itemize bullet settings need to be last in case the user
+ // defines their own bullets that use a package included
+ // in the user-defined preamble -- ARRae
+ // Actually it has to be done much later than that
+ // since some packages like frenchb make modifications
+ // at \begin{document} time -- JMarc
+ string bullets_def;
+ for (int i = 0; i < 4; ++i) {
+ if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
+ if (bullets_def.empty())
+ bullets_def="\\AtBeginDocument{\n";
+ bullets_def += " \\renewcommand{\\labelitemi";
+ switch (i) {
+ // `i' is one less than the item to modify
+ case 0:
+ break;
+ case 1:
+ bullets_def += 'i';
+ break;
+ case 2:
+ bullets_def += "ii";
+ break;
+ case 3:
+ bullets_def += 'v';
+ break;
+ }
+ bullets_def += "}{" +
+ user_defined_bullet(i).getText()
+ + "}\n";
+ }
+ }
+
+ if (!bullets_def.empty())
+ lyxpreamble += bullets_def + "}\n\n";
+
+ // We try to load babel late, in case it interferes
+ // with other packages.
+ // Jurabib has to be called after babel, though.
+ if (use_babel && !features.isRequired("jurabib")) {
+ lyxpreamble += babelCall(language_options.str()) + '\n';
+ lyxpreamble += features.getBabelOptions();
+ }
+
+ lyxpreamble += "\\makeatother\n";
+
+ // dvipost settings come after everything else
+ if (features.isAvailable("dvipost") && tracking_changes && output_changes) {
+ lyxpreamble +=
+ "\\dvipostlayout\n"
+ "\\dvipost{osstart color push Red}\n"
+ "\\dvipost{osend color pop}\n"
+ "\\dvipost{cbstart color push Blue}\n"
+ "\\dvipost{cbend color pop}\n";
+ }
+
+ int const nlines =
+ int(lyx::count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
+ for (int j = 0; j != nlines; ++j) {
+ texrow.newline();
+ }
+
+ os << lyxpreamble;
+ return use_babel;