]> git.lyx.org Git - lyx.git/blob - src/insets/ExternalTemplate.C
Portability fixes; crash fix with external templates; small things
[lyx.git] / src / insets / ExternalTemplate.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-2000 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include <algorithm>
18
19 #include "ExternalTemplate.h"
20
21 #include "lyxlex.h"
22 #include "support/path.h"
23 #include "support/LAssert.h"
24
25 using std::endl;
26 using std::ostream;
27 using std::for_each;
28
29 extern string user_lyxdir;
30
31
32 // We have to have dummy default commands for security reasons!
33
34 ExternalTemplate::ExternalTemplate()
35         : viewCommand("true"), editCommand("true")
36 {}
37
38 ExternalTemplate::FormatTemplate::FormatTemplate()
39         : updateCommand("true") {}
40
41
42 ExternalTemplateManager::ExternalTemplateManager()
43 {
44         // gimp gnuchess gnuplot ical netscape tetris xpaint
45         readTemplates(user_lyxdir);
46         dumpTemplates();
47 }
48
49
50 class dumpTemplate {
51 public:
52         dumpTemplate(std::ostream & o) 
53                 : ost(o) {}
54         void operator()(ExternalTemplateManager::Templates::value_type const & vt) {
55                 ExternalTemplate const & et = vt.second;
56                 
57                 ost << "Template " << et.lyxName << "\n"
58                     << "\tGuiName " << et.guiName << "\n"
59                     << "\tHelpText\n"
60                     << et.helpText
61                     << "\tHelpTextEnd\n"
62                     << "\tFileFilter " << et.fileRegExp << "\n"
63                     << "\tViewCommand " << et.viewCommand << "\n"
64                     << "\tEditCommand " << et.editCommand << "\n"
65                     << "\tAutomaticProduction " << et.automaticProduction << "\n";
66                 et.dumpFormats(ost);
67                 ost << "TemplateEnd" << endl;
68                 
69         }
70
71 private:
72         ostream & ost;
73 };
74
75 class dumpFormat {
76 public:
77         dumpFormat(ostream & o) 
78                 : ost(o) {}
79         void operator()(ExternalTemplate::Formats::value_type const & vt) const{
80                 ExternalTemplate::FormatTemplate const & ft = vt.second;
81                 ost << "\tFormat " << vt.first << "\n"
82                     << "\t\tProduct " << ft.product << "\n"
83                     << "\t\tUpdateCommand " << ft.updateCommand << "\n"
84                     << "\t\tRequirement " << ft.requirement << "\n"
85                     << "\t\tPreamble\n"
86                     << ft.preamble
87                     << "\t\tPreambleEnd\n"
88                     << "\tFormatEnd\n";
89         }
90 private:
91         ostream & ost;
92 };
93
94
95 void ExternalTemplate::dumpFormats(ostream & os) const 
96 {
97         for_each(formats.begin(), formats.end(), dumpFormat(os));
98 }
99
100 void ExternalTemplateManager::dumpTemplates() const 
101 {
102         for_each(templates.begin(), templates.end(), dumpTemplate(lyxerr));
103 }
104
105
106 ExternalTemplateManager & ExternalTemplateManager::get()
107 {
108         static ExternalTemplateManager externalTemplateManager;
109         return externalTemplateManager;
110 }
111
112
113 ExternalTemplateManager::Templates &
114 ExternalTemplateManager::getTemplates()
115 {
116         return templates;
117 }
118
119
120 ExternalTemplateManager::Templates const &
121 ExternalTemplateManager::getTemplates() const
122 {
123         return templates;
124 }
125
126
127 void ExternalTemplateManager::readTemplates(string const & path) 
128 {
129         Path p(path);
130
131         enum TemplateTags {
132                 TM_TEMPLATE = 1,
133                 TM_END
134         };
135         
136         keyword_item templatetags[] = {
137                 { "template", TM_TEMPLATE },
138                 { "templateend", TM_END }
139         };
140
141         string filename = LibFileSearch("", "external_templates");
142         if (filename.empty()) {
143                 lyxerr << "No template file" << endl;
144                 return;
145         }
146
147         LyXLex lex(templatetags, TM_END);
148         if (!lex.setFile(filename)) {
149                 lyxerr << "No template file" << endl;
150                 return;
151         }
152         
153         while (lex.IsOK()) {
154                 switch(lex.lex()) {
155                 case TM_TEMPLATE: {
156                         lex.next();
157                         string temp = lex.GetString();
158                         ExternalTemplate & tmp = templates[temp];
159                         tmp.lyxName = temp;
160                         tmp.readTemplate(lex);
161                 }
162                 break;
163                 
164                 case TM_END:
165                         lyxerr << "TemplateEnd: " << lex.GetString() << endl;
166                         lyxerr << "Warning: End outside Template." << endl;
167                 break;
168                 }
169         }
170 }
171
172
173 void ExternalTemplate::readTemplate(LyXLex & lex)
174 {
175         enum TemplateOptionTags {
176                 TO_GUINAME = 1,
177                 TO_HELPTEXT,
178                 TO_FILTER,
179                 TO_VIEWCMD,
180                 TO_EDITCMD,
181                 TO_AUTOMATIC,
182                 TO_FORMAT,
183                 TO_END
184         };
185
186         keyword_item templateoptiontags[] = {
187                 { "automaticproduction", TO_AUTOMATIC },
188                 { "editcommand", TO_EDITCMD },
189                 { "filefilter", TO_FILTER },
190                 { "format", TO_FORMAT },
191                 { "guiname", TO_GUINAME },
192                 { "helptext", TO_HELPTEXT },
193                 { "templateend", TO_END },
194                 { "viewcommand", TO_VIEWCMD }
195         };
196
197         pushpophelper pph(lex, templateoptiontags, TO_END);
198         
199         while (lex.IsOK()) {
200                 switch (lex.lex()) {
201                 case TO_GUINAME:
202                         lex.next(true);
203                         guiName = lex.GetString();
204                         break;
205                         
206                 case TO_HELPTEXT:
207                         helpText = lex.getLongString("HelpTextEnd");
208                         break;
209                         
210                 case TO_FILTER:
211                         lex.next(true);
212                         fileRegExp = lex.GetString();
213                         break;
214                         
215                 case TO_VIEWCMD:
216                         lex.next(true);
217                         viewCommand = lex.GetString();
218                         // For security reasons, a command may not be empty!
219                         if (viewCommand.empty())
220                                 viewCommand = "true";
221                         break;
222                         
223                 case TO_EDITCMD:
224                         lex.next(true);
225                         editCommand = lex.GetString();
226                         // For security reasons, a command may not be empty!
227                         if (editCommand.empty())
228                                 editCommand = "true";
229                         break;
230                         
231                 case TO_AUTOMATIC:
232                         lex.next();
233                         automaticProduction = lex.GetBool();
234                         break;
235                         
236                 case TO_FORMAT:
237                         lex.next(true);
238                         formats[lex.GetString()].readFormat(lex);
239                         break;
240                         
241                 case TO_END:
242                         return;
243                         
244                 default:
245                         lyxerr << "Default: " << lex.GetString() << endl;
246                         Assert(false);
247                         break;
248                 }
249         }
250 }
251
252
253 void ExternalTemplate::FormatTemplate::readFormat(LyXLex & lex) 
254 {
255         enum FormatTags {
256                 FO_PRODUCT = 1,
257                 FO_UPDATECMD,
258                 FO_REQUIREMENT,
259                 FO_PREAMBLE,
260                 FO_END
261         };
262         
263         keyword_item formattags[] = {
264                 { "formatend", FO_END },
265                 { "preamble", FO_PREAMBLE },
266                 { "product", FO_PRODUCT },
267                 { "requirement", FO_REQUIREMENT },
268                 { "updatecommand", FO_UPDATECMD }
269         };
270
271         pushpophelper pph(lex, formattags, FO_END);
272         
273         while (lex.IsOK()) {
274                 switch(lex.lex()) {
275                 case FO_PRODUCT:
276                         lex.next(true);
277                         product = lex.GetString();
278                         break;
279                         
280                 case FO_UPDATECMD:
281                         lex.next(true);
282                         updateCommand = lex.GetString();
283                         // For security reasons, a command may not be empty!
284                         if (updateCommand.empty())
285                                 updateCommand = "true";
286                         break;
287                         
288                 case FO_REQUIREMENT:
289                         lex.next(true);
290                         requirement = lex.GetString();
291                         break;
292                         
293                 case FO_PREAMBLE:
294                         preamble = lex.getLongString("preambleend");
295                         break;
296                         
297                 case FO_END:
298                         lyxerr << "FormatEnd: " << lex.GetString() << endl;
299                         return;
300                 }
301         }
302 }
303