Implement Provides tag to LaTeXFonts

This allows to suppress conflicting packages, such as amssymb with mathdesign.
This commit is contained in:
Juergen Spitzmueller 2012-09-19 15:46:19 +02:00
parent 4517c6f9a5
commit f4261030e2
6 changed files with 55 additions and 17 deletions

View File

@ -18,6 +18,7 @@
# ScOption <option for true smallcaps support> # ScOption <option for true smallcaps support>
# OsfScOption <option for combined osf and true smallcaps support> # OsfScOption <option for combined osf and true smallcaps support>
# ScaleOption <option for font scaling> # ScaleOption <option for font scaling>
# Provides <features provided by the font packages (comma-separated)>
# EndFont # EndFont
# #
# #
@ -127,6 +128,7 @@ Font mdbch
Package mathdesign Package mathdesign
PackageOption charter PackageOption charter
Requires mdbch Requires mdbch
Provides amssymb,amsfonts
EndFont EndFont
Font mdput Font mdput
@ -138,6 +140,7 @@ Font mdput
Package mathdesign Package mathdesign
PackageOption utopia PackageOption utopia
Requires mdput Requires mdput
Provides amssymb,amsfonts
EndFont EndFont
Font mdugm Font mdugm
@ -149,6 +152,7 @@ Font mdugm
Package mathdesign Package mathdesign
PackageOption garamond PackageOption garamond
Requires mdugm Requires mdugm
Provides amssymb,amsfonts
EndFont EndFont
Font newcent Font newcent

View File

@ -1204,7 +1204,7 @@ void BufferParams::validate(LaTeXFeatures & features) const
if (it->first == "amsmath") { if (it->first == "amsmath") {
// AMS Style is at document level // AMS Style is at document level
if (it->second == package_on || if (it->second == package_on ||
documentClass().provides("amsmath")) features.isProvided("amsmath"))
features.require(it->first); features.require(it->first);
} else if (it->second == package_on) } else if (it->second == package_on)
features.require(it->first); features.require(it->first);
@ -1372,7 +1372,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
features.useLanguage(default_language); features.useLanguage(default_language);
ostringstream language_options; ostringstream language_options;
bool const use_babel = features.useBabel() && !tclass.provides("babel"); bool const use_babel = features.useBabel() && !features.isProvided("babel");
bool const use_polyglossia = features.usePolyglossia(); bool const use_polyglossia = features.usePolyglossia();
bool const global = lyxrc.language_global_options; bool const global = lyxrc.language_global_options;
if (use_babel || (use_polyglossia && global)) { if (use_babel || (use_polyglossia && global)) {
@ -1432,7 +1432,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
// LFE encoding // LFE encoding
// XeTeX and LuaTeX (with OS fonts) work without fontenc // XeTeX and LuaTeX (with OS fonts) work without fontenc
if (font_encoding() != "default" && language->lang() != "japanese" if (font_encoding() != "default" && language->lang() != "japanese"
&& !useNonTeXFonts && !tclass.provides("fontenc")) { && !useNonTeXFonts && !features.isProvided("fontenc")) {
size_t fars = language_options.str().find("farsi"); size_t fars = language_options.str().find("farsi");
size_t arab = language_options.str().find("arabic"); size_t arab = language_options.str().find("arabic");
if (language->lang() == "arabic_arabi" if (language->lang() == "arabic_arabi"
@ -1490,7 +1490,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
os << from_utf8(par) os << from_utf8(par)
<< "}\n"; << "}\n";
} }
if (!tclass.provides("geometry") if (!features.isProvided("geometry")
&& (use_geometry || nonstandard_papersize)) { && (use_geometry || nonstandard_papersize)) {
odocstringstream ods; odocstringstream ods;
if (!getGraphicsDriver("geometry").empty()) if (!getGraphicsDriver("geometry").empty())
@ -1765,7 +1765,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
} }
// Line spacing // Line spacing
lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace"))); lyxpreamble += from_utf8(spacing().writePreamble(features.isProvided("SetSpace")));
// PDF support. // PDF support.
// * Hyperref manual: "Make sure it comes last of your loaded // * Hyperref manual: "Make sure it comes last of your loaded
@ -1783,7 +1783,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
OutputParams tmp_params = features.runparams(); OutputParams tmp_params = features.runparams();
pdfoptions().writeLaTeX(tmp_params, os, pdfoptions().writeLaTeX(tmp_params, os,
documentClass().provides("hyperref")); features.isProvided("hyperref"));
// set back for the rest // set back for the rest
lyxpreamble.clear(); lyxpreamble.clear();
// correctly break URLs with hyperref and dvi output // correctly break URLs with hyperref and dvi output

View File

@ -24,6 +24,7 @@
#include "Floating.h" #include "Floating.h"
#include "FloatList.h" #include "FloatList.h"
#include "Language.h" #include "Language.h"
#include "LaTeXFonts.h"
#include "LaTeXPackages.h" #include "LaTeXPackages.h"
#include "Layout.h" #include "Layout.h"
#include "Lexer.h" #include "Lexer.h"
@ -317,7 +318,7 @@ LaTeXFeatures::LangPackage LaTeXFeatures::langPackage(bool englishbabel) const
bool const polyglossia_required = bool const polyglossia_required =
isRequired("polyglossia") isRequired("polyglossia")
&& isAvailable("polyglossia") && isAvailable("polyglossia")
&& !params_.documentClass().provides("babel") && !isProvided("babel")
&& this->hasOnlyPolyglossiaLanguages(); && this->hasOnlyPolyglossiaLanguages();
bool const babel_required = bool const babel_required =
((englishbabel || bufferParams().language->lang() != "english") ((englishbabel || bufferParams().language->lang() != "english")
@ -435,9 +436,17 @@ bool LaTeXFeatures::isRequired(string const & name) const
} }
bool LaTeXFeatures::isProvided(string const & name) const
{
return params_.documentClass().provides(name)
|| theLaTeXFonts().getLaTeXFont(from_ascii(params_.fonts_roman)).provides(name)
|| theLaTeXFonts().getLaTeXFont(from_ascii(params_.fonts_sans)).provides(name)
|| theLaTeXFonts().getLaTeXFont(from_ascii(params_.fonts_typewriter)).provides(name);
}
bool LaTeXFeatures::mustProvide(string const & name) const bool LaTeXFeatures::mustProvide(string const & name) const
{ {
return isRequired(name) && !params_.documentClass().provides(name); return isRequired(name) && !isProvided(name);
} }
@ -721,7 +730,6 @@ string const LaTeXFeatures::getColorOptions() const
string const LaTeXFeatures::getPackages() const string const LaTeXFeatures::getPackages() const
{ {
ostringstream packages; ostringstream packages;
DocumentClass const & tclass = params_.documentClass();
// FIXME: currently, we can only load packages and macros known // FIXME: currently, we can only load packages and macros known
// to LyX. // to LyX.
@ -792,9 +800,9 @@ string const LaTeXFeatures::getPackages() const
// makeidx.sty // makeidx.sty
if (isRequired("makeidx") || isRequired("splitidx")) { if (isRequired("makeidx") || isRequired("splitidx")) {
if (!tclass.provides("makeidx") && !isRequired("splitidx")) if (!isProvided("makeidx") && !isRequired("splitidx"))
packages << "\\usepackage{makeidx}\n"; packages << "\\usepackage{makeidx}\n";
if (!tclass.provides("splitidx") && isRequired("splitidx")) if (mustProvide("splitidx"))
packages << "\\usepackage{splitidx}\n"; packages << "\\usepackage{splitidx}\n";
packages << "\\makeindex\n"; packages << "\\makeindex\n";
} }
@ -814,7 +822,7 @@ string const LaTeXFeatures::getPackages() const
packages << "\\usepackage[ps,mover]{lyxskak}\n"; packages << "\\usepackage[ps,mover]{lyxskak}\n";
// setspace.sty // setspace.sty
if (mustProvide("setspace") && !tclass.provides("SetSpace")) if (mustProvide("setspace") && !isProvided("SetSpace"))
packages << "\\usepackage{setspace}\n"; packages << "\\usepackage{setspace}\n";
// esint must be after amsmath and wasysym, since it will redeclare // esint must be after amsmath and wasysym, since it will redeclare
@ -827,7 +835,7 @@ string const LaTeXFeatures::getPackages() const
// Some classes load natbib themselves, but still allow (or even require) // Some classes load natbib themselves, but still allow (or even require)
// plain numeric citations (ReVTeX is such a case, see bug 5182). // plain numeric citations (ReVTeX is such a case, see bug 5182).
// This special case is indicated by the "natbib-internal" key. // 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["; packages << "\\usepackage[";
if (params_.citeEngineType() == ENGINE_TYPE_NUMERICAL) if (params_.citeEngineType() == ENGINE_TYPE_NUMERICAL)
packages << "numbers"; packages << "numbers";

View File

@ -101,9 +101,12 @@ public:
static bool isAvailable(std::string const & name); static bool isAvailable(std::string const & name);
/// Has the package been required? /// Has the package been required?
bool isRequired(std::string const & name) const; bool isRequired(std::string const & name) const;
/** Is this feature already provided
* e.g. by the document class?
*/
bool isProvided(std::string const & name) const;
/** Is it necessary to load the package? This is true if /** Is it necessary to load the package? This is true if
isRequired is true and the feature is not provided by the isRequired is true and the feature is not already provided
textclass.
*/ */
bool mustProvide(std::string const & name) const; bool mustProvide(std::string const & name) const;
/// ///

View File

@ -78,6 +78,17 @@ bool LaTeXFont::providesScale(bool ot1) const
return (!scaleoption_.empty()); return (!scaleoption_.empty());
} }
bool LaTeXFont::provides(std::string const & name) const
{
if (provides_.empty())
return false;
for (size_t i = 0; i < provides_.size(); ++i) {
if (provides_[i] == name)
return true;
}
return false;
}
string const LaTeXFont::getAvailablePackage(bool dryrun, bool ot1, bool complete, bool & alt) string const LaTeXFont::getAvailablePackage(bool dryrun, bool ot1, bool complete, bool & alt)
{ {
@ -206,6 +217,7 @@ bool LaTeXFont::readFont(Lexer & lex)
LF_OT1_PACKAGE, LF_OT1_PACKAGE,
LF_PACKAGE, LF_PACKAGE,
LF_PACKAGEOPTION, LF_PACKAGEOPTION,
LF_PROVIDES,
LF_REQUIRES, LF_REQUIRES,
LF_SCALEOPTION, LF_SCALEOPTION,
LF_SCOPTION, LF_SCOPTION,
@ -225,6 +237,7 @@ bool LaTeXFont::readFont(Lexer & lex)
{ "ot1package", LF_OT1_PACKAGE }, { "ot1package", LF_OT1_PACKAGE },
{ "package", LF_PACKAGE }, { "package", LF_PACKAGE },
{ "packageoption", LF_PACKAGEOPTION }, { "packageoption", LF_PACKAGEOPTION },
{ "provides", LF_PROVIDES },
{ "requires", LF_REQUIRES }, { "requires", LF_REQUIRES },
{ "scaleoption", LF_SCALEOPTION }, { "scaleoption", LF_SCALEOPTION },
{ "scoption", LF_SCOPTION }, { "scoption", LF_SCOPTION },
@ -255,8 +268,8 @@ bool LaTeXFont::readFont(Lexer & lex)
finished = true; finished = true;
break; break;
case LF_ALT_PACKAGES: { case LF_ALT_PACKAGES: {
docstring altp; lex.eatLine();
lex >> altp; docstring altp = lex.getDocString();
altpackages_ = getVectorFromString(altp); altpackages_ = getVectorFromString(altp);
break; break;
} }
@ -287,6 +300,12 @@ bool LaTeXFont::readFont(Lexer & lex)
case LF_PACKAGEOPTION: case LF_PACKAGEOPTION:
lex >> packageoption_; lex >> packageoption_;
break; break;
case LF_PROVIDES: {
lex.eatLine();
string features = lex.getString();
provides_ = getVectorFromString(features);
break;
}
case LF_REQUIRES: case LF_REQUIRES:
lex >> requires_; lex >> requires_;
break; break;

View File

@ -55,6 +55,8 @@ public:
docstring const & scaleoption() { return scaleoption_; } docstring const & scaleoption() { return scaleoption_; }
/// Alternative requirement to test for /// Alternative requirement to test for
docstring const & requires() { return requires_; } docstring const & requires() { return requires_; }
/// Does this font provide a given \p feature
bool provides(std::string const & name) const;
/// Issue the familydefault switch /// Issue the familydefault switch
bool switchdefault() const { return switchdefault_; } bool switchdefault() const { return switchdefault_; }
/// Is this font available? /// Is this font available?
@ -111,6 +113,8 @@ private:
/// ///
docstring scaleoption_; docstring scaleoption_;
/// ///
std::vector<std::string> provides_;
///
docstring requires_; docstring requires_;
/// ///
bool switchdefault_; bool switchdefault_;