+ 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, ",");
+ // FIXME UNICODE
+ os << '[' << from_utf8(strOptions) << ']';
+ }
+
+ os << '{' << from_ascii(tclass.latexname()) << "}\n";
+ texrow.newline();
+ // end of \documentclass defs
+
+ // font selection must be done before loading fontenc.sty
+ string const fonts =
+ loadFonts(fontsRoman, fontsSans,
+ fontsTypewriter, fontsSC, fontsOSF,
+ fontsSansScale, fontsTypewriterScale);
+ if (!fonts.empty()) {
+ os << from_ascii(fonts);
+ texrow.newline();
+ }
+ if (fontsDefaultFamily != "default")
+ os << "\\renewcommand{\\familydefault}{\\"
+ << from_ascii(fontsDefaultFamily) << "}\n";
+ // this one is not per buffer
+ if (lyxrc.fontenc != "default") {
+ os << "\\usepackage[" << from_ascii(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);
+
+ // thailatex does not use the inputenc package, but sets up
+ // babel directly for tis620-0 encoding, therefore we must
+ // not request inputenc for tis620-0 encoding
+ if (!encodings.empty() || doc_encoding != "tis620-0") {
+ os << "\\usepackage[";
+ std::set<string>::const_iterator it = encodings.begin();
+ std::set<string>::const_iterator const end = encodings.end();
+ if (it != end) {
+ os << from_ascii(*it);
+ ++it;
+ }
+ for (; it != end; ++it)
+ os << ',' << from_ascii(*it);
+ if (doc_encoding != "tis620-0") {
+ if (!encodings.empty())
+ os << ',';
+ os << from_ascii(doc_encoding);
+ }
+ os << "]{inputenc}\n";
+ texrow.newline();
+ }
+ } else if (inputenc != "default" && inputenc != "tis620-0" &&
+ inputenc != "ascii") {
+ os << "\\usepackage[" << from_ascii(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="
+ << from_ascii(paperwidth);
+ if (!paperheight.empty())
+ os << ",paperheight="
+ << from_ascii(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=" << from_ascii(topmargin);
+ if (!bottommargin.empty())
+ os << ",bmargin=" << from_ascii(bottommargin);
+ if (!leftmargin.empty())
+ os << ",lmargin=" << from_ascii(leftmargin);
+ if (!rightmargin.empty())
+ os << ",rmargin=" << from_ascii(rightmargin);
+ if (!headheight.empty())
+ os << ",headheight=" << from_ascii(headheight);
+ if (!headsep.empty())
+ os << ",headsep=" << from_ascii(headsep);
+ if (!footskip.empty())
+ os << ",footskip=" << from_ascii(footskip);
+ os << "}\n";
+ texrow.newline();
+ }
+
+ if (tokenPos(tclass.opt_pagestyle(),
+ '|', pagestyle) >= 0) {
+ if (pagestyle == "fancy") {
+ os << "\\usepackage{fancyhdr}\n";
+ texrow.newline();
+ }
+ os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
+ texrow.newline();
+ }
+
+ // Only if class has a ToC hierarchy
+ if (tclass.hasTocLevels()) {
+ 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}{"
+ << from_utf8(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 << from_ascii(babelCall(language_options.str()))
+ << '\n'
+ << from_ascii(features.getBabelOptions());
+ texrow.newline();
+ }
+
+ // Now insert the LyX specific LaTeX commands...
+
+ // The optional packages;
+ docstring lyxpreamble(from_ascii(features.getPackages()));
+
+ // this might be useful...
+ lyxpreamble += "\n\\makeatletter\n";
+
+ // Some macros LyX will need
+ docstring tmppreamble(from_ascii(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()) {
+ // FIXME UNICODE
+ lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
+ "User specified LaTeX commands.\n"
+ + from_utf8(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
+ docstring 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 += " \\def\\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")) {
+ // FIXME UNICODE
+ lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
+ lyxpreamble += from_utf8(features.getBabelOptions());
+ }
+
+ lyxpreamble += "\\makeatother\n";
+
+ // dvipost settings come after everything else
+ if (features.isAvailable("dvipost") && outputChanges) {
+ 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;