]> git.lyx.org Git - features.git/blobdiff - src/BufferParams.cpp
Use \babelfonts only if babel >= 3.15 is available.
[features.git] / src / BufferParams.cpp
index 523e5c9a018e2f7b61b8f141dda232861af8cfbf..e65e6e4a12c742faa8e950cd9a19a51a2024e905 100644 (file)
@@ -104,18 +104,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 {
 
@@ -475,6 +463,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;
@@ -845,12 +834,18 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                lex >> fonts_expert_sc;
        } else if (token == "\\font_osf") {
                lex >> fonts_old_figures;
+       } 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 +1113,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 +1257,20 @@ 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_osf " << convert<string>(fonts_old_figures);
+       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 +1325,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)
@@ -1752,7 +1762,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"))
@@ -1770,8 +1782,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")
@@ -1805,7 +1818,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & 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);
+               writeEncodingPreamble(os, features);
 
        // includeonly
        if (!features.runparams().includeall && !included_children_.empty()) {
@@ -2132,6 +2145,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"))
@@ -2292,7 +2313,11 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & 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);
+               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";
@@ -2651,10 +2676,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);
@@ -2685,8 +2708,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");
@@ -3310,16 +3333,12 @@ 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;
                }
        }
@@ -3372,36 +3391,71 @@ 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 (babelfonts)
+                               os << "\\babelfont{rm}[";
+                       else
+                               os << "\\setmainfont[";
+                       if (!font_roman_opts.empty())
+                               os << font_roman_opts << ',';
+                       os << texmapping;
                        if (fonts_old_figures)
                                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 (!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 (!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 (!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())
+                                       os << '[' << font_typewriter_opts << ']';
+                               os << '{' << mono << "}\n";
+                       }
                }
                return os.str();
        }
@@ -3415,17 +3469,17 @@ 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);
+               nomath, font_roman_opts);
 
        // SANS SERIF
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsSans())).getLaTeXCode(
                dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
-               nomath, fontsSansScale());
+               nomath, font_roman_opts, fontsSansScale());
 
        // MONOSPACED/TYPEWRITER
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsTypewriter())).getLaTeXCode(
                dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures,
-               nomath, fontsTypewriterScale());
+               nomath, font_roman_opts, fontsTypewriterScale());
 
        // MATH
        os << theLaTeXFonts().getLaTeXFont(from_ascii(fontsMath())).getLaTeXCode(