3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Jürgen Spitzmüller
8 * Full author contact details are available in file CREDITS.
13 #include "LaTeXFonts.h"
15 #include "LaTeXFeatures.h"
18 #include "frontends/alert.h"
20 #include "support/convert.h"
21 #include "support/debug.h"
22 #include "support/FileName.h"
23 #include "support/filetools.h"
24 #include "support/gettext.h"
25 #include "support/lstrings.h"
29 using namespace lyx::support;
34 LaTeXFonts latexfonts;
37 bool LaTeXFont::available(bool ot1) const
39 return ot1 ? available_ot1_ : available_;
43 bool LaTeXFont::providesOSF(bool ot1) const
45 if (!osfpackage_.empty())
46 return LaTeXFeatures::isAvailable(to_ascii(osfpackage_));
48 if (ot1 && !ot1package_.empty() && ot1package_ != "none")
51 if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_)))
54 return (!osfoption_.empty() || !osfscoption_.empty());
58 bool LaTeXFont::providesSC(bool ot1) const
60 if (ot1 && !ot1package_.empty() && ot1package_ != "none")
63 if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_)))
66 return (!scoption_.empty() || !osfscoption_.empty());
70 bool LaTeXFont::providesScale(bool ot1) const
72 if (ot1 && !ot1package_.empty() && ot1package_ != "none")
75 if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_)))
78 return (!scaleoption_.empty());
82 string const LaTeXFont::getAvailablePackage(bool dryrun, bool ot1, bool complete)
84 if (ot1 && !ot1package_.empty()) {
85 if (ot1package_ != "none"
86 && (LaTeXFeatures::isAvailable(to_ascii(ot1package_)) || dryrun))
87 return to_ascii(ot1package_);
88 if (!dryrun && ot1package_ != "none")
89 frontend::Alert::warning(_("Font not available"),
90 bformat(_("The LaTeX package `%1$s' needed for the font `%2$s'\n"
91 "is not available on your system. LyX will fall back to the default font."),
92 ot1package_, guiname_), true);
95 if (complete && !completepackage_.empty()) {
96 if (LaTeXFeatures::isAvailable(to_ascii(completepackage_)) || dryrun)
97 return to_ascii(completepackage_);
99 if (!package_.empty()) {
100 if (!requires_.empty() && LaTeXFeatures::isAvailable(to_ascii(requires_)))
101 return to_ascii(package_);
102 if (LaTeXFeatures::isAvailable(to_ascii(package_)))
103 return to_ascii(package_);
104 else if (!altpackages_.empty()) {
105 for (size_t i = 0; i < altpackages_.size(); ++i) {
106 if (LaTeXFeatures::isAvailable(to_ascii(altpackages_[i])))
107 return to_ascii(altpackages_[i]);
110 // Output unavailable packages in source preview
112 return to_ascii(package_);
113 docstring const req = requires_.empty() ? package_ : requires_;
114 frontend::Alert::warning(_("Font not available"),
115 bformat(_("The LaTeX package `%1$s' needed for the font `%2$s'\n"
116 "is not available on your system. LyX will fall back to the default font."),
117 req, guiname_), true);
123 string const LaTeXFont::getPackageOptions(bool const & ot1, bool const & sc,
124 bool const & osf, int const & scale)
126 if (ot1 && !ot1package_.empty())
130 if (sc && osf && providesOSF() && providesSC()) {
131 if (!osfscoption_.empty())
132 os << to_ascii(osfscoption_);
134 os << to_ascii(osfoption_) << ',' << to_ascii(scoption_);
135 } else if (osf && providesOSF())
136 os << to_ascii(osfoption_);
137 else if (sc && providesSC())
138 os << to_ascii(scoption_);
139 if (scale != 100 && !scaleoption_.empty()) {
140 if (!os.str().empty())
142 os << subst(to_ascii(scaleoption_), "$$val",
143 convert<std::string>(float(scale) / 100));
149 bool LaTeXFont::readFont(Lexer & lex)
168 // Keep these sorted alphabetically!
169 LexerKeyword latexFontTags[] = {
170 { "altpackages", LF_ALT_PACKAGES },
171 { "completepackage", LF_COMPLETE_PACKAGE },
172 { "endfont", LF_END },
173 { "family", LF_FAMILY },
174 { "guiname", LF_GUINAME },
175 { "osfoption", LF_OSFOPTION },
176 { "osfpackage", LF_OSFPACKAGE },
177 { "osfscoption", LF_OSFSCOPTION },
178 { "ot1package", LF_OT1_PACKAGE },
179 { "package", LF_PACKAGE },
180 { "requires", LF_REQUIRES },
181 { "scaleoption", LF_SCALEOPTION },
182 { "scoption", LF_SCOPTION },
183 { "switchdefault", LF_SWITCHDEFAULT }
187 bool finished = false;
188 lex.pushTable(latexFontTags);
189 // parse style section
190 while (!finished && lex.isOK() && !error) {
192 // See comment in LyXRC.cpp.
194 case Lexer::LEX_FEOF:
197 case Lexer::LEX_UNDEF: // parse error
198 lex.printError("Unknown LaTeXFont tag `$$Token'");
205 switch (static_cast<LaTeXFontTags>(le)) {
206 case LF_END: // end of structure
209 case LF_ALT_PACKAGES: {
212 altpackages_ = getVectorFromString(altp);
215 case LF_COMPLETE_PACKAGE:
216 lex >> completepackage_;
248 case LF_SWITCHDEFAULT:
249 lex >> switchdefault_;
254 lex.printError("No End tag found for LaTeXFont tag `$$Token'");
258 return finished && !error;
262 bool LaTeXFont::read(Lexer & lex)
267 lex.printError("No name given for LaTeX font: `$$Token'.");
271 name_ = lex.getDocString();
272 LYXERR(Debug::INFO, "Reading LaTeX font " << name_);
273 if (!readFont(lex)) {
274 LYXERR0("Error parsing LaTeX font `" << name_ << '\'');
278 bool available = true;
279 if (!requires_.empty())
280 available = LaTeXFeatures::isAvailable(to_ascii(requires_));
281 else if (!package_.empty()) {
282 available = LaTeXFeatures::isAvailable(to_ascii(package_));
283 if (!available && !altpackages_.empty()) {
284 for (size_t i = 0; i < altpackages_.size(); ++i) {
285 available = LaTeXFeatures::isAvailable(to_ascii(altpackages_[i]));
291 available_ = available;
293 if (!ot1package_.empty() && ot1package_ != "none")
294 available_ot1_ = LaTeXFeatures::isAvailable(to_ascii(ot1package_));
296 available_ot1_ = available;
302 void LaTeXFonts::readLaTeXFonts()
304 // Read latexfonts file
305 FileName filename = libFileSearch(string(), "latexfonts");
306 if (filename.empty()) {
307 LYXERR0("Error: latexfonts file not found!");
311 lex.setFile(filename);
312 lex.setContext("LaTeXFeatures::readLaTeXFonts");
316 case Lexer::LEX_FEOF:
322 if (lex.getString() != "Font") {
323 lex.printError("Unknown LaTeXFont tag `$$Token'");
331 texfontmap_[f.name()] = f;
336 LaTeXFonts::TexFontMap LaTeXFonts::getLaTeXFonts()
338 if (texfontmap_.empty())
344 LaTeXFont LaTeXFonts::getLaTeXFont(docstring const & name)
346 if (texfontmap_.empty())
348 return texfontmap_[name];