]> git.lyx.org Git - lyx.git/blobdiff - src/BufferParams.cpp
Update Win installer for new dictionary links. Untested.
[lyx.git] / src / BufferParams.cpp
index d94af3a410e69e70962a0d73667c97f50fe01ff9..0d1600c5cf201f4efa3acf4d1f4f62bbfcf0ce6c 100644 (file)
@@ -74,7 +74,7 @@ static char const * const string_paragraph_separation[] = {
 static char const * const string_quotes_style[] = {
        "english", "swedish", "german", "polish", "swiss", "danish", "plain",
        "british", "swedishg", "french", "frenchin", "russian", "cjk", "cjkangle",
-       "hungarian", ""
+       "hungarian", "hebrew", ""
 };
 
 
@@ -158,6 +158,7 @@ QuotesStyleTranslator const init_quotesstyletranslator()
        translator.addPair(string_quotes_style[12], QuoteStyle::CJK);
        translator.addPair(string_quotes_style[13], QuoteStyle::CJKAngle);
        translator.addPair(string_quotes_style[14], QuoteStyle::Hungarian);
+       translator.addPair(string_quotes_style[15], QuoteStyle::Hebrew);
        return translator;
 }
 
@@ -487,6 +488,7 @@ BufferParams::BufferParams()
        shell_escape = false;
        output_sync = false;
        use_refstyle = true;
+       use_formatted_ref = false;
        use_minted = false;
        use_lineno = false;
 
@@ -1204,6 +1206,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                lex >> output_sync_macro;
        } else if (token == "\\use_refstyle") {
                lex >> use_refstyle;
+       } else if (token == "\\use_formatted_ref") {
+               lex >> use_formatted_ref;
        } else if (token == "\\use_minted") {
                lex >> use_minted;
        } else if (token == "\\use_lineno") {
@@ -1432,6 +1436,7 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
           << "\n\\suppress_date " << convert<string>(suppress_date)
           << "\n\\justification " << convert<string>(justification)
           << "\n\\use_refstyle " << use_refstyle
+          << "\n\\use_formatted_ref " << use_formatted_ref
           << "\n\\use_minted " << use_minted
           << "\n\\use_lineno " << use_lineno
           << '\n';
@@ -1588,7 +1593,8 @@ void BufferParams::validate(LaTeXFeatures & features) const
 {
        features.require(documentClass().required());
 
-       if (columns > 1 && language->rightToLeft())
+       if (columns > 1 && language->rightToLeft()
+           && !features.runparams().isFullUnicode())
                features.require("rtloutputdblcol");
 
        if (output_changes) {
@@ -1614,7 +1620,6 @@ void BufferParams::validate(LaTeXFeatures & features) const
                                features.require("ulem");
                                features.require("xcolor");
                                // improves color handling in PDF output
-                               features.require("pdfcolmk");
                        } else {
                                features.require("ct-none");
                        }
@@ -1703,7 +1708,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                              FileName const & filepath) const
 {
        // DocumentMetadata must come before anything else
-       if (features.isAvailable("LaTeX-2022/06/01")
+       if (features.isAvailableAtLeastFrom("LaTeX", 2022, 6)
            && !containsOnly(document_metadata, " \n\t")) {
                // Check if the user preamble contains uncodable glyphs
                odocstringstream doc_metadata;
@@ -1742,7 +1747,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                                    "\n\nPlease select an appropriate "
                                    "document encoding\n"
                                    "(such as utf8) or change the "
-                                   "preamble code accordingly."),
+                                   "metadata accordingly."),
                                  uncodable_glyphs));
                }
                if (!doc_metadata.str().empty()) {
@@ -1921,8 +1926,18 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
 
        if (useNonTeXFonts) {
                // Babel (as of 2017/11/03) loads fontspec itself
+               // However, it does so only if a non-default font is requested via \babelfont
+               // Thus load fontspec if this is not the case and we need fontspec features
+               bool const babel_needfontspec =
+                               !features.isAvailableAtLeastFrom("babel", 2017, 11, 3)
+                               || (fontsRoman() == "default"
+                                   && fontsSans() == "default"
+                                   && fontsTypewriter() == "default"
+                                   // these need fontspec features
+                                   && (features.isRequired("textquotesinglep")
+                                       || features.isRequired("textquotedblp")));
                if (!features.isProvided("fontspec")
-                   && !(features.useBabel() && features.isAvailable("babel-2017/11/03")))
+                   && (!features.useBabel() || babel_needfontspec))
                        os << "\\usepackage{fontspec}\n";
                if (features.mustProvide("unicode-math")
                    && features.isAvailable("unicode-math"))
@@ -2138,6 +2153,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
        if (paragraph_separation) {
                // when skip separation
                string psopt;
+               bool default_skip = false;
                switch (getDefSkip().kind()) {
                case VSpace::SMALLSKIP:
                        psopt = "\\smallskipamount";
@@ -2150,6 +2166,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                        break;
                case VSpace::HALFLINE:
                        // default (no option)
+                       default_skip = true;
                        break;
                case VSpace::FULLLINE:
                        psopt = "\\baselineskip";
@@ -2160,12 +2177,30 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
                default:
                        break;
                }
-               if (!features.isProvided("parskip")) {
+               if (features.isProvided("parskip")) {
+                       // package already loaded (with arbitrary options)
+                       // change parskip value only
                        if (!psopt.empty())
-                               psopt = "[skip=" + psopt + "]";
-                       os << "\\usepackage" + psopt + "{parskip}\n";
+                               os << "\\setlength{\\parskip}{" + psopt + "}\n";
+                       else if (default_skip)
+                               // explicitly reset default (might have been changed
+                               // in a class or package)
+                               os << "\\parskip=.5\\baselineskip plus 2pt\\relax\n";
                } else {
-                       os << "\\setlength{\\parskip}{" + psopt + "}\n";
+                       // load parskip package with required options
+                       string psopts;
+                       if (!psopt.empty())
+                               psopts = "skip=" + psopt;
+                       string const xpsopts = getPackageOptions("parskip");
+                       if (!xpsopts.empty()) {
+                               if (!psopts.empty())
+                                       psopts += ",";
+                               psopts += xpsopts;
+                       }
+                       os << "\\usepackage";
+                       if (!psopts.empty())
+                               os << "[" << psopts << "]";
+                       os << "{parskip}\n";
                }
        } else {
                // when separation by indentation
@@ -2937,6 +2972,42 @@ bool BufferParams::isLiterate() const
 }
 
 
+bool BufferParams::hasPackageOption(string const package, string const opt) const
+{
+       for (auto const & p : documentClass().packageOptions())
+               if (package == p.first && opt == p.second)
+                       return true;
+       return false;
+}
+
+
+string BufferParams::getPackageOptions(string const package) const
+{
+       for (auto const & p : documentClass().packageOptions())
+               if (package == p.first)
+                       return p.second;
+       return string();
+}
+
+
+bool BufferParams::useBidiPackage(OutputParams const & rp) const
+{
+       return (rp.use_polyglossia
+               // as of babel 3.29, bidi=bidi-* is supported by babel
+               // So we check whether we use a respective version and
+               // whethert bidi-r or bidi-l have been requested either via class
+               // or package options
+               || (rp.use_babel
+                   && LaTeXFeatures::isAvailableAtLeastFrom("babel", 2019, 4, 3)
+                   && (hasPackageOption("babel", "bidi-r")
+                       || hasPackageOption("babel", "bidi-l")
+                       || contains(options, "bidi-r")
+                       || contains(options, "bidi-l")))
+               )
+               && rp.flavor == Flavor::XeTeX;
+}
+
+
 void BufferParams::readPreamble(Lexer & lex)
 {
        if (lex.getString() != "\\begin_preamble")
@@ -3404,9 +3475,8 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                    && !features.isProvided("inputenc")) {
                        if (package == Encoding::inputenc) {
                                // Main language requires (lua)inputenc
-                               os << "\\usepackage["
-                                  << from_ascii(doc_encoding);
-                               os << "]{" << inputenc_package << "}\n";
+                               os << "\\usepackage[" << doc_encoding << "]{"
+                                  << inputenc_package << "}\n";
                        } else {
                                // We might have an additional language that requires inputenc
                                set<string> encoding_set = features.getEncodingSet(doc_encoding);
@@ -3430,10 +3500,10 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                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";
+                           && !features.runparams().isFullUnicode()
+                           && features.isAvailableAtLeastFrom("LaTeX", 2018, 4))
+                               // don't default to [utf8]{inputenc} with LaTeX >= 2018/04
+                               os << "\\UseRawInputEncoding\n";
                        break;
                case Encoding::inputenc:
                        // do not load inputenc if japanese is used
@@ -3449,20 +3519,18 @@ void BufferParams::writeEncodingPreamble(otexstream & os,
                        // Thus we load ucs.sty in order to keep functionality
                        // that would otherwise be silently dropped.
                        if (doc_encoding == "utf8x"
-                           && features.isAvailable("ucs-2022/08/07")
+                           && features.isAvailableAtLeastFrom("ucs", 2022, 8, 7)
                            && !features.isProvided("ucs"))
                                os << "\\usepackage{ucs}\n";
-                       os << "\\usepackage["
-                          << from_ascii(doc_encoding)
-                          << "]{" << inputenc_package << "}\n";
+                       os << "\\usepackage[" << doc_encoding << "]{"
+                          << inputenc_package << "}\n";
                        break;
                }
        }
-       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";
-       }
+       if ((inputenc == "auto-legacy-plain" || features.isRequired("japanese"))
+           && features.isAvailableAtLeastFrom("LaTeX", 2018, 4))
+               // don't default to [utf8]{inputenc} with LaTeX >= 2018/04
+               os << "\\UseRawInputEncoding\n";
 }
 
 
@@ -3510,7 +3578,7 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
                // 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");
+                               && features.isAvailableAtLeastFrom("babel", 2017, 11, 3);
                string const texmapping =
                        (features.runparams().flavor == Flavor::XeTeX) ?
                        "Mapping=tex-text" : "Ligatures=TeX";
@@ -3519,11 +3587,11 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
                                os << "\\babelfont{rm}[";
                        else
                                os << "\\setmainfont[";
-                       if (!font_roman_opts.empty())
-                               os << font_roman_opts << ',';
                        os << texmapping;
                        if (fonts_roman_osf)
                                os << ",Numbers=OldStyle";
+                       if (!font_roman_opts.empty())
+                               os << ',' << font_roman_opts;
                        os << "]{" << parseFontName(fontsRoman()) << "}\n";
                }
                if (fontsSans() != "default") {
@@ -3537,10 +3605,10 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
                                   << float(fontsSansScale()) / 100 << ',';
                                if (fonts_sans_osf)
                                        os << "Numbers=OldStyle,";
+                               os << texmapping;
                                if (!font_sans_opts.empty())
-                                       os << font_sans_opts << ',';
-                               os << texmapping << "]{"
-                                  << sans << "}\n";
+                                       os << ',' << font_sans_opts;
+                               os << "]{" << sans << "}\n";
                        } else {
                                if (babelfonts)
                                        os << "\\babelfont{sf}[";
@@ -3548,10 +3616,10 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
                                        os << "\\setsansfont[";
                                if (fonts_sans_osf)
                                        os << "Numbers=OldStyle,";
+                               os << texmapping;
                                if (!font_sans_opts.empty())
-                                       os << font_sans_opts << ',';
-                               os << texmapping << "]{"
-                                  << sans << "}\n";
+                                       os << ',' << font_sans_opts;
+                               os << "]{" << sans << "}\n";
                        }
                }
                if (fontsTypewriter() != "default") {