/** * \file bufferparams.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Alfredo Braunstein * \author Lars Gullik Bjønnes * \author Jean-Marc Lasgouttes * \author John Levon * \author André Pönitz * \author Martin Vermeer * * Full author contact details are available in file CREDITS. */ #include #include "bufferparams.h" #include "author.h" #include "BranchList.h" #include "Bullet.h" #include "debug.h" #include "encoding.h" #include "gettext.h" #include "language.h" #include "LaTeXFeatures.h" #include "LColor.h" #include "lyxlex.h" #include "lyxrc.h" #include "lyxtextclasslist.h" #include "outputparams.h" #include "tex-strings.h" #include "Spacing.h" #include "texrow.h" #include "vspace.h" #include "frontends/Alert.h" #include "support/lyxalgo.h" // for lyx::count #include "support/convert.h" #include "support/translator.h" #include #include namespace support = lyx::support; using lyx::support::bformat; using lyx::support::rtrim; using lyx::support::tokenPos; using std::endl; using std::string; using std::istringstream; using std::ostream; using std::ostringstream; using std::pair; namespace biblio = lyx::biblio; // Local translators namespace { // Paragraph separation typedef Translator ParSepTranslator; ParSepTranslator const init_parseptranslator() { ParSepTranslator translator(string_paragraph_separation[0], BufferParams::PARSEP_INDENT); translator.addPair(string_paragraph_separation[1], BufferParams::PARSEP_SKIP); return translator; } ParSepTranslator const & parseptranslator() { static ParSepTranslator translator = init_parseptranslator(); return translator; } // Quotes language typedef Translator QuotesLangTranslator; QuotesLangTranslator const init_quoteslangtranslator() { QuotesLangTranslator translator(string_quotes_language[0], InsetQuotes::EnglishQ); translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQ); translator.addPair(string_quotes_language[2], InsetQuotes::GermanQ); translator.addPair(string_quotes_language[3], InsetQuotes::PolishQ); translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQ); translator.addPair(string_quotes_language[5], InsetQuotes::DanishQ); return translator; } QuotesLangTranslator const & quoteslangtranslator() { static QuotesLangTranslator translator = init_quoteslangtranslator(); return translator; } // Paper size typedef Translator PaperSizeTranslator; PaperSizeTranslator const init_papersizetranslator() { PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT); translator.addPair(string_papersize[1], PAPER_CUSTOM); translator.addPair(string_papersize[2], PAPER_USLETTER); translator.addPair(string_papersize[3], PAPER_USLEGAL); translator.addPair(string_papersize[4], PAPER_USEXECUTIVE); translator.addPair(string_papersize[5], PAPER_A3); translator.addPair(string_papersize[6], PAPER_A4); translator.addPair(string_papersize[7], PAPER_A5); translator.addPair(string_papersize[8], PAPER_B3); translator.addPair(string_papersize[9], PAPER_B4); translator.addPair(string_papersize[10], PAPER_B5); return translator; } PaperSizeTranslator const & papersizetranslator() { static PaperSizeTranslator translator = init_papersizetranslator(); return translator; } // Paper orientation typedef Translator PaperOrientationTranslator; PaperOrientationTranslator const init_paperorientationtranslator() { PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT); translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE); return translator; } PaperOrientationTranslator const & paperorientationtranslator() { static PaperOrientationTranslator translator = init_paperorientationtranslator(); return translator; } // Page sides typedef Translator SidesTranslator; SidesTranslator const init_sidestranslator() { SidesTranslator translator(1, LyXTextClass::OneSide); translator.addPair(2, LyXTextClass::TwoSides); return translator; } SidesTranslator const & sidestranslator() { static SidesTranslator translator = init_sidestranslator(); return translator; } // AMS typedef Translator AMSTranslator; AMSTranslator const init_amstranslator() { AMSTranslator translator(0, BufferParams::AMS_OFF); translator.addPair(1, BufferParams::AMS_AUTO); translator.addPair(2, BufferParams::AMS_ON); return translator; } AMSTranslator const & amstranslator() { static AMSTranslator translator = init_amstranslator(); return translator; } // Cite engine typedef Translator CiteEngineTranslator; CiteEngineTranslator const init_citeenginetranslator() { CiteEngineTranslator translator("basic", biblio::ENGINE_BASIC); translator.addPair("natbib_numerical", biblio::ENGINE_NATBIB_NUMERICAL); translator.addPair("natbib_authoryear", biblio::ENGINE_NATBIB_AUTHORYEAR); translator.addPair("jurabib", biblio::ENGINE_JURABIB); return translator; } CiteEngineTranslator const & citeenginetranslator() { static CiteEngineTranslator translator = init_citeenginetranslator(); return translator; } // Spacing typedef Translator SpaceTranslator; SpaceTranslator const init_spacetranslator() { SpaceTranslator translator("default", Spacing::Default); translator.addPair("single", Spacing::Single); translator.addPair("onehalf", Spacing::Onehalf); translator.addPair("double", Spacing::Double); translator.addPair("other", Spacing::Other); return translator; } SpaceTranslator const & spacetranslator() { static SpaceTranslator translator = init_spacetranslator(); return translator; } // ends annonym namespace } class BufferParams::Impl { public: Impl(); AuthorList authorlist; BranchList branchlist; boost::array temp_bullets; boost::array user_defined_bullets; Spacing spacing; /** This is the amount of space used for paragraph_separation "skip", * and for detached paragraphs in "indented" documents. */ VSpace defskip; }; BufferParams::Impl::Impl() : defskip(VSpace::MEDSKIP) { // set initial author authorlist.record(Author(lyxrc.user_name, lyxrc.user_email)); } BufferParams::Impl * BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr) { BOOST_ASSERT(ptr); return new BufferParams::Impl(*ptr); } void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr) { delete ptr; } BufferParams::BufferParams() : // Initialize textclass to point to article. if `first' is // true in the returned pair, then `second' is the textclass // number; if it is false, second is 0. In both cases, second // is what we want. textclass(textclasslist.NumberOfClass("article").second), pimpl_(new Impl) { paragraph_separation = PARSEP_INDENT; quotes_language = InsetQuotes::EnglishQ; fontsize = "default"; /* PaperLayout */ papersize = PAPER_DEFAULT; orientation = ORIENTATION_PORTRAIT; use_geometry = false; use_amsmath = AMS_AUTO; cite_engine = biblio::ENGINE_BASIC; use_bibtopic = false; tracking_changes = false; output_changes = false; secnumdepth = 3; tocdepth = 3; language = default_language; fonts = "default"; inputenc = "auto"; graphicsDriver = "default"; sides = LyXTextClass::OneSide; columns = 1; pagestyle = "default"; compressed = false; for (int iter = 0; iter < 4; ++iter) { user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter]; temp_bullet(iter) = ITEMIZE_DEFAULTS[iter]; } } BufferParams::~BufferParams() {} AuthorList & BufferParams::authors() { return pimpl_->authorlist; } AuthorList const & BufferParams::authors() const { return pimpl_->authorlist; } BranchList & BufferParams::branchlist() { return pimpl_->branchlist; } BranchList const & BufferParams::branchlist() const { return pimpl_->branchlist; } Bullet & BufferParams::temp_bullet(lyx::size_type const index) { BOOST_ASSERT(index < 4); return pimpl_->temp_bullets[index]; } Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const { BOOST_ASSERT(index < 4); return pimpl_->temp_bullets[index]; } Bullet & BufferParams::user_defined_bullet(lyx::size_type const index) { BOOST_ASSERT(index < 4); return pimpl_->user_defined_bullets[index]; } Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const { BOOST_ASSERT(index < 4); return pimpl_->user_defined_bullets[index]; } Spacing & BufferParams::spacing() { return pimpl_->spacing; } Spacing const & BufferParams::spacing() const { return pimpl_->spacing; } VSpace const & BufferParams::getDefSkip() const { return pimpl_->defskip; } void BufferParams::setDefSkip(VSpace const & vs) { pimpl_->defskip = vs; } string const BufferParams::readToken(LyXLex & lex, string const & token) { if (token == "\\textclass") { lex.next(); string const classname = lex.getString(); pair pp = textclasslist.NumberOfClass(classname); if (pp.first) { textclass = pp.second; } else { textclass = 0; return classname; } if (!getLyXTextClass().isTeXClassAvailable()) { string const msg = bformat(_("The document uses a missing " "TeX class \"%1$s\".\n"), classname); Alert::warning(_("Document class not available"), msg + _("LyX will not be able to produce output.")); } } else if (token == "\\begin_preamble") { readPreamble(lex); } else if (token == "\\options") { lex.eatLine(); options = lex.getString(); } else if (token == "\\language") { readLanguage(lex); } else if (token == "\\inputencoding") { lex >> inputenc; } else if (token == "\\graphics") { readGraphicsDriver(lex); } else if (token == "\\fontscheme") { lex >> fonts; } else if (token == "\\paragraph_separation") { string parsep; lex >> parsep; paragraph_separation = parseptranslator().find(parsep); } else if (token == "\\defskip") { lex.next(); pimpl_->defskip = VSpace(lex.getString()); } else if (token == "\\quotes_language") { string quotes_lang; lex >> quotes_lang; quotes_language = quoteslangtranslator().find(quotes_lang); } else if (token == "\\papersize") { string ppsize; lex >> ppsize; papersize = papersizetranslator().find(ppsize); } else if (token == "\\use_geometry") { lex >> use_geometry; } else if (token == "\\use_amsmath") { int use_ams; lex >> use_ams; use_amsmath = amstranslator().find(use_ams); } else if (token == "\\cite_engine") { string engine; lex >> engine; cite_engine = citeenginetranslator().find(engine); } else if (token == "\\use_bibtopic") { lex >> use_bibtopic; } else if (token == "\\tracking_changes") { lex >> tracking_changes; } else if (token == "\\output_changes") { lex >> output_changes; } else if (token == "\\branch") { lex.next(); string branch = lex.getString(); branchlist().add(branch); while (true) { lex.next(); string const tok = lex.getString(); if (tok == "\\end_branch") break; Branch * branch_ptr = branchlist().find(branch); if (tok == "\\selected") { lex.next(); if (branch_ptr) branch_ptr->setSelected(lex.getInteger()); } // not yet operational if (tok == "\\color") { lex.eatLine(); string color = lex.getString(); if (branch_ptr) branch_ptr->setColor(color); // Update also the LColor table: if (color == "none") color = lcolor.getX11Name(LColor::background); lcolor.setColor(branch, color); } } } else if (token == "\\author") { lex.eatLine(); istringstream ss(lex.getString()); Author a; ss >> a; author_map.push_back(pimpl_->authorlist.record(a)); } else if (token == "\\paperorientation") { string orient; lex >> orient; orientation = paperorientationtranslator().find(orient); } else if (token == "\\paperwidth") { lex >> paperwidth; } else if (token == "\\paperheight") { lex >> paperheight; } else if (token == "\\leftmargin") { lex >> leftmargin; } else if (token == "\\topmargin") { lex >> topmargin; } else if (token == "\\rightmargin") { lex >> rightmargin; } else if (token == "\\bottommargin") { lex >> bottommargin; } else if (token == "\\headheight") { lex >> headheight; } else if (token == "\\headsep") { lex >> headsep; } else if (token == "\\footskip") { lex >> footskip; } else if (token == "\\paperfontsize") { lex >> fontsize; } else if (token == "\\papercolumns") { lex >> columns; } else if (token == "\\papersides") { int psides; lex >> psides; sides = sidestranslator().find(psides); } else if (token == "\\paperpagestyle") { lex >> pagestyle; } else if (token == "\\bullet") { readBullets(lex); } else if (token == "\\bulletLaTeX") { readBulletsLaTeX(lex); } else if (token == "\\secnumdepth") { lex >> secnumdepth; } else if (token == "\\tocdepth") { lex >> tocdepth; } else if (token == "\\spacing") { string nspacing; lex >> nspacing; string tmp_val; if (nspacing == "other") { lex >> tmp_val; } spacing().set(spacetranslator().find(nspacing), tmp_val); } else if (token == "\\float_placement") { lex >> float_placement; } else { return token; } return string(); } void BufferParams::writeFile(ostream & os) const { // The top of the file is written by the buffer. // Prints out the buffer info into the .lyx file given by file // the textclass os << "\\textclass " << textclasslist[textclass].name() << '\n'; // then the the preamble if (!preamble.empty()) { // remove '\n' from the end of preamble string const tmppreamble = rtrim(preamble, "\n"); os << "\\begin_preamble\n" << tmppreamble << "\n\\end_preamble\n"; } // the options if (!options.empty()) { os << "\\options " << options << '\n'; } // then the text parameters if (language != ignore_language) os << "\\language " << language->lang() << '\n'; os << "\\inputencoding " << inputenc << "\n\\fontscheme " << fonts << "\n\\graphics " << graphicsDriver << '\n'; if (!float_placement.empty()) { os << "\\float_placement " << float_placement << '\n'; } os << "\\paperfontsize " << fontsize << '\n'; spacing().writeFile(os); os << "\\papersize " << string_papersize[papersize] << "\n\\use_geometry " << convert(use_geometry) << "\n\\use_amsmath " << use_amsmath << "\n\\cite_engine " << citeenginetranslator().find(cite_engine) << "\n\\use_bibtopic " << convert(use_bibtopic) << "\n\\paperorientation " << string_orientation[orientation] << '\n'; BranchList::const_iterator it = branchlist().begin(); BranchList::const_iterator end = branchlist().end(); for (; it != end; ++it) { os << "\\branch " << it->getBranch() << "\n\\selected " << it->getSelected() << "\n\\color " << lyx::X11hexname(it->getColor()) << "\n\\end_branch" << "\n"; } if (!paperwidth.empty()) os << "\\paperwidth " << VSpace(paperwidth).asLyXCommand() << '\n'; if (!paperheight.empty()) os << "\\paperheight " << VSpace(paperheight).asLyXCommand() << '\n'; if (!leftmargin.empty()) os << "\\leftmargin " << VSpace(leftmargin).asLyXCommand() << '\n'; if (!topmargin.empty()) os << "\\topmargin " << VSpace(topmargin).asLyXCommand() << '\n'; if (!rightmargin.empty()) os << "\\rightmargin " << VSpace(rightmargin).asLyXCommand() << '\n'; if (!bottommargin.empty()) os << "\\bottommargin " << VSpace(bottommargin).asLyXCommand() << '\n'; if (!headheight.empty()) os << "\\headheight " << VSpace(headheight).asLyXCommand() << '\n'; if (!headsep.empty()) os << "\\headsep " << VSpace(headsep).asLyXCommand() << '\n'; if (!footskip.empty()) os << "\\footskip " << VSpace(footskip).asLyXCommand() << '\n'; os << "\\secnumdepth " << secnumdepth << "\n\\tocdepth " << tocdepth << "\n\\paragraph_separation " << string_paragraph_separation[paragraph_separation] << "\n\\defskip " << getDefSkip().asLyXCommand() << "\n\\quotes_language " << string_quotes_language[quotes_language] << "\n\\papercolumns " << columns << "\n\\papersides " << sides << "\n\\paperpagestyle " << pagestyle << '\n'; for (int i = 0; i < 4; ++i) { if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) { if (user_defined_bullet(i).getFont() != -1) { os << "\\bullet " << i << " " << user_defined_bullet(i).getFont() << " " << user_defined_bullet(i).getCharacter() << " " << user_defined_bullet(i).getSize() << "\n"; } else { os << "\\bulletLaTeX " << i << " \"" << user_defined_bullet(i).getText() << "\"\n"; } } } os << "\\tracking_changes " << convert(tracking_changes) << "\n"; os << "\\output_changes " << convert(output_changes) << "\n"; if (tracking_changes) { AuthorList::Authors::const_iterator it = pimpl_->authorlist.begin(); AuthorList::Authors::const_iterator end = pimpl_->authorlist.end(); for (; it != end; ++it) { os << "\\author " << it->second << "\n"; } } } bool BufferParams::writeLaTeX(ostream & os, LaTeXFeatures & features, TexRow & texrow) const { 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 encodings = features.getEncodingSet(doc_encoding); os << "\\usepackage["; std::copy(encodings.begin(), encodings.end(), std::ostream_iterator(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(); } // 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{" << 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 += " \\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")) { 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; } void BufferParams::useClassDefaults() { LyXTextClass const & tclass = textclasslist[textclass]; sides = tclass.sides(); columns = tclass.columns(); pagestyle = tclass.pagestyle(); options = tclass.options(); // Only if class has a ToC hierarchy if (tclass.hasTocLevels()) { secnumdepth = tclass.secnumdepth(); tocdepth = tclass.tocdepth(); } } bool BufferParams::hasClassDefaults() const { LyXTextClass const & tclass = textclasslist[textclass]; return (sides == tclass.sides() && columns == tclass.columns() && pagestyle == tclass.pagestyle() && options == tclass.options() && secnumdepth == tclass.secnumdepth() && tocdepth == tclass.tocdepth()); } LyXTextClass const & BufferParams::getLyXTextClass() const { return textclasslist[textclass]; } LyXFont const BufferParams::getFont() const { LyXFont f = getLyXTextClass().defaultfont(); f.setLanguage(language); return f; } void BufferParams::readPreamble(LyXLex & lex) { if (lex.getString() != "\\begin_preamble") lyxerr << "Error (BufferParams::readPreamble):" "consistency check failed." << endl; preamble = lex.getLongString("\\end_preamble"); } void BufferParams::readLanguage(LyXLex & lex) { if (!lex.next()) return; string const tmptok = lex.getString(); // check if tmptok is part of tex_babel in tex-defs.h language = languages.getLanguage(tmptok); if (!language) { // Language tmptok was not found language = default_language; lyxerr << "Warning: Setting language `" << tmptok << "' to `" << language->lang() << "'." << endl; } } void BufferParams::readGraphicsDriver(LyXLex & lex) { if (!lex.next()) return; string const tmptok = lex.getString(); // check if tmptok is part of tex_graphics in tex_defs.h int n = 0; while (true) { string const test = tex_graphics[n++]; if (test == tmptok) { graphicsDriver = tmptok; break; } else if (test == "") { lex.printError( "Warning: graphics driver `$$Token' not recognized!\n" " Setting graphics driver to `default'.\n"); graphicsDriver = "default"; break; } } } void BufferParams::readBullets(LyXLex & lex) { if (!lex.next()) return; int const index = lex.getInteger(); lex.next(); int temp_int = lex.getInteger(); user_defined_bullet(index).setFont(temp_int); temp_bullet(index).setFont(temp_int); lex >> temp_int; user_defined_bullet(index).setCharacter(temp_int); temp_bullet(index).setCharacter(temp_int); lex >> temp_int; user_defined_bullet(index).setSize(temp_int); temp_bullet(index).setSize(temp_int); } void BufferParams::readBulletsLaTeX(LyXLex & lex) { // The bullet class should be able to read this. if (!lex.next()) return; int const index = lex.getInteger(); lex.next(true); string const temp_str = lex.getString(); user_defined_bullet(index).setText(temp_str); temp_bullet(index).setText(temp_str); } string const BufferParams::paperSizeName() const { char real_papersize = papersize; if (real_papersize == PAPER_DEFAULT) real_papersize = lyxrc.default_papersize; switch (real_papersize) { case PAPER_A3: return "a3"; case PAPER_A4: return "a4"; case PAPER_A5: return "a5"; case PAPER_B5: return "b5"; case PAPER_USEXECUTIVE: return "foolscap"; case PAPER_USLEGAL: return "legal"; case PAPER_USLETTER: default: return "letter"; } } string const BufferParams::dvips_options() const { string result; if (use_geometry && papersize == PAPER_CUSTOM && !lyxrc.print_paper_dimension_flag.empty() && !paperwidth.empty() && !paperheight.empty()) { // using a custom papersize result = lyxrc.print_paper_dimension_flag; result += ' ' + paperwidth; result += ',' + paperheight; } else { string const paper_option = paperSizeName(); if (paper_option != "letter" || orientation != ORIENTATION_LANDSCAPE) { // dvips won't accept -t letter -t landscape. // In all other cases, include the paper size // explicitly. result = lyxrc.print_paper_flag; result += ' ' + paper_option; } } if (orientation == ORIENTATION_LANDSCAPE && papersize != PAPER_CUSTOM) result += ' ' + lyxrc.print_landscape_flag; return result; } string const BufferParams::babelCall(string const & lang_opts) const { string tmp = lyxrc.language_package; if (!lyxrc.language_global_options && tmp == "\\usepackage{babel}") tmp = string("\\usepackage[") + lang_opts + "]{babel}"; return tmp; }