X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeXFeatures.cpp;h=8340940ef9be365760302e0eb7ca4ebd3048dcb8;hb=1acedf11da79f509da706bc8d6d2f491c9676087;hp=dae61ec0695457ecc983d48d66a40571f956eb64;hpb=547bceb62e6a1c6b820410a38a1aab1bb2bf162f;p=lyx.git diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index dae61ec069..8340940ef9 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -16,36 +16,27 @@ #include "LaTeXFeatures.h" -#include "BufferParams.h" #include "Color.h" -#include "debug.h" +#include "BufferParams.h" +#include "support/debug.h" #include "Encoding.h" #include "Floating.h" #include "FloatList.h" #include "Language.h" +#include "Layout.h" #include "Lexer.h" #include "LyXRC.h" +#include "TextClass.h" #include "support/docstream.h" +#include "support/FileName.h" #include "support/filetools.h" -#include "frontends/controllers/frontend_helpers.h" +using namespace std; +using namespace lyx::support; namespace lyx { -using support::isSGMLFilename; -using support::libFileSearch; -using support::makeRelPath; -using support::onlyPath; - -using std::endl; -using std::find; -using std::string; -using std::list; -using std::ostream; -using std::ostringstream; -using std::set; - ///////////////////////////////////////////////////////////////////// // // Strings @@ -159,7 +150,7 @@ static string const mathcircumflex_def = static string const tabularnewline_def = "%% Because html converters don't know tabularnewline\n" "\\providecommand{\\tabularnewline}{\\\\}\n"; - + static string const lyxgreyedout_def = "%% The greyedout annotation environment\n" "\\newenvironment{lyxgreyedout}{\\textcolor[gray]{0.8}\\bgroup}{\\egroup}\n"; @@ -186,7 +177,115 @@ static string const changetracking_none_def = "\\newcommand{\\lyxadded}[3]{#3}\n" "\\newcommand{\\lyxdeleted}[3]{}\n"; - +static string const textgreek_def = + "\\DeclareRobustCommand{\\greektext}{%\n" + " \\fontencoding{LGR}\\selectfont\n" + " \\def\\encodingdefault{LGR}}\n" + "\\DeclareRobustCommand{\\textgreek}[1]{\\leavevmode{\\greektext #1}}\n" + "\\DeclareFontEncoding{LGR}{}{}\n"; + +static string const textcyr_def = + "\\DeclareRobustCommand{\\cyrtext}{%\n" + " \\fontencoding{T2A}\\selectfont\n" + " \\def\\encodingdefault{T2A}}\n" + "\\DeclareRobustCommand{\\textcyr}[1]{\\leavevmode{\\cyrtext #1}}\n" + "\\DeclareFontEncoding{T2A}{}{}\n"; + +static string const newlyxcommand_def = + "%% Math macros with multiple optional parameters\n" + "% #1<-\\foo\n" + "\\def\\newlyxcommand#1{\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@arity{#1}}\n" + " {\\newlyxcommand@arity{#1}[0]}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-arity\n" + "\\def\\newlyxcommand@arity#1[#2]{\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@firstopt{#1}{}{#2}}\n" + " {\\newlyxcommand@def#1{#2}}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-iii #3<-arity #4<-default value for (#2+1)th argument\n" + "\\def\\newlyxcommand@firstopt#1#2#3[#4]{\n" + " % ##1<-\\foo@\n" + " \\def\\@defclause##1{\n" + " \\def#1{\n" + " \\@ifnextchar[%]\n" + " {##1{}{#4}}\n" + " {##1{}{#4}[#4]}}\n" + " }\n" + " \\expandafter\\@defclause\\csname\\expandafter\\@gobble\\string#1@\\endcsname\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@opt{#1}{#2}{#3}}\n" + " {\\newlyxcommand@last{#1}{#2}{#3}[#4]}\n" + "}\n" + "\n" + "\\begingroup\n" + "\\catcode`\\Q=3\n" + "\\gdef\\@myempty{Q}\n" + "\\endgroup\n" + "\n" + "% #1<-\\foo #2<-iii #3<-arity #4<-default value for (#2+1)th argument\n" + "\\def\\newlyxcommand@opt#1#2#3[#4]{\n" + " % ##1<-\\foo@iii ##2<-\\foo@iiii \n" + " % ####1<-{a}{b}{c} ####2<-default value ####3<- default arg\n" + " \\def\\@defclause##1##2{\n" + " \\def##1####1####2[####3]{\n" + " \\ifx\\@myempty####3\\@myempty%\n" + " \\def\\@callnext{\n" + " \\@ifnextchar[%]\n" + " {##2{####1{####2}}{#4}}\n" + " {##2{####1{####2}}{#4}[#4]}\n" + " }\n" + " \\else\n" + " \\def\\@callnext{\n" + " \\@ifnextchar[%]\n" + " {##2{####1{####3}}{#4}}\n" + " {##2{####1{####3}}{#4}[#4]}\n" + " }\n" + " \\fi\n" + " \\@callnext\n" + " }\n" + " }\n" + " \\expandafter\\def\\expandafter\\@clausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2\\endcsname}\n" + " \\expandafter\\def\\expandafter\\@nextclausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2i\\endcsname}\n" + " \\expandafter\\expandafter\\expandafter \n" + " \\@defclause\\expandafter\\@clausename\\@nextclausename\n" + " \\@ifnextchar[%]\n" + " {\\newlyxcommand@opt{#1}{#2i}{#3}}\n" + " {\\newlyxcommand@last{#1}{#2i}{#3}[#4]}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-iii #3<-arity #4<-default value for (#2+1)th argument\n" + "\\def\\newlyxcommand@last#1#2#3[#4]{\n" + " \\def\\@defclause##1##2{\n" + " \\def##1####1####2[####3]{\n" + " \\ifx\\@myempty####3\\@myempty%\n" + " \\def\\@callnext{##2####1{####2}}\n" + " \\else\n" + " \\def\\@callnext{##2####1{####3}}\n" + " \\fi\n" + " \\@callnext\n" + " }\n" + " }\n" + " \\expandafter\\def\\expandafter\\@clausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2\\endcsname}\n" + " \\expandafter\\def\\expandafter\\@nextclausename\\expandafter{\\csname\\expandafter\\@gobble\\string#1@#2i\\endcsname}\n" + " \\expandafter\\expandafter\\expandafter\n" + " \\@defclause\\expandafter\\@clausename\\@nextclausename\n" + " \\expandafter\\newlyxcommand@def\\csname\\expandafter\\@gobble\\string#1@#2i\\endcsname{#3}\n" + "}\n" + "\n" + "% #1<-\\foo #2<-arity #3<-definition\n" + "\\def\\newlyxcommand@def#1#2#3{\n" + " \\ifx#20\n" + " \\def#1{#3}\n" + " \\else\n" + " \\def\\@splitargs##1#2##2.{\\def#1##1#2}\\@splitargs##1##2##3##4##5##6##7##8##9.{#3}\n" + " \\fi\n" + "}\n"; + ///////////////////////////////////////////////////////////////////// // // LaTeXFeatures @@ -254,7 +353,7 @@ void LaTeXFeatures::getAvailable() } -void LaTeXFeatures::useLayout(string const & layoutname) +void LaTeXFeatures::useLayout(docstring const & layoutname) { // Some code to avoid loops in dependency definition static int level = 0; @@ -262,21 +361,21 @@ void LaTeXFeatures::useLayout(string const & layoutname) if (level > maxlevel) { lyxerr << "LaTeXFeatures::useLayout: maximum level of " << "recursion attained by layout " - << layoutname << endl; + << to_utf8(layoutname) << endl; return; } TextClass const & tclass = params_.getTextClass(); if (tclass.hasLayout(layoutname)) { // Is this layout already in usedLayouts? - list::const_iterator cit = usedLayouts_.begin(); - list::const_iterator end = usedLayouts_.end(); + list::const_iterator cit = usedLayouts_.begin(); + list::const_iterator end = usedLayouts_.end(); for (; cit != end; ++cit) { if (layoutname == *cit) return; } - Layout_ptr const & lyt = tclass[layoutname]; + LayoutPtr const & lyt = tclass[layoutname]; if (!lyt->depends_on().empty()) { ++level; useLayout(lyt->depends_on()); @@ -285,7 +384,7 @@ void LaTeXFeatures::useLayout(string const & layoutname) usedLayouts_.push_back(layoutname); } else { lyxerr << "LaTeXFeatures::useLayout: layout `" - << layoutname << "' does not exist in this class" + << to_utf8(layoutname) << "' does not exist in this class" << endl; } @@ -307,9 +406,13 @@ bool LaTeXFeatures::mustProvide(string const & name) const bool LaTeXFeatures::isAvailable(string const & name) { + string n = name; if (packages_.empty()) getAvailable(); - return find(packages_.begin(), packages_.end(), name) != packages_.end(); + size_t loc = n.rfind(".sty"); + if (loc == n.length() - 4) + n = n.erase(name.length() - 4); + return find(packages_.begin(), packages_.end(), n) != packages_.end(); } @@ -339,6 +442,10 @@ void LaTeXFeatures::useLanguage(Language const * lang) { if (!lang->babel().empty()) UsedLanguages_.insert(lang); + // CJK languages do not have a babel name. + // They use the CJK package + if (lang->encoding()->package() == Encoding::CJK) + require("CJK"); } @@ -396,21 +503,24 @@ char const * simplefeatures[] = { "latexsym", "pifont", "subfigure", - "floatflt", "varioref", "prettyref", + /*For a successful cooperation of the `wrapfig' package with the + `float' package you should load the `wrapfig' package *after* + the `float' package. See the caption package documentation + for explanation.*/ "float", + "rotfloat", + "wrapfig", "booktabs", "dvipost", "fancybox", "calc", - "nicefrac", + "units", "tipa", "framed", - "pdfcolmk", "soul", "textcomp", - "xcolor", "pmboxdraw", "bbding", "ifsym", @@ -418,6 +528,13 @@ char const * simplefeatures[] = { "txfonts", "mathrsfs", "ascii", + "url", + "covington", + "csquotes", + "enumitem", + "endnotes", + "ifthen", + "amsthm" }; int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *); @@ -430,6 +547,12 @@ string const LaTeXFeatures::getPackages() const ostringstream packages; TextClass const & tclass = params_.getTextClass(); + // FIXME: currently, we can only load packages and macros known + // to LyX. + // However, with the Require tag of layouts/custom insets, + // also inknown packages can be requested. They are silently + // swallowed now. We should change this eventually. + // // These are all the 'simple' includes. i.e // packages which we just \usepackage{package} @@ -445,11 +568,14 @@ string const LaTeXFeatures::getPackages() const // than those above. // - if (mustProvide("amsmath") - && params_.use_amsmath != BufferParams::package_off) { + // esint is preferred for esintoramsmath + if ((mustProvide("amsmath") && + params_.use_amsmath != BufferParams::package_off) || + (mustProvide("esintoramsmath") && + params_.use_esint == BufferParams::package_off)) { packages << "\\usepackage{amsmath}\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 @@ -462,14 +588,21 @@ string const LaTeXFeatures::getPackages() const (params_.use_esint != BufferParams::package_off || !isRequired("esint"))) packages << "\\usepackage{wasysym}\n"; - // color.sty - if (mustProvide("color")) { + // [x]color.sty + if (mustProvide("color") || mustProvide("xcolor")) { + string const package = + (mustProvide("xcolor") ? "xcolor" : "color"); if (params_.graphicsDriver == "default") - packages << "\\usepackage{color}\n"; + packages << "\\usepackage{" << package << "}\n"; else packages << "\\usepackage[" << params_.graphicsDriver - << "]{color}\n"; + << "]{" << package << "}\n"; + } + + // pdfcolmk must be loaded after color + if (mustProvide("pdfcolmk")) { + packages << "\\usepackage{pdfcolmk}\n"; } // makeidx.sty @@ -489,8 +622,8 @@ string const LaTeXFeatures::getPackages() const << "]{graphicx}\n"; } // shadecolor for shaded - if (mustProvide("framed") && mustProvide("color")) { - RGBColor c = RGBColor(lcolor.getX11Name(Color::shadedbg)); + if (isRequired("framed") && mustProvide("color")) { + RGBColor c = rgbFromHexName(lcolor.getX11Name(Color_shadedbg)); //255.0 to force conversion to double //NOTE As Jürgen Spitzmüller pointed out, an alternative would be //to use the xcolor package instead, and then we can do @@ -509,11 +642,13 @@ string const LaTeXFeatures::getPackages() const } // setspace.sty - if ((params_.spacing().getSpace() != Spacing::Single - && !params_.spacing().isDefault()) - || isRequired("setspace")) { - packages << "\\usepackage{setspace}\n"; + if ((isRequired("setspace") + || ((params_.spacing().getSpace() != Spacing::Single + && !params_.spacing().isDefault()))) + && !tclass.provides("SetSpace")) { + packages << "\\usepackage{setspace}\n"; } + bool const upcase = tclass.provides("SetSpace"); switch (params_.spacing().getSpace()) { case Spacing::Default: case Spacing::Single: @@ -521,13 +656,13 @@ string const LaTeXFeatures::getPackages() const //packages += "\\singlespacing\n"; break; case Spacing::Onehalf: - packages << "\\onehalfspacing\n"; + packages << (upcase ? "\\OnehalfSpacing\n" : "\\onehalfspacing\n"); break; case Spacing::Double: - packages << "\\doublespacing\n"; + packages << (upcase ? "\\DoubleSpacing\n" : "\\doublespacing\n"); break; case Spacing::Other: - packages << "\\setstretch{" + packages << (upcase ? "\\setSingleSpace{" : "\\setstretch{") << params_.spacing().getValue() << "}\n"; break; } @@ -539,15 +674,10 @@ string const LaTeXFeatures::getPackages() const // esint must be after amsmath and wasysym, since it will redeclare // inconsistent integral symbols - if (mustProvide("esint") - && params_.use_esint != BufferParams::package_off) + if ((mustProvide("esint") || mustProvide("esintoramsmath")) && + params_.use_esint != BufferParams::package_off) packages << "\\usepackage{esint}\n"; - // url.sty - if (mustProvide("url")) - packages << "\\IfFileExists{url.sty}{\\usepackage{url}}\n" - " {\\newcommand{\\url}{\\texttt}}\n"; - // natbib.sty if (mustProvide("natbib")) { packages << "\\usepackage["; @@ -599,9 +729,8 @@ string const LaTeXFeatures::getMacros() const macros << '\n'; FeaturesList::const_iterator pit = preamble_snippets_.begin(); FeaturesList::const_iterator pend = preamble_snippets_.end(); - for (; pit != pend; ++pit) { + for (; pit != pend; ++pit) macros << *pit << '\n'; - } if (mustProvide("LyX")) macros << lyx_def << '\n'; @@ -615,6 +744,12 @@ string const LaTeXFeatures::getMacros() const if (mustProvide("lyxarrow")) macros << lyxarrow_def << '\n'; + if (mustProvide("textgreek")) + macros << textgreek_def << '\n'; + + if (mustProvide("textcyr")) + macros << textcyr_def << '\n'; + // quotes. if (mustProvide("quotesinglbase")) macros << quotesinglbase_def << '\n'; @@ -636,6 +771,8 @@ string const LaTeXFeatures::getMacros() const macros << binom_def << '\n'; if (mustProvide("mathcircumflex")) macros << mathcircumflex_def << '\n'; + if (mustProvide("newlyxcommand")) + macros << newlyxcommand_def << '\n'; // other if (mustProvide("ParagraphLeftIndent")) @@ -658,17 +795,17 @@ string const LaTeXFeatures::getMacros() const getFloatDefinitions(macros); // change tracking - if (mustProvide("ct-dvipost")) { + if (mustProvide("ct-dvipost")) macros << changetracking_dvipost_def; - } + if (mustProvide("ct-xcolor-soul")) { int const prec = macros.precision(2); - RGBColor cadd = RGBColor(lcolor.getX11Name(Color::addedtext)); + RGBColor cadd = rgbFromHexName(lcolor.getX11Name(Color_addedtext)); macros << "\\providecolor{lyxadded}{rgb}{" << cadd.r / 255.0 << ',' << cadd.g / 255.0 << ',' << cadd.b / 255.0 << "}\n"; - RGBColor cdel = RGBColor(lcolor.getX11Name(Color::deletedtext)); + RGBColor cdel = rgbFromHexName(lcolor.getX11Name(Color_deletedtext)); macros << "\\providecolor{lyxdeleted}{rgb}{" << cdel.r / 255.0 << ',' << cdel.g / 255.0 << ',' << cdel.b / 255.0 << "}\n"; @@ -677,9 +814,9 @@ string const LaTeXFeatures::getMacros() const macros << "\\newcommand{\\lyxadded}[3]{{\\color{lyxadded}#3}}\n" << "\\newcommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\st{#3}}}\n"; } - if (mustProvide("ct-none")) { + + if (mustProvide("ct-none")) macros << changetracking_none_def; - } return macros.str(); } @@ -709,19 +846,12 @@ docstring const LaTeXFeatures::getTClassPreamble() const tcpreamble << tclass.preamble(); - list::const_iterator cit = usedLayouts_.begin(); - list::const_iterator end = usedLayouts_.end(); + list::const_iterator cit = usedLayouts_.begin(); + list::const_iterator end = usedLayouts_.end(); for (; cit != end; ++cit) { tcpreamble << tclass[*cit]->preamble(); } - CharStyles::iterator cs = tclass.charstyles().begin(); - CharStyles::iterator csend = tclass.charstyles().end(); - for (; cs != csend; ++cs) { - if (isRequired(cs->name)) - tcpreamble << cs->preamble; - } - return tcpreamble.str(); }