]> git.lyx.org Git - lyx.git/blobdiff - src/LaTeXFeatures.cpp
Provide option to force a local language switch where a global is not allowed (fixes...
[lyx.git] / src / LaTeXFeatures.cpp
index d5a0b6f6b90043b7015f37d64dad51804ea5071b..bbc76d18523eb714573fdc7dc874e90baf90e8e5 100644 (file)
@@ -24,6 +24,7 @@
 #include "Floating.h"
 #include "FloatList.h"
 #include "Language.h"
+#include "LaTeXFonts.h"
 #include "LaTeXPackages.h"
 #include "Layout.h"
 #include "Lexer.h"
@@ -276,6 +277,42 @@ static docstring const lyxref_def = from_ascii(
                "  {\\def\\RSlemtxt{lemma~}\\newref{lem}{name = \\RSlemtxt}}\n" 
                "  {}\n");
 
+// Make sure the columns are also outputed as rtl
+static docstring const rtloutputdblcol_def = from_ascii(
+       "\\def\\@outputdblcol{%\n"
+       "  \\if@firstcolumn\n"
+       "    \\global \\@firstcolumnfalse\n"
+       "    \\global \\setbox\\@leftcolumn \\box\\@outputbox\n"
+       "  \\else\n"
+       "    \\global \\@firstcolumntrue\n"
+       "    \\setbox\\@outputbox \\vbox {%\n"
+       "      \\hb@xt@\\textwidth {%\n"
+       "      \\kern\\textwidth \\kern-\\columnwidth %**\n"
+       "      \\hb@xt@\\columnwidth {%\n"
+       "         \\box\\@leftcolumn \\hss}%\n"
+       "      \\kern-\\textwidth %**\n"
+       "      \\hfil\n"
+       "      {\\normalcolor\\vrule \\@width\\columnseprule}%\n"
+       "      \\hfil\n"
+       "      \\kern-\\textwidth  %**\n"
+       "      \\hb@xt@\\columnwidth {%\n"
+       "         \\box\\@outputbox \\hss}%\n"
+       "      \\kern-\\columnwidth \\kern\\textwidth %**\n"
+       "    }%\n"
+       "  }%\n"
+       "  \\@combinedblfloats\n"
+       "  \\@outputpage\n"
+       "  \\begingroup\n"
+       "  \\@dblfloatplacement\n"
+       "  \\@startdblcolumn\n"
+       "  \\@whilesw\\if@fcolmade \\fi\n"
+       "  {\\@outputpage\n"
+       "    \\@startdblcolumn}%\n"
+       "  \\endgroup\n"
+       "  \\fi\n"
+       "}\n"
+       "\\@mparswitchtrue\n");
+
 
 /////////////////////////////////////////////////////////////////////
 //
@@ -290,35 +327,74 @@ LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p,
 {}
 
 
-bool LaTeXFeatures::useBabel() const
+LaTeXFeatures::LangPackage LaTeXFeatures::langPackage(bool englishbabel) const
 {
-       if (usePolyglossia())
-               return false;
-       if (bufferParams().lang_package == "default")
-               return (lyxrc.language_package_selection != LyXRC::LP_NONE)
-                       || (bufferParams().language->lang() != lyxrc.default_language
-                           && !bufferParams().language->babel().empty())
-                       || this->hasLanguages();
-       return (bufferParams().lang_package != "none")
-               || (bufferParams().language->lang() != lyxrc.default_language
-                   && !bufferParams().language->babel().empty())
-               || this->hasLanguages();
-}
+       string const local_lp = bufferParams().lang_package;
+
+       // Locally, custom is just stored as a string
+       // in bufferParams().lang_package.
+       if (local_lp != "auto"
+           && local_lp != "babel"
+           && local_lp != "default"
+           && local_lp != "none")
+                return LANG_PACK_CUSTOM;
+
+       if (local_lp == "none")
+               return LANG_PACK_NONE;
+
+       /* If "auto" is selected, we load polyglossia if required,
+        * else we select babel.
+        * If babel is selected (either directly or via the "auto"
+        * mechanism), we really do only require it if we have
+        * a language that needs it.
+        * English alone normally does not require babel (since it is
+        * the default language of LaTeX). However, in some cases we
+        * need to surpass this exception (see Font::validate).
+        */
+       bool const polyglossia_required =
+               isRequired("polyglossia")
+               && isAvailable("polyglossia")
+               && !isProvided("babel")
+               && this->hasOnlyPolyglossiaLanguages();
+       bool const babel_required = 
+               ((englishbabel || bufferParams().language->lang() != "english")
+                && !bufferParams().language->babel().empty())
+               || !this->getBabelLanguages().empty();
+
+       if (local_lp == "auto") {
+               // polyglossia requirement has priority over babel
+               if (polyglossia_required)
+                       return LANG_PACK_POLYGLOSSIA;
+               else if (babel_required)
+                       return LANG_PACK_BABEL;
+       }
 
+       if (local_lp == "babel") {
+               if (babel_required)
+                       return LANG_PACK_BABEL;
+       }
 
-bool LaTeXFeatures::usePolyglossia() const
-{
-       if (bufferParams().lang_package == "default")
-               return (lyxrc.language_package_selection == LyXRC::LP_AUTO)
-                       && isRequired("polyglossia")
-                       && isAvailable("polyglossia")
-                       && !params_.documentClass().provides("babel")
-                       && this->hasPolyglossiaLanguages();
-       return (bufferParams().lang_package == "auto")
-               && isRequired("polyglossia")
-               && isAvailable("polyglossia")
-               && !params_.documentClass().provides("babel")
-               && this->hasPolyglossiaLanguages();
+       if (local_lp == "default") {
+               switch (lyxrc.language_package_selection) {
+               case LyXRC::LP_AUTO:
+                       // polyglossia requirement has priority over babel
+                       if (polyglossia_required)
+                               return LANG_PACK_POLYGLOSSIA;
+                       else if (babel_required)
+                               return LANG_PACK_BABEL;
+                       break;
+               case LyXRC::LP_BABEL:
+                       if (babel_required)
+                               return LANG_PACK_BABEL;
+                       break;
+               case LyXRC::LP_CUSTOM:
+                       return LANG_PACK_CUSTOM;
+               case LyXRC::LP_NONE:
+                       return LANG_PACK_NONE;
+               }
+       }
+
+       return LANG_PACK_NONE;
 }
 
 
@@ -396,9 +472,39 @@ bool LaTeXFeatures::isRequired(string const & name) const
 }
 
 
+bool LaTeXFeatures::isProvided(string const & name) const
+{
+       if (params_.useNonTeXFonts)
+               return params_.documentClass().provides(name);
+
+       bool const ot1 = (params_.font_encoding() == "default"
+               || params_.font_encoding() == "OT1");
+       bool const complete = (params_.fonts_sans == "default")
+               && (params_.fonts_typewriter == "default");
+       bool const nomath = (params_.fonts_math == "default");
+       return params_.documentClass().provides(name)
+               || theLaTeXFonts().getLaTeXFont(
+                       from_ascii(params_.fonts_roman)).provides(name, ot1,
+                                                                 complete,
+                                                                 nomath)
+               || theLaTeXFonts().getLaTeXFont(
+                       from_ascii(params_.fonts_sans)).provides(name, ot1,
+                                                                complete,
+                                                                nomath)
+               || theLaTeXFonts().getLaTeXFont(
+                       from_ascii(params_.fonts_typewriter)).provides(name, ot1,
+                                                                      complete,
+                                                                      nomath)
+               || theLaTeXFonts().getLaTeXFont(
+                       from_ascii(params_.fonts_math)).provides(name, ot1,
+                                                                      complete,
+                                                                      nomath);
+}
+
+
 bool LaTeXFeatures::mustProvide(string const & name) const
 {
-       return isRequired(name) && !params_.documentClass().provides(name);
+       return isRequired(name) && !isProvided(name);
 }
 
 
@@ -451,10 +557,10 @@ void LaTeXFeatures::useFloat(string const & name, bool subfloat)
 
 void LaTeXFeatures::useLanguage(Language const * lang)
 {
-       if (!lang->babel().empty())
+       if (!lang->babel().empty() || !lang->polyglossia().empty())
                UsedLanguages_.insert(lang);
-       if (lang->lang() == "vietnamese")
-               require("vietnamese");
+       if (!lang->requires().empty())
+               require(lang->requires());
        // CJK languages do not have a babel name.
        // They use the CJK package
        if (lang->encoding()->package() == Encoding::CJK)
@@ -477,7 +583,7 @@ bool LaTeXFeatures::hasLanguages() const
 }
 
 
-bool LaTeXFeatures::hasPolyglossiaLanguages() const
+bool LaTeXFeatures::hasOnlyPolyglossiaLanguages() const
 {
        LanguageList::const_iterator const begin = UsedLanguages_.begin();
        for (LanguageList::const_iterator cit = begin;
@@ -490,16 +596,34 @@ bool LaTeXFeatures::hasPolyglossiaLanguages() const
 }
 
 
-string LaTeXFeatures::getLanguages() const
+bool LaTeXFeatures::hasPolyglossiaExclusiveLanguages() const
+{
+       LanguageList::const_iterator const begin = UsedLanguages_.begin();
+       for (LanguageList::const_iterator cit = begin;
+            cit != UsedLanguages_.end();
+            ++cit) {
+               if ((*cit)->babel().empty() && !(*cit)->polyglossia().empty() && (*cit)->requires().empty())
+                       return true;
+       }
+       return false;
+}
+
+
+string LaTeXFeatures::getBabelLanguages() const
 {
        ostringstream languages;
 
+       bool first = true;
        LanguageList::const_iterator const begin = UsedLanguages_.begin();
        for (LanguageList::const_iterator cit = begin;
             cit != UsedLanguages_.end();
             ++cit) {
-               if (cit != begin)
+               if ((*cit)->babel().empty())
+                       continue;
+               if (!first)
                        languages << ',';
+               else
+                       first = false;
                languages << (*cit)->babel();
        }
        return languages.str();
@@ -564,6 +688,7 @@ char const * simplefeatures[] = {
        "units",
        "tipa",
        "tipx",
+       "tone",
        "framed",
        "soul",
        "textcomp",
@@ -663,7 +788,6 @@ string const LaTeXFeatures::getColorOptions() const
 string const LaTeXFeatures::getPackages() const
 {
        ostringstream packages;
-       DocumentClass const & tclass = params_.documentClass();
 
        // FIXME: currently, we can only load packages and macros known
        // to LyX.
@@ -734,9 +858,9 @@ string const LaTeXFeatures::getPackages() const
 
        // makeidx.sty
        if (isRequired("makeidx") || isRequired("splitidx")) {
-               if (!tclass.provides("makeidx") && !isRequired("splitidx"))
+               if (!isProvided("makeidx") && !isRequired("splitidx"))
                        packages << "\\usepackage{makeidx}\n";
-               if (!tclass.provides("splitidx") && isRequired("splitidx"))
+               if (mustProvide("splitidx"))
                        packages << "\\usepackage{splitidx}\n";
                packages << "\\makeindex\n";
        }
@@ -756,7 +880,7 @@ string const LaTeXFeatures::getPackages() const
                packages << "\\usepackage[ps,mover]{lyxskak}\n";
 
        // setspace.sty
-       if (mustProvide("setspace") && !tclass.provides("SetSpace"))
+       if (mustProvide("setspace") && !isProvided("SetSpace"))
                packages << "\\usepackage{setspace}\n";
 
        // esint must be after amsmath and wasysym, since it will redeclare
@@ -769,7 +893,7 @@ string const LaTeXFeatures::getPackages() const
        // Some classes load natbib themselves, but still allow (or even require)
        // plain numeric citations (ReVTeX is such a case, see bug 5182).
        // This special case is indicated by the "natbib-internal" key.
-       if (mustProvide("natbib") && !tclass.provides("natbib-internal")) {
+       if (mustProvide("natbib") && !isProvided("natbib-internal")) {
                packages << "\\usepackage[";
                if (params_.citeEngineType() == ENGINE_TYPE_NUMERICAL)
                        packages << "numbers";
@@ -786,11 +910,6 @@ string const LaTeXFeatures::getPackages() const
        if (mustProvide("xargs"))
                packages << "\\usepackage{xargs}[2008/03/08]\n";
 
-       // bibtopic -- the dot provides the aux file naming which
-       // LyX can detect.
-       if (mustProvide("bibtopic"))
-               packages << "\\usepackage[dot]{bibtopic}\n";
-
        if (mustProvide("xy"))
                packages << "\\usepackage[all]{xy}\n";
 
@@ -997,6 +1116,9 @@ docstring const LaTeXFeatures::getMacros() const
        if (mustProvide("ct-none"))
                macros << changetracking_none_def;
 
+       if (mustProvide("rtloutputdblcol"))
+               macros << rtloutputdblcol_def;
+
        return macros.str();
 }
 
@@ -1013,7 +1135,10 @@ string const LaTeXFeatures::getBabelPresettings() const
        if (!params_.language->babel_presettings().empty())
                tmp << params_.language->babel_presettings() << '\n';
 
-       return tmp.str();
+       if (!contains(tmp.str(), '@'))
+               return tmp.str();
+
+       return "\\makeatletter\n" + tmp.str() + "\\makeatother\n";
 }
 
 
@@ -1029,7 +1154,10 @@ string const LaTeXFeatures::getBabelPostsettings() const
        if (!params_.language->babel_postsettings().empty())
                tmp << params_.language->babel_postsettings() << '\n';
 
-       return tmp.str();
+       if (!contains(tmp.str(), '@'))
+               return tmp.str();
+
+       return "\\makeatletter\n" + tmp.str() + "\\makeatother\n";
 }
 
 
@@ -1066,7 +1194,7 @@ string const LaTeXFeatures::loadAMSPackages() const
        }
 
        if (mustProvide("amssymb")
-           || params_.use_package("amsmath") == BufferParams::package_on)
+           && params_.use_package("amssymb") != BufferParams::package_off)
                tmp << "\\usepackage{amssymb}\n";
 
        return tmp.str();
@@ -1153,6 +1281,7 @@ docstring const LaTeXFeatures::getTClassHTMLStyles() const
 
 
 namespace {
+
 docstring const getFloatI18nPreamble(docstring const & type,
                        docstring const & name, Language const * lang,
                        Encoding const & enc, bool const polyglossia)