]> git.lyx.org Git - lyx.git/blobdiff - src/BufferParams.cpp
GuiWorkArea: coding style.
[lyx.git] / src / BufferParams.cpp
index eda655b9d40bafe6469ed3154bf95ff99702aeac..375780cb8a0ba8e7b28e8f8d0a3e4c841654030a 100644 (file)
@@ -385,6 +385,7 @@ BufferParams::BufferParams()
        fonts_sans_scale = 100;
        fonts_typewriter_scale = 100;
        inputenc = "auto";
+       lang_package = "default";
        graphics_driver = "default";
        default_output_format = "default";
        bibtex_command = "default";
@@ -572,8 +573,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                                                 "document cannot be compiled until the following\n"
                                                 "prerequisites are installed:\n"
                                                 "\t%2$s\n"
-                                                "See section 3.1.2.2 of the User's Guide for\n"
-                                                "more information."), desc, prereqs);
+                                                "See section 3.1.2.2 (Class Availability) of the\n"
+                                                "User's Guide for more information."), desc, prereqs);
                        frontend::Alert::warning(_("Document class not available"),
                                       msg);
                }
@@ -601,6 +602,9 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                lex >> suppress_date;
        } else if (token == "\\language") {
                readLanguage(lex);
+       } else if (token == "\\language_package") {
+               lex.eatLine();
+               lang_package = lex.getString();
        } else if (token == "\\inputencoding") {
                lex >> inputenc;
        } else if (token == "\\graphics") {
@@ -945,7 +949,8 @@ void BufferParams::writeFile(ostream & os) const
        // then the text parameters
        if (language != ignore_language)
                os << "\\language " << language->lang() << '\n';
-       os << "\\inputencoding " << inputenc
+       os << "\\language_package " << lang_package
+          << "\n\\inputencoding " << inputenc
           << "\n\\fontencoding " << fontenc
           << "\n\\font_roman " << fonts_roman
           << "\n\\font_sans " << fonts_sans
@@ -1188,7 +1193,8 @@ void BufferParams::validate(LaTeXFeatures & features) const
                        features.require("color");
        }
 
-       if (features.runparams().flavor == OutputParams::XETEX)
+       if (features.runparams().flavor == OutputParams::XETEX
+           && useNonTeXFonts)
                features.require("polyglossia");
 
        if (language->lang() == "vietnamese")
@@ -1201,6 +1207,17 @@ void BufferParams::validate(LaTeXFeatures & features) const
 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
                              TexRow & texrow, FileName const & filepath) const
 {
+       // http://www.tug.org/texmf-dist/doc/latex/base/fixltx2e.pdf
+       // !! To use the Fix-cm package, load it before \documentclass, and use the command
+       // \RequirePackage to do so, rather than the normal \usepackage
+       // Do not to load any other package before the document class, unless you
+       // have a thorough understanding of the LATEX internals and know exactly what you
+       // are doing!
+       if (features.mustProvide("fix-cm")) {
+               os << "\\RequirePackage{fix-cm}\n";
+               texrow.newline();
+       }
+
        os << "\\documentclass";
 
        DocumentClass const & tclass = documentClass();
@@ -1339,23 +1356,31 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
        texrow.newline();
        // end of \documentclass defs
 
-       // Fontspec must also be loaded if XeTeX is used with tex fonts
-       // (in order to prevent later loading which overrides the tex
-       // fonts)
-       if (features.runparams().flavor == OutputParams::XETEX
-           || useNonTeXFonts) {
+       int nlines;
+       // if we use fontspec, we have to load the AMS packages here
+       string const ams = features.loadAMSPackages();
+       if (useNonTeXFonts && !ams.empty()) {
+               os << from_ascii(ams);
+               nlines = int(count(ams.begin(), ams.end(), '\n'));
+               texrow.newlines(nlines);
+       }
+
+       if (useNonTeXFonts) {
                os << "\\usepackage{fontspec}\n";
                texrow.newline();
        }
 
        // font selection must be done before loading fontenc.sty
        string const fonts =
-               loadFonts(fonts_roman, fonts_sans,
-                         fonts_typewriter, fonts_expert_sc, fonts_old_figures,
-                         fonts_sans_scale, fonts_typewriter_scale, useNonTeXFonts);
+               loadFonts(fonts_roman, fonts_sans, fonts_typewriter,
+                         fonts_expert_sc, fonts_old_figures,
+                         fonts_sans_scale, fonts_typewriter_scale,
+                         useNonTeXFonts, features);
        if (!fonts.empty()) {
                os << from_ascii(fonts);
-               texrow.newline();
+               nlines =
+                       int(count(fonts.begin(), fonts.end(), '\n'));
+               texrow.newlines(nlines);
        }
        if (fonts_default_family != "default")
                os << "\\renewcommand{\\familydefault}{\\"
@@ -1545,6 +1570,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
                        // default papersize ie PAPER_DEFAULT
                        switch (lyxrc.default_papersize) {
                        case PAPER_DEFAULT: // keep compiler happy
+                               break;
                        case PAPER_USLETTER:
                                ods << ",letterpaper";
                                break;
@@ -1781,6 +1807,10 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
                texrow.newlines(lines);
                // set back for the rest
                lyxpreamble.clear();
+               // correctly break URLs with hyperref and dvi output
+               if (features.runparams().flavor == OutputParams::LATEX
+                   && features.isAvailable("breakurl"))
+                       lyxpreamble += "\\usepackage{breakurl}\n";
        } else if (features.isRequired("nameref"))
                // hyperref loads this automatically
                lyxpreamble += "\\usepackage{nameref}\n";
@@ -1884,46 +1914,42 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
                lyxpreamble += from_utf8(features.getBabelPostsettings());
        }
 
-       // FIXME Polyglossia?
-       docstring const i18npreamble = features.getTClassI18nPreamble(use_babel);
-       if (!i18npreamble.empty())
-               lyxpreamble += i18npreamble + '\n';
-
-       int const nlines =
-               int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
-       texrow.newlines(nlines);
-
-       os << lyxpreamble;
-
        // xunicode needs to be loaded at least after amsmath, amssymb,
        // esint and the other packages that provide special glyphs
-       if (features.runparams().flavor == OutputParams::XETEX) {
-               os << "\\usepackage{xunicode}\n";
-               texrow.newline();
-       }
+       if (features.runparams().flavor == OutputParams::XETEX)
+               lyxpreamble += "\\usepackage{xunicode}\n";
+
        // Polyglossia must be loaded last
        if (use_polyglossia) {
                // call the package
-               os << "\\usepackage{polyglossia}\n";
-               texrow.newline();
+               lyxpreamble += "\\usepackage{polyglossia}\n";
                // set the main language
-               os << "\\setdefaultlanguage";
+               lyxpreamble += "\\setdefaultlanguage";
                if (!language->polyglossiaOpts().empty())
-                       os << "[" << from_ascii(language->polyglossiaOpts()) << "]";
-               os << "{" + from_ascii(language->polyglossia()) + "}\n";
-               texrow.newline();
+                       lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]";
+               lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n";
                // now setup the other languages
                std::map<std::string, std::string> const polylangs = 
                        features.getPolyglossiaLanguages();
                for (std::map<std::string, std::string>::const_iterator mit = polylangs.begin();
                     mit != polylangs.end() ; ++mit) {
-                       os << "\\setotherlanguage";
+                       lyxpreamble += "\\setotherlanguage";
                        if (!mit->second.empty())
-                               os << "[" << from_ascii(mit->second) << "]";
-                       os << "{" << from_ascii(mit->first) << "}\n";
-                       texrow.newline();
+                               lyxpreamble += "[" + from_ascii(mit->second) + "]";
+                       lyxpreamble += "{" + from_ascii(mit->first) + "}\n";
                }
        }
+
+       docstring const i18npreamble =
+               features.getTClassI18nPreamble(use_babel, use_polyglossia);
+       if (!i18npreamble.empty())
+               lyxpreamble += i18npreamble + '\n';
+
+       nlines = int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
+       texrow.newlines(nlines);
+
+       os << lyxpreamble;
+
        return use_babel;
 }
 
@@ -2422,6 +2448,9 @@ string const BufferParams::font_encoding() const
 
 string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const
 {
+       if (lang_package != "auto" && lang_package != "babel"
+           && lang_package != "default" && lang_package != "none")
+               return lang_package;
        if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM)
                return lyxrc.language_custom_package;
        // suppress the babel call if there is no BabelName defined
@@ -2459,9 +2488,20 @@ docstring BufferParams::getGraphicsDriver(string const & package) const
 void BufferParams::writeEncodingPreamble(odocstream & os,
                LaTeXFeatures & features, TexRow & texrow) const
 {
-       // fully unicode-aware backends (such as XeTeX) do not need this
-       if (features.runparams().isFullUnicode())
+       // XeTeX does not need this
+       if (features.runparams().flavor == OutputParams::XETEX)
+               return;
+       // LuaTeX neither, but with tex fonts, we need to load
+       // the luainputenc package.
+       if (features.runparams().flavor == OutputParams::LUATEX) {
+               if (!useNonTeXFonts && inputenc != "default"
+                   && ((inputenc == "auto" && language->encoding()->package() == Encoding::inputenc)
+                       || (inputenc != "auto" && encoding().package() == Encoding::inputenc))) {
+                       os << "\\usepackage[utf8]{luainputenc}\n";
+                       texrow.newline();
+               }
                return;
+       }
        if (inputenc == "auto") {
                string const doc_encoding =
                        language->encoding()->latexName();
@@ -2555,7 +2595,8 @@ string const BufferParams::loadFonts(string const & rm,
                                     string const & sf, string const & tt,
                                     bool const & sc, bool const & osf,
                                     int const & sfscale, int const & ttscale,
-                                    bool const & use_systemfonts) const
+                                    bool const & use_systemfonts,
+                                    LaTeXFeatures & features) const
 {
        /* The LaTeX font world is in a flux. In the PSNFSS font interface,
           several packages have been replaced by others, that might not
@@ -2575,9 +2616,30 @@ string const BufferParams::loadFonts(string const & rm,
 
        ostringstream os;
 
-       if (use_systemfonts) {
+       /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle
+        * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/
+        * Mapping=tex-text option assures TeX ligatures (such as "--")
+        * are resolved. Note that tt does not use these ligatures.
+        * TODO:
+        *    -- add more GUI options?
+        *    -- add more fonts (fonts for other scripts)
+        *    -- if there's a way to find out if a font really supports
+        *       OldStyle, enable/disable the widget accordingly. 
+       */
+       if (use_systemfonts && features.isAvailable("fontspec")) {
+               // "Mapping=tex-text" and "Ligatures=TeX" are equivalent.
+               // However, until v.2 (2010/07/11) fontspec only knew
+               // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX"
+               // was introduced for both XeTeX and LuaTeX (LuaTeX
+               // didn't understand "Mapping=tex-text", while XeTeX
+               // understood both. With most recent versions, both
+               // variants are understood by both engines. However,
+               // we want to provide support for at least TeXLive 2009.
+               string const texmapping =
+                       (features.runparams().flavor == OutputParams::XETEX) ?
+                       "Mapping=tex-text" : "Ligatures=TeX";
                if (rm != "default") {
-                       os << "\\setmainfont[Mapping=tex-text";
+                       os << "\\setmainfont[" << texmapping;
                        if (osf)
                                os << ",Numbers=OldStyle";
                        os << "]{" << parseFontName(rm) << "}\n";
@@ -2587,21 +2649,21 @@ string const BufferParams::loadFonts(string const & rm,
                        if (sfscale != 100)
                                os << "\\setsansfont[Scale=" 
                                   << float(sfscale) / 100 
-                                  << ",Mapping=tex-text]{"
+                                  << "," << texmapping << "]{"
                                   << sans << "}\n";
                        else
-                               os << "\\setsansfont[Mapping=tex-text]{"
+                               os << "\\setsansfont[" << texmapping << "]{"
                                   << sans << "}\n";
                }
                if (tt != "default") {
                        string const mono = parseFontName(tt);
                        if (ttscale != 100)
                                os << "\\setmonofont[Scale=" 
-                                  << float(sfscale) / 100 
+                                  << float(ttscale) / 100 
                                   << "]{"
                                   << mono << "}\n";
                        else
-                               os << "\\setmonofont[Mapping=tex-text]{"
+                               os << "\\setmonofont{"
                                   << mono << "}\n";
                }
                return os.str();
@@ -2724,9 +2786,9 @@ string const BufferParams::loadFonts(string const & rm,
 Encoding const & BufferParams::encoding() const
 {
        // FIXME: actually, we should check for the flavor
-       // or runparams.isFullyUnicode() here.
-       // useNonTeXFonts happens to match the flavors, but
-       // this may well likely change!
+       // or runparams.isFullyUnicode() here:
+       // This check will not work with XeTeX/LuaTeX and tex fonts.
+       // Thus we have to reset the encoding in Buffer::makeLaTeXFile.
        if (useNonTeXFonts)
                return *(encodings.fromLaTeXName("utf8-plain"));
        if (inputenc == "auto" || inputenc == "default")