X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=fa0b7c3b92819ccb8d4beea6f64c898a71fd9487;hb=5fdc577badb1cb133d6a0dc7d831bb1f82576adb;hp=3439095e447da9b2e5de15d3245cf91c90603ea8;hpb=1f945177b9628b213c60872df88f2d155c3d6c54;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 3439095e44..fa0b7c3b92 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -71,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", "cjk", "cjkangle", "" }; @@ -127,27 +128,35 @@ 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); + translator.addPair(string_quotes_style[12], InsetQuotesParams::CJKQuotes); + translator.addPair(string_quotes_style[13], InsetQuotesParams::CJKAngleQuotes); return translator; } -QuotesLangTranslator const & quoteslangtranslator() +QuotesStyleTranslator const & quotesstyletranslator() { - static QuotesLangTranslator const translator = - init_quoteslangtranslator(); + static QuotesStyleTranslator const translator = + init_quotesstyletranslator(); return translator; } @@ -355,11 +364,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 @@ -389,7 +403,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 */ @@ -823,10 +838,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; @@ -1294,8 +1311,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'; @@ -1447,7 +1465,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"); @@ -1899,21 +1917,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 @@ -1921,7 +1938,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 @@ -1931,15 +1948,15 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, || features.isRequired("varioref") || features.isRequired("vietnamese") || features.isRequired("japanese"))) { - lyxpreamble += features.getBabelPresettings(); + os << features.getBabelPresettings(); // FIXME UNICODE - lyxpreamble += from_utf8(babelCall(language_options.str(), - features.needBabelLangOptions())) + '\n'; - lyxpreamble += 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")) { @@ -1957,16 +1974,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 @@ -1978,57 +1995,54 @@ 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 odocstringstream user_preamble; @@ -2071,7 +2085,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 @@ -2079,7 +2093,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 @@ -2091,11 +2105,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.mustProvide("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 @@ -2130,11 +2143,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 @@ -2144,24 +2158,24 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, && !features.isRequired("varioref") && !features.isRequired("vietnamese") && !features.isRequired("japanese")) { - lyxpreamble += features.getBabelPresettings(); + os << features.getBabelPresettings(); // FIXME UNICODE - lyxpreamble += from_utf8(babelCall(language_options.str(), - features.needBabelLangOptions())) + '\n'; - lyxpreamble += features.getBabelPostsettings(); + os << from_utf8(babelCall(language_options.str(), + features.needBabelLangOptions())) + '\n'; + os << features.getBabelPostsettings(); } if (features.isRequired("bicaption")) - lyxpreamble += "\\usepackage{bicaption}\n"; + os << "\\usepackage{bicaption}\n"; if (!listings_params.empty() || features.mustProvide("listings")) - lyxpreamble += "\\usepackage{listings}\n"; + 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, @@ -2169,44 +2183,45 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // 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; } @@ -2257,6 +2272,7 @@ void BufferParams::setDocumentClass(DocumentClassConstPtr tc) { // evil, but this function is evil doc_class_ = const_pointer_cast(tc); + invalidateConverterCache(); } @@ -2315,6 +2331,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(); @@ -2390,49 +2407,46 @@ string BufferParams::bufferFormat() const } -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; } @@ -2522,7 +2536,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 @@ -2546,9 +2560,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); } @@ -3290,4 +3304,10 @@ vector BufferParams::citeStyles() const return styles; } +void BufferParams::invalidateConverterCache() const +{ + pimpl_->isExportCacheValid = false; + pimpl_->isViewCacheValid = false; +} + } // namespace lyx