X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=6355dbcc6729d3f5a439c50f33936d5c6a260963;hb=0362c6aae73c293d1c20277c12d362acfe0b2ef6;hp=f13fb287bc222891debee435c61d6c53b75b33e3;hpb=433eda2ccafb0ae545c493246642fa3bd56b3dfa;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index f13fb287bc..6355dbcc67 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -53,21 +53,8 @@ #include #include -using std::count; -using std::endl; -using std::find; -using std::string; -using std::istringstream; -using std::ostream; -using std::ostringstream; -using std::pair; -using std::string; -using lyx::support::FileName; -using lyx::support::libFileSearch; -using lyx::support::bformat; -using lyx::support::rtrim; -using lyx::support::tokenPos; -using lyx::support::prefixIs; +using namespace std; +using namespace lyx::support; static char const * const string_paragraph_separation[] = { @@ -150,7 +137,7 @@ QuotesLangTranslator const & quoteslangtranslator() // Paper size -typedef Translator PaperSizeTranslator; +typedef Translator PaperSizeTranslator; PaperSizeTranslator const init_papersizetranslator() @@ -327,6 +314,7 @@ BufferParams::BufferParams() : pimpl_(new Impl) { setBaseClass(defaultTextclass()); + makeTextClass(); paragraph_separation = PARSEP_INDENT; quotes_language = InsetQuotes::EnglishQ; fontsize = "default"; @@ -474,7 +462,8 @@ string const BufferParams::readToken(Lexer & lex, string const & token, string const classname = lex.getString(); // if there exists a local layout file, ignore the system one // NOTE: in this case, the textclass (.cls file) is assumed to be available. - pair pp; + pair pp = + make_pair(false, textclass_type(0)); if (!filepath.empty()) pp = textclasslist.addTextClass( classname, filepath.absFilename()); @@ -493,7 +482,7 @@ string const BufferParams::readToken(Lexer & lex, string const & token, // FIXME: this warning will be given even if there exists a local .cls // file. Even worse, the .lyx file can not be compiled or exported // because the textclass is marked as unavilable. - if (!getTextClass().isTeXClassAvailable()) { + if (!textClass().isTeXClassAvailable()) { docstring const msg = bformat(_("The layout file requested by this document,\n" "%1$s.layout,\n" @@ -509,7 +498,6 @@ string const BufferParams::readToken(Lexer & lex, string const & token, readPreamble(lex); } else if (token == "\\begin_modules") { readModules(lex); - makeTextClass(); } else if (token == "\\options") { lex.eatLine(); options = lex.getString(); @@ -541,7 +529,11 @@ string const BufferParams::readToken(Lexer & lex, string const & token, paragraph_separation = parseptranslator().find(parsep); } else if (token == "\\defskip") { lex.next(); - pimpl_->defskip = VSpace(lex.getString()); + string defskip = lex.getString(); + if (defskip == "defskip") + // this is invalid + defskip = "medskip"; + pimpl_->defskip = VSpace(defskip); } else if (token == "\\quotes_language") { string quotes_lang; lex >> quotes_lang; @@ -627,6 +619,8 @@ string const BufferParams::readToken(Lexer & lex, string const & token, lex >> headsep; } else if (token == "\\footskip") { lex >> footskip; + } else if (token == "\\columnsep") { + lex >> columnsep; } else if (token == "\\paperfontsize") { lex >> fontsize; } else if (token == "\\papercolumns") { @@ -776,6 +770,9 @@ void BufferParams::writeFile(ostream & os) const if (!footskip.empty()) os << "\\footskip " << VSpace(footskip).asLyXCommand() << '\n'; + if (!columnsep.empty()) + os << "\\columnsep " + << VSpace(columnsep).asLyXCommand() << '\n'; os << "\\secnumdepth " << secnumdepth << "\n\\tocdepth " << tocdepth << "\n\\paragraph_separation " @@ -820,12 +817,92 @@ void BufferParams::writeFile(ostream & os) const } +void BufferParams::validate(LaTeXFeatures & features) const +{ + features.require(textClass().requires()); + + if (outputChanges) { + bool dvipost = LaTeXFeatures::isAvailable("dvipost"); + bool xcolorsoul = LaTeXFeatures::isAvailable("soul") && + LaTeXFeatures::isAvailable("xcolor"); + + switch (features.runparams().flavor) { + case OutputParams::LATEX: + if (dvipost) { + features.require("ct-dvipost"); + features.require("dvipost"); + } else if (xcolorsoul) { + features.require("ct-xcolor-soul"); + features.require("soul"); + features.require("xcolor"); + } else { + features.require("ct-none"); + } + break; + case OutputParams::PDFLATEX: + if (xcolorsoul) { + features.require("ct-xcolor-soul"); + features.require("soul"); + features.require("xcolor"); + // improves color handling in PDF output + features.require("pdfcolmk"); + } else { + features.require("ct-none"); + } + break; + default: + break; + } + } + + // Floats with 'Here definitely' as default setting. + if (float_placement.find('H') != string::npos) + features.require("float"); + + // AMS Style is at document level + if (use_amsmath == package_on + || textClass().provides("amsmath")) + features.require("amsmath"); + if (use_esint == package_on) + features.require("esint"); + + // Document-level line spacing + if (spacing().getSpace() != Spacing::Single && !spacing().isDefault()) + features.require("setspace"); + + // the bullet shapes are buffer level not paragraph level + // so they are tested here + for (int i = 0; i < 4; ++i) { + if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i]) + continue; + int const font = user_defined_bullet(i).getFont(); + if (font == 0) { + int const c = user_defined_bullet(i).getCharacter(); + if (c == 16 + || c == 17 + || c == 25 + || c == 26 + || c == 31) { + features.require("latexsym"); + } + } else if (font == 1) { + features.require("amssymb"); + } else if (font >= 2 && font <= 5) { + features.require("pifont"); + } + } + + if (pdfoptions().use_hyperref) + features.require("hyperref"); +} + + bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, TexRow & texrow) const { os << "\\documentclass"; - TextClass const & tclass = getTextClass(); + TextClass const & tclass = textClass(); ostringstream clsoptions; // the document class options. @@ -1067,6 +1144,8 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, os << ",headsep=" << from_ascii(Length(headsep).asLatexString()); if (!footskip.empty()) os << ",footskip=" << from_ascii(Length(footskip).asLatexString()); + if (!columnsep.empty()) + os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString()); os << "}\n"; texrow.newline(); } @@ -1136,6 +1215,9 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // The optional packages; docstring lyxpreamble(from_ascii(features.getPackages())); + // Line spacing + lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace"))); + // We try to load babel late, in case it interferes // with other packages. But some packages also need babel to be loaded // before, e.g. jurabib has to be called after babel. @@ -1161,7 +1243,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // hyperref, see // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html if (language->lang() == "japanese-plain" && - !getTextClass().provides("japanese")) { + !textClass().provides("japanese")) { //load babel in case it was not loaded due to an empty language list if (language_options.str().empty()) lyxpreamble += "\\usepackage{babel}\n"; @@ -1176,10 +1258,12 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // before hyperref. Then hyperref has a chance to detect babel. // * Has to be loaded before the "LyX specific LaTeX commands" to // avoid errors with algorithm floats. - odocstringstream oss; // use hyperref explicitely when it is required - pdfoptions().writeLaTeX(oss, features.isRequired("hyperref")); - lyxpreamble += oss.str(); + if (features.isRequired("hyperref")) { + odocstringstream oss; + pdfoptions().writeLaTeX(oss, textClass().provides("hyperref")); + lyxpreamble += oss.str(); + } // this might be useful... lyxpreamble += "\n\\makeatletter\n"; @@ -1286,13 +1370,13 @@ bool BufferParams::hasClassDefaults() const } -TextClass const & BufferParams::getTextClass() const +TextClass const & BufferParams::textClass() const { return *textClass_; } -TextClassPtr BufferParams::getTextClassPtr() const { +TextClassPtr BufferParams::textClassPtr() const { return textClass_; } @@ -1304,24 +1388,16 @@ void BufferParams::setTextClass(TextClassPtr tc) { bool BufferParams::setBaseClass(textclass_type tc) { - bool retVal = true; - if (textclasslist[tc].load()) + if (textclasslist[tc].load()) { baseClass_ = tc; - else { - docstring s = - bformat(_("The document class %1$s could not be loaded."), - from_utf8(textclasslist[tc].name())); - frontend::Alert::error(_("Could not load class"), s); - retVal = false; + return true; } - makeTextClass(); - return retVal; -} - - -void BufferParams::setJustBaseClass(textclass_type tc) -{ - baseClass_ = tc; + + docstring s = + bformat(_("The document class %1$s could not be loaded."), + from_utf8(textclasslist[tc].name())); + frontend::Alert::error(_("Could not load class"), s); + return false; } @@ -1334,6 +1410,7 @@ textclass_type BufferParams::getBaseClass() const void BufferParams::makeTextClass() { textClass_.reset(new TextClass(textclasslist[getBaseClass()])); + //FIXME It might be worth loading the children's modules here, //just as we load their bibliographies and such, instead of just //doing a check in InsetInclude. @@ -1346,7 +1423,7 @@ void BufferParams::makeTextClass() bformat(_("The module %1$s has been requested by\n" "this document but has not been found in the list of\n" "available modules. If you recently installed it, you\n" - "probalby need to reconfigure LyX.\n"), from_utf8(modName)); + "probably need to reconfigure LyX.\n"), from_utf8(modName)); frontend::Alert::warning(_("Module not available"), msg + _("Some layouts may not be available.")); lyxerr << "BufferParams::makeTextClass(): Module " << @@ -1354,19 +1431,30 @@ void BufferParams::makeTextClass() endl; continue; } - FileName layout_file = libFileSearch("layouts", lm->filename); - textClass_->read(layout_file, TextClass::MODULE); + if (!lm->isAvailable()) { + docstring const msg = + bformat(_("The module %1$s requires a package that is\n" + "not available in your LaTeX installation. LaTeX output\n" + "may not be possible.\n"), from_utf8(modName)); + frontend::Alert::warning(_("Package not available"), msg); + } + FileName layout_file = libFileSearch("layouts", lm->getFilename()); + if (!textClass_->read(layout_file, TextClass::MODULE)) { + docstring const msg = + bformat(_("Error reading module %1$s\n"), from_utf8(modName)); + frontend::Alert::warning(_("Read Error"), msg); + } } } -std::vector const & BufferParams::getModules() const { +vector const & BufferParams::getModules() const { return layoutModules_; } -bool BufferParams::addLayoutModule(string modName, bool makeClass) { +bool BufferParams::addLayoutModule(string const & modName) { LayoutModuleList::const_iterator it = layoutModules_.begin(); LayoutModuleList::const_iterator end = layoutModules_.end(); for (; it != end; it++) { @@ -1376,33 +1464,18 @@ bool BufferParams::addLayoutModule(string modName, bool makeClass) { if (it != layoutModules_.end()) return false; layoutModules_.push_back(modName); - if (makeClass) - makeTextClass(); return true; } -bool BufferParams::addLayoutModules(std::vectormodNames) -{ - bool retval = true; - std::vector::const_iterator it = modNames.begin(); - std::vector::const_iterator end = modNames.end(); - for (; it != end; ++it) - retval &= addLayoutModule(*it, false); - makeTextClass(); - return retval; -} - - void BufferParams::clearLayoutModules() { layoutModules_.clear(); - makeTextClass(); } Font const BufferParams::getFont() const { - FontInfo f = getTextClass().defaultfont(); + FontInfo f = textClass().defaultfont(); if (fontsDefaultFamily == "rmdefault") f.setFamily(ROMAN_FAMILY); else if (fontsDefaultFamily == "sfdefault") @@ -1513,27 +1586,62 @@ void BufferParams::readModules(Lexer & lex) } -string const BufferParams::paperSizeName() const +string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const { char real_papersize = papersize; if (real_papersize == PAPER_DEFAULT) real_papersize = lyxrc.default_papersize; switch (real_papersize) { + case PAPER_DEFAULT: + // could be anything, so don't guess + return string(); + case PAPER_CUSTOM: { + if (purpose == XDVI && !paperwidth.empty() && + !paperheight.empty()) { + // heightxwidth + string first = paperwidth; + string second = paperheight; + if (orientation == ORIENTATION_LANDSCAPE) + first.swap(second); + // cut off unit. + return first.erase(first.length() - 2) + + "x" + second; + } + return string(); + } case PAPER_A3: return "a3"; case PAPER_A4: return "a4"; case PAPER_A5: return "a5"; + case PAPER_B3: + // dvips and dvipdfm do not know this + if (purpose == DVIPS || purpose == DVIPDFM) + return string(); + return "b3"; + case PAPER_B4: + // dvipdfm does not know this + if (purpose == DVIPDFM) + return string(); + return "b4"; case PAPER_B5: + // dvipdfm does not know this + if (purpose == DVIPDFM) + return string(); return "b5"; case PAPER_USEXECUTIVE: + // dvipdfm does not know this + if (purpose == DVIPDFM) + return string(); return "foolscap"; case PAPER_USLEGAL: return "legal"; case PAPER_USLETTER: default: + if (purpose == XDVI) + return "us"; return "letter"; } } @@ -1553,9 +1661,9 @@ string const BufferParams::dvips_options() const result += ' ' + paperwidth; result += ',' + paperheight; } else { - string const paper_option = paperSizeName(); - if (paper_option != "letter" || - orientation != ORIENTATION_LANDSCAPE) { + string const paper_option = paperSizeName(DVIPS); + if (!paper_option.empty() && (paper_option != "letter" || + orientation != ORIENTATION_LANDSCAPE)) { // dvips won't accept -t letter -t landscape. // In all other cases, include the paper size // explicitly. @@ -1602,7 +1710,7 @@ void BufferParams::writeEncodingPreamble(odocstream & os, // Create a list with all the input encodings used // in the document - std::set encodings = + set encodings = features.getEncodingSet(doc_encoding); // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the @@ -1614,8 +1722,8 @@ void BufferParams::writeEncodingPreamble(odocstream & os, if (!encodings.empty() || package == Encoding::inputenc) { os << "\\usepackage["; - std::set::const_iterator it = encodings.begin(); - std::set::const_iterator const end = encodings.end(); + set::const_iterator it = encodings.begin(); + set::const_iterator const end = encodings.end(); if (it != end) { os << from_ascii(*it); ++it; @@ -1814,7 +1922,7 @@ biblio::CiteEngine BufferParams::getEngine() const { // FIXME the class should provide the numerical/ // authoryear choice - if (getTextClass().provides("natbib") + if (textClass().provides("natbib") && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL) return biblio::ENGINE_NATBIB_AUTHORYEAR; return cite_engine_;