X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=c48e1cfcca971fdcbcd4147a39666035f58b9584;hb=36a679344a2aceb07ea881b60610afee87175b31;hp=2d113bad4579bbc7851700c03ce4e59048a92c7e;hpb=b032e2dfafbf1e86918dd0cd66e5de602edeee00;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 2d113bad45..c48e1cfcca 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -38,6 +38,7 @@ #include "LyXRC.h" #include "OutputParams.h" #include "Spacing.h" +#include "texstream.h" #include "TexRow.h" #include "VSpace.h" #include "PDFOptions.h" @@ -70,8 +71,9 @@ static char const * const string_paragraph_separation[] = { }; -static char const * const string_quotes_language[] = { - "english", "swedish", "german", "polish", "french", "danish", "" +static char const * const string_quotes_style[] = { + "english", "swedish", "german", "polish", "swiss", "danish", "plain", + "british", "swedishg", "french", "frenchin", "russian", "" }; @@ -126,27 +128,33 @@ ParSepTranslator const & parseptranslator() } -// Quotes language -typedef Translator QuotesLangTranslator; +// Quotes style +typedef Translator QuotesStyleTranslator; -QuotesLangTranslator const init_quoteslangtranslator() +QuotesStyleTranslator const init_quotesstyletranslator() { - 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); + QuotesStyleTranslator translator + (string_quotes_style[0], InsetQuotesParams::EnglishQuotes); + translator.addPair(string_quotes_style[1], InsetQuotesParams::SwedishQuotes); + translator.addPair(string_quotes_style[2], InsetQuotesParams::GermanQuotes); + translator.addPair(string_quotes_style[3], InsetQuotesParams::PolishQuotes); + translator.addPair(string_quotes_style[4], InsetQuotesParams::SwissQuotes); + translator.addPair(string_quotes_style[5], InsetQuotesParams::DanishQuotes); + translator.addPair(string_quotes_style[6], InsetQuotesParams::PlainQuotes); + translator.addPair(string_quotes_style[7], InsetQuotesParams::BritishQuotes); + translator.addPair(string_quotes_style[8], InsetQuotesParams::SwedishGQuotes); + translator.addPair(string_quotes_style[9], InsetQuotesParams::FrenchQuotes); + translator.addPair(string_quotes_style[10], InsetQuotesParams::FrenchINQuotes); + translator.addPair(string_quotes_style[11], InsetQuotesParams::RussianQuotes); return translator; } -QuotesLangTranslator const & quoteslangtranslator() +QuotesStyleTranslator const & quotesstyletranslator() { - static QuotesLangTranslator const translator = - init_quoteslangtranslator(); + static QuotesStyleTranslator const translator = + init_quotesstyletranslator(); return translator; } @@ -304,6 +312,35 @@ SpaceTranslator const & spacetranslator() return translator; } + +bool inSystemDir(FileName const & document_dir, string & system_dir) +{ + // A document is assumed to be in a system LyX directory (not + // necessarily the system directory of the running instance) + // if both "configure.py" and "chkconfig.ltx" are found in + // either document_dir/../ or document_dir/../../. + // If true, the system directory path is returned in system_dir + // with a trailing path separator. + + string const msg = "Checking whether document is in a system dir..."; + + string dir = document_dir.absFileName(); + + for (int i = 0; i < 2; ++i) { + dir = addPath(dir, ".."); + if (!fileSearch(dir, "configure.py").empty() && + !fileSearch(dir, "chkconfig.ltx").empty()) { + LYXERR(Debug::FILES, msg << " yes"); + system_dir = addPath(FileName(dir).realPath(), ""); + return true; + } + } + + LYXERR(Debug::FILES, msg << " no"); + system_dir = string(); + return false; +} + } // anon namespace @@ -325,11 +362,16 @@ public: VSpace defskip; PDFOptions pdfoptions; LayoutFileIndex baseClass_; + FormatList exportableFormatList; + FormatList viewableFormatList; + bool isViewCacheValid; + bool isExportCacheValid; }; BufferParams::Impl::Impl() - : defskip(VSpace::MEDSKIP), baseClass_(string("")) + : defskip(VSpace::MEDSKIP), baseClass_(string("")), + isViewCacheValid(false), isExportCacheValid(false) { // set initial author // FIXME UNICODE @@ -359,7 +401,8 @@ BufferParams::BufferParams() cite_engine_type_ = ENGINE_TYPE_DEFAULT; makeDocumentClass(); paragraph_separation = ParagraphIndentSeparation; - quotes_language = InsetQuotes::EnglishQuotes; + quotes_style = InsetQuotesParams::EnglishQuotes; + dynamic_quotes = false; fontsize = "default"; /* PaperLayout */ @@ -682,8 +725,12 @@ string BufferParams::readToken(Lexer & lex, string const & token, origin = lex.getString(); string const sysdirprefix = "/systemlyxdir/"; if (prefixIs(origin, sysdirprefix)) { - origin.replace(0, sysdirprefix.length() - 1, - package().system_support().absFileName()); + string docsys; + if (inSystemDir(filepath, docsys)) + origin.replace(0, sysdirprefix.length() - 1, docsys); + else + origin.replace(0, sysdirprefix.length() - 1, + package().system_support().absFileName()); } } else if (token == "\\begin_preamble") { readPreamble(lex); @@ -789,10 +836,12 @@ string BufferParams::readToken(Lexer & lex, string const & token, if (pimpl_->defskip.kind() == VSpace::DEFSKIP) // that is invalid pimpl_->defskip = VSpace(VSpace::MEDSKIP); - } else if (token == "\\quotes_language") { - string quotes_lang; - lex >> quotes_lang; - quotes_language = quoteslangtranslator().find(quotes_lang); + } else if (token == "\\quotes_style") { + string qstyle; + lex >> qstyle; + quotes_style = quotesstyletranslator().find(qstyle); + } else if (token == "\\dynamic_quotes") { + lex >> dynamic_quotes; } else if (token == "\\papersize") { string ppsize; lex >> ppsize; @@ -1027,8 +1076,10 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const // the document directory (must end with a path separator) // realPath() is used to resolve symlinks, while addPath(..., "") // ensures a trailing path separator. + string docsys; string filepath = addPath(buf->fileName().onlyPath().realPath(), ""); - string const sysdir = addPath(package().system_support().realPath(), ""); + string const sysdir = inSystemDir(FileName(filepath), docsys) ? docsys + : addPath(package().system_support().realPath(), ""); string const relpath = to_utf8(makeRelPath(from_utf8(filepath), from_utf8(sysdir))); if (!prefixIs(relpath, "../") && !FileName::isAbsolute(relpath)) @@ -1046,9 +1097,9 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const // then the preamble if (!preamble.empty()) { // remove '\n' from the end of preamble - string const tmppreamble = rtrim(preamble, "\n"); + docstring const tmppreamble = rtrim(preamble, "\n"); os << "\\begin_preamble\n" - << tmppreamble + << to_utf8(tmppreamble) << "\n\\end_preamble\n"; } @@ -1099,20 +1150,20 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const << convert(maintain_unincluded_children) << '\n'; // local layout information - string const local_layout = getLocalLayout(false); + docstring const local_layout = getLocalLayout(false); if (!local_layout.empty()) { // remove '\n' from the end - string const tmplocal = rtrim(local_layout, "\n"); + docstring const tmplocal = rtrim(local_layout, "\n"); os << "\\begin_local_layout\n" - << tmplocal + << to_utf8(tmplocal) << "\n\\end_local_layout\n"; } - string const forced_local_layout = getLocalLayout(true); + docstring const forced_local_layout = getLocalLayout(true); if (!forced_local_layout.empty()) { // remove '\n' from the end - string const tmplocal = rtrim(forced_local_layout, "\n"); + docstring const tmplocal = rtrim(forced_local_layout, "\n"); os << "\\begin_forced_local_layout\n" - << tmplocal + << to_utf8(tmplocal) << "\n\\end_forced_local_layout\n"; } @@ -1258,8 +1309,9 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand(); else os << "\n\\defskip " << getDefSkip().asLyXCommand(); - os << "\n\\quotes_language " - << string_quotes_language[quotes_language] + os << "\n\\quotes_style " + << string_quotes_style[quotes_style] + << "\n\\dynamic_quotes " << dynamic_quotes << "\n\\papercolumns " << columns << "\n\\papersides " << sides << "\n\\paperpagestyle " << pagestyle << '\n'; @@ -1411,7 +1463,7 @@ void BufferParams::validate(LaTeXFeatures & features) const // some languages are only available via polyglossia if (features.hasPolyglossiaExclusiveLanguages()) - features.require("polyglossia"); + features.require("polyglossia"); if (useNonTeXFonts && fontsMath() != "auto") features.require("unicode-math"); @@ -1589,7 +1641,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << from_ascii(ams); if (useNonTeXFonts) { - os << "\\usepackage{fontspec}\n"; + if (!features.isProvided("fontspec")) + os << "\\usepackage{fontspec}\n"; if (features.mustProvide("unicode-math") && features.isAvailable("unicode-math")) os << "\\usepackage{unicode-math}\n"; @@ -1862,20 +1915,20 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } // Now insert the LyX specific LaTeX commands... - docstring lyxpreamble; features.resolveAlternatives(); + features.expandMultiples(); if (output_sync) { if (!output_sync_macro.empty()) - lyxpreamble += from_utf8(output_sync_macro) +"\n"; + os << from_utf8(output_sync_macro) +"\n"; else if (features.runparams().flavor == OutputParams::LATEX) - lyxpreamble += "\\usepackage[active]{srcltx}\n"; + os << "\\usepackage[active]{srcltx}\n"; else if (features.runparams().flavor == OutputParams::PDFLATEX) - lyxpreamble += "\\synctex=-1\n"; + os << "\\synctex=-1\n"; } // The package options (via \PassOptionsToPackage) - lyxpreamble += from_ascii(features.getPackageOptions()); + os << from_ascii(features.getPackageOptions()); // due to interferences with babel and hyperref, the color package has to // be loaded (when it is not already loaded) before babel when hyperref @@ -1883,7 +1936,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // http://www.lyx.org/trac/ticket/5291 // we decided therefore to load color always before babel, see // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html - lyxpreamble += from_ascii(features.getColorOptions()); + os << from_ascii(features.getColorOptions()); // If we use hyperref, jurabib, japanese, varioref or vietnamese, // we have to call babel before @@ -1893,15 +1946,15 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, || features.isRequired("varioref") || features.isRequired("vietnamese") || features.isRequired("japanese"))) { + os << features.getBabelPresettings(); // FIXME UNICODE - lyxpreamble += from_utf8(features.getBabelPresettings()); - lyxpreamble += from_utf8(babelCall(language_options.str(), - features.needBabelLangOptions())) + '\n'; - lyxpreamble += from_utf8(features.getBabelPostsettings()); + os << from_utf8(babelCall(language_options.str(), + features.needBabelLangOptions())) + '\n'; + os << features.getBabelPostsettings(); } // The optional packages; - lyxpreamble += from_ascii(features.getPackages()); + os << from_ascii(features.getPackages()); // Additional Indices if (features.isRequired("splitidx")) { @@ -1919,16 +1972,16 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, "representable in the current encoding and therefore have been omitted:\n%1$s."), indexname_latex.second)); } - lyxpreamble += "\\newindex["; - lyxpreamble += indexname_latex.first; - lyxpreamble += "]{"; - lyxpreamble += escape(iit->shortcut()); - lyxpreamble += "}\n"; + os << "\\newindex["; + os << indexname_latex.first; + os << "]{"; + os << escape(iit->shortcut()); + os << "}\n"; } } // Line spacing - lyxpreamble += from_utf8(spacing().writePreamble(features.isProvided("SetSpace"))); + os << from_utf8(spacing().writePreamble(features.isProvided("SetSpace"))); // PDF support. // * Hyperref manual: "Make sure it comes last of your loaded @@ -1940,66 +1993,62 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // avoid errors with algorithm floats. // use hyperref explicitly if it is required if (features.isRequired("hyperref")) { - // pass what we have to stream here, since we need - // to access the stream itself in PDFOptions. - os << lyxpreamble; - OutputParams tmp_params = features.runparams(); pdfoptions().writeLaTeX(tmp_params, os, features.isProvided("hyperref")); - // set back for the rest - lyxpreamble.clear(); // correctly break URLs with hyperref and dvi output if (features.runparams().flavor == OutputParams::LATEX && features.isAvailable("breakurl")) - lyxpreamble += "\\usepackage{breakurl}\n"; + os << "\\usepackage{breakurl}\n"; } else if (features.isRequired("nameref")) // hyperref loads this automatically - lyxpreamble += "\\usepackage{nameref}\n"; + os << "\\usepackage{nameref}\n"; // bibtopic needs to be loaded after hyperref. // the dot provides the aux file naming which LyX can detect. if (features.mustProvide("bibtopic")) - lyxpreamble += "\\usepackage[dot]{bibtopic}\n"; + os << "\\usepackage[dot]{bibtopic}\n"; // Will be surrounded by \makeatletter and \makeatother when not empty - docstring atlyxpreamble; + otexstringstream atlyxpreamble; // Some macros LyX will need - docstring tmppreamble(features.getMacros()); - - if (!tmppreamble.empty()) - atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " - "LyX specific LaTeX commands.\n" - + tmppreamble + '\n'; - + { + TexString tmppreamble = features.getMacros(); + if (!tmppreamble.str.empty()) + atlyxpreamble << "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + "LyX specific LaTeX commands.\n" + << move(tmppreamble) + << '\n'; + } // the text class specific preamble - tmppreamble = features.getTClassPreamble(); - if (!tmppreamble.empty()) - atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " - "Textclass specific LaTeX commands.\n" - + tmppreamble + '\n'; - + { + docstring tmppreamble = features.getTClassPreamble(); + if (!tmppreamble.empty()) + atlyxpreamble << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + "Textclass specific LaTeX commands.\n" + << tmppreamble + << '\n'; + } // suppress date if selected // use \@ifundefined because we cannot be sure that every document class // has a \date command if (suppress_date) - atlyxpreamble += "\\@ifundefined{date}{}{\\date{}}\n"; + atlyxpreamble << "\\@ifundefined{date}{}{\\date{}}\n"; /* the user-defined preamble */ if (!containsOnly(preamble, " \n\t")) { // FIXME UNICODE - atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " - "User specified LaTeX commands.\n"; + atlyxpreamble << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + "User specified LaTeX commands.\n"; // Check if the user preamble contains uncodable glyphs - docstring const u_preamble = from_utf8(preamble); odocstringstream user_preamble; docstring uncodable_glyphs; Encoding const * const enc = features.runparams().encoding; if (enc) { - for (size_t n = 0; n < u_preamble.size(); ++n) { - char_type c = u_preamble[n]; + for (size_t n = 0; n < preamble.size(); ++n) { + char_type c = preamble[n]; if (!enc->encodable(c)) { docstring const glyph(1, c); LYXERR0("Uncodable character '" @@ -2016,7 +2065,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, user_preamble.put(c); } } else - user_preamble << u_preamble; + user_preamble << preamble; // On BUFFER_VIEW|UPDATE, warn user if we found uncodable glyphs if (!features.runparams().dryrun && !uncodable_glyphs.empty()) { @@ -2034,7 +2083,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, "preamble code accordingly."), uncodable_glyphs)); } - atlyxpreamble += user_preamble.str() + '\n'; + atlyxpreamble << user_preamble.str() << '\n'; } // footmisc must be loaded after setspace @@ -2042,7 +2091,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // preamble. For that reason we also pass the options via // \PassOptionsToPackage in getPreamble() and not here. if (features.mustProvide("footmisc")) - atlyxpreamble += "\\usepackage{footmisc}\n"; + atlyxpreamble << "\\usepackage{footmisc}\n"; // subfig loads internally the LaTeX package "caption". As // caption is a very popular package, users will load it in @@ -2054,11 +2103,10 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // 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"; - } + if (features.mustProvide("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 @@ -2093,11 +2141,12 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } if (!bullets_def.empty()) - atlyxpreamble += bullets_def + "}\n\n"; + atlyxpreamble << bullets_def << "}\n\n"; if (!atlyxpreamble.empty()) - lyxpreamble += "\n\\makeatletter\n" - + atlyxpreamble + "\\makeatother\n\n"; + os << "\n\\makeatletter\n" + << atlyxpreamble.release() + << "\\makeatother\n\n"; // We try to load babel late, in case it interferes with other packages. // Jurabib, hyperref, varioref, bicaption and listings (bug 8995) have to be @@ -2107,68 +2156,70 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, && !features.isRequired("varioref") && !features.isRequired("vietnamese") && !features.isRequired("japanese")) { + os << features.getBabelPresettings(); // FIXME UNICODE - lyxpreamble += from_utf8(features.getBabelPresettings()); - lyxpreamble += from_utf8(babelCall(language_options.str(), - features.needBabelLangOptions())) + '\n'; - lyxpreamble += from_utf8(features.getBabelPostsettings()); + os << from_utf8(babelCall(language_options.str(), + features.needBabelLangOptions())) + '\n'; + os << features.getBabelPostsettings(); } if (features.isRequired("bicaption")) - lyxpreamble += "\\usepackage{bicaption}\n"; - if (!listings_params.empty() || features.isRequired("listings")) - lyxpreamble += "\\usepackage{listings}\n"; + os << "\\usepackage{bicaption}\n"; + if (!listings_params.empty() || features.mustProvide("listings")) + os << "\\usepackage{listings}\n"; if (!listings_params.empty()) { - lyxpreamble += "\\lstset{"; + os << "\\lstset{"; // do not test validity because listings_params is // supposed to be valid string par = InsetListingsParams(listings_params).separatedParams(true); - lyxpreamble += from_utf8(par); - lyxpreamble += "}\n"; + os << from_utf8(par); + os << "}\n"; } // xunicode needs to be loaded at least after amsmath, amssymb, // esint and the other packages that provide special glyphs + // The package only supports XeTeX currently. if (features.runparams().flavor == OutputParams::XETEX && useNonTeXFonts) - lyxpreamble += "\\usepackage{xunicode}\n"; + os << "\\usepackage{xunicode}\n"; // Polyglossia must be loaded last if (use_polyglossia) { // call the package - lyxpreamble += "\\usepackage{polyglossia}\n"; + os << "\\usepackage{polyglossia}\n"; // set the main language - lyxpreamble += "\\setdefaultlanguage"; + os << "\\setdefaultlanguage"; if (!language->polyglossiaOpts().empty()) - lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]"; - lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n"; + os << "[" << from_ascii(language->polyglossiaOpts()) << "]"; + os << "{" << from_ascii(language->polyglossia()) << "}\n"; // now setup the other languages - std::map const polylangs = + set const polylangs = features.getPolyglossiaLanguages(); - for (std::map::const_iterator mit = polylangs.begin(); + for (set::const_iterator mit = polylangs.begin(); mit != polylangs.end() ; ++mit) { - lyxpreamble += "\\setotherlanguage"; - if (!mit->second.empty()) - lyxpreamble += "[" + from_ascii(mit->second) + "]"; - lyxpreamble += "{" + from_ascii(mit->first) + "}\n"; + // We do not output the options here; they are output in + // the language switch commands. This is safer if multiple + // varieties are used. + if (*mit == language->polyglossia()) + continue; + os << "\\setotherlanguage"; + os << "{" << from_ascii(*mit) << "}\n"; } } // Load custom language package here if (features.langPackage() == LaTeXFeatures::LANG_PACK_CUSTOM) { if (lang_package == "default") - lyxpreamble += from_utf8(lyxrc.language_custom_package); + os << from_utf8(lyxrc.language_custom_package); else - lyxpreamble += from_utf8(lang_package); - lyxpreamble += '\n'; + os << from_utf8(lang_package); + os << '\n'; } docstring const i18npreamble = features.getTClassI18nPreamble(use_babel, use_polyglossia); if (!i18npreamble.empty()) - lyxpreamble += i18npreamble + '\n'; - - os << lyxpreamble; + os << i18npreamble + '\n'; return use_babel; } @@ -2219,6 +2270,7 @@ void BufferParams::setDocumentClass(DocumentClassConstPtr tc) { // evil, but this function is evil doc_class_ = const_pointer_cast(tc); + invalidateConverterCache(); } @@ -2277,6 +2329,7 @@ void BufferParams::makeDocumentClass(bool const clone) if (!baseClass()) return; + invalidateConverterCache(); LayoutModuleList mods; LayoutModuleList::iterator it = layout_modules_.begin(); LayoutModuleList::iterator en = layout_modules_.end(); @@ -2292,10 +2345,11 @@ void BufferParams::makeDocumentClass(bool const clone) TextClass::ReturnValues success = TextClass::OK; if (!forced_local_layout_.empty()) - success = doc_class_->read(forced_local_layout_, TextClass::MODULE); + success = doc_class_->read(to_utf8(forced_local_layout_), + TextClass::MODULE); if (!local_layout_.empty() && (success == TextClass::OK || success == TextClass::OK_OLDFORMAT)) - success = doc_class_->read(local_layout_, TextClass::MODULE); + success = doc_class_->read(to_utf8(local_layout_), TextClass::MODULE); if (success != TextClass::OK && success != TextClass::OK_OLDFORMAT) { docstring const msg = _("Error reading internal layout information"); frontend::Alert::warning(_("Read Error"), msg); @@ -2315,16 +2369,16 @@ bool BufferParams::citationModuleCanBeAdded(string const & modName) const } -std::string BufferParams::getLocalLayout(bool forced) const +docstring BufferParams::getLocalLayout(bool forced) const { if (forced) - return doc_class_->forcedLayouts(); + return from_utf8(doc_class_->forcedLayouts()); else return local_layout_; } -void BufferParams::setLocalLayout(string const & layout, bool forced) +void BufferParams::setLocalLayout(docstring const & layout, bool forced) { if (forced) forced_local_layout_ = layout; @@ -2347,60 +2401,50 @@ bool BufferParams::addLayoutModule(string const & modName) string BufferParams::bufferFormat() const { - string format = documentClass().outputFormat(); - if (format == "latex") { - if (useNonTeXFonts) - return "xetex"; // actually "xetex or luatex" - if (encoding().package() == Encoding::japanese) - return "platex"; - } - return format; + return documentClass().outputFormat(); } -bool BufferParams::isExportable(string const & format) const +bool BufferParams::isExportable(string const & format, bool need_viewable) const { - vector backs = backends(); - for (vector::const_iterator it = backs.begin(); - it != backs.end(); ++it) - if (theConverters().isReachable(*it, format)) + FormatList const & formats = exportableFormats(need_viewable); + FormatList::const_iterator fit = formats.begin(); + FormatList::const_iterator end = formats.end(); + for (; fit != end ; ++fit) { + if ((*fit)->name() == format) return true; + } return false; } -vector BufferParams::exportableFormats(bool only_viewable) const +FormatList const & BufferParams::exportableFormats(bool only_viewable) const { + FormatList & cached = only_viewable ? + pimpl_->viewableFormatList : pimpl_->exportableFormatList; + bool & valid = only_viewable ? + pimpl_->isViewCacheValid : pimpl_->isExportCacheValid; + if (valid) + return cached; + vector const backs = backends(); set excludes; if (useNonTeXFonts) { excludes.insert("latex"); excludes.insert("pdflatex"); } - vector result = + FormatList result = theConverters().getReachable(backs[0], only_viewable, true, excludes); for (vector::const_iterator it = backs.begin() + 1; it != backs.end(); ++it) { - vector r = - theConverters().getReachable(*it, only_viewable, false, excludes); + FormatList r = theConverters().getReachable(*it, only_viewable, + false, excludes); result.insert(result.end(), r.begin(), r.end()); } - return result; -} - - -bool BufferParams::isExportableFormat(string const & format) const -{ - typedef vector Formats; - Formats formats; - formats = exportableFormats(true); - Formats::const_iterator fit = formats.begin(); - Formats::const_iterator end = formats.end(); - for (; fit != end ; ++fit) { - if ((*fit)->name() == format) - return true; - } - return false; + sort(result.begin(), result.end(), Format::formatSorter); + cached = result; + valid = true; + return cached; } @@ -2411,17 +2455,14 @@ vector BufferParams::backends() const // FIXME: Don't hardcode format names here, but use a flag if (buffmt == "latex") { - if (!useNonTeXFonts) { - v.push_back("pdflatex"); - v.push_back("latex"); - } - v.push_back("luatex"); - v.push_back("dviluatex"); - v.push_back("xetex"); - } else if (buffmt == "xetex") { - v.push_back("xetex"); - // FIXME: need to test all languages (bug 8205) - if (!language || !language->isPolyglossiaExclusive()) { + if (encoding().package() == Encoding::japanese) + v.push_back("platex"); + else { + if (!useNonTeXFonts) { + v.push_back("pdflatex"); + v.push_back("latex"); + } + v.push_back("xetex"); v.push_back("luatex"); v.push_back("dviluatex"); } @@ -2493,7 +2534,7 @@ string BufferParams::getDefaultOutputFormat() const return default_output_format; if (isDocBook() || encoding().package() == Encoding::japanese) { - vector const formats = exportableFormats(true); + FormatList const & formats = exportableFormats(true); if (formats.empty()) return string(); // return the first we find @@ -2517,9 +2558,9 @@ Font const BufferParams::getFont() const } -InsetQuotes::QuoteLanguage BufferParams::getQuoteStyle(string const & qs) const +InsetQuotesParams::QuoteStyle BufferParams::getQuoteStyle(string const & qs) const { - return quoteslangtranslator().find(qs); + return quotesstyletranslator().find(qs); } @@ -2547,7 +2588,7 @@ void BufferParams::readPreamble(Lexer & lex) lyxerr << "Error (BufferParams::readPreamble):" "consistency check failed." << endl; - preamble = lex.getLongString("\\end_preamble"); + preamble = lex.getLongString(from_ascii("\\end_preamble")); } @@ -2561,9 +2602,9 @@ void BufferParams::readLocalLayout(Lexer & lex, bool forced) if (forced) forced_local_layout_ = - lex.getLongString("\\end_forced_local_layout"); + lex.getLongString(from_ascii("\\end_forced_local_layout")); else - local_layout_ = lex.getLongString("\\end_local_layout"); + local_layout_ = lex.getLongString(from_ascii("\\end_local_layout")); } @@ -2973,8 +3014,8 @@ void BufferParams::writeEncodingPreamble(otexstream & os, // XeTeX/LuaTeX: (see also #9740) // With Unicode fonts we use utf8-plain without encoding package. // With TeX fonts, we cannot use utf8-plain, but "inputenc" fails. - // XeTeX must use ASCII encoding, for LuaTeX, we load - // "luainputenc" (see below). + // XeTeX must use ASCII encoding (see Buffer.cpp), + // for LuaTeX, we load "luainputenc" (see below). if (useNonTeXFonts || features.runparams().flavor == OutputParams::XETEX) return; @@ -3261,4 +3302,10 @@ vector BufferParams::citeStyles() const return styles; } +void BufferParams::invalidateConverterCache() const +{ + pimpl_->isExportCacheValid = false; + pimpl_->isViewCacheValid = false; +} + } // namespace lyx