]> git.lyx.org Git - lyx.git/blobdiff - src/BufferParams.cpp
Use unsigned values for enum
[lyx.git] / src / BufferParams.cpp
index c0f8a60be932950faaf6f1c6f08315c5f4c34753..22793ecb997c75b96942363b33794efb3a1d309d 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", ""
 };
 
 
@@ -104,18 +112,6 @@ static char const * const tex_graphics[] = {
 
 namespace lyx {
 
-// XeTeX with TeX fonts:
-// run in 8-bit emulation mode and trick `inputenc` into working with XeTeX
-static docstring const xetex_pre_inputenc = from_ascii(
-       "\\XeTeXinputencoding \"bytes\" % current file\n"
-       "\\XeTeXdefaultencoding \"bytes\" % included files\n"
-       "\\makeatletter\n"
-       "\\let\\origUmathchar\\Umathchar\n"
-       "\\let\\Umathchar\\@undefined\n");
-static docstring const xetex_post_inputenc = from_ascii(
-       "\\let\\Umathchar\\origUmathchar\n"
-       "\\makeatother\n");
-
 // Local translators
 namespace {
 
@@ -431,12 +427,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";
@@ -475,6 +473,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;
@@ -843,14 +842,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") {
@@ -1118,6 +1127,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;
@@ -1257,15 +1271,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';
@@ -1320,7 +1341,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)
@@ -1599,69 +1625,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()) {
@@ -1719,8 +1694,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                                language_options << ',';
                        language_options << language->babel();
                }
-               if (global && !features.needBabelLangOptions()
-                   && !language_options.str().empty())
+               if (global && !language_options.str().empty())
                        clsoptions << language_options.str() << ',';
        }
 
@@ -1753,7 +1727,9 @@ 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"))
@@ -1771,8 +1747,9 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
        }
 
        // 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")
@@ -1786,6 +1763,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                // 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["
@@ -1799,9 +1778,12 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                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()) {
@@ -1829,8 +1811,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");
@@ -1846,126 +1827,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) {
@@ -2086,7 +2021,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();
        }
 
@@ -2128,6 +2063,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"))
@@ -2282,9 +2225,18 @@ 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()
@@ -2642,10 +2594,8 @@ FormatList const & BufferParams::exportableFormats(bool only_viewable) const
        if (useNonTeXFonts) {
                excludes.insert("latex");
                excludes.insert("pdflatex");
-       } else if (inputenc != "ascii" && inputenc != "utf8"
-                          && inputenc != "utf8x" && inputenc != "utf8-plain")
-                 // XeTeX with TeX fonts requires input encoding ascii or utf8
-                 // (https://www.tug.org/pipermail/xetex/2010-April/016452.html).
+       } 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);
@@ -2676,8 +2626,8 @@ vector<string> BufferParams::backends() const
                                v.push_back("pdflatex");
                                v.push_back("latex");
                        }
-                       if (useNonTeXFonts || inputenc == "ascii" || inputenc == "utf8"
-                           || inputenc == "utf8x" || inputenc == "utf8-plain")
+                       if (useNonTeXFonts 
+                               || inputenc == "ascii" || inputenc == "utf8-plain")
                                v.push_back("xetex");
                        v.push_back("luatex");
                        v.push_back("dviluatex");
@@ -2985,12 +2935,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()) {
@@ -3211,8 +3164,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}";
@@ -3245,7 +3197,7 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
        if (useNonTeXFonts)
                return;
 
-       if (inputenc == "auto") {
+       if (inputenc == "auto-legacy") {
                string const doc_encoding =
                        language->encoding()->latexName();
                Encoding::Package const package =
@@ -3285,7 +3237,7 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                        else
                                os << "]{inputenc}\n";
                }
-       } else if (inputenc != "default") {
+       } else if (inputenc != "auto-legacy-plain") {
                switch (encoding().package()) {
                case Encoding::none:
                case Encoding::CJK:
@@ -3302,20 +3254,16 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                        if (features.isRequired("japanese")
                            || features.isProvided("inputenc"))
                                break;
-                       if (features.runparams().flavor == OutputParams::XETEX)
-                               os << xetex_pre_inputenc;
                        os << "\\usepackage[" << from_ascii(encoding().latexName());
                        if (features.runparams().flavor == OutputParams::LUATEX
                            || features.runparams().flavor == OutputParams::DVILUATEX)
                                os << "]{luainputenc}\n";
                        else
                                os << "]{inputenc}\n";
-                       if (features.runparams().flavor == OutputParams::XETEX)
-                               os << xetex_post_inputenc;
                        break;
                }
        }
-       if (inputenc == "default" || features.isRequired("japanese")) {
+       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";
@@ -3364,36 +3312,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();
        }
@@ -3406,22 +3404,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();
@@ -3433,7 +3431,7 @@ Encoding const & BufferParams::encoding() const
        // Main encoding for LaTeX output.
        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"));