X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=95744c6669d896f8b034adda6f1797548cda2fd6;hb=d145c2dc9f27666ca0ed9f8589f99f502d7b2a4d;hp=b444a2b4a97b1d05574e59e7439e0e604d5fd31c;hpb=c4bcdf837a3beac6ea8b11596cb6360e411eb5c0;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index b444a2b4a9..95744c6669 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -68,7 +68,7 @@ static char const * const string_quotes_language[] = { static char const * const string_papersize[] = { - "default", "custom", "letterpaper", "executivepaper", "legalpaper", + "default", "custom", "letterpaper", "legalpaper", "executivepaper", "a3paper", "a4paper", "a5paper", "b3paper", "b4paper", "b5paper", "" }; @@ -463,19 +463,13 @@ string BufferParams::readToken(Lexer & lex, string const & token, string tcp; LayoutFileList & bcl = LayoutFileList::get(); if (tcp.empty() && !filepath.empty()) - tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local); + tcp = bcl.addLocalLayout(classname, filepath.absFilename()); if (!tcp.empty()) setBaseClass(tcp); - else if (bcl.haveClass(classname)) { + else setBaseClass(classname); - } else { - // a warning will be given for unknown class - setBaseClass(defaultBaseclass()); - return classname; - } - // 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. + // We assume that a tex class exists for local or unknown layouts so this warning + // will only be given for system layouts. if (!baseClass()->isTeXClassAvailable()) { docstring const msg = bformat(_("The layout file requested by this document,\n" @@ -487,13 +481,14 @@ string BufferParams::readToken(Lexer & lex, string const & token, frontend::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 == "\\begin_local_layout") { readLocalLayout(lex); } else if (token == "\\begin_modules") { readModules(lex); + } else if (token == "\\begin_removed_modules") { + readRemovedModules(lex); } else if (token == "\\options") { lex.eatLine(); options = lex.getString(); @@ -522,6 +517,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, lex >> fontsSansScale; } else if (token == "\\font_tt_scale") { lex >> fontsTypewriterScale; + } else if (token == "\\font_cjk") { + lex >> fontsCJK; } else if (token == "\\paragraph_separation") { string parsep; lex >> parsep; @@ -697,15 +694,26 @@ void BufferParams::writeFile(ostream & os) const os << "\\master " << master << '\n'; } - //the modules + // removed modules + if (!removedModules_.empty()) { + os << "\\begin_removed_modules" << '\n'; + set::const_iterator it = removedModules_.begin(); + set::const_iterator en = removedModules_.end(); + for (; it != en; it++) + os << *it << '\n'; + os << "\\end_removed_modules" << '\n'; + } + + // the modules if (!layoutModules_.empty()) { os << "\\begin_modules" << '\n'; LayoutModuleList::const_iterator it = layoutModules_.begin(); - for (; it != layoutModules_.end(); it++) + LayoutModuleList::const_iterator en = layoutModules_.end(); + for (; it != en; it++) os << *it << '\n'; os << "\\end_modules" << '\n'; } - + // local layout information if (!local_layout.empty()) { // remove '\n' from the end @@ -727,7 +735,11 @@ void BufferParams::writeFile(ostream & os) const << "\n\\font_osf " << convert(fontsOSF) << "\n\\font_sf_scale " << fontsSansScale << "\n\\font_tt_scale " << fontsTypewriterScale - << "\n\\graphics " << graphicsDriver << '\n'; + << '\n'; + if (!fontsCJK.empty()) { + os << "\\font_cjk " << fontsCJK << '\n'; + } + os << "\n\\graphics " << graphicsDriver << '\n'; if (!float_placement.empty()) { os << "\\float_placement " << float_placement << '\n'; @@ -907,6 +919,11 @@ void BufferParams::validate(LaTeXFeatures & features) const if (pdfoptions().use_hyperref) features.require("hyperref"); + + if (language->lang() == "vietnamese") + features.require("vietnamese"); + else if (language->lang() == "japanese") + features.require("japanese"); } @@ -999,12 +1016,12 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, language_options << ','; language_options << language->babel(); } - // when Vietnamese is used, babel must directly be loaded with the + // if Vietnamese is used, babel must directly be loaded with the // language options, not in the class options, see // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html size_t viet = language_options.str().find("vietnam"); // viet = string::npos when not found - // when Japanese is used, babel must directly be loaded with the + // if Japanese is used, babel must directly be loaded with the // language options, not in the class options, see // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4 size_t japan = language_options.str().find("japanese"); @@ -1166,6 +1183,8 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString()); os << "}\n"; texrow.newline(); + } else if (orientation == ORIENTATION_LANDSCAPE) { + features.require("papersize"); } if (tokenPos(tclass.opt_pagestyle(), @@ -1220,11 +1239,16 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, 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())) + // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel here. + if (use_babel + && (features.isRequired("jurabib") + || features.isRequired("hyperref") + || features.isRequired("vietnamese") + || features.isRequired("japanese") ) ) { + // FIXME UNICODE + os << from_utf8(babelCall(language_options.str())) << '\n' - << from_ascii(features.getBabelOptions()); + << from_utf8(features.getBabelOptions()); texrow.newline(); } @@ -1236,26 +1260,6 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // 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. - // So load babel after the optional packages but before the user-defined - // preamble. This allows the users to redefine babel commands, e.g. to - // translate the word "Index" to the German "Stichwortverzeichnis". - // For more infos why this place was chosen, see - // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html - // If you encounter problems, you can shift babel to its old place behind - // the user-defined preamble. But in this case you must change the Vietnamese - // support from currently "\usepackage[vietnamese]{babel}" to: - // \usepackage{vietnamese} - // \usepackage{babel} - // because vietnamese must be loaded before hyperref - if (use_babel && !features.isRequired("jurabib")) { - // FIXME UNICODE - lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n'; - lyxpreamble += from_utf8(features.getBabelOptions()); - } - // PDF support. // * Hyperref manual: "Make sure it comes last of your loaded // packages, to give it a fighting chance of not being over-written, @@ -1296,6 +1300,22 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, "User specified LaTeX commands.\n" + from_utf8(preamble) + '\n'; + // subfig loads internally the LaTeX package "caption". As + // caption is a very popular package, users will load it in + // the preamble. Therefore we must load subfig behind the + // user-defined preamble and check if the caption package was + // loaded or not. For the case that caption is loaded before + // subfig, there is the subfig option "caption=false". This + // option also works when a koma-script class is used and + // koma's own caption commands are used instead of caption. We + // use \PassOptionsToPackage here because the user could have + // already loaded subfig in the preamble. + if (features.isRequired("subfig")) { + atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n" + " \\PassOptionsToPackage{caption=false}{subfig}}\n" + "\\usepackage{subfig}\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 @@ -1337,6 +1357,18 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, else lyxpreamble += '\n' + atlyxpreamble; + // We try to load babel late, in case it interferes + // with other packages. + // Jurabib and Hyperref have to be called after babel, though. + if (use_babel && !features.isRequired("jurabib") + && !features.isRequired("hyperref") + && !features.isRequired("vietnamese") + && !features.isRequired("japanese")) { + // FIXME UNICODE + lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n'; + lyxpreamble += from_utf8(features.getBabelOptions()) + '\n'; + } + int const nlines = int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n')); for (int j = 0; j != nlines; ++j) { @@ -1383,7 +1415,7 @@ DocumentClass const & BufferParams::documentClass() const } -DocumentClass * BufferParams::documentClassPtr() const { +DocumentClass const * BufferParams::documentClassPtr() const { return doc_class_; } @@ -1397,25 +1429,75 @@ void BufferParams::setDocumentClass(DocumentClass const * const tc) { bool BufferParams::setBaseClass(string const & classname) { LYXERR(Debug::TCLASS, "setBaseClass: " << classname); - LayoutFileList const & bcl = LayoutFileList::get(); + LayoutFileList & bcl = LayoutFileList::get(); if (!bcl.haveClass(classname)) { docstring s = - bformat(_("The document class %1$s could not be found."), + bformat(_("The document class %1$s could not be found. " + "A default textclass with default layouts will be used. " + "LyX might not be able to produce output unless a correct " + "textclass is selected from the document settings dialog."), from_utf8(classname)); - frontend::Alert::error(_("Class not found"), s); + frontend::Alert::error(_("Document class not found"), s); + bcl.addEmptyClass(classname); + } + + bool const success = bcl[classname].load(); + if (!success) { + docstring s = + bformat(_("The document class %1$s could not be loaded."), + from_utf8(classname)); + frontend::Alert::error(_("Could not load class"), s); return false; } - if (bcl[classname].load()) { - pimpl_->baseClass_ = classname; - return true; + pimpl_->baseClass_ = classname; + + // add any required modules not already in use + set const & mods = baseClass()->defaultModules(); + set::const_iterator mit = mods.begin(); + set::const_iterator men = mods.end(); + for (; mit != men; mit++) { + string const & modName = *mit; + // see if we're already in use + if (find(layoutModules_.begin(), layoutModules_.end(), modName) != + layoutModules_.end()) { + LYXERR(Debug::TCLASS, "Default module `" << modName << + "' not added because already used."); + continue; + } + // make sure the user hasn't removed it + if (find(removedModules_.begin(), removedModules_.end(), modName) != + removedModules_.end()) { + LYXERR(Debug::TCLASS, "Default module `" << modName << + "' not added because removed by user."); + continue; + } + // Now we want to check the list of selected modules to see if any of them + // exclude this one. + bool foundit = false; + // so iterate over the selected modules... + LayoutModuleList::const_iterator lit = layoutModules_.begin(); + LayoutModuleList::const_iterator len = layoutModules_.end(); + for (; lit != len; lit++) { + LyXModule * lm = moduleList[*lit]; + if (!lm) + continue; + vector const & exc = lm->getExcludedModules(); + // ...and see if this one excludes us. + if (find(exc.begin(), exc.end(), modName) != exc.end()) { + foundit = true; + LYXERR(Debug::TCLASS, "Default module `" << modName << + "' not added because excluded by loaded module `" << + *lit << "'."); + break; + } + } + if (!foundit) { + LYXERR(Debug::TCLASS, "Default module `" << modName << "' added."); + layoutModules_.push_back(modName); + } } - - docstring s = - bformat(_("The document class %1$s could not be loaded."), - from_utf8(classname)); - frontend::Alert::error(_("Could not load class"), s); - return false; + return true; } @@ -1440,10 +1522,10 @@ void BufferParams::makeDocumentClass() return; doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass())); - - //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. + + // 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. LayoutModuleList::const_iterator it = layoutModules_.begin(); for (; it != layoutModules_.end(); it++) { string const modName = *it; @@ -1483,13 +1565,6 @@ void BufferParams::makeDocumentClass() } -vector const & BufferParams::getModules() const -{ - return layoutModules_; -} - - - bool BufferParams::addLayoutModule(string const & modName) { LayoutModuleList::const_iterator it = layoutModules_.begin(); @@ -1502,12 +1577,6 @@ bool BufferParams::addLayoutModule(string const & modName) } -void BufferParams::clearLayoutModules() -{ - layoutModules_.clear(); -} - - Font const BufferParams::getFont() const { FontInfo f = documentClass().defaultfont(); @@ -1635,6 +1704,37 @@ void BufferParams::readModules(Lexer & lex) } +void BufferParams::readRemovedModules(Lexer & lex) +{ + if (!lex.eatLine()) { + lyxerr << "Error (BufferParams::readRemovedModules):" + "Unexpected end of input." << endl; + return; + } + while (true) { + string mod = lex.getString(); + if (mod == "\\end_removed_modules") + break; + removedModules_.insert(mod); + lex.eatLine(); + } + // now we want to remove any removed modules that were previously + // added. normally, that will be because default modules were added in + // setBaseClass(), which gets called when \textclass is read at the + // start of the read. + set::const_iterator rit = removedModules_.begin(); + set::const_iterator const ren = removedModules_.end(); + for (; rit != ren; rit++) { + LayoutModuleList::iterator const mit = layoutModules_.begin(); + LayoutModuleList::iterator const men = layoutModules_.end(); + LayoutModuleList::iterator found = find(mit, men, *rit); + if (found == men) + continue; + layoutModules_.erase(found); + } +} + + string BufferParams::paperSizeName(PapersizePurpose purpose) const { char real_papersize = papersize; @@ -1737,12 +1837,12 @@ string BufferParams::babelCall(string const & lang_opts) const // other languages are used (lang_opts is then empty) if (lang_opts.empty()) return string(); - // when Vietnamese is used, babel must directly be loaded with the + // If Vietnamese is used, babel must directly be loaded with the // language options, see // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html size_t viet = lang_opts.find("vietnam"); // viet = string::npos when not found - // when Japanese is used, babel must directly be loaded with the + // If Japanese is used, babel must directly be loaded with the // language options, see // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4 size_t japan = lang_opts.find("japanese"); @@ -1767,7 +1867,7 @@ void BufferParams::writeEncodingPreamble(odocstream & os, set encodings = features.getEncodingSet(doc_encoding); - // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the + // If the encodings EUC-JP-plain, JIS-plain, or SJIS-plain are used, the // package inputenc must be omitted. Therefore set the encoding to empty. // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||