+void BufferParams::validate(LaTeXFeatures & features) const
+{
+ features.require(documentClass().requires());
+
+ if (outputChanges) {
+ bool dvipost = LaTeXFeatures::isAvailable("dvipost");
+ bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
+ LaTeXFeatures::isAvailable("xcolor");
+
+ switch (features.runparams().flavor) {
+ case OutputParams::LATEX:
+ if (dvipost) {
+ features.require("ct-dvipost");
+ features.require("dvipost");
+ } else if (xcolorsoul) {
+ features.require("ct-xcolor-soul");
+ features.require("soul");
+ features.require("xcolor");
+ } else {
+ features.require("ct-none");
+ }
+ break;
+ case OutputParams::PDFLATEX:
+ if (xcolorsoul) {
+ features.require("ct-xcolor-soul");
+ features.require("soul");
+ features.require("xcolor");
+ // improves color handling in PDF output
+ features.require("pdfcolmk");
+ } else {
+ features.require("ct-none");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Floats with 'Here definitely' as default setting.
+ if (float_placement.find('H') != string::npos)
+ features.require("float");
+
+ // AMS Style is at document level
+ if (use_amsmath == package_on
+ || documentClass().provides("amsmath"))
+ features.require("amsmath");
+ if (use_esint == package_on)
+ features.require("esint");
+
+ // Document-level line spacing
+ if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
+ features.require("setspace");
+
+ // the bullet shapes are buffer level not paragraph level
+ // so they are tested here
+ for (int i = 0; i < 4; ++i) {
+ if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
+ continue;
+ int const font = user_defined_bullet(i).getFont();
+ if (font == 0) {
+ int const c = user_defined_bullet(i).getCharacter();
+ if (c == 16
+ || c == 17
+ || c == 25
+ || c == 26
+ || c == 31) {
+ features.require("latexsym");
+ }
+ } else if (font == 1) {
+ features.require("amssymb");
+ } else if (font >= 2 && font <= 5) {
+ features.require("pifont");
+ }
+ }
+
+ if (pdfoptions().use_hyperref) {
+ features.require("hyperref");
+ // due to interferences with babel and hyperref, the color package has to
+ // be loaded after hyperref when hyperref is used with the colorlinks
+ // option, see http://bugzilla.lyx.org/show_bug.cgi?id=5291
+ if (pdfoptions().colorlinks)
+ features.require("color");
+ }
+
+ if (language->lang() == "vietnamese")
+ features.require("vietnamese");
+ else if (language->lang() == "japanese")
+ features.require("japanese");
+}
+
+/// Find out if we need special treatment for babel.
+static bool needsSpecialBabelCall(LaTeXFeatures const & features)
+{
+ // FIXME: don't hardcode this!!
+ // 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
+ //
+ // viet = string::npos when not found
+ // the same is for all other languages that are not directly supported by
+ // babel, but where LaTeX-packages add babel support.
+ // this is currently the case for Latvian, Lithuanian, and Mongolian
+ //
+ // If Japanese is used, babel must directly be loaded with the
+ // language options, see
+ // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
+ return !lyxrc.language_global_options
+ || features.hasLanguage("vietnam")
+ || features.hasLanguage("latvian")
+ || features.hasLanguage("japanese")
+ || features.hasLanguage("lithuanian")
+ || features.hasLanguage("mongolian");
+}
+
+/// set up if and how babel is called
+static docstring babelCall(LaTeXFeatures const & features,
+ string const & lang_opts)
+{
+ string babel_call = lyxrc.language_package;
+ if (babel_call != "\\usepackage{babel}")
+ return from_utf8(babel_call);
+ // suppress the babel call when there is no babel language defined
+ // for the document language in the lib/languages file and if no
+ // other languages are used (lang_opts is then empty)
+ if (!features.hasLanguages())
+ return docstring();
+
+ if (needsSpecialBabelCall(features))
+ babel_call = "\\usepackage[" + lang_opts + "]{babel}";
+
+ return from_utf8(babel_call);
+}
+
+