]> git.lyx.org Git - features.git/blob - src/CiteEnginesList.cpp
Disentangle CiteEngines and Modules
[features.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 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 #include "Lexer.h"
19
20 #include "support/debug.h"
21 #include "support/FileName.h"
22 #include "support/gettext.h"
23 #include "support/filetools.h"
24 #include "support/lstrings.h"
25
26 #include <algorithm>
27
28 using namespace std;
29 using namespace lyx::support;
30
31 namespace lyx {
32
33
34 //global variable: cite engine list
35 CiteEnginesList theCiteEnginesList;
36
37
38 LyXCiteEngine::LyXCiteEngine(string const & n, string const & i,
39                              vector<string> const & cet, string const & d,
40                              vector<string> const & p,
41                              vector<string> const & r, vector<string> const & e):
42         name_(n), id_(i), engine_types_(cet), description_(d), package_list_(p),
43         required_engines_(r), excluded_engines_(e),
44         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::isCompatible(string const & cename) const
80 {
81         // do we exclude it?
82         if (find(excluded_engines_.begin(), excluded_engines_.end(), cename) !=
83                         excluded_engines_.end())
84                 return false;
85
86         LyXCiteEngine const * const lm = theCiteEnginesList[cename];
87         if (!lm)
88                 return true;
89
90         // does it exclude us?
91         vector<string> const excengs = lm->getExcludedEngines();
92         if (find(excengs.begin(), excengs.end(), id_) != excengs.end())
93                 return false;
94
95         return true;
96 }
97
98
99 bool LyXCiteEngine::areCompatible(string const & eng1, string const & eng2)
100 {
101         LyXCiteEngine const * const lm1 = theCiteEnginesList[eng1];
102         if (lm1)
103                 return lm1->isCompatible(eng2);
104         LyXCiteEngine const * const lm2 = theCiteEnginesList[eng2];
105         if (lm2)
106                 return lm2->isCompatible(eng1);
107         // Can't check it either way.
108         return true;
109 }
110
111
112 // used when sorting the cite engine list.
113 class EngineSorter {
114 public:
115         int operator()(LyXCiteEngine const & ce1, LyXCiteEngine const & ce2) const
116         {
117                 return _(ce1.getName()) < _(ce2.getName());
118         }
119 };
120
121
122 // Much of this is borrowed from LayoutFileList::read()
123 bool CiteEnginesList::read()
124 {
125         FileName const real_file = libFileSearch("", "lyxciteengines.lst");
126         LYXERR(Debug::TCLASS, "Reading cite engines from `" << real_file << '\'');
127
128         if (real_file.empty()) {
129                 LYXERR0("unable to find cite engines file `citeengines.lst'.\n"
130                         << "No cite engines will be available.");
131                 return false;
132         }
133
134         Lexer lex;
135         if (!lex.setFile(real_file)) {
136                 LYXERR0("lyxlex was not able to set file: "
137                         << real_file << ".\nNo cite engines will be available.");
138                 return false;
139         }
140
141         if (!lex.isOK()) {
142                 LYXERR0("unable to open cite engines file  `"
143                         << to_utf8(makeDisplayPath(real_file.absFileName(), 1000))
144                         << "'\nNo cite engines will be available.");
145                 return false;
146         }
147
148         bool finished = false;
149         // Parse cite engines files
150         LYXERR(Debug::TCLASS, "Starting parsing of lyxciteengines.lst");
151         while (lex.isOK() && !finished) {
152                 LYXERR(Debug::TCLASS, "\tline by line");
153                 switch (lex.lex()) {
154                 case Lexer::LEX_FEOF:
155                         finished = true;
156                         break;
157                 default:
158                         string const cename = lex.getString();
159                         LYXERR(Debug::TCLASS, "Engine name: " << cename);
160                         if (!lex.next())
161                                 break;
162                         string const fname = lex.getString();
163                         LYXERR(Debug::TCLASS, "Filename: " << fname);
164                         if (!lex.next(true))
165                                 break;
166                         string cet = lex.getString();
167                         LYXERR(Debug::TCLASS, "Engine Type: " << cet);
168                         vector<string> cets;
169                         while (!cet.empty()) {
170                                 string p;
171                                 cet = split(cet, p, '|');
172                                 cets.push_back(p);
173                         }
174                         if (!lex.next(true))
175                                 break;
176                         string const desc = lex.getString();
177                         LYXERR(Debug::TCLASS, "Description: " << desc);
178                         //FIXME Add packages
179                         if (!lex.next())
180                                 break;
181                         string str = lex.getString();
182                         LYXERR(Debug::TCLASS, "Packages: " << str);
183                         vector<string> pkgs;
184                         while (!str.empty()) {
185                                 string p;
186                                 str = split(str, p, ',');
187                                 pkgs.push_back(p);
188                         }
189                         if (!lex.next())
190                                 break;
191                         str = lex.getString();
192                         LYXERR(Debug::TCLASS, "Required: " << str);
193                         vector<string> req;
194                         while (!str.empty()) {
195                                 string p;
196                                 str = split(str, p, '|');
197                                 req.push_back(p);
198                         }
199                         if (!lex.next())
200                                 break;
201                         str = lex.getString();
202                         LYXERR(Debug::TCLASS, "Excluded: " << str);
203                         vector<string> exc;
204                         while (!str.empty()) {
205                                 string p;
206                                 str = split(str, p, '|');
207                                 exc.push_back(p);
208                         }
209                         // This code is run when we have
210                         // cename, fname, desc, pkgs, req and exc
211                         addCiteEngine(cename, fname, cets, desc, pkgs, req, exc);
212                 } // end switch
213         } //end while
214
215         LYXERR(Debug::TCLASS, "End of parsing of lyxciteengines.lst");
216
217         if (!theCiteEnginesList.empty())
218                 sort(theCiteEnginesList.begin(), theCiteEnginesList.end(), EngineSorter());
219         return true;
220 }
221
222
223 void CiteEnginesList::addCiteEngine(string const & cename,
224         string const & filename, vector<string> const & cets, string const & description,
225         vector<string> const & pkgs, vector<string> const & req,
226         vector<string> const & exc)
227 {
228         LyXCiteEngine ce(cename, filename, cets, description, pkgs, req, exc);
229         englist_.push_back(ce);
230 }
231
232
233 LyXCiteEnginesList::const_iterator CiteEnginesList::begin() const
234 {
235         return englist_.begin();
236 }
237
238
239 LyXCiteEnginesList::iterator CiteEnginesList::begin()
240 {
241         return englist_.begin();
242 }
243
244
245 LyXCiteEnginesList::const_iterator CiteEnginesList::end() const
246 {
247         return englist_.end();
248 }
249
250
251 LyXCiteEnginesList::iterator CiteEnginesList::end()
252 {
253         return englist_.end();
254 }
255
256
257 LyXCiteEngine const * CiteEnginesList::operator[](string const & str) const
258 {
259         LyXCiteEnginesList::const_iterator it = englist_.begin();
260         for (; it != englist_.end(); ++it)
261                 if (it->getID() == str) {
262                         LyXCiteEngine const & eng = *it;
263                         return &eng;
264                 }
265         return 0;
266 }
267
268
269 LyXCiteEngine * CiteEnginesList::operator[](string const & str)
270 {
271         LyXCiteEnginesList::iterator it = englist_.begin();
272         for (; it != englist_.end(); ++it)
273                 if (it->getID() == str) {
274                         LyXCiteEngine & eng = *it;
275                         return &eng;
276                 }
277         return 0;
278 }
279
280 } // namespace lyx