]> git.lyx.org Git - lyx.git/blobdiff - src/LaTeXFeatures.cpp
installer: further preparation
[lyx.git] / src / LaTeXFeatures.cpp
index 489d7a4627d1102d1956814467e9b9ffd03c9a48..d23f8b0b47157c37e387415b41554a4a244d6038 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"
@@ -183,19 +184,19 @@ static docstring const changetracking_dvipost_def = from_ascii(
        "\\dvipost{osend color pop}\n"
        "\\dvipost{cbstart color push Blue}\n"
        "\\dvipost{cbend color pop}\n"
-       "\\newcommand{\\lyxadded}[3]{\\changestart#3\\changeend}\n"
-       "\\newcommand{\\lyxdeleted}[3]{%\n"
+       "\\DeclareRobustCommand{\\lyxadded}[3]{\\changestart#3\\changeend}\n"
+       "\\DeclareRobustCommand{\\lyxdeleted}[3]{%\n"
        "\\changestart\\overstrikeon#3\\overstrikeoff\\changeend}\n");
 
 static docstring const changetracking_xcolor_ulem_def = from_ascii(
        "%% Change tracking with ulem\n"
-       "\\newcommand{\\lyxadded}[3]{{\\color{lyxadded}{}#3}}\n"
-       "\\newcommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\sout{#3}}}\n");
+       "\\DeclareRobustCommand{\\lyxadded}[3]{{\\color{lyxadded}{}#3}}\n"
+       "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\sout{#3}}}\n");
 
 static docstring const changetracking_xcolor_ulem_hyperref_def = from_ascii(
        "%% Change tracking with ulem\n"
-       "\\newcommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}{}}{}#3}}\n"
-       "\\newcommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\sout{#3}}{}}}\n");
+       "\\DeclareRobustCommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}{}}{}#3}}\n"
+       "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\sout{#3}}{}}}\n");
 
 static docstring const changetracking_none_def = from_ascii(
        "\\newcommand{\\lyxadded}[3]{#3}\n"
@@ -276,6 +277,61 @@ 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");
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// LyXHTML strings
+//
+/////////////////////////////////////////////////////////////////////
+
+static docstring const lyxnoun_style = from_ascii(
+       "dfn.lyxnoun {\n"
+  "  font-variant: small-caps;\n"
+  "}\n");
+
+
+// this is how it normally renders, but it might not always do so.
+static docstring const lyxstrikeout_style = from_ascii(
+       "del.strikeout {\n"
+  "  text-decoration: line-through;\n"
+  "}\n");
+
 
 /////////////////////////////////////////////////////////////////////
 //
@@ -290,33 +346,70 @@ LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p,
 {}
 
 
-bool LaTeXFeatures::useBabel() const
+LaTeXFeatures::LangPackage LaTeXFeatures::langPackage() const
 {
-       if (usePolyglossia()
-           || bufferParams().lang_package == "none"
-           || (bufferParams().lang_package == "default"
-               && lyxrc.language_package_selection == LyXRC::LP_NONE))
-               return false;
-
-       return (bufferParams().language->lang() != lyxrc.default_language
-               && !bufferParams().language->babel().empty())
-               || this->hasLanguages();
-}
-
-
-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->hasOnlyPolyglossiaLanguages();
-       return (bufferParams().lang_package == "auto")
-               && isRequired("polyglossia")
+       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.
+        */
+       bool const polyglossia_required =
+               isRequired("polyglossia")
                && isAvailable("polyglossia")
-               && !params_.documentClass().provides("babel")
+               && !isProvided("babel")
                && this->hasOnlyPolyglossiaLanguages();
+       bool const babel_required = 
+               !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;
+       }
+
+       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;
 }
 
 
@@ -394,9 +487,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);
 }
 
 
@@ -494,7 +617,7 @@ bool LaTeXFeatures::hasPolyglossiaExclusiveLanguages() const
        for (LanguageList::const_iterator cit = begin;
             cit != UsedLanguages_.end();
             ++cit) {
-               if ((*cit)->babel().empty() && !(*cit)->polyglossia().empty() && (*cit)->requires().empty())
+               if ((*cit)->isPolyglossiaExclusive())
                        return true;
        }
        return false;
@@ -580,6 +703,7 @@ char const * simplefeatures[] = {
        "units",
        "tipa",
        "tipx",
+       "tone",
        "framed",
        "soul",
        "textcomp",
@@ -593,7 +717,7 @@ char const * simplefeatures[] = {
        "mathrsfs",
        "mathabx",
        "mathtools",
-       "cancel",
+       // "cancel",
        "ascii",
        "url",
        "covington",
@@ -607,10 +731,31 @@ char const * simplefeatures[] = {
        "pdfpages",
        "amscd",
        "slashed",
+       "multicol",
        "multirow",
-       "tfrupee"
+       "tfrupee",
+       "shapepar",
+       "rsphrase"
 };
 
+char const * bibliofeatures[] = {
+       // Known bibliography packages (will be loaded before natbib)
+       "achicago",
+       "apacite",
+       "apalike",
+       "astron",
+       "authordate1-4",
+       "babelbib",
+       "bibgerm",
+       "chicago",
+       "chscite",
+       "harvard",
+       "mslapa",
+       "named"
+};
+
+int const nb_bibliofeatures = sizeof(bibliofeatures) / sizeof(char const *);
+
 int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *);
 
 }
@@ -679,7 +824,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.
@@ -687,20 +831,25 @@ string const LaTeXFeatures::getPackages() const
        // also unknown packages can be requested. They are silently
        // swallowed now. We should change this eventually.
 
-       //
+       // Output all the package option stuff we have been asked to do.
+       map<string, string>::const_iterator it =
+           params_.documentClass().packageOptions().begin();
+       map<string, string>::const_iterator en =
+           params_.documentClass().packageOptions().end();
+       for (; it != en; ++it)
+               if (mustProvide(it->first))
+                       packages << "\\PassOptionsToPackage{" << it->second << "}"
+                                << "{" << it->first << "}\n";
+
        //  These are all the 'simple' includes.  i.e
        //  packages which we just \usepackage{package}
-       //
        for (int i = 0; i < nb_simplefeatures; ++i) {
                if (mustProvide(simplefeatures[i]))
-                       packages << "\\usepackage{"
-                                << simplefeatures[i] << "}\n";
+                       packages << "\\usepackage{" << simplefeatures[i] << "}\n";
        }
 
-       //
        // The rest of these packages are somewhat more complicated
        // than those above.
-       //
 
        // if fontspec is used, AMS packages have to be loaded before
        // fontspec (in BufferParams)
@@ -714,6 +863,9 @@ string const LaTeXFeatures::getPackages() const
        if (mustProvide("fixltx2e"))
                packages << "\\usepackage{fixltx2e}\n";
 
+        if (mustProvide("cancel") &&
+            params_.use_package("cancel") != BufferParams::package_off)
+                packages << "\\usepackage{cancel}\n";
        // wasysym is a simple feature, but it must be after amsmath if both
        // are used
        // wasysym redefines some integrals (e.g. iint) from amsmath. That
@@ -742,6 +894,15 @@ string const LaTeXFeatures::getPackages() const
            params_.use_package("yhmath") != BufferParams::package_off)
                packages << "\\usepackage{yhmath}\n";
 
+       // stmaryrd must be loaded after amsmath
+       if (mustProvide("stmaryrd") &&
+           params_.use_package("stmaryrd") != BufferParams::package_off)
+               packages << "\\usepackage{stmaryrd}\n";
+
+       if (mustProvide("stackrel") &&
+           params_.use_package("stackrel") != BufferParams::package_off)
+               packages << "\\usepackage{stackrel}\n";
+
        if (mustProvide("undertilde") &&
                params_.use_package("undertilde") != BufferParams::package_off)
                packages << "\\usepackage{undertilde}\n";
@@ -750,9 +911,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";
        }
@@ -772,7 +933,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
@@ -781,11 +942,22 @@ string const LaTeXFeatures::getPackages() const
            params_.use_package("esint") != BufferParams::package_off)
                packages << "\\usepackage{esint}\n";
 
+       // Known bibliography packages (simple \usepackage{package})
+       for (int i = 0; i < nb_bibliofeatures; ++i) {
+               if (mustProvide(bibliofeatures[i]))
+                       packages << "\\usepackage{"
+                                << bibliofeatures[i] << "}\n";
+       }
+
+       // Compatibility between achicago and natbib
+       if (mustProvide("achicago") && mustProvide("natbib"))
+               packages << "\\let\\achicagobib\\thebibliography\n";
+
        // natbib.sty
        // 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";
@@ -794,10 +966,25 @@ string const LaTeXFeatures::getPackages() const
                packages << "]{natbib}\n";
        }
 
+       // Compatibility between achicago and natbib
+       if (mustProvide("achicago") && mustProvide("natbib")) {
+               packages << "\\let\\thebibliography\\achicagobib\n";
+               packages << "\\let\\SCcite\\astroncite\n";
+               packages << "\\let\\UnexpandableProtect\\protect\n";
+       }
+
        // jurabib -- we need version 0.6 at least.
        if (mustProvide("jurabib"))
                packages << "\\usepackage{jurabib}[2004/01/25]\n";
 
+       // opcit -- we pass custombst as we output \bibliographystyle ourselves
+       if (mustProvide("opcit")) {
+               if (isRequired("hyperref"))
+                       packages << "\\usepackage[custombst,hyperref]{opcit}\n";
+               else
+                       packages << "\\usepackage[custombst]{opcit}\n";
+       }
+
        // xargs -- we need version 1.09 at least
        if (mustProvide("xargs"))
                packages << "\\usepackage{xargs}[2008/03/08]\n";
@@ -1008,6 +1195,9 @@ docstring const LaTeXFeatures::getMacros() const
        if (mustProvide("ct-none"))
                macros << changetracking_none_def;
 
+       if (mustProvide("rtloutputdblcol"))
+               macros << rtloutputdblcol_def;
+
        return macros.str();
 }
 
@@ -1148,6 +1338,13 @@ docstring const LaTeXFeatures::getTClassHTMLStyles() const
        DocumentClass const & tclass = params_.documentClass();
        odocstringstream tcpreamble;
 
+       if (mustProvide("noun"))
+               tcpreamble << lyxnoun_style;
+       // this isn't exact, but it won't hurt that much if it
+       // wasn't for this.
+       if (mustProvide("ulem"))
+               tcpreamble << lyxstrikeout_style;
+
        tcpreamble << tclass.htmlstyles();
 
        list<docstring>::const_iterator cit = usedLayouts_.begin();
@@ -1170,6 +1367,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)