X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeXFeatures.cpp;h=ecf02295f54f0ec5d1e3c1ee8e5e9bfc5289efd4;hb=6154a90fba843789b65d2a023c7f3cc7b72ef775;hp=72ce130ca0f1ab3bca5f01cfe74dcd6725742822;hpb=e0b4fc9da4f1a187e4d08607c0fb0ff402124b82;p=lyx.git diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index 72ce130ca0..ecf02295f5 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -18,7 +18,6 @@ #include "Color.h" #include "BufferParams.h" -#include "support/debug.h" #include "Encoding.h" #include "Floating.h" #include "FloatList.h" @@ -28,25 +27,17 @@ #include "LyXRC.h" #include "TextClass.h" +#include "support/debug.h" #include "support/docstream.h" +#include "support/FileName.h" #include "support/filetools.h" +#include "support/lstrings.h" -using std::endl; -using std::find; -using std::string; -using std::list; -using std::ostream; -using std::ostringstream; -using std::set; - +using namespace std; +using namespace lyx::support; namespace lyx { -using support::isSGMLFilename; -using support::libFileSearch; -using support::makeRelPath; -using support::onlyPath; - ///////////////////////////////////////////////////////////////////// // // Strings @@ -160,7 +151,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"; @@ -183,6 +174,16 @@ static string const changetracking_dvipost_def = "\\newcommand{\\lyxdeleted}[3]{%\n" "\\changestart\\overstrikeon#3\\overstrikeoff\\changeend}\n"; +static string const changetracking_xcolor_soul_def = + "%% Change tracking with soul\n" + "\\newcommand{\\lyxadded}[3]{{\\color{lyxadded}#3}}\n" + "\\newcommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\st{#3}}}\n"; + +static string const changetracking_xcolor_soul_hyperref_def = + "%% Change tracking with soul\n" + "\\newcommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}}{}#3}}\n" + "\\newcommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\st{#3}}{}}}\n"; + static string const changetracking_none_def = "\\newcommand{\\lyxadded}[3]{#3}\n" "\\newcommand{\\lyxdeleted}[3]{}\n"; @@ -201,14 +202,108 @@ static string const textcyr_def = "\\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 // ///////////////////////////////////////////////////////////////////// -LaTeXFeatures::PackagesList LaTeXFeatures::packages_; +LaTeXFeatures::Packages LaTeXFeatures::packages_; LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p, @@ -228,10 +323,13 @@ bool LaTeXFeatures::useBabel() const void LaTeXFeatures::require(string const & name) { - if (isRequired(name)) - return; + features_.insert(name); +} + - features_.push_back(name); +void LaTeXFeatures::require(set const & names) +{ + features_.insert(names.begin(), names.end()); } @@ -259,11 +357,7 @@ void LaTeXFeatures::getAvailable() finished = true; break; default: - string const name = lex.getString(); - PackagesList::const_iterator begin = packages_.begin(); - PackagesList::const_iterator end = packages_.end(); - if (find(begin, end, name) == end) - packages_.push_back(name); + packages_.insert(lex.getString()); } } } @@ -284,17 +378,16 @@ void LaTeXFeatures::useLayout(docstring const & layoutname) 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(); - for (; cit != end; ++cit) { - if (layoutname == *cit) - return; - } + if (find(usedLayouts_.begin(), usedLayouts_.end(), layoutname) + != usedLayouts_.end()) + return; - LayoutPtr const & lyt = tclass[layoutname]; - if (!lyt->depends_on().empty()) { + Layout const & layout = *tclass[layoutname]; + require(layout.requires()); + + if (!layout.depends_on().empty()) { ++level; - useLayout(lyt->depends_on()); + useLayout(layout.depends_on()); --level; } usedLayouts_.push_back(layoutname); @@ -310,7 +403,7 @@ void LaTeXFeatures::useLayout(docstring const & layoutname) bool LaTeXFeatures::isRequired(string const & name) const { - return find(features_.begin(), features_.end(), name) != features_.end(); + return features_.find(name) != features_.end(); } @@ -324,14 +417,17 @@ bool LaTeXFeatures::isAvailable(string const & name) { if (packages_.empty()) getAvailable(); - return find(packages_.begin(), packages_.end(), name) != packages_.end(); + string n = name; + if (suffixIs(n, ".sty")) + n.erase(name.length() - 4); + return packages_.find(n) != packages_.end(); } void LaTeXFeatures::addPreambleSnippet(string const & preamble) { - FeaturesList::const_iterator begin = preamble_snippets_.begin(); - FeaturesList::const_iterator end = preamble_snippets_.end(); + SnippetList::const_iterator begin = preamble_snippets_.begin(); + SnippetList::const_iterator end = preamble_snippets_.end(); if (find(begin, end, preamble) == end) preamble_snippets_.push_back(preamble); } @@ -422,6 +518,7 @@ char const * simplefeatures[] = { the `float' package. See the caption package documentation for explanation.*/ "float", + "rotfloat", "wrapfig", "booktabs", "dvipost", @@ -430,10 +527,8 @@ char const * simplefeatures[] = { "units", "tipa", "framed", - "pdfcolmk", "soul", "textcomp", - "xcolor", "pmboxdraw", "bbding", "ifsym", @@ -442,6 +537,13 @@ char const * simplefeatures[] = { "mathrsfs", "ascii", "url", + "covington", + "csquotes", + "enumitem", + "endnotes", + "ifthen", + "amsthm", + "listings" }; int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *); @@ -454,6 +556,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} @@ -476,7 +584,7 @@ string const LaTeXFeatures::getPackages() const 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 @@ -489,14 +597,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 @@ -536,28 +651,8 @@ string const LaTeXFeatures::getPackages() const } // setspace.sty - if ((params_.spacing().getSpace() != Spacing::Single - && !params_.spacing().isDefault()) - || isRequired("setspace")) { - packages << "\\usepackage{setspace}\n"; - } - switch (params_.spacing().getSpace()) { - case Spacing::Default: - case Spacing::Single: - // we dont use setspace.sty so dont print anything - //packages += "\\singlespacing\n"; - break; - case Spacing::Onehalf: - packages << "\\onehalfspacing\n"; - break; - case Spacing::Double: - packages << "\\doublespacing\n"; - break; - case Spacing::Other: - packages << "\\setstretch{" - << params_.spacing().getValue() << "}\n"; - break; - } + if (mustProvide("setspace") && !tclass.provides("SetSpace")) + packages << "\\usepackage{setspace}\n"; // amssymb.sty if (mustProvide("amssymb") @@ -606,9 +701,6 @@ string const LaTeXFeatures::getPackages() const "\\makenomenclature\n"; } - if (mustProvide("listings")) - packages << "\\usepackage{listings}\n"; - return packages.str(); } @@ -619,8 +711,8 @@ string const LaTeXFeatures::getMacros() const if (!preamble_snippets_.empty()) macros << '\n'; - FeaturesList::const_iterator pit = preamble_snippets_.begin(); - FeaturesList::const_iterator pend = preamble_snippets_.end(); + SnippetList::const_iterator pit = preamble_snippets_.begin(); + SnippetList::const_iterator pend = preamble_snippets_.end(); for (; pit != pend; ++pit) macros << *pit << '\n'; @@ -663,6 +755,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")) @@ -700,9 +794,11 @@ string const LaTeXFeatures::getMacros() const << cdel.r / 255.0 << ',' << cdel.g / 255.0 << ',' << cdel.b / 255.0 << "}\n"; macros.precision(prec); - - macros << "\\newcommand{\\lyxadded}[3]{{\\color{lyxadded}#3}}\n" - << "\\newcommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\st{#3}}}\n"; + + if (isRequired("hyperref")) + macros << changetracking_xcolor_soul_hyperref_def; + else + macros << changetracking_xcolor_soul_def; } if (mustProvide("ct-none")) @@ -742,15 +838,6 @@ docstring const LaTeXFeatures::getTClassPreamble() const tcpreamble << tclass[*cit]->preamble(); } - InsetLayouts const & insetlayouts = tclass.insetlayouts(); - InsetLayouts::const_iterator cit2 = insetlayouts.begin(); - InsetLayouts::const_iterator end2 = insetlayouts.end(); - for (; cit2 != end2; ++cit2) { - if (isRequired(to_utf8(cit2->first))) { - tcpreamble << from_utf8(cit2->second.preamble); - } - } - return tcpreamble.str(); }