]> git.lyx.org Git - lyx.git/blob - src/CiteEnginesList.cpp
Move Lexer to support/ directory (and lyx::support namespace)
[lyx.git] / src / CiteEnginesList.cpp
1 // -*- C++ -*-
2 /**
3  * \file CiteEnginesList.cpp
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Richard Kimberly Heck
8  * \author Jürgen Spitzmüller
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "CiteEnginesList.h"
16
17 #include "LaTeXFeatures.h"
18
19 #include "support/debug.h"
20 #include "support/FileName.h"
21 #include "support/gettext.h"
22 #include "support/filetools.h"
23 #include "support/Lexer.h"
24 #include "support/lstrings.h"
25 #include "support/Translator.h"
26
27 #include <algorithm>
28
29 using namespace std;
30 using namespace lyx::support;
31
32 namespace lyx {
33
34
35 //global variable: cite engine list
36 CiteEnginesList theCiteEnginesList;
37
38
39 LyXCiteEngine::LyXCiteEngine(string const & n, string const & i,
40                              vector<string> const & cet, string const & cfm,
41                              vector<string> const & dbs,
42                              string const & d, vector<string> const & p):
43         name_(n), id_(i), engine_types_(cet), cite_framework_(cfm), default_biblios_(dbs),
44         description_(d), package_list_(p), checked_(false), available_(false)
45 {
46         filename_ = id_ + ".citeengine";
47 }
48
49
50 vector<string> LyXCiteEngine::prerequisites() const
51 {
52         if (!checked_)
53                 isAvailable();
54         return prerequisites_;
55 }
56
57
58 bool LyXCiteEngine::isAvailable() const
59 {
60         if (package_list_.empty())
61                 return true;
62         if (checked_)
63                 return available_;
64         checked_ = true;
65         available_ = true;
66         //check whether all of the required packages are available
67         vector<string>::const_iterator it  = package_list_.begin();
68         vector<string>::const_iterator end = package_list_.end();
69         for (; it != end; ++it) {
70                 if (!LaTeXFeatures::isAvailable(*it)) {
71                         available_ = false;
72                         prerequisites_.push_back(*it);
73                 }
74         }
75         return available_;
76 }
77
78
79 bool LyXCiteEngine::hasEngineType(CiteEngineType const & et) const
80 {
81         return std::find(engine_types_.begin(), engine_types_.end(),
82                          theCiteEnginesList.getTypeAsString(et)) != engine_types_.end();
83 }
84
85
86 string LyXCiteEngine::getDefaultBiblio(CiteEngineType const & cet) const
87 {
88         string res;
89         string const etp = theCiteEnginesList.getTypeAsString(cet) + ":";
90         //check whether all of the required packages are available
91         for (string const &s: default_biblios_) {
92                 if (prefixIs(s, etp))
93                         res = split(s, ':');
94                 else if (!contains(s, ':') && res.empty())
95                         res = s;
96         }
97         return res;
98 }
99
100
101 bool LyXCiteEngine::isDefaultBiblio(string const & bf) const
102 {
103         string const bfs = ":" + bf;
104         for (string const & s: default_biblios_)
105                 if (suffixIs(s, bfs) || bf == s)
106                         return true;
107
108         return false;
109 }
110
111
112 bool LyXCiteEngine::required(string const & p) const
113 {
114         return find(package_list_.begin(), package_list_.end(), p) != package_list_.end();
115 }
116
117
118 // used when sorting the cite engine list.
119 class EngineSorter {
120 public:
121         int operator()(LyXCiteEngine const & ce1, LyXCiteEngine const & ce2) const
122         {
123                 return _(ce1.getName()) < _(ce2.getName());
124         }
125 };
126
127
128 // Local translators
129 namespace {
130
131 typedef Translator<string, CiteEngineType> CiteEngineTypeTranslator;
132
133
134 CiteEngineTypeTranslator const init_citeenginetypetranslator()
135 {
136         CiteEngineTypeTranslator translator("authoryear", ENGINE_TYPE_AUTHORYEAR);
137         translator.addPair("numerical", ENGINE_TYPE_NUMERICAL);
138         translator.addPair("default", ENGINE_TYPE_DEFAULT);
139         return translator;
140 }
141
142
143 CiteEngineTypeTranslator const & citeenginetypetranslator()
144 {
145         static CiteEngineTypeTranslator const translator =
146                 init_citeenginetypetranslator();
147         return translator;
148 }
149
150 } // namespace
151
152
153 string CiteEnginesList::getTypeAsString(CiteEngineType const & et) const
154 {
155         return citeenginetypetranslator().find(et);
156 }
157
158
159 CiteEngineType CiteEnginesList::getType(string const & et) const
160 {
161         return citeenginetypetranslator().find(et);
162 }
163
164
165 // Much of this is borrowed from LayoutFileList::read()
166 bool CiteEnginesList::read()
167 {
168         FileName const real_file = libFileSearch("", "lyxciteengines.lst");
169         LYXERR(Debug::TCLASS, "Reading cite engines from `" << real_file << '\'');
170
171         if (real_file.empty()) {
172                 LYXERR0("unable to find cite engines file `citeengines.lst'.\n"
173                         << "No cite engines will be available.");
174                 return false;
175         }
176
177         Lexer lex;
178         if (!lex.setFile(real_file)) {
179                 LYXERR0("lyxlex was not able to set file: "
180                         << real_file << ".\nNo cite engines will be available.");
181                 return false;
182         }
183
184         if (!lex.isOK()) {
185                 LYXERR0("unable to open cite engines file  `"
186                         << to_utf8(makeDisplayPath(real_file.absFileName(), 1000))
187                         << "'\nNo cite engines will be available.");
188                 return false;
189         }
190
191         bool finished = false;
192         // Parse cite engines files
193         LYXERR(Debug::TCLASS, "Starting parsing of lyxciteengines.lst");
194         while (lex.isOK() && !finished) {
195                 LYXERR(Debug::TCLASS, "\tline by line");
196                 switch (lex.lex()) {
197                 case Lexer::LEX_FEOF:
198                         finished = true;
199                         break;
200                 default:
201                         string const cename = lex.getString();
202                         LYXERR(Debug::TCLASS, "Engine name: " << cename);
203                         if (!lex.next())
204                                 break;
205                         string const fname = lex.getString();
206                         LYXERR(Debug::TCLASS, "Filename: " << fname);
207                         if (!lex.next(true))
208                                 break;
209                         string cet = lex.getString();
210                         LYXERR(Debug::TCLASS, "Engine Type: " << cet);
211                         vector<string> cets;
212                         while (!cet.empty()) {
213                                 string p;
214                                 cet = split(cet, p, '|');
215                                 cets.push_back(p);
216                         }
217                         if (!lex.next(true))
218                                 break;
219                         string const citeframework = lex.getString();
220                         LYXERR(Debug::TCLASS, "CiteFramework: " << citeframework);
221                         if (!lex.next(true))
222                                 break;
223                         string db = lex.getString();
224                         LYXERR(Debug::TCLASS, "Default Biblio: " << db);
225                         vector<string> dbs;
226                         while (!db.empty()) {
227                                 string p;
228                                 db = split(db, p, '|');
229                                 dbs.push_back(p);
230                         }
231                         if (!lex.next(true))
232                                 break;
233                         string const desc = lex.getString();
234                         LYXERR(Debug::TCLASS, "Description: " << desc);
235                         //FIXME Add packages
236                         if (!lex.next())
237                                 break;
238                         string str = lex.getString();
239                         LYXERR(Debug::TCLASS, "Packages: " << str);
240                         vector<string> pkgs;
241                         while (!str.empty()) {
242                                 string p;
243                                 str = split(str, p, ',');
244                                 pkgs.push_back(p);
245                         }
246                         // This code is run when we have
247                         // cename, fname, cets, citeframework, dbs, desc, pkgs
248                         addCiteEngine(cename, fname, cets, citeframework, dbs, desc, pkgs);
249                 } // end switch
250         } //end while
251
252         LYXERR(Debug::TCLASS, "End of parsing of lyxciteengines.lst");
253
254         if (!theCiteEnginesList.empty())
255                 sort(theCiteEnginesList.begin(), theCiteEnginesList.end(), EngineSorter());
256         return true;
257 }
258
259
260 void CiteEnginesList::addCiteEngine(string const & cename,
261         string const & filename, vector<string> const & cets,
262         string const & citeframework, vector<string> const & dbs,
263         string const & description, vector<string> const & pkgs)
264 {
265         LyXCiteEngine ce(cename, filename, cets, citeframework, dbs, description, pkgs);
266         englist_.push_back(ce);
267 }
268
269
270 LyXCiteEnginesList::const_iterator CiteEnginesList::begin() const
271 {
272         return englist_.begin();
273 }
274
275
276 LyXCiteEnginesList::iterator CiteEnginesList::begin()
277 {
278         return englist_.begin();
279 }
280
281
282 LyXCiteEnginesList::const_iterator CiteEnginesList::end() const
283 {
284         return englist_.end();
285 }
286
287
288 LyXCiteEnginesList::iterator CiteEnginesList::end()
289 {
290         return englist_.end();
291 }
292
293
294 LyXCiteEngine const * CiteEnginesList::operator[](string const & str) const
295 {
296         for (auto const & eng : englist_)
297                 if (eng.getID() == str) {
298                         return &eng;
299                 }
300         return nullptr;
301 }
302
303
304 LyXCiteEngine * CiteEnginesList::operator[](string const & str)
305 {
306         for (auto & eng : englist_)
307                 if (eng.getID() == str) {
308                         return &eng;
309                 }
310         return nullptr;
311 }
312
313 } // namespace lyx