X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fbufferparams.C;h=be159dc2a31e652896f7ae1c7c017c8f5eb533ad;hb=b9963e1a57135c3e2ab128a9ec4300f0e4886992;hp=09f291d39f1ba6a983b319bdaef34f1060c2fe69;hpb=b922cdd796f9e4b9a46a79808cdee596e04903eb;p=lyx.git diff --git a/src/bufferparams.C b/src/bufferparams.C index 09f291d39f..be159dc2a3 100644 --- a/src/bufferparams.C +++ b/src/bufferparams.C @@ -1,58 +1,304 @@ -/* This file is part of - * ====================================================== - * - * LyX, The Document Processor - * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. +/** + * \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 -#ifdef __GNUG__ -#pragma implementation -#endif - #include "bufferparams.h" -#include "tex-strings.h" -#include "layout.h" -#include "vspace.h" + +#include "author.h" +#include "BranchList.h" +#include "Bullet.h" #include "debug.h" -#include "lyxrc.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 "support/lyxlib.h" -#include "support/lstrings.h" +#include "frontends/Alert.h" -#include +#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::ostream; 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) + : // 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; - defskip = VSpace(VSpace::MEDSKIP); quotes_language = InsetQuotes::EnglishQ; - quotes_times = InsetQuotes::DoubleQ; fontsize = "default"; /* PaperLayout */ papersize = PAPER_DEFAULT; - papersize2 = VM_PAPER_DEFAULT; /* DEFAULT */ - paperpackage = PACKAGE_NONE; orientation = ORIENTATION_PORTRAIT; use_geometry = false; - use_amsmath = false; - use_natbib = false; - use_numerical_citations = 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; @@ -62,36 +308,273 @@ BufferParams::BufferParams() sides = LyXTextClass::OneSide; columns = 1; pagestyle = "default"; + compressed = false; for (int iter = 0; iter < 4; ++iter) { - user_defined_bullets[iter] = ITEMIZE_DEFAULTS[iter]; - temp_bullets[iter] = ITEMIZE_DEFAULTS[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.NameOfClass(textclass) << '\n'; - + // 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 = strip(preamble, '\n'); + string const tmppreamble = rtrim(preamble, "\n"); os << "\\begin_preamble\n" << tmppreamble << "\n\\end_preamble\n"; } - - /* the options */ + + // the options if (!options.empty()) { os << "\\options " << options << '\n'; } - - /* then the text parameters */ + + // then the text parameters if (language != ignore_language) os << "\\language " << language->lang() << '\n'; os << "\\inputencoding " << inputenc @@ -103,113 +586,483 @@ void BufferParams::writeFile(ostream & os) const } os << "\\paperfontsize " << fontsize << '\n'; - spacing.writeFile(os); + spacing().writeFile(os); - os << "\\papersize " << string_papersize[papersize2] - << "\n\\paperpackage " << string_paperpackages[paperpackage] - << "\n\\use_geometry " << use_geometry + os << "\\papersize " << string_papersize[papersize] + << "\n\\use_geometry " << convert(use_geometry) << "\n\\use_amsmath " << use_amsmath - << "\n\\use_natbib " << use_natbib - << "\n\\use_numerical_citations " << use_numerical_citations + << "\n\\cite_engine " << citeenginetranslator().find(cite_engine) + << "\n\\use_bibtopic " << convert(use_bibtopic) << "\n\\paperorientation " << string_orientation[orientation] << '\n'; - if (!paperwidth.empty()) + + 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 " << it->getColor() + << "\n\\end_branch" + << "\n"; + } + + if (!paperwidth.empty()) os << "\\paperwidth " << VSpace(paperwidth).asLyXCommand() << '\n'; - if (!paperheight.empty()) + if (!paperheight.empty()) os << "\\paperheight " << VSpace(paperheight).asLyXCommand() << '\n'; - if (!leftmargin.empty()) + if (!leftmargin.empty()) os << "\\leftmargin " << VSpace(leftmargin).asLyXCommand() << '\n'; - if (!topmargin.empty()) + if (!topmargin.empty()) os << "\\topmargin " << VSpace(topmargin).asLyXCommand() << '\n'; - if (!rightmargin.empty()) + if (!rightmargin.empty()) os << "\\rightmargin " << VSpace(rightmargin).asLyXCommand() << '\n'; - if (!bottommargin.empty()) + if (!bottommargin.empty()) os << "\\bottommargin " << VSpace(bottommargin).asLyXCommand() << '\n'; - if (!headheight.empty()) + if (!headheight.empty()) os << "\\headheight " << VSpace(headheight).asLyXCommand() << '\n'; - if (!headsep.empty()) + if (!headsep.empty()) os << "\\headsep " << VSpace(headsep).asLyXCommand() << '\n'; - if (!footskip.empty()) + 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 " << defskip.asLyXCommand() + << "\n\\defskip " << getDefSkip().asLyXCommand() << "\n\\quotes_language " - << string_quotes_language[quotes_language] << '\n'; - switch (quotes_times) { - // An output operator for insetquotes would be nice - case InsetQuotes::SingleQ: - os << "\\quotes_times 1\n"; break; - case InsetQuotes::DoubleQ: - os << "\\quotes_times 2\n"; break; - } - os << "\\papercolumns " << columns + << 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_bullets[i] != ITEMIZE_DEFAULTS[i]) { - if (user_defined_bullets[i].getFont() != -1) { - os << "\\bullet " << i - << "\n\t" - << user_defined_bullets[i].getFont() - << "\n\t" - << user_defined_bullets[i].getCharacter() - << "\n\t" - << user_defined_bullets[i].getSize() - << "\n\\end_bullet\n"; + 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 - << "\n\t" - << user_defined_bullets[i].getText() - << "\n\\end_bullet\n"; + 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"; + } + } } -void BufferParams::setPaperStuff() +bool BufferParams::writeLaTeX(ostream & os, LaTeXFeatures & features, + TexRow & texrow) const { - papersize = PAPER_DEFAULT; - char const c1 = paperpackage; - if (c1 == PACKAGE_NONE) { - char const c2 = papersize2; - if (c2 == VM_PAPER_USLETTER) - papersize = PAPER_USLETTER; - else if (c2 == VM_PAPER_USLEGAL) - papersize = PAPER_LEGALPAPER; - else if (c2 == VM_PAPER_USEXECUTIVE) - papersize = PAPER_EXECUTIVEPAPER; - else if (c2 == VM_PAPER_A3) - papersize = PAPER_A3PAPER; - else if (c2 == VM_PAPER_A4) - papersize = PAPER_A4PAPER; - else if (c2 == VM_PAPER_A5) - papersize = PAPER_A5PAPER; - else if ((c2 == VM_PAPER_B3) || (c2 == VM_PAPER_B4) || - (c2 == VM_PAPER_B5)) - papersize = PAPER_B5PAPER; - } else if ((c1 == PACKAGE_A4) || (c1 == PACKAGE_A4WIDE) || - (c1 == PACKAGE_WIDEMARGINSA4)) - papersize = PAPER_A4PAPER; + 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(); + } + + 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; } void BufferParams::useClassDefaults() { - LyXTextClass const & tclass = textclasslist.TextClass(textclass); + LyXTextClass const & tclass = textclasslist[textclass]; sides = tclass.sides(); columns = tclass.columns(); @@ -222,8 +1075,8 @@ void BufferParams::useClassDefaults() bool BufferParams::hasClassDefaults() const { - LyXTextClass const & tclass = textclasslist.TextClass(textclass); - + LyXTextClass const & tclass = textclasslist[textclass]; + return (sides == tclass.sides() && columns == tclass.columns() && pagestyle == tclass.pagestyle() @@ -233,6 +1086,12 @@ bool BufferParams::hasClassDefaults() const } +LyXTextClass const & BufferParams::getLyXTextClass() const +{ + return textclasslist[textclass]; +} + + void BufferParams::readPreamble(LyXLex & lex) { if (lex.getString() != "\\begin_preamble") @@ -246,7 +1105,7 @@ void BufferParams::readPreamble(LyXLex & lex) 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 @@ -264,22 +1123,119 @@ void BufferParams::readLanguage(LyXLex & lex) 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) { + + if (test == tmptok) { graphicsDriver = tmptok; break; - } else if (test == "last_item") { + } 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; }