]> git.lyx.org Git - lyx.git/blobdiff - src/BufferParams.cpp
Add buffer param to opt-out fragile content movement
[lyx.git] / src / BufferParams.cpp
index 7211f12b836714c4c5f2effc98e0d2b8382ed3ba..b1cedda6fa5b29682e64946ab7b52f7b35e0ce5c 100644 (file)
@@ -79,12 +79,20 @@ static char const * const string_quotes_style[] = {
 
 
 static char const * const string_papersize[] = {
+       "default", "custom", "letter", "legal", "executive",
+       "a0", "a1", "a2", "a3", "a4", "a5", "a6",
+       "b0", "b1", "b2", "b3", "b4", "b5", "b6",
+       "c0", "c1", "c2", "c3", "c4", "c5", "c6",
+       "b0j", "b1j", "b2j", "b3j", "b4j", "b5j", "b6j", ""
+};
+
+
+static char const * const string_papersize_geometry[] = {
        "default", "custom", "letterpaper", "legalpaper", "executivepaper",
-       "a0paper", "a1paper", "a2paper", "a3paper",     "a4paper", "a5paper",
-       "a6paper", "b0paper", "b1paper", "b2paper","b3paper", "b4paper",
-       "b5paper", "b6paper", "c0paper", "c1paper", "c2paper", "c3paper",
-       "c4paper", "c5paper", "c6paper", "b0j", "b1j", "b2j", "b3j", "b4j", "b5j",
-       "b6j", ""
+       "a0paper", "a1paper", "a2paper", "a3paper", "a4paper", "a5paper", "a6paper",
+       "b0paper", "b1paper", "b2paper", "b3paper", "b4paper", "b5paper", "b6paper",
+       "c0paper", "c1paper", "c2paper", "c3paper", "c4paper", "c5paper", "c6paper",
+       "b0j", "b1j", "b2j", "b3j", "b4j", "b5j", "b6j", ""
 };
 
 
@@ -102,7 +110,6 @@ static char const * const tex_graphics[] = {
 };
 
 
-
 namespace lyx {
 
 // Local translators
@@ -308,7 +315,7 @@ bool inSystemDir(FileName const & document_dir, string & system_dir)
 
        string dir = document_dir.absFileName();
 
-       for (int i = 0; i < 2; ++i) {
+       for (int i = 0; i < 3; ++i) {
                dir = addPath(dir, "..");
                if (!fileSearch(dir, "configure.py").empty() &&
                    !fileSearch(dir, "chkconfig.ltx").empty()) {
@@ -358,7 +365,9 @@ BufferParams::Impl::Impl()
 {
        // set initial author
        // FIXME UNICODE
-       authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
+       authorlist.record(Author(from_utf8(lyxrc.user_name),
+                                from_utf8(lyxrc.user_email),
+                                from_utf8(lyxrc.user_initials)));
 }
 
 
@@ -380,7 +389,7 @@ BufferParams::BufferParams()
        : pimpl_(new Impl)
 {
        setBaseClass(defaultBaseclass());
-       cite_engine_.push_back("basic");
+       cite_engine_ = "basic";
        cite_engine_type_ = ENGINE_TYPE_DEFAULT;
        makeDocumentClass();
        paragraph_separation = ParagraphIndentSeparation;
@@ -401,6 +410,8 @@ BufferParams::BufferParams()
        save_transient_properties = true;
        track_changes = false;
        output_changes = false;
+       change_bars = false;
+       postpone_fragile_content = true;
        use_default_options = true;
        maintain_unincluded_children = false;
        secnumdepth = 3;
@@ -420,12 +431,14 @@ BufferParams::BufferParams()
        use_microtype = false;
        use_dash_ligatures = true;
        fonts_expert_sc = false;
-       fonts_old_figures = false;
+       fonts_roman_osf = false;
+       fonts_sans_osf = false;
+       fonts_typewriter_osf = false;
        fonts_sans_scale[0] = 100;
        fonts_sans_scale[1] = 100;
        fonts_typewriter_scale[0] = 100;
        fonts_typewriter_scale[1] = 100;
-       inputenc = "auto";
+       inputenc = "utf8";
        lang_package = "default";
        graphics_driver = "default";
        default_output_format = "default";
@@ -435,6 +448,7 @@ BufferParams::BufferParams()
        columns = 1;
        listings_params = string();
        pagestyle = "default";
+       tablestyle = "default";
        suppress_date = false;
        justification = true;
        // no color is the default (white)
@@ -463,6 +477,7 @@ BufferParams::BufferParams()
        output_sync = false;
        use_refstyle = true;
        use_minted = false;
+       use_lineno = false;
 
        // map current author
        author_map_[pimpl_->authorlist.get(0).bufferId()] = 0;
@@ -831,14 +846,24 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                lex >> useNonTeXFonts;
        } else if (token == "\\font_sc") {
                lex >> fonts_expert_sc;
-       } else if (token == "\\font_osf") {
-               lex >> fonts_old_figures;
+       } else if (token == "\\font_roman_osf") {
+               lex >> fonts_roman_osf;
+       } else if (token == "\\font_sans_osf") {
+               lex >> fonts_sans_osf;
+       } else if (token == "\\font_typewriter_osf") {
+               lex >> fonts_typewriter_osf;
+       } else if (token == "\\font_roman_opts") {
+               lex >> font_roman_opts;
        } else if (token == "\\font_sf_scale") {
                lex >> fonts_sans_scale[0];
                lex >> fonts_sans_scale[1];
+       } else if (token == "\\font_sans_opts") {
+               lex >> font_sans_opts;
        } else if (token == "\\font_tt_scale") {
                lex >> fonts_typewriter_scale[0];
                lex >> fonts_typewriter_scale[1];
+       } else if (token == "\\font_typewriter_opts") {
+               lex >> font_typewriter_opts;
        } else if (token == "\\font_cjk") {
                lex >> fonts_cjk;
        } else if (token == "\\use_microtype") {
@@ -901,8 +926,7 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                use_package(package, packagetranslator().find(use));
        } else if (token == "\\cite_engine") {
                lex.eatLine();
-               vector<string> engine = getVectorFromString(lex.getString());
-               setCiteEngine(engine);
+               cite_engine_ = lex.getString();
        } else if (token == "\\cite_engine_type") {
                string engine_type;
                lex >> engine_type;
@@ -929,6 +953,10 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                lex >> track_changes;
        } else if (token == "\\output_changes") {
                lex >> output_changes;
+       } else if (token == "\\change_bars") {
+               lex >> change_bars;
+       } else if (token == "\\postpone_fragile_content") {
+               lex >> postpone_fragile_content;
        } else if (token == "\\branch") {
                lex.eatLine();
                docstring branch = lex.getDocString();
@@ -1053,6 +1081,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                sides = sidestranslator().find(psides);
        } else if (token == "\\paperpagestyle") {
                lex >> pagestyle;
+       } else if (token == "\\tablestyle") {
+               lex >> tablestyle;
        } else if (token == "\\bullet") {
                readBullets(lex);
        } else if (token == "\\bulletLaTeX") {
@@ -1071,6 +1101,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                spacing().set(spacetranslator().find(nspacing), tmp_val);
        } else if (token == "\\float_placement") {
                lex >> float_placement;
+       } else if (token == "\\float_alignment") {
+               lex >> float_alignment;
 
        } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
                string toktmp = pdfoptions().readToken(lex, token);
@@ -1103,6 +1135,11 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                lex >> use_refstyle;
        } else if (token == "\\use_minted") {
                lex >> use_minted;
+       } else if (token == "\\use_lineno") {
+               lex >> use_lineno;
+       } else if (token == "\\lineno_options") {
+               lex.eatLine();
+               lineno_opts = trim(lex.getString());
        } else {
                lyxerr << "BufferParams::readToken(): Unknown token: " <<
                        token << endl;
@@ -1242,15 +1279,22 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
           << "\n\\font_default_family " << fonts_default_family
           << "\n\\use_non_tex_fonts " << convert<string>(useNonTeXFonts)
           << "\n\\font_sc " << convert<string>(fonts_expert_sc)
-          << "\n\\font_osf " << convert<string>(fonts_old_figures)
-          << "\n\\font_sf_scale " << fonts_sans_scale[0]
-          << ' ' << fonts_sans_scale[1]
-          << "\n\\font_tt_scale " << fonts_typewriter_scale[0]
-          << ' ' << fonts_typewriter_scale[1]
-          << '\n';
-       if (!fonts_cjk.empty()) {
+          << "\n\\font_roman_osf " << convert<string>(fonts_roman_osf)
+          << "\n\\font_sans_osf " << convert<string>(fonts_sans_osf)
+          << "\n\\font_typewriter_osf " << convert<string>(fonts_typewriter_osf);
+       if (!font_roman_opts.empty())
+               os << "\n\\font_roman_opts \"" << font_roman_opts << "\"";
+       os << "\n\\font_sf_scale " << fonts_sans_scale[0]
+          << ' ' << fonts_sans_scale[1];
+       if (!font_sans_opts.empty())
+               os << "\n\\font_sans_opts \"" << font_sans_opts << "\"";
+       os << "\n\\font_tt_scale " << fonts_typewriter_scale[0]
+          << ' ' << fonts_typewriter_scale[1];
+       if (!font_typewriter_opts.empty())
+               os << "\n\\font_typewriter_opts \"" << font_typewriter_opts << "\"";
+       os << '\n';
+       if (!fonts_cjk.empty())
                os << "\\font_cjk " << fonts_cjk << '\n';
-       }
        os << "\\use_microtype " << convert<string>(use_microtype) << '\n';
        os << "\\use_dash_ligatures " << convert<string>(use_dash_ligatures) << '\n';
        os << "\\graphics " << graphics_driver << '\n';
@@ -1261,9 +1305,10 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
        os << "\\bibtex_command " << bibtex_command << '\n';
        os << "\\index_command " << index_command << '\n';
 
-       if (!float_placement.empty()) {
+       if (!float_placement.empty())
                os << "\\float_placement " << float_placement << '\n';
-       }
+       if (!float_alignment.empty())
+               os << "\\float_alignment " << float_alignment << '\n';
        os << "\\paperfontsize " << fontsize << '\n';
 
        spacing().writeFile(os);
@@ -1279,17 +1324,10 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
 
        os << "\n\\cite_engine ";
 
-       if (!cite_engine_.empty()) {
-               LayoutModuleList::const_iterator be = cite_engine_.begin();
-               LayoutModuleList::const_iterator en = cite_engine_.end();
-               for (LayoutModuleList::const_iterator it = be; it != en; ++it) {
-                       if (it != be)
-                               os << ',';
-                       os << *it;
-               }
-       } else {
+       if (!cite_engine_.empty())
+               os << cite_engine_;
+       else
                os << "basic";
-       }
 
        os << "\n\\cite_engine_type " << theCiteEnginesList.getTypeAsString(cite_engine_type_);
 
@@ -1311,7 +1349,12 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
           << "\n\\justification " << convert<string>(justification)
           << "\n\\use_refstyle " << use_refstyle
           << "\n\\use_minted " << use_minted
+          << "\n\\use_lineno " << use_lineno
           << '\n';
+
+       if (!lineno_opts.empty())
+               os << "\\lineno_options " << lineno_opts << '\n';
+
        if (isbackgroundcolor == true)
                os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
        if (isfontcolor == true)
@@ -1401,7 +1444,8 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
           << "\n\\dynamic_quotes " << dynamic_quotes
           << "\n\\papercolumns " << columns
           << "\n\\papersides " << sides
-          << "\n\\paperpagestyle " << pagestyle << '\n';
+          << "\n\\paperpagestyle " << pagestyle
+          << "\n\\tablestyle " << tablestyle << '\n';
        if (!listings_params.empty())
                os << "\\listings_params \"" <<
                        InsetListingsParams(listings_params).encodedString() << "\"\n";
@@ -1430,6 +1474,12 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
           << (save_transient_properties ? convert<string>(output_changes) : "false")
           << '\n';
 
+       os << "\\change_bars "
+          << (save_transient_properties ? convert<string>(change_bars) : "false")
+          << '\n';
+
+       os << "\\postpone_fragile_content " << convert<string>(postpone_fragile_content) << '\n';
+
        os << "\\html_math_output " << html_math_output << '\n'
           << "\\html_css_as_file " << html_css_as_file << '\n'
           << "\\html_be_strict " << convert<string>(html_be_strict) << '\n';
@@ -1487,6 +1537,8 @@ void BufferParams::validate(LaTeXFeatures & features) const
                default:
                        break;
                }
+               if (change_bars)
+                       features.require("changebar");
        }
 
        // Floats with 'Here definitely' as default setting.
@@ -1589,69 +1641,18 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
        if (tokenPos(tclass.opt_fontsize(),
                     '|', fontsize) >= 0) {
                // only write if existing in list (and not default)
-               clsoptions << fontsize << "pt,";
+               clsoptions << subst(tclass.fontsizeformat(), "$$s", fontsize) << ",";
        }
 
-       // all paper sizes except of A4, A5, B5 and the US sizes need the
+       // paper sizes not supported by the class itself need the
        // geometry package
-       bool nonstandard_papersize = papersize != PAPER_DEFAULT
-               && papersize != PAPER_USLETTER
-               && papersize != PAPER_USLEGAL
-               && papersize != PAPER_USEXECUTIVE
-               && papersize != PAPER_A4
-               && papersize != PAPER_A5
-               && papersize != PAPER_B5;
-
-       if (!use_geometry) {
-               switch (papersize) {
-               case PAPER_A4:
-                       clsoptions << "a4paper,";
-                       break;
-               case PAPER_USLETTER:
-                       clsoptions << "letterpaper,";
-                       break;
-               case PAPER_A5:
-                       clsoptions << "a5paper,";
-                       break;
-               case PAPER_B5:
-                       clsoptions << "b5paper,";
-                       break;
-               case PAPER_USEXECUTIVE:
-                       clsoptions << "executivepaper,";
-                       break;
-               case PAPER_USLEGAL:
-                       clsoptions << "legalpaper,";
-                       break;
-               case PAPER_DEFAULT:
-               case PAPER_A0:
-               case PAPER_A1:
-               case PAPER_A2:
-               case PAPER_A3:
-               case PAPER_A6:
-               case PAPER_B0:
-               case PAPER_B1:
-               case PAPER_B2:
-               case PAPER_B3:
-               case PAPER_B4:
-               case PAPER_B6:
-               case PAPER_C0:
-               case PAPER_C1:
-               case PAPER_C2:
-               case PAPER_C3:
-               case PAPER_C4:
-               case PAPER_C5:
-               case PAPER_C6:
-               case PAPER_JISB0:
-               case PAPER_JISB1:
-               case PAPER_JISB2:
-               case PAPER_JISB3:
-               case PAPER_JISB4:
-               case PAPER_JISB5:
-               case PAPER_JISB6:
-               case PAPER_CUSTOM:
-                       break;
-               }
-       }
+       vector<string> classpsizes = getVectorFromString(tclass.opt_pagesize(), "|");
+       bool class_supported_papersize = papersize == PAPER_DEFAULT
+               || find(classpsizes.begin(), classpsizes.end(), string_papersize[papersize]) != classpsizes.end();
+
+       if ((!use_geometry || features.isProvided("geometry-light"))
+           && class_supported_papersize && papersize != PAPER_DEFAULT)
+               clsoptions << subst(tclass.pagesizeformat(), "$$s", string_papersize[papersize]) << ",";
 
        // if needed
        if (sides != tclass.sides()) {
@@ -1702,15 +1703,14 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
        bool const use_babel = features.useBabel() && !features.isProvided("babel");
        bool const use_polyglossia = features.usePolyglossia();
        bool const global = lyxrc.language_global_options;
-       if (use_babel || (use_polyglossia && global)) {
+       if (features.useBabel() || (use_polyglossia && global)) {
                language_options << features.getBabelLanguages();
                if (!language->babel().empty()) {
                        if (!language_options.str().empty())
                                language_options << ',';
                        language_options << language->babel();
                }
-               if (global && !features.needBabelLangOptions()
-                   && !language_options.str().empty())
+               if (global && !language_options.str().empty())
                        clsoptions << language_options.str() << ',';
        }
 
@@ -1743,16 +1743,29 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                os << from_ascii(ams);
 
        if (useNonTeXFonts) {
-               if (!features.isProvided("fontspec"))
+               // Babel (as of 2017/11/03) loads fontspec itself
+               if (!features.isProvided("fontspec")
+                   && !(features.useBabel() && features.isAvailable("babel-2017/11/03")))
                        os << "\\usepackage{fontspec}\n";
                if (features.mustProvide("unicode-math")
                    && features.isAvailable("unicode-math"))
                        os << "\\usepackage{unicode-math}\n";
        }
 
+       // load CJK support package before font selection
+       // (see autotests/export/latex/CJK/micro-sign_utf8-cjk-libertine.lyx)
+       if (!useNonTeXFonts && encoding().package() != Encoding::none && inputenc != "utf8x"
+               && (encoding().package() == Encoding::CJK || features.mustProvide("CJK"))) {
+               if (inputenc == "utf8-cjk" || inputenc == "utf8")
+                       os << "\\usepackage{CJKutf8}\n";
+               else
+                       os << "\\usepackage[encapsulated]{CJK}\n";
+       }
+
        // font selection must be done before loading fontenc.sty
+       // but after babel with non-TeX fonts
        string const fonts = loadFonts(features);
-       if (!fonts.empty())
+       if (!fonts.empty() && (!features.useBabel() || !useNonTeXFonts))
                os << from_utf8(fonts);
 
        if (fonts_default_family != "default")
@@ -1760,12 +1773,14 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                   << from_ascii(fonts_default_family) << "}\n";
 
        // set font encoding
-       // XeTeX and LuaTeX (with OS fonts) do not need fontenc
+       // non-TeX fonts use font encoding TU (set by fontspec)
        if (!useNonTeXFonts && !features.isProvided("fontenc")
            && main_font_encoding() != "default") {
                // get main font encodings
                vector<string> fontencs = font_encodings();
                // get font encodings of secondary languages
+               // FIXME: some languages (hebrew, ...) assume a standard font encoding as last
+               // option (for text in other languages).
                features.getFontEncodings(fontencs);
                if (!fontencs.empty()) {
                        os << "\\usepackage["
@@ -1774,8 +1789,17 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                }
        }
 
+       // Load textcomp and pmboxdraw before (lua)inputenc (#11454)
+       if (features.mustProvide("textcomp"))
+               os << "\\usepackage{textcomp}\n";
+       if (features.mustProvide("pmboxdraw"))
+               os << "\\usepackage{pmboxdraw}\n";
+       
        // handle inputenc etc.
-       writeEncodingPreamble(os, features);
+       // (In documents containing text in Thai language, 
+       // we must load inputenc after babel, see lib/languages).
+       if (!contains(features.getBabelPostsettings(), from_ascii("thai.ldf")))
+               writeEncodingPreamble(os, features);
 
        // includeonly
        if (!features.runparams().includeall && !included_children_.empty()) {
@@ -1803,8 +1827,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                os << "}\n";
        }
 
-       if (!features.isProvided("geometry")
-           && (use_geometry || nonstandard_papersize)) {
+       if (use_geometry || !class_supported_papersize) {
                odocstringstream ods;
                if (!getGraphicsDriver("geometry").empty())
                        ods << getGraphicsDriver("geometry");
@@ -1820,126 +1843,80 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                                   << from_ascii(paperheight);
                        break;
                case PAPER_USLETTER:
-                       ods << ",letterpaper";
-                       break;
                case PAPER_USLEGAL:
-                       ods << ",legalpaper";
-                       break;
                case PAPER_USEXECUTIVE:
-                       ods << ",executivepaper";
-                       break;
                case PAPER_A0:
-                       ods << ",a0paper";
-                       break;
                case PAPER_A1:
-                       ods << ",a1paper";
-                       break;
                case PAPER_A2:
-                       ods << ",a2paper";
-                       break;
                case PAPER_A3:
-                       ods << ",a3paper";
-                       break;
                case PAPER_A4:
-                       ods << ",a4paper";
-                       break;
                case PAPER_A5:
-                       ods << ",a5paper";
-                       break;
                case PAPER_A6:
-                       ods << ",a6paper";
-                       break;
                case PAPER_B0:
-                       ods << ",b0paper";
-                       break;
                case PAPER_B1:
-                       ods << ",b1paper";
-                       break;
                case PAPER_B2:
-                       ods << ",b2paper";
-                       break;
                case PAPER_B3:
-                       ods << ",b3paper";
-                       break;
                case PAPER_B4:
-                       ods << ",b4paper";
-                       break;
                case PAPER_B5:
-                       ods << ",b5paper";
-                       break;
                case PAPER_B6:
-                       ods << ",b6paper";
-                       break;
                case PAPER_C0:
-                       ods << ",c0paper";
-                       break;
                case PAPER_C1:
-                       ods << ",c1paper";
-                       break;
                case PAPER_C2:
-                       ods << ",c2paper";
-                       break;
                case PAPER_C3:
-                       ods << ",c3paper";
-                       break;
                case PAPER_C4:
-                       ods << ",c4paper";
-                       break;
                case PAPER_C5:
-                       ods << ",c5paper";
-                       break;
                case PAPER_C6:
-                       ods << ",c6paper";
-                       break;
                case PAPER_JISB0:
-                       ods << ",b0j";
-                       break;
                case PAPER_JISB1:
-                       ods << ",b1j";
-                       break;
                case PAPER_JISB2:
-                       ods << ",b2j";
-                       break;
                case PAPER_JISB3:
-                       ods << ",b3j";
-                       break;
                case PAPER_JISB4:
-                       ods << ",b4j";
-                       break;
                case PAPER_JISB5:
-                       ods << ",b5j";
-                       break;
                case PAPER_JISB6:
-                       ods << ",b6j";
+                       ods << "," << from_ascii(string_papersize_geometry[papersize]);
                        break;
                case PAPER_DEFAULT:
                        break;
                }
-               docstring const g_options = trim(ods.str(), ",");
-               os << "\\usepackage";
-               if (!g_options.empty())
-                       os << '[' << g_options << ']';
-               os << "{geometry}\n";
-               // output this only if use_geometry is true
-               if (use_geometry) {
+               docstring g_options = trim(ods.str(), ",");
+               // geometry-light means that the class works with geometry, but overwrites
+               // the package options and paper sizes (memoir does this).
+               // In this case, all options need to go to \geometry
+               // and the standard paper sizes need to go to the class options.
+               if (!features.isProvided("geometry")) {
+                       os << "\\usepackage";
+                       if (!g_options.empty() && !features.isProvided("geometry-light")) {
+                               os << '[' << g_options << ']';
+                               g_options.clear();
+                       }
+                       os << "{geometry}\n";
+               }
+               if (use_geometry || features.isProvided("geometry")
+                   || features.isProvided("geometry-light")) {
                        os << "\\geometry{verbose";
-                       if (!topmargin.empty())
-                               os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
-                       if (!bottommargin.empty())
-                               os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
-                       if (!leftmargin.empty())
-                               os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
-                       if (!rightmargin.empty())
-                               os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
-                       if (!headheight.empty())
-                               os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
-                       if (!headsep.empty())
-                               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";
+                       if (!g_options.empty())
+                               // Output general options here with "geometry light".
+                               os << "," << g_options;
+                       // output this only if use_geometry is true
+                       if (use_geometry) {
+                               if (!topmargin.empty())
+                                       os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
+                               if (!bottommargin.empty())
+                                       os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
+                               if (!leftmargin.empty())
+                                       os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
+                               if (!rightmargin.empty())
+                                       os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
+                               if (!headheight.empty())
+                                       os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
+                               if (!headsep.empty())
+                                       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";
                }
        } else if (orientation == ORIENTATION_LANDSCAPE
                   || papersize != PAPER_DEFAULT) {
@@ -2060,7 +2037,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                        os << features.getBabelPresettings();
                        // FIXME UNICODE
                        os << from_utf8(babelCall(language_options.str(),
-                                                 features.needBabelLangOptions())) + '\n';
+                                                                         !lyxrc.language_global_options)) + '\n';
                        os << features.getBabelPostsettings();
        }
 
@@ -2102,6 +2079,14 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                // hyperref loads this automatically
                os << "\\usepackage{nameref}\n";
 
+       if (use_lineno){
+               os << "\\usepackage";
+               if (!lineno_opts.empty())
+                       os << "[" << lineno_opts << "]";
+               os << "{lineno}\n";
+               os << "\\linenumbers\n";
+       }
+
        // bibtopic needs to be loaded after hyperref.
        // the dot provides the aux file naming which LyX can detect.
        if (features.mustProvide("bibtopic"))
@@ -2247,8 +2232,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                   << "\\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
-       // called after babel, though.
+       // Jurabib, hyperref, varioref, bicaption, menukeys and listings (bug 8995)
+       // have to be called after babel, though.
        if (use_babel && !features.isRequired("jurabib")
            && !features.isRequired("hyperref")
            && !features.isRequired("varioref")
@@ -2256,28 +2241,48 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                os << features.getBabelPresettings();
                // FIXME UNICODE
                os << from_utf8(babelCall(language_options.str(),
-                                         features.needBabelLangOptions())) + '\n';
+                                         !lyxrc.language_global_options)) + '\n';
                os << features.getBabelPostsettings();
        }
+       // In documents containing text in Thai language, 
+       // we must load inputenc after babel (see lib/languages).
+       if (contains(features.getBabelPostsettings(), from_ascii("thai.ldf")))
+               writeEncodingPreamble(os, features);
+
+       // font selection must be done after babel with non-TeX fonts
+       if (!fonts.empty() && features.useBabel() && useNonTeXFonts)
+               os << from_utf8(fonts);
+
        if (features.isRequired("bicaption"))
                os << "\\usepackage{bicaption}\n";
        if (!listings_params.empty()
            || features.mustProvide("listings")
            || features.mustProvide("minted")) {
-               if (features.mustProvide("listings"))
-                       os << "\\usepackage{listings}\n";
-               else
+               if (use_minted)
                        os << "\\usepackage{minted}\n";
-       }
-       if (!listings_params.empty()) {
-               if (features.mustProvide("listings"))
-                       os << "\\lstset{";
                else
+                       os << "\\usepackage{listings}\n";
+       }
+       string lst_params = listings_params;
+       // If minted, do not output the language option (bug 11203)
+       if (use_minted && contains(lst_params, "language=")) {
+               vector<string> opts =
+                       getVectorFromString(lst_params, ",", false);
+               for (size_t i = 0; i < opts.size(); ++i) {
+                       if (prefixIs(opts[i], "language="))
+                               opts.erase(opts.begin() + i--);
+               }
+               lst_params = getStringFromVector(opts, ",");
+       }
+       if (!lst_params.empty()) {
+               if (use_minted)
                        os << "\\setminted{";
+               else
+                       os << "\\lstset{";
                // do not test validity because listings_params is
                // supposed to be valid
                string par =
-                       InsetListingsParams(listings_params).separatedParams(true);
+                       InsetListingsParams(lst_params).separatedParams(true);
                os << from_utf8(par);
                os << "}\n";
        }
@@ -2288,8 +2293,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
        // esint and the other packages that provide special glyphs
        if (features.mustProvide("tipa") && useNonTeXFonts
            && !features.isProvided("xunicode")) {
-               // The package officially only supports XeTeX, but also works
-               // with LuaTeX. Thus we work around its XeTeX test.
+               // The `xunicode` package officially only supports XeTeX,
+               //  but also works with LuaTeX. We work around its XeTeX test.
                if (features.runparams().flavor != OutputParams::XETEX) {
                        os << "% Pretend to xunicode that we are XeTeX\n"
                           << "\\def\\XeTeXpicfile{}\n";
@@ -2297,6 +2302,10 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                os << "\\usepackage{xunicode}\n";
        }
 
+       // covington must be loaded after beamerarticle
+       if (features.isRequired("covington"))
+           os << "\\usepackage{covington}\n";
+
        // Polyglossia must be loaded last ...
        if (use_polyglossia) {
                // call the package
@@ -2322,19 +2331,25 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
        }
 
        // ... but before biblatex (see #7065)
-       if (features.mustProvide("biblatex")
+       if ((features.mustProvide("biblatex")
+            || features.isRequired("biblatex-chicago"))
+           && !features.isProvided("biblatex-chicago")
            && !features.isProvided("biblatex-natbib")
            && !features.isProvided("natbib-internal")
            && !features.isProvided("natbib")
            && !features.isProvided("jurabib")) {
+               // The biblatex-chicago package has a differing interface
+               // it uses a wrapper package and loads styles via fixed options
+               bool const chicago = features.isRequired("biblatex-chicago");
                string delim = "";
                string opts;
                os << "\\usepackage";
                if (!biblatex_bibstyle.empty()
-                   && (biblatex_bibstyle == biblatex_citestyle)) {
+                   && (biblatex_bibstyle == biblatex_citestyle)
+                   && !chicago) {
                        opts = "style=" + biblatex_bibstyle;
                        delim = ",";
-               } else {
+               } else if (!chicago) {
                        if (!biblatex_bibstyle.empty()) {
                                opts = "bibstyle=" + biblatex_bibstyle;
                                delim = ",";
@@ -2357,11 +2372,19 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                        opts += delim + "backend=bibtex";
                        delim = ",";
                }
+               if (!bib_encoding.empty() && encodings.fromLyXName(bib_encoding)) {
+                       opts += delim + "bibencoding="
+                               + encodings.fromLyXName(bib_encoding)->latexName();
+                       delim = ",";
+               }
                if (!biblio_opts.empty())
                        opts += delim + biblio_opts;
                if (!opts.empty())
                        os << "[" << opts << "]";
-               os << "{biblatex}\n";
+               if (chicago)
+                       os << "{biblatex-chicago}\n";
+               else
+                       os << "{biblatex}\n";
        }
 
 
@@ -2374,6 +2397,11 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                os << '\n';
        }
 
+       // Since menukeys uses catoptions, which does some heavy changes on key-value options,
+       // it is recommended to load menukeys as the last package (even after hyperref)
+       if (features.isRequired("menukeys"))
+               os << "\\usepackage{menukeys}\n";
+
        docstring const i18npreamble =
                features.getTClassI18nPreamble(use_babel, use_polyglossia,
                                               use_minted);
@@ -2391,6 +2419,7 @@ void BufferParams::useClassDefaults()
        sides = tclass.sides();
        columns = tclass.columns();
        pagestyle = tclass.pagestyle();
+       tablestyle = tclass.tablestyle();
        use_default_options = true;
        // Only if class has a ToC hierarchy
        if (tclass.hasTocLevels()) {
@@ -2407,6 +2436,7 @@ bool BufferParams::hasClassDefaults() const
        return sides == tclass.sides()
                && columns == tclass.columns()
                && pagestyle == tclass.pagestyle()
+               && tablestyle == tclass.tablestyle()
                && use_default_options
                && secnumdepth == tclass.secnumdepth()
                && tocdepth == tclass.tocdepth();
@@ -2433,7 +2463,7 @@ void BufferParams::setDocumentClass(DocumentClassConstPtr tc)
 }
 
 
-bool BufferParams::setBaseClass(string const & classname)
+bool BufferParams::setBaseClass(string const & classname, string const & path)
 {
        LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
        LayoutFileList & bcl = LayoutFileList::get();
@@ -2449,7 +2479,7 @@ bool BufferParams::setBaseClass(string const & classname)
                bcl.addEmptyClass(classname);
        }
 
-       bool const success = bcl[classname].load();
+       bool const success = bcl[classname].load(path);
        if (!success) {
                docstring s =
                        bformat(_("Due to some error in it, the layout file:\n"
@@ -2490,18 +2520,12 @@ void BufferParams::makeDocumentClass(bool const clone)
 
        invalidateConverterCache();
        LayoutModuleList mods;
-       LayoutModuleList ces;
        LayoutModuleList::iterator it = layout_modules_.begin();
        LayoutModuleList::iterator en = layout_modules_.end();
        for (; it != en; ++it)
                mods.push_back(*it);
 
-       it = cite_engine_.begin();
-       en = cite_engine_.end();
-       for (; it != en; ++it)
-               ces.push_back(*it);
-
-       doc_class_ = getDocumentClass(*baseClass(), mods, ces, clone);
+       doc_class_ = getDocumentClass(*baseClass(), mods, cite_engine_, clone);
 
        TextClass::ReturnValues success = TextClass::OK;
        if (!forced_local_layout_.empty())
@@ -2523,12 +2547,6 @@ bool BufferParams::layoutModuleCanBeAdded(string const & modName) const
 }
 
 
-bool BufferParams::citationModuleCanBeAdded(string const & modName) const
-{
-       return cite_engine_.moduleCanBeAdded(modName, baseClass());
-}
-
-
 docstring BufferParams::getLocalLayout(bool forced) const
 {
        if (forced)
@@ -2592,13 +2610,15 @@ FormatList const & BufferParams::exportableFormats(bool only_viewable) const
        if (useNonTeXFonts) {
                excludes.insert("latex");
                excludes.insert("pdflatex");
-       }
-       FormatList result =
-               theConverters().getReachable(backs[0], only_viewable, true, excludes);
+       } else if (inputenc != "ascii" && inputenc != "utf8-plain")
+                 // XeTeX with TeX fonts requires input encoding ascii (#10600).
+                 excludes.insert("xetex");
+       FormatList result = theConverters().getReachable(backs[0], only_viewable,
+                                                                                                        true, excludes);
        for (vector<string>::const_iterator it = backs.begin() + 1;
             it != backs.end(); ++it) {
                FormatList r = theConverters().getReachable(*it, only_viewable,
-                               false, excludes);
+                                                                                                       false, excludes);
                result.insert(result.end(), r.begin(), r.end());
        }
        sort(result.begin(), result.end(), Format::formatSorter);
@@ -2622,7 +2642,9 @@ vector<string> BufferParams::backends() const
                                v.push_back("pdflatex");
                                v.push_back("latex");
                        }
-                       v.push_back("xetex");
+                       if (useNonTeXFonts 
+                               || inputenc == "ascii" || inputenc == "utf8-plain")
+                               v.push_back("xetex");
                        v.push_back("luatex");
                        v.push_back("dviluatex");
                }
@@ -2929,12 +2951,15 @@ void BufferParams::readIncludeonly(Lexer & lex)
 }
 
 
-string BufferParams::paperSizeName(PapersizePurpose purpose) const
+string BufferParams::paperSizeName(PapersizePurpose purpose, string const & psize) const
 {
-       switch (papersize) {
+       PAPER_SIZE ppsize = psize.empty() ? papersize : papersizetranslator().find(psize);
+       switch (ppsize) {
        case PAPER_DEFAULT:
-               // could be anything, so don't guess
-               return string();
+               if (documentClass().pagesize() == "default")
+                       // could be anything, so don't guess
+                       return string();
+               return paperSizeName(purpose, documentClass().pagesize());
        case PAPER_CUSTOM: {
                if (purpose == XDVI && !paperwidth.empty() &&
                    !paperheight.empty()) {
@@ -3155,8 +3180,7 @@ string BufferParams::babelCall(string const & lang_opts, bool const langoptions)
        // other languages are used (lang_opts is then empty)
        if (lang_opts.empty())
                return string();
-       // either a specific language (AsBabelOptions setting in
-       // lib/languages) or the prefs require the languages to
+       // The prefs may require the languages to
        // be submitted to babel itself (not the class).
        if (langoptions)
                return "\\usepackage[" + lang_opts + "]{babel}";
@@ -3185,15 +3209,11 @@ docstring BufferParams::getGraphicsDriver(string const & package) const
 void BufferParams::writeEncodingPreamble(otexstream & os,
                                         LaTeXFeatures & features) const
 {
-       // 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 (see Buffer.cpp),
-       //  for LuaTeX, we load "luainputenc" (see below).
-       if (useNonTeXFonts || features.runparams().flavor == OutputParams::XETEX)
+       // With no-TeX fonts we use utf8-plain without encoding package.
+       if (useNonTeXFonts)
                return;
 
-       if (inputenc == "auto") {
+       if (inputenc == "auto-legacy") {
                string const doc_encoding =
                        language->encoding()->latexName();
                Encoding::Package const package =
@@ -3202,13 +3222,14 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                // Create list of inputenc options:
                set<string> encoding_set;
                // luainputenc fails with more than one encoding
-               if (!features.runparams().isFullUnicode()) // if we reach this point, this means LuaTeX with TeX fonts
+               if (features.runparams().flavor != OutputParams::LUATEX
+                       && features.runparams().flavor != OutputParams::DVILUATEX)
                        // list all input encodings used in the document
                        encoding_set = features.getEncodingSet(doc_encoding);
 
-               // If the "japanese" package (i.e. pLaTeX) is used,
-               // inputenc must be omitted.
-               // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
+               // The "japanese" babel-language requires  the pLaTeX engine
+               // which conflicts with "inputenc".
+               // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
                if ((!encoding_set.empty() || package == Encoding::inputenc)
                    && !features.isRequired("japanese")
                    && !features.isProvided("inputenc")) {
@@ -3232,17 +3253,16 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                        else
                                os << "]{inputenc}\n";
                }
-               if (package == Encoding::CJK || features.mustProvide("CJK")) {
-                       if (language->encoding()->name() == "utf8-cjk"
-                           && LaTeXFeatures::isAvailable("CJKutf8"))
-                               os << "\\usepackage{CJKutf8}\n";
-                       else
-                               os << "\\usepackage{CJK}\n";
-               }
-       } else if (inputenc != "default") {
+       } else if (inputenc != "auto-legacy-plain") {
                switch (encoding().package()) {
                case Encoding::none:
+               case Encoding::CJK:
                case Encoding::japanese:
+                       if (encoding().iconvName() != "UTF-8"
+                               && !features.runparams().isFullUnicode())
+                         // don't default to [utf8]{inputenc} with TeXLive >= 18
+                         os << "\\ifdefined\\UseRawInputEncoding\n"
+                                << "  \\UseRawInputEncoding\\fi\n";
                        break;
                case Encoding::inputenc:
                        // do not load inputenc if japanese is used
@@ -3257,24 +3277,13 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                        else
                                os << "]{inputenc}\n";
                        break;
-               case Encoding::CJK:
-                       if (encoding().name() == "utf8-cjk"
-                           && LaTeXFeatures::isAvailable("CJKutf8"))
-                               os << "\\usepackage{CJKutf8}\n";
-                       else
-                               os << "\\usepackage{CJK}\n";
-                       break;
-               }
-               // Load the CJK package if needed by a secondary language.
-               // If the main encoding is some variant of UTF8, use CJKutf8.
-               if (encoding().package() != Encoding::CJK && features.mustProvide("CJK")) {
-                       if (encoding().iconvName() == "UTF-8"
-                           && LaTeXFeatures::isAvailable("CJKutf8"))
-                               os << "\\usepackage{CJKutf8}\n";
-                       else
-                               os << "\\usepackage{CJK}\n";
                }
        }
+       if (inputenc == "auto-legacy-plain" || features.isRequired("japanese")) {
+               // don't default to [utf8]{inputenc} with TeXLive >= 18
+               os << "\\ifdefined\\UseRawInputEncoding\n";
+               os << "  \\UseRawInputEncoding\\fi\n";
+       }
 }
 
 
@@ -3319,36 +3328,86 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
                // variants are understood by both engines. However,
                // we want to provide support for at least TeXLive 2009
                // (for XeTeX; LuaTeX is only supported as of v.2)
+               // As of 2017/11/03, Babel has its own higher-level
+               // interface on top of fontspec that is to be used.
+               bool const babelfonts = features.useBabel()
+                               && features.isAvailable("babel-2017/11/03");
                string const texmapping =
                        (features.runparams().flavor == OutputParams::XETEX) ?
                        "Mapping=tex-text" : "Ligatures=TeX";
                if (fontsRoman() != "default") {
-                       os << "\\setmainfont[" << texmapping;
-                       if (fonts_old_figures)
+                       if (babelfonts)
+                               os << "\\babelfont{rm}[";
+                       else
+                               os << "\\setmainfont[";
+                       if (!font_roman_opts.empty())
+                               os << font_roman_opts << ',';
+                       os << texmapping;
+                       if (fonts_roman_osf)
                                os << ",Numbers=OldStyle";
                        os << "]{" << parseFontName(fontsRoman()) << "}\n";
                }
                if (fontsSans() != "default") {
                        string const sans = parseFontName(fontsSans());
-                       if (fontsSansScale() != 100)
-                               os << "\\setsansfont[Scale="
-                                  << float(fontsSansScale()) / 100
-                                  << "," << texmapping << "]{"
+                       if (fontsSansScale() != 100) {
+                               if (babelfonts)
+                                       os << "\\babelfont{sf}";
+                               else
+                                       os << "\\setsansfont";
+                               os << "[Scale="
+                                  << float(fontsSansScale()) / 100 << ',';
+                               if (fonts_sans_osf)
+                                       os << "Numbers=OldStyle,";
+                               if (!font_sans_opts.empty())
+                                       os << font_sans_opts << ',';
+                               os << texmapping << "]{"
                                   << sans << "}\n";
-                       else
-                               os << "\\setsansfont[" << texmapping << "]{"
+                       } else {
+                               if (babelfonts)
+                                       os << "\\babelfont{sf}[";
+                               else
+                                       os << "\\setsansfont[";
+                               if (fonts_sans_osf)
+                                       os << "Numbers=OldStyle,";
+                               if (!font_sans_opts.empty())
+                                       os << font_sans_opts << ',';
+                               os << texmapping << "]{"
                                   << sans << "}\n";
+                       }
                }
                if (fontsTypewriter() != "default") {
                        string const mono = parseFontName(fontsTypewriter());
-                       if (fontsTypewriterScale() != 100)
-                               os << "\\setmonofont[Scale="
-                                  << float(fontsTypewriterScale()) / 100
-                                  << "]{"
-                                  << mono << "}\n";
-                       else
-                               os << "\\setmonofont{"
+                       if (fontsTypewriterScale() != 100) {
+                               if (babelfonts)
+                                       os << "\\babelfont{tt}";
+                               else
+                                       os << "\\setmonofont";
+                               os << "[Scale="
+                                  << float(fontsTypewriterScale()) / 100;
+                               if (fonts_typewriter_osf)
+                                       os << ",Numbers=OldStyle";
+                               if (!font_typewriter_opts.empty())
+                                       os << ',' << font_typewriter_opts;
+                               os << "]{"
                                   << mono << "}\n";
+                       } else {
+                               if (babelfonts)
+                                       os << "\\babelfont{tt}";
+                               else
+                                       os << "\\setmonofont";
+                               if (!font_typewriter_opts.empty() || fonts_typewriter_osf) {
+                                       os << '[';
+                                       if (fonts_typewriter_osf)
+                                               os << "Numbers=OldStyle";
+                                       if (!font_typewriter_opts.empty()) {
+                                               if (fonts_typewriter_osf)
+                                                       os << ',';
+                                               os << font_typewriter_opts;
+                                       }
+                                       os << ']';
+                               }
+                               os << '{' << mono << "}\n";
+                       }
                }
                return os.str();
        }
@@ -3361,22 +3420,22 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
 
        // ROMAN FONTS
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsRoman())).getLaTeXCode(
-               dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
-               nomath);
+               dryrun, ot1, complete, fonts_expert_sc, fonts_roman_osf,
+               nomath, font_roman_opts);
 
        // SANS SERIF
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsSans())).getLaTeXCode(
-               dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
-               nomath, fontsSansScale());
+               dryrun, ot1, complete, fonts_expert_sc, fonts_sans_osf,
+               nomath, font_sans_opts, fontsSansScale());
 
        // MONOSPACED/TYPEWRITER
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsTypewriter())).getLaTeXCode(
-               dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
-               nomath, fontsTypewriterScale());
+               dryrun, ot1, complete, fonts_expert_sc, fonts_typewriter_osf,
+               nomath, font_typewriter_opts, fontsTypewriterScale());
 
        // MATH
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsMath())).getLaTeXCode(
-               dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
+               dryrun, ot1, complete, fonts_expert_sc, fonts_roman_osf,
                nomath);
 
        return os.str();
@@ -3386,16 +3445,12 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
 Encoding const & BufferParams::encoding() const
 {
        // Main encoding for LaTeX output.
-       //
-       // Exception: XeTeX with 8-bit TeX fonts requires ASCII (see #9740).
-       // As the "flavor" is only known once export started, this
-       // cannot be handled here. Instead, runparams.encoding is set
-       // to ASCII in Buffer::makeLaTeXFile (for export)
-       // and Buffer::writeLaTeXSource (for preview).
        if (useNonTeXFonts)
                return *(encodings.fromLyXName("utf8-plain"));
-       if (inputenc == "auto" || inputenc == "default")
+       if (inputenc == "auto-legacy" || inputenc == "auto-legacy-plain")
                return *language->encoding();
+       if (inputenc == "utf8" && language->lang() == "japanese")
+               return *(encodings.fromLyXName("utf8-platex"));
        Encoding const * const enc = encodings.fromLyXName(inputenc);
        if (enc)
                return *enc;
@@ -3405,30 +3460,6 @@ Encoding const & BufferParams::encoding() const
 }
 
 
-bool BufferParams::addCiteEngine(string const & engine)
-{
-       LayoutModuleList::const_iterator it = cite_engine_.begin();
-       LayoutModuleList::const_iterator en = cite_engine_.end();
-       for (; it != en; ++it)
-               if (*it == engine)
-                       return false;
-       cite_engine_.push_back(engine);
-       return true;
-}
-
-
-bool BufferParams::addCiteEngine(vector<string> const & engine)
-{
-       vector<string>::const_iterator it = engine.begin();
-       vector<string>::const_iterator en = engine.end();
-       bool ret = true;
-       for (; it != en; ++it)
-               if (!addCiteEngine(*it))
-                       ret = false;
-       return ret;
-}
-
-
 string const & BufferParams::defaultBiblioStyle() const
 {
        if (!biblio_style.empty())
@@ -3463,20 +3494,6 @@ string BufferParams::getCiteAlias(string const & s) const
 }
 
 
-void BufferParams::setCiteEngine(string const & engine)
-{
-       clearCiteEngine();
-       addCiteEngine(engine);
-}
-
-
-void BufferParams::setCiteEngine(vector<string> const & engine)
-{
-       clearCiteEngine();
-       addCiteEngine(engine);
-}
-
-
 vector<string> BufferParams::citeCommands() const
 {
        static CitationStyle const default_style;
@@ -3540,8 +3557,7 @@ string const BufferParams::bibtexCommand() const
 
 bool BufferParams::useBiblatex() const
 {
-       return theCiteEnginesList[citeEngine().list().front()]
-                       ->getCiteFramework() == "biblatex";
+       return theCiteEnginesList[citeEngine()]->getCiteFramework() == "biblatex";
 }
 
 
@@ -3551,4 +3567,32 @@ void BufferParams::invalidateConverterCache() const
        pimpl_->isViewCacheValid = false;
 }
 
+
+// We shouldn't need to reset the params here, since anything
+// we need will be recopied.
+void BufferParams::copyForAdvFR(const BufferParams & bp)
+{
+       string const & lang = bp.language->lang();
+       setLanguage(lang);
+       layout_modules_ = bp.layout_modules_;
+       string const & doc_class = bp.documentClass().name();
+       setBaseClass(doc_class);
+}
+
+
+void BufferParams::setBibFileEncoding(string const & file, string const & enc)
+{
+       bib_encodings[file] = enc;
+}
+
+
+string const BufferParams::bibFileEncoding(string const & file) const
+{
+       if (bib_encodings.find(file) == bib_encodings.end())
+               return string();
+       return bib_encodings.find(file)->second;
+}
+
+
+
 } // namespace lyx