]> git.lyx.org Git - lyx.git/blob - src/ModuleList.cpp
Correction: The inset name is citation, not cite
[lyx.git] / src / ModuleList.cpp
1 // -*- C++ -*-
2 /**
3  * \file ModuleList.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  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "ModuleList.h"
15
16 #include "LaTeXFeatures.h"
17 #include "Lexer.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/lstrings.h"
24
25 #include <algorithm>
26         
27 using namespace std;
28 using namespace lyx::support;
29
30 namespace lyx {
31
32
33 //global variable: module list
34 ModuleList theModuleList;
35
36
37 LyXModule::LyXModule(string const & n, string const & i, 
38                            string const & d, vector<string> const & p,
39                            vector<string> const & r, vector<string> const & e,
40                            string const & c):
41         name_(n), id_(i), description_(d), package_list_(p), 
42         required_modules_(r), excluded_modules_(e), category_(c),
43         checked_(false)
44 {
45         filename_ = id_ + ".module";
46 }
47
48
49 vector<string> LyXModule::prerequisites() const {
50 #ifdef TEX2LYX
51         return vector<string>();
52 #else
53         if (!checked_)
54                 isAvailable();
55         return prerequisites_;
56 #endif
57 }
58
59
60 bool LyXModule::isAvailable() const {
61 #ifdef TEX2LYX
62         return true;
63 #else
64         if (package_list_.empty())
65                 return true;
66         if (checked_)
67                 return available_;
68         checked_ = true;
69         available_ = true;
70         //check whether all of the required packages are available
71         vector<string>::const_iterator it  = package_list_.begin();
72         vector<string>::const_iterator end = package_list_.end(); 
73         for (; it != end; ++it) {
74                 if (!LaTeXFeatures::isAvailable(*it)) {
75                         available_ = false;
76                         prerequisites_.push_back(*it);
77                 }
78         }
79         return available_;
80 #endif
81 }
82
83
84 bool LyXModule::isCompatible(string const & modname) const
85 {
86         // do we exclude it?
87         if (find(excluded_modules_.begin(), excluded_modules_.end(), modname) !=
88                         excluded_modules_.end())
89                 return false;
90
91         LyXModule const * const lm = theModuleList[modname];
92         if (!lm)
93                 return true;
94
95         // does it exclude us?
96         vector<string> const excmods = lm->getExcludedModules();
97         if (find(excmods.begin(), excmods.end(), id_) != excmods.end())
98                 return false;
99
100         return true;
101 }
102
103
104 bool LyXModule::areCompatible(string const & mod1, string const & mod2)
105 {
106         LyXModule const * const lm1 = theModuleList[mod1];
107         if (lm1)
108                 return lm1->isCompatible(mod2);
109         LyXModule const * const lm2 = theModuleList[mod2];
110         if (lm2)
111                 return lm2->isCompatible(mod1);
112         // Can't check it either way.
113         return true;
114 }
115
116
117 // used when sorting the module list.
118 class ModuleSorter
119 {
120 public:
121         int operator()(LyXModule const & lm1, LyXModule const & lm2) const
122         {
123                 return _(lm1.getName()) < _(lm2.getName());
124         }
125 };
126
127
128 // Much of this is borrowed from LayoutFileList::read()
129 bool ModuleList::read()
130 {
131         FileName const real_file = libFileSearch("", "lyxmodules.lst");
132         LYXERR(Debug::TCLASS, "Reading modules from `" << real_file << '\'');
133
134         if (real_file.empty()) {
135                 LYXERR0("unable to find modules file `lyxmodules.lst'.\n"
136                         << "No modules will be available.");
137                 return false;
138         }
139
140         Lexer lex;
141         if (!lex.setFile(real_file)) {
142                 LYXERR0("lyxlex was not able to set file: "
143                         << real_file << ".\nNo modules will be available.");
144                 return false;
145         }
146
147         if (!lex.isOK()) {
148                 LYXERR0("unable to open modules file  `"
149                         << to_utf8(makeDisplayPath(real_file.absFileName(), 1000))
150                         << "'\nNo modules will be available.");
151                 return false;
152         }
153
154         bool finished = false;
155         // Parse modules files
156         LYXERR(Debug::TCLASS, "Starting parsing of lyxmodules.lst");
157         while (lex.isOK() && !finished) {
158                 LYXERR(Debug::TCLASS, "\tline by line");
159                 switch (lex.lex()) {
160                 case Lexer::LEX_FEOF:
161                         finished = true;
162                         break;
163                 default:
164                         string const modname = lex.getString();
165                         LYXERR(Debug::TCLASS, "Module name: " << modname);
166                         if (!lex.next())
167                                 break;
168                         string const fname = lex.getString();
169                         LYXERR(Debug::TCLASS, "Filename: " << fname);
170                         if (!lex.next(true))
171                                 break;
172                         string const desc = lex.getString();
173                         LYXERR(Debug::TCLASS, "Description: " << desc);
174                         //FIXME Add packages
175                         if (!lex.next())
176                                 break;
177                         string str = lex.getString();
178                         LYXERR(Debug::TCLASS, "Packages: " << str);
179                         vector<string> pkgs;
180                         while (!str.empty()) {
181                                 string p;
182                                 str = split(str, p, ',');
183                                 pkgs.push_back(p);
184                         }
185                         if (!lex.next())
186                                 break;
187                         str = lex.getString();
188                         LYXERR(Debug::TCLASS, "Required: " << str);
189                         vector<string> req;
190                         while (!str.empty()) {
191                                 string p;
192                                 str = split(str, p, '|');
193                                 req.push_back(p);
194                         }
195                         if (!lex.next())
196                                 break;
197                         str = lex.getString();
198                         LYXERR(Debug::TCLASS, "Excluded: " << str);
199                         vector<string> exc;
200                         while (!str.empty()) {
201                                 string p;
202                                 str = split(str, p, '|');
203                                 exc.push_back(p);
204                         }
205                         if (!lex.next())
206                                 break;
207                         string const catgy = lex.getString();
208                         LYXERR(Debug::TCLASS, "Category: " << catgy);
209                         // This code is run when we have
210                         // modName, fname, desc, pkgs, req, exc, and catgy
211                         addLayoutModule(modname, fname, desc, pkgs, req, exc, catgy);
212                 } // end switch
213         } //end while
214         
215         LYXERR(Debug::TCLASS, "End of parsing of lyxmodules.lst");
216
217         if (!theModuleList.empty())
218                 sort(theModuleList.begin(), theModuleList.end(), ModuleSorter());
219         return true;
220 }
221
222
223 void ModuleList::addLayoutModule(string const & modname, 
224         string const & filename, string const & description,
225         vector<string> const & pkgs, vector<string> const & req,
226         vector<string> const & exc, string const & catgy)
227 {
228         LyXModule lm(modname, filename, description, pkgs, req, exc, catgy);
229         modlist_.push_back(lm);
230 }
231
232
233 LyXModuleList::const_iterator ModuleList::begin() const
234 {
235         return modlist_.begin();
236 }
237
238
239 LyXModuleList::iterator ModuleList::begin()
240 {
241         return modlist_.begin();
242 }
243
244
245 LyXModuleList::const_iterator ModuleList::end() const
246 {
247         return modlist_.end();
248 }
249
250
251 LyXModuleList::iterator ModuleList::end()
252 {
253         return modlist_.end();
254 }
255
256
257 LyXModule const * ModuleList::operator[](string const & str) const
258 {
259         LyXModuleList::const_iterator it = modlist_.begin();
260         for (; it != modlist_.end(); ++it)
261                 if (it->getID() == str) {
262                         LyXModule const & mod = *it;
263                         return &mod;
264                 }
265         return 0;
266 }
267
268 LyXModule * ModuleList::operator[](string const & str)
269 {
270         LyXModuleList::iterator it = modlist_.begin();
271         for (; it != modlist_.end(); ++it)
272                 if (it->getID() == str) {
273                 LyXModule & mod = *it;
274                 return &mod;
275                 }
276                 return 0;
277 }
278
279 } // namespace lyx