]> git.lyx.org Git - lyx.git/blob - src/LaTeXFonts.cpp
8d18a04f6bad8baa2ef23b8497d3bea664959e5f
[lyx.git] / src / LaTeXFonts.cpp
1 /**
2  * \file LaTeXFonts.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Spitzmüller
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "LaTeXFonts.h"
14
15 #include "LaTeXFeatures.h"
16 #include "Lexer.h"
17
18 #include "support/convert.h"
19 #include "support/debug.h"
20 #include "support/FileName.h"
21 #include "support/filetools.h"
22 #include "support/lstrings.h"
23
24
25 using namespace std;
26 using namespace lyx::support;
27
28
29 namespace lyx {
30
31 LaTeXFonts latexfonts;
32
33
34 bool LaTeXFont::available(bool ot1) const
35 {
36         return ot1 ? available_ot1_ : available_;
37 }
38
39
40 bool LaTeXFont::providesOSF(bool ot1) const
41 {
42         if (!osfpackage_.empty())
43                 return LaTeXFeatures::isAvailable(to_ascii(osfpackage_));
44
45         if (ot1 && !ot1package_.empty() && ot1package_ != "none")
46                 return false;
47
48         if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_)))
49                 return false;
50
51         return (!osfoption_.empty() || !osfscoption_.empty());
52 }
53
54
55 bool LaTeXFont::providesSC(bool ot1) const
56 {
57         if (ot1 && !ot1package_.empty() && ot1package_ != "none")
58                 return false;
59
60         if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_)))
61                 return false;
62
63         return (!scoption_.empty() || !osfscoption_.empty());
64 }
65
66
67 bool LaTeXFont::providesScale(bool ot1) const
68 {
69         if (ot1 && !ot1package_.empty() && ot1package_ != "none")
70                 return false;
71
72         if (!package_.empty() && !LaTeXFeatures::isAvailable(to_ascii(package_)))
73                 return false;
74
75         return (!scaleoption_.empty());
76 }
77
78
79 string const LaTeXFont::getAvailablePackage(bool ot1, bool complete)
80 {
81         if (ot1 && !ot1package_.empty()) {
82                 if (ot1package_ != "none" && LaTeXFeatures::isAvailable(to_ascii(ot1package_)))
83                         return to_ascii(ot1package_);
84                 return string();
85         }
86         if (complete && !completepackage_.empty()) {
87                 if (LaTeXFeatures::isAvailable(to_ascii(completepackage_)))
88                         return to_ascii(completepackage_);
89         }
90         if (!package_.empty()) {
91                 if (!requires_.empty() && LaTeXFeatures::isAvailable(to_ascii(requires_)))
92                         return to_ascii(package_);
93                 if (LaTeXFeatures::isAvailable(to_ascii(package_)))
94                         return to_ascii(package_);
95                 else if (!altpackages_.empty()) {
96                         for (size_t i = 0; i < altpackages_.size(); ++i) {
97                                 if (LaTeXFeatures::isAvailable(to_ascii(altpackages_[i])))
98                                         return to_ascii(altpackages_[i]);
99                         }
100                 }
101         }
102         return string();
103 }
104
105
106 string const LaTeXFont::getPackageOptions(bool const & ot1, bool const & sc,
107                                           bool const & osf, int const & scale)
108 {
109         if (ot1 && !ot1package_.empty())
110                 return string();
111
112         ostringstream os;
113         if (sc && osf && providesOSF() && providesSC()) {
114                 if (!osfscoption_.empty())
115                         os << to_ascii(osfscoption_);
116                 else
117                         os << to_ascii(osfoption_) << ',' << to_ascii(scoption_);
118         } else if (osf && providesOSF())
119                 os << to_ascii(osfoption_);
120         else if (sc && providesSC())
121                 os << to_ascii(scoption_);
122         if (scale != 100 && !scaleoption_.empty()) {
123                 if (!os.str().empty())
124                         os << ',';
125                 os << subst(to_ascii(scaleoption_), "$$val",
126                             convert<std::string>(float(scale) / 100));
127         }
128         return os.str();
129 }
130
131
132 bool LaTeXFont::readFont(Lexer & lex)
133 {
134         enum LaTeXFontTags {
135                 LF_ALT_PACKAGES = 1,
136                 LF_COMPLETE_PACKAGE,
137                 LF_END,
138                 LF_FAMILY,
139                 LF_GUINAME,
140                 LF_OSFOPTION,
141                 LF_OSFPACKAGE,
142                 LF_OSFSCOPTION,
143                 LF_OT1_PACKAGE,
144                 LF_PACKAGE,
145                 LF_REQUIRES,
146                 LF_SCALEOPTION,
147                 LF_SCOPTION,
148                 LF_SWITCHDEFAULT
149         };
150
151         // Keep these sorted alphabetically!
152         LexerKeyword latexFontTags[] = {
153                 { "altpackages",          LF_ALT_PACKAGES },
154                 { "completepackage",      LF_COMPLETE_PACKAGE },
155                 { "endfont",              LF_END },
156                 { "family",               LF_FAMILY },
157                 { "guiname",              LF_GUINAME },
158                 { "osfoption",            LF_OSFOPTION },
159                 { "osfpackage",           LF_OSFPACKAGE },
160                 { "osfscoption",          LF_OSFSCOPTION },
161                 { "ot1package",           LF_OT1_PACKAGE },
162                 { "package",              LF_PACKAGE },
163                 { "requires",             LF_REQUIRES },
164                 { "scaleoption",          LF_SCALEOPTION },
165                 { "scoption",             LF_SCOPTION },
166                 { "switchdefault",        LF_SWITCHDEFAULT }
167         };
168
169         bool error = false;
170         bool finished = false;
171         lex.pushTable(latexFontTags);
172         // parse style section
173         while (!finished && lex.isOK() && !error) {
174                 int le = lex.lex();
175                 // See comment in LyXRC.cpp.
176                 switch (le) {
177                 case Lexer::LEX_FEOF:
178                         continue;
179
180                 case Lexer::LEX_UNDEF: // parse error
181                         lex.printError("Unknown LaTeXFont tag `$$Token'");
182                         error = true;
183                         continue;
184
185                 default: 
186                         break;
187                 }
188                 switch (static_cast<LaTeXFontTags>(le)) {
189                 case LF_END: // end of structure
190                         finished = true;
191                         break;
192                 case LF_ALT_PACKAGES: {
193                         docstring altp;
194                         lex >> altp;
195                         altpackages_ = getVectorFromString(altp);
196                         break;
197                 }
198                 case LF_COMPLETE_PACKAGE:
199                         lex >> completepackage_;
200                         break;
201                 case LF_FAMILY:
202                         lex >> family_;
203                         break;
204                 case LF_GUINAME:
205                         lex >> guiname_;
206                         break;
207                 case LF_OSFOPTION:
208                         lex >> osfoption_;
209                         break;
210                 case LF_OSFPACKAGE:
211                         lex >> osfpackage_;
212                         break;
213                 case LF_OSFSCOPTION:
214                         lex >> osfscoption_;
215                         break;
216                 case LF_OT1_PACKAGE:
217                         lex >> ot1package_;
218                         break;
219                 case LF_PACKAGE:
220                         lex >> package_;
221                         break;
222                 case LF_REQUIRES:
223                         lex >> requires_;
224                         break;
225                 case LF_SCALEOPTION:
226                         lex >> scaleoption_;
227                         break;
228                 case LF_SCOPTION:
229                         lex >> scoption_;
230                         break;
231                 case LF_SWITCHDEFAULT:
232                         lex >> switchdefault_;
233                         break;
234                 }
235         }
236         if (!finished) {
237                 lex.printError("No End tag found for LaTeXFont tag `$$Token'");
238                 return false;
239         }
240         lex.popTable();
241         return finished && !error;
242 }
243
244
245 bool LaTeXFont::read(Lexer & lex)
246 {
247         switchdefault_ = 0;
248
249         if (!lex.next()) {
250                 lex.printError("No name given for LaTeX font: `$$Token'.");
251                 return false;
252         }
253
254         name_ = lex.getDocString();
255         LYXERR(Debug::INFO, "Reading LaTeX font " << name_);
256         if (!readFont(lex)) {
257                 LYXERR0("Error parsing LaTeX font `" << name_ << '\'');
258                 return false;
259         }
260
261         bool available = true;
262         if (!requires_.empty())
263                 available = LaTeXFeatures::isAvailable(to_ascii(requires_));
264         else if (!package_.empty()) {
265                 available = LaTeXFeatures::isAvailable(to_ascii(package_));
266                 if (!available && !altpackages_.empty()) {
267                         for (size_t i = 0; i < altpackages_.size(); ++i) {
268                                 available = LaTeXFeatures::isAvailable(to_ascii(altpackages_[i]));
269                                 if (available)
270                                         break;
271                         }
272                 }
273         }
274         available_ = available;
275
276         if (!ot1package_.empty() && ot1package_ != "none")
277                 available_ot1_ = LaTeXFeatures::isAvailable(to_ascii(ot1package_));
278         else
279                 available_ot1_ = available;
280
281         return true;
282 }
283
284
285 void LaTeXFonts::readLaTeXFonts()
286 {
287         // Read latexfonts file
288         FileName filename = libFileSearch(string(), "latexfonts");
289         if (filename.empty()) {
290                 LYXERR0("Error: latexfonts file not found!");
291                 return;
292         }
293         Lexer lex;
294         lex.setFile(filename);
295         lex.setContext("LaTeXFeatures::readLaTeXFonts");
296         while (lex.isOK()) {
297                 int le = lex.lex();
298                 switch (le) {
299                 case Lexer::LEX_FEOF:
300                         continue;
301
302                 default:
303                         break;
304                 }
305                 if (lex.getString() != "Font") {
306                         lex.printError("Unknown LaTeXFont tag `$$Token'");
307                         continue;
308                 }
309                 LaTeXFont f;
310                 f.read(lex);
311                 if (!lex)
312                         break;
313
314                 texfontmap_[f.name()] = f;
315         }
316 }
317
318
319 LaTeXFonts::TexFontMap LaTeXFonts::getLaTeXFonts()
320 {
321         if (texfontmap_.empty())
322                 readLaTeXFonts();
323         return texfontmap_;
324 }
325
326
327 LaTeXFont LaTeXFonts::getLaTeXFont(docstring const & name)
328 {
329         if (texfontmap_.empty())
330                 readLaTeXFonts();
331         return texfontmap_[name];
332 }
333
334
335 } // namespace lyx