X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=95744c6669d896f8b034adda6f1797548cda2fd6;hb=d145c2dc9f27666ca0ed9f8589f99f502d7b2a4d;hp=e4d241d56c5664ba65be38f4c2f2437aab3b065c;hpb=ebc464950801141403091ebf8f2adefe0419226b;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index e4d241d56c..95744c6669 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -18,6 +18,7 @@ #include "BufferParams.h" #include "Author.h" +#include "LayoutFile.h" #include "BranchList.h" #include "buffer_funcs.h" #include "Bullet.h" @@ -29,7 +30,6 @@ #include "Font.h" #include "Lexer.h" #include "LyXRC.h" -#include "TextClassList.h" #include "OutputParams.h" #include "Spacing.h" #include "TexRow.h" @@ -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", "" }; @@ -95,13 +95,14 @@ namespace lyx { namespace { // Paragraph separation -typedef Translator ParSepTranslator; +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); + ParSepTranslator translator + (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation); + translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation); return translator; } @@ -114,17 +115,18 @@ ParSepTranslator const & parseptranslator() // Quotes language -typedef Translator QuotesLangTranslator; +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); + QuotesLangTranslator translator + (string_quotes_language[0], InsetQuotes::EnglishQuotes); + translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes); + translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes); + translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes); + translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes); + translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes); return translator; } @@ -140,7 +142,7 @@ QuotesLangTranslator const & quoteslangtranslator() typedef Translator PaperSizeTranslator; -PaperSizeTranslator const init_papersizetranslator() +static PaperSizeTranslator initPaperSizeTranslator() { PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT); translator.addPair(string_papersize[1], PAPER_CUSTOM); @@ -159,7 +161,7 @@ PaperSizeTranslator const init_papersizetranslator() PaperSizeTranslator const & papersizetranslator() { - static PaperSizeTranslator translator = init_papersizetranslator(); + static PaperSizeTranslator translator = initPaperSizeTranslator(); return translator; } @@ -223,15 +225,15 @@ PackageTranslator const & packagetranslator() // Cite engine -typedef Translator CiteEngineTranslator; +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); + CiteEngineTranslator translator("basic", ENGINE_BASIC); + translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL); + translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR); + translator.addPair("jurabib", ENGINE_JURABIB); return translator; } @@ -283,11 +285,12 @@ public: */ VSpace defskip; PDFOptions pdfoptions; + LayoutFileIndex baseClass_; }; BufferParams::Impl::Impl() - : defskip(VSpace::MEDSKIP) + : defskip(VSpace::MEDSKIP), baseClass_(string("")) { // set initial author // FIXME UNICODE @@ -298,7 +301,7 @@ BufferParams::Impl::Impl() BufferParams::Impl * BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr) { - BOOST_ASSERT(ptr); + LASSERT(ptr, /**/); return new BufferParams::Impl(*ptr); } @@ -313,10 +316,10 @@ void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr) BufferParams::BufferParams() : pimpl_(new Impl) { - setBaseClass(defaultTextclass()); - makeTextClass(); - paragraph_separation = PARSEP_INDENT; - quotes_language = InsetQuotes::EnglishQ; + setBaseClass(defaultBaseclass()); + makeDocumentClass(); + paragraph_separation = ParagraphIndentSeparation; + quotes_language = InsetQuotes::EnglishQuotes; fontsize = "default"; /* PaperLayout */ @@ -325,7 +328,7 @@ BufferParams::BufferParams() use_geometry = false; use_amsmath = package_auto; use_esint = package_auto; - cite_engine_ = biblio::ENGINE_BASIC; + cite_engine_ = ENGINE_BASIC; use_bibtopic = false; trackChanges = false; outputChanges = false; @@ -347,7 +350,6 @@ BufferParams::BufferParams() listings_params = string(); pagestyle = "default"; compressed = false; - embedded = false; for (int iter = 0; iter < 4; ++iter) { user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter]; temp_bullet(iter) = ITEMIZE_DEFAULTS[iter]; @@ -355,13 +357,9 @@ BufferParams::BufferParams() } -BufferParams::~BufferParams() -{} - - -docstring const BufferParams::B_(string const & l10n) const +docstring BufferParams::B_(string const & l10n) const { - BOOST_ASSERT(language); + LASSERT(language, /**/); return getMessages(language->code()).get(l10n); } @@ -392,28 +390,28 @@ BranchList const & BufferParams::branchlist() const Bullet & BufferParams::temp_bullet(lyx::size_type const index) { - BOOST_ASSERT(index < 4); + LASSERT(index < 4, /**/); return pimpl_->temp_bullets[index]; } Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const { - BOOST_ASSERT(index < 4); + LASSERT(index < 4, /**/); return pimpl_->temp_bullets[index]; } Bullet & BufferParams::user_defined_bullet(lyx::size_type const index) { - BOOST_ASSERT(index < 4); + LASSERT(index < 4, /**/); return pimpl_->user_defined_bullets[index]; } Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const { - BOOST_ASSERT(index < 4); + LASSERT(index < 4, /**/); return pimpl_->user_defined_bullets[index]; } @@ -454,7 +452,7 @@ void BufferParams::setDefSkip(VSpace const & vs) } -string const BufferParams::readToken(Lexer & lex, string const & token, +string BufferParams::readToken(Lexer & lex, string const & token, FileName const & filepath) { if (token == "\\textclass") { @@ -462,27 +460,17 @@ 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 = - make_pair(false, textclass_type(0)); - if (!filepath.empty()) - pp = textclasslist.addTextClass( - classname, filepath.absFilename()); - if (pp.first) - setBaseClass(pp.second); - else { - pp = textclasslist.numberOfClass(classname); - if (pp.first) - setBaseClass(pp.second); - else { - // a warning will be given for unknown class - setBaseClass(defaultTextclass()); - 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. - if (!getTextClass().isTeXClassAvailable()) { + string tcp; + LayoutFileList & bcl = LayoutFileList::get(); + if (tcp.empty() && !filepath.empty()) + tcp = bcl.addLocalLayout(classname, filepath.absFilename()); + if (!tcp.empty()) + setBaseClass(tcp); + else + setBaseClass(classname); + // 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" "%1$s.layout,\n" @@ -493,14 +481,20 @@ string const 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(); + } else if (token == "\\master") { + lex.eatLine(); + master = lex.getString(); } else if (token == "\\language") { readLanguage(lex); } else if (token == "\\inputencoding") { @@ -523,6 +517,8 @@ string const 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; @@ -619,6 +615,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") { @@ -675,7 +673,7 @@ void BufferParams::writeFile(ostream & os) const // Prints out the buffer info into the .lyx file given by file // the textclass - os << "\\textclass " << textclasslist[baseClass_].name() << '\n'; + os << "\\textclass " << baseClass()->name() << '\n'; // then the preamble if (!preamble.empty()) { @@ -690,15 +688,40 @@ void BufferParams::writeFile(ostream & os) const if (!options.empty()) { os << "\\options " << options << '\n'; } + + // the master document + if (!master.empty()) { + 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 + string const tmplocal = rtrim(local_layout, "\n"); + os << "\\begin_local_layout\n" + << tmplocal + << "\n\\end_local_layout\n"; + } // then the text parameters if (language != ignore_language) @@ -712,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'; @@ -768,6 +795,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 " @@ -814,7 +844,7 @@ void BufferParams::writeFile(ostream & os) const void BufferParams::validate(LaTeXFeatures & features) const { - features.require(getTextClass().requires()); + features.require(documentClass().requires()); if (outputChanges) { bool dvipost = LaTeXFeatures::isAvailable("dvipost"); @@ -856,7 +886,7 @@ void BufferParams::validate(LaTeXFeatures & features) const // AMS Style is at document level if (use_amsmath == package_on - || getTextClass().provides("amsmath")) + || documentClass().provides("amsmath")) features.require("amsmath"); if (use_esint == package_on) features.require("esint"); @@ -889,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"); } @@ -897,7 +932,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, { os << "\\documentclass"; - TextClass const & tclass = getTextClass(); + DocumentClass const & tclass = documentClass(); ostringstream clsoptions; // the document class options. @@ -981,13 +1016,18 @@ 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 + // 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"); + // japan = string::npos when not found if (lyxrc.language_global_options && !language_options.str().empty() - && viet == string::npos) + && viet == string::npos && japan == string::npos) clsoptions << language_options.str() << ','; } @@ -1139,8 +1179,12 @@ 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(); + } else if (orientation == ORIENTATION_LANDSCAPE) { + features.require("papersize"); } if (tokenPos(tclass.opt_pagestyle(), @@ -1195,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(); } @@ -1211,38 +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()); - } - - // When the language "japanese-plain" is used, the package "japanese" must - // be loaded behind babel (it provides babel support for Japanese) but before - // hyperref, see - // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html - if (language->lang() == "japanese-plain" && - !getTextClass().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"; - lyxpreamble += "\\usepackage{japanese}\n"; - } - // PDF support. // * Hyperref manual: "Make sure it comes last of your loaded // packages, to give it a fighting chance of not being over-written, @@ -1254,36 +1271,49 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // use hyperref explicitely when it is required if (features.isRequired("hyperref")) { odocstringstream oss; - pdfoptions().writeLaTeX(oss, getTextClass().provides("hyperref")); + pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref")); lyxpreamble += oss.str(); } - // this might be useful... - lyxpreamble += "\n\\makeatletter\n"; + // Will be surrounded by \makeatletter and \makeatother when needed + docstring atlyxpreamble; // Some macros LyX will need docstring tmppreamble(from_ascii(features.getMacros())); - if (!tmppreamble.empty()) { - lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + if (!tmppreamble.empty()) + atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " "LyX specific LaTeX commands.\n" + tmppreamble + '\n'; - } // the text class specific preamble tmppreamble = features.getTClassPreamble(); - if (!tmppreamble.empty()) { - lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + if (!tmppreamble.empty()) + atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " "Textclass specific LaTeX commands.\n" + tmppreamble + '\n'; - } /* the user-defined preamble */ - if (!preamble.empty()) { + if (!preamble.empty()) // FIXME UNICODE - lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " "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 @@ -1319,9 +1349,25 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, } if (!bullets_def.empty()) - lyxpreamble += bullets_def + "}\n\n"; + atlyxpreamble += bullets_def + "}\n\n"; - lyxpreamble += "\\makeatother\n\n"; + if (atlyxpreamble.find(from_ascii("@")) != docstring::npos) + lyxpreamble += "\n\\makeatletter\n" + + atlyxpreamble + "\\makeatother\n\n"; + 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')); @@ -1336,7 +1382,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, void BufferParams::useClassDefaults() { - TextClass const & tclass = textclasslist[baseClass_]; + DocumentClass const & tclass = documentClass(); sides = tclass.sides(); columns = tclass.columns(); @@ -1352,61 +1398,134 @@ void BufferParams::useClassDefaults() bool BufferParams::hasClassDefaults() const { - TextClass const & tclass = textclasslist[baseClass_]; + DocumentClass const & tclass = documentClass(); - return (sides == tclass.sides() + return sides == tclass.sides() && columns == tclass.columns() && pagestyle == tclass.pagestyle() && options == tclass.options() && secnumdepth == tclass.secnumdepth() - && tocdepth == tclass.tocdepth()); + && tocdepth == tclass.tocdepth(); } -TextClass const & BufferParams::getTextClass() const +DocumentClass const & BufferParams::documentClass() const { - return *textClass_; + return *doc_class_; } -TextClassPtr BufferParams::getTextClassPtr() const { - return textClass_; +DocumentClass const * BufferParams::documentClassPtr() const { + return doc_class_; } -void BufferParams::setTextClass(TextClassPtr tc) { - textClass_ = tc; +void BufferParams::setDocumentClass(DocumentClass const * const tc) { + // evil, but this function is evil + doc_class_ = const_cast(tc); } -bool BufferParams::setBaseClass(textclass_type tc) +bool BufferParams::setBaseClass(string const & classname) { - if (textclasslist[tc].load()) { - baseClass_ = tc; - return true; + LYXERR(Debug::TCLASS, "setBaseClass: " << classname); + LayoutFileList & bcl = LayoutFileList::get(); + if (!bcl.haveClass(classname)) { + docstring s = + 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(_("Document class not found"), s); + bcl.addEmptyClass(classname); } - - 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; + + 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; + } + + 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); + } + } + return true; } -textclass_type BufferParams::getBaseClass() const +LayoutFile const * BufferParams::baseClass() const { - return baseClass_; + if (LayoutFileList::get().haveClass(pimpl_->baseClass_)) + return &(LayoutFileList::get()[pimpl_->baseClass_]); + else + return 0; } -void BufferParams::makeTextClass() +LayoutFileIndex const & BufferParams::baseClassID() const { - 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. + return pimpl_->baseClass_; +} + + +void BufferParams::makeDocumentClass() +{ + if (!baseClass()) + 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. LayoutModuleList::const_iterator it = layoutModules_.begin(); for (; it != layoutModules_.end(); it++) { string const modName = *it; @@ -1419,9 +1538,8 @@ void BufferParams::makeTextClass() "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 " << - modName << " requested but not found in module list." << - endl; + LYXERR0("BufferParams::makeDocumentClass(): Module " << + modName << " requested but not found in module list."); continue; } if (!lm->isAvailable()) { @@ -1432,43 +1550,36 @@ void BufferParams::makeTextClass() frontend::Alert::warning(_("Package not available"), msg); } FileName layout_file = libFileSearch("layouts", lm->getFilename()); - if (!textClass_->read(layout_file, TextClass::MODULE)) { + if (!doc_class_->read(layout_file, TextClass::MODULE)) { docstring const msg = bformat(_("Error reading module %1$s\n"), from_utf8(modName)); frontend::Alert::warning(_("Read Error"), msg); } } + if (!local_layout.empty()) { + if (!doc_class_->read(local_layout, TextClass::MODULE)) { + docstring const msg = _("Error reading internal layout information"); + frontend::Alert::warning(_("Read Error"), msg); + } + } } -vector const & BufferParams::getModules() const { - return layoutModules_; -} - - - -bool BufferParams::addLayoutModule(string const & modName) { +bool BufferParams::addLayoutModule(string const & modName) +{ LayoutModuleList::const_iterator it = layoutModules_.begin(); LayoutModuleList::const_iterator end = layoutModules_.end(); - for (; it != end; it++) { + for (; it != end; it++) if (*it == modName) - break; - } - if (it != layoutModules_.end()) - return false; + return false; layoutModules_.push_back(modName); return true; } -void BufferParams::clearLayoutModules() { - layoutModules_.clear(); -} - - Font const BufferParams::getFont() const { - FontInfo f = getTextClass().defaultfont(); + FontInfo f = documentClass().defaultfont(); if (fontsDefaultFamily == "rmdefault") f.setFamily(ROMAN_FAMILY); else if (fontsDefaultFamily == "sfdefault") @@ -1489,6 +1600,16 @@ void BufferParams::readPreamble(Lexer & lex) } +void BufferParams::readLocalLayout(Lexer & lex) +{ + if (lex.getString() != "\\begin_local_layout") + lyxerr << "Error (BufferParams::readLocalLayout):" + "consistency check failed." << endl; + + local_layout = lex.getLongString("\\end_local_layout"); +} + + void BufferParams::readLanguage(Lexer & lex) { if (!lex.next()) return; @@ -1509,7 +1630,8 @@ void BufferParams::readLanguage(Lexer & lex) void BufferParams::readGraphicsDriver(Lexer & lex) { - if (!lex.next()) return; + if (!lex.next()) + return; string const tmptok = lex.getString(); // check if tmptok is part of tex_graphics in tex_defs.h @@ -1520,7 +1642,8 @@ void BufferParams::readGraphicsDriver(Lexer & lex) if (test == tmptok) { graphicsDriver = tmptok; break; - } else if (test == "") { + } + if (test.empty()) { lex.printError( "Warning: graphics driver `$$Token' not recognized!\n" " Setting graphics driver to `default'.\n"); @@ -1533,7 +1656,8 @@ void BufferParams::readGraphicsDriver(Lexer & lex) void BufferParams::readBullets(Lexer & lex) { - if (!lex.next()) return; + if (!lex.next()) + return; int const index = lex.getInteger(); lex.next(); @@ -1552,7 +1676,8 @@ void BufferParams::readBullets(Lexer & lex) void BufferParams::readBulletsLaTeX(Lexer & lex) { // The bullet class should be able to read this. - if (!lex.next()) return; + if (!lex.next()) + return; int const index = lex.getInteger(); lex.next(true); docstring const temp_str = lex.getDocString(); @@ -1579,7 +1704,38 @@ void BufferParams::readModules(Lexer & lex) } -string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const +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; if (real_papersize == PAPER_DEFAULT) @@ -1671,7 +1827,7 @@ string const BufferParams::dvips_options() const } -string const BufferParams::babelCall(string const & lang_opts) const +string BufferParams::babelCall(string const & lang_opts) const { string lang_pack = lyxrc.language_package; if (lang_pack != "\\usepackage{babel}") @@ -1681,12 +1837,17 @@ string const 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 - if (!lyxrc.language_global_options || viet != string::npos) + // 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"); + // japan = string::npos when not found + if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos) return "\\usepackage[" + lang_opts + "]{babel}"; return lang_pack; } @@ -1706,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" || @@ -1890,7 +2051,7 @@ string const BufferParams::loadFonts(string const & rm, else if (tt == "courier" ) os << "\\usepackage{" << tt << "}\n"; // Computer Modern, Latin Modern, CM Bright - else if (tt != "default") + else if (tt != "default") os << "\\renewcommand{\\ttdefault}{" << tt << "}\n"; return os.str(); @@ -1900,29 +2061,28 @@ string const BufferParams::loadFonts(string const & rm, Encoding const & BufferParams::encoding() const { if (inputenc == "auto" || inputenc == "default") - return *(language->encoding()); - Encoding const * const enc = - encodings.getFromLaTeXName(inputenc); + return *language->encoding(); + Encoding const * const enc = encodings.fromLaTeXName(inputenc); if (enc) return *enc; - lyxerr << "Unknown inputenc value `" << inputenc - << "'. Using `auto' instead." << endl; - return *(language->encoding()); + LYXERR0("Unknown inputenc value `" << inputenc + << "'. Using `auto' instead."); + return *language->encoding(); } -biblio::CiteEngine BufferParams::getEngine() const +CiteEngine BufferParams::citeEngine() const { // FIXME the class should provide the numerical/ // authoryear choice - if (getTextClass().provides("natbib") - && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL) - return biblio::ENGINE_NATBIB_AUTHORYEAR; + if (documentClass().provides("natbib") + && cite_engine_ != ENGINE_NATBIB_NUMERICAL) + return ENGINE_NATBIB_AUTHORYEAR; return cite_engine_; } -void BufferParams::setCiteEngine(biblio::CiteEngine const cite_engine) +void BufferParams::setCiteEngine(CiteEngine cite_engine) { cite_engine_ = cite_engine; }