]> git.lyx.org Git - lyx.git/blob - src/insets/insetinclude.C
rename docBook method to docbook
[lyx.git] / src / insets / insetinclude.C
1
2 #include <config.h>
3
4 #include <cstdlib>
5
6 #ifdef __GNUG__
7 #pragma implementation
8 #endif
9
10 #include "frontends/Dialogs.h"
11
12 #include "insetinclude.h"
13 #include "buffer.h"
14 #include "bufferlist.h"
15 #include "BufferView.h"
16 #include "debug.h"
17 #include "support/filetools.h"
18 #include "lyxrc.h"
19 #include "LyXView.h"
20 #include "LaTeXFeatures.h"
21 #include "gettext.h"
22 #include "support/FileInfo.h"
23 #include "support/lstrings.h"
24 #include "layout.h"
25
26 using std::ostream;
27 using std::endl;
28 using std::vector;
29 using std::pair;
30
31 extern BufferList bufferlist;
32
33 namespace {
34
35 string const unique_id()
36 {
37         static unsigned int seed = 1000;
38
39         ostringstream ost;
40         ost << "file" << ++seed;
41
42         // Needed if we use lyxstring.
43         return ost.str().c_str();
44 }
45
46 } // namespace anon
47
48
49 InsetInclude::InsetInclude(Params const & p)
50         : params_(p), include_label(unique_id())
51 {}
52
53
54 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b)
55 {
56         params_.cparams = p;
57         params_.masterFilename_ = b.fileName();
58         include_label = unique_id();
59 }
60
61
62 InsetInclude::~InsetInclude()
63 {
64         hideDialog();
65 }
66
67
68 InsetInclude::Params const & InsetInclude::params() const
69 {
70         return params_;
71 }
72
73
74 bool InsetInclude::Params::operator==(Params const & o) const
75 {
76         if (cparams == o.cparams && flag == o.flag &&
77             noload == o.noload && masterFilename_ == o.masterFilename_)
78                 return true;
79         
80         return false;
81 }
82
83
84 bool InsetInclude::Params::operator!=(Params const & o) const
85 {
86         return !(*this == o);
87 }
88
89
90 void InsetInclude::set(Params const & p)
91 {
92         params_ = p;
93
94         // Just to be safe...
95         string command;
96  
97         switch (params_.flag) {
98                 case INCLUDE:
99                         command="include";
100                         break;
101                 case VERB:
102                         command="verbatiminput";
103                         break;
104                 case INPUT:
105                         command="input";
106                         break;
107                 case VERBAST:
108                         command="verbatiminput*";
109                         break;
110         }
111  
112         params_.cparams.setCmdName(command);
113 }
114
115
116 Inset * InsetInclude::clone(Buffer const & buffer, bool) const
117 {
118         Params p(params_);
119         p.masterFilename_ = buffer.fileName();
120
121         return new InsetInclude(p);
122 }
123
124
125 void InsetInclude::edit(BufferView * bv, int, int, unsigned int)
126 {
127         bv->owner()->getDialogs()->showInclude(this);
128 }
129
130
131 void InsetInclude::edit(BufferView * bv, bool)
132 {
133         edit(bv, 0, 0, 0);
134 }
135
136
137 void InsetInclude::write(Buffer const *, ostream & os) const
138 {
139         os << "Include " << params_.cparams.getCommand() << "\n";
140 }
141
142
143 void InsetInclude::read(Buffer const *, LyXLex & lex)
144 {
145         params_.cparams.read(lex);
146    
147         if (params_.cparams.getCmdName() == "include")
148                 params_.flag = INCLUDE;
149         else if (params_.cparams.getCmdName() == "input")
150                 params_.flag = INPUT;
151         /* FIXME: is this logic necessary now ? */
152         else if (contains(params_.cparams.getCmdName(), "verbatim")) {
153                 params_.flag = VERB;
154                 if (params_.cparams.getCmdName() == "verbatiminput*")
155                         params_.flag = VERBAST;
156         }
157 }
158
159
160 bool InsetInclude::display() const
161 {
162         return !(params_.flag == INPUT);
163 }
164
165
166 string const InsetInclude::getScreenLabel(Buffer const *) const
167 {
168         string temp;
169
170         switch (params_.flag) {
171                 case INPUT: temp += _("Input"); break;
172                 case VERB: temp += _("Verbatim Input"); break;
173                 case VERBAST: temp += _("Verbatim Input*"); break;
174                 case INCLUDE: temp += _("Include"); break;
175         }
176
177         temp += ": ";
178         
179         if (params_.cparams.getContents().empty())
180                 temp += "???";
181         else
182                 temp += params_.cparams.getContents();
183
184         return temp;
185 }
186
187
188 string const InsetInclude::getRelFileBaseName() const
189 {
190         return OnlyFilename(ChangeExtension(params_.cparams.getContents(), string()));
191 }
192
193  
194 string const InsetInclude::getFileName() const
195 {
196         return MakeAbsPath(params_.cparams.getContents(),
197                            OnlyPath(getMasterFilename()));
198 }
199
200
201 string const InsetInclude::getMasterFilename() const
202 {
203         return params_.masterFilename_;
204 }
205
206
207 bool InsetInclude::loadIfNeeded() const
208 {
209         if (params_.noload || isVerbatim())
210                 return false;
211
212         if (!IsLyXFilename(getFileName()))
213                 return false;
214         
215         if (bufferlist.exists(getFileName()))
216                 return true;
217         
218         // the readonly flag can/will be wrong, not anymore I think.
219         FileInfo finfo(getFileName());
220         bool const ro = !finfo.writable();
221         return bufferlist.readFile(getFileName(), ro) != 0;
222 }
223
224
225 int InsetInclude::latex(Buffer const * buffer, ostream & os,
226                         bool /*fragile*/, bool /*fs*/) const
227 {
228         string incfile(params_.cparams.getContents());
229         
230         // Do nothing if no file name has been specified
231         if (incfile.empty())
232                 return 0;
233    
234         if (loadIfNeeded()) {
235                 Buffer * tmp = bufferlist.getBuffer(getFileName());
236
237                 // FIXME: this should be a GUI warning
238                 if (tmp->params.textclass != buffer->params.textclass) {
239                         lyxerr << "WARNING: Included file `"
240                                << MakeDisplayPath(getFileName())
241                                << "' has textclass `"
242                                << textclasslist.NameOfClass(tmp->params.textclass)
243                                << "' while parent file has textclass `"
244                                << textclasslist.NameOfClass(buffer->params.textclass)
245                                << "'." << endl;
246                         //return 0;
247                 }
248                 
249                 // write it to a file (so far the complete file)
250                 string writefile = ChangeExtension(getFileName(), ".tex");
251
252                 if (!buffer->tmppath.empty()
253                     && !buffer->niceFile) {
254                         incfile = subst(incfile, '/','@');
255 #ifdef __EMX__
256                         incfile = subst(incfile, ':', '$');
257 #endif
258                         writefile = AddName(buffer->tmppath, incfile);
259                 } else
260                         writefile = getFileName();
261                 writefile = ChangeExtension(writefile, ".tex");
262                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
263                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
264                 
265                 tmp->markDepClean(buffer->tmppath);
266                 
267                 tmp->makeLaTeXFile(writefile,
268                                    OnlyPath(getMasterFilename()),
269                                    buffer->niceFile, true);
270         }
271
272         if (isVerbatim()) {
273                 os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
274         } else if (params_.flag == INPUT) {
275                 // \input wants file with extension (default is .tex)
276                 if (!IsLyXFilename(getFileName())) {
277                         os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
278                 } else {
279                         os << '\\' << params_.cparams.getCmdName() << '{'
280                            << ChangeExtension(incfile, ".tex")
281                            <<  '}';
282                 }
283         } else {
284                 // \include don't want extension and demands that the
285                 // file really have .tex
286                 os << '\\' << params_.cparams.getCmdName() << '{'
287                    << ChangeExtension(incfile, string())
288                    << '}';
289         }
290
291         return 0;
292 }
293
294
295 int InsetInclude::ascii(Buffer const *, std::ostream & os, int) const
296 {
297         if (isVerbatim())
298                 os << GetFileContents(getFileName());
299         return 0;
300 }
301
302
303 int InsetInclude::linuxdoc(Buffer const * buffer, ostream & os) const
304 {
305         string incfile(params_.cparams.getContents());
306         
307         // Do nothing if no file name has been specified
308         if (incfile.empty())
309                 return 0;
310    
311         if (loadIfNeeded()) {
312                 Buffer * tmp = bufferlist.getBuffer(getFileName());
313
314                 // write it to a file (so far the complete file)
315                 string writefile = ChangeExtension(getFileName(), ".sgml");
316                 if (!buffer->tmppath.empty() && !buffer->niceFile) {
317                         incfile = subst(incfile, '/','@');
318                         writefile = AddName(buffer->tmppath, incfile);
319                 } else
320                         writefile = getFileName();
321
322                 if (IsLyXFilename(getFileName()))
323                         writefile = ChangeExtension(writefile, ".sgml");
324
325                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
326                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
327                 
328                 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
329         }
330
331         if (isVerbatim()) {
332                 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
333                    << "\" format=\"linespecific\">"
334                    << "</inlinegraphic>";
335         } else
336                 os << '&' << include_label << ';';
337         
338         return 0;
339 }
340
341
342 int InsetInclude::docbook(Buffer const * buffer, ostream & os) const
343 {
344         string incfile(params_.cparams.getContents());
345
346         // Do nothing if no file name has been specified
347         if (incfile.empty())
348                 return 0;
349    
350         if (loadIfNeeded()) {
351                 Buffer * tmp = bufferlist.getBuffer(getFileName());
352
353                 // write it to a file (so far the complete file)
354                 string writefile = ChangeExtension(getFileName(), ".sgml");
355                 if (!buffer->tmppath.empty() && !buffer->niceFile) {
356                         incfile = subst(incfile, '/','@');
357                         writefile = AddName(buffer->tmppath, incfile);
358                 } else
359                         writefile = getFileName();
360                 if (IsLyXFilename(getFileName()))
361                         writefile = ChangeExtension(writefile, ".sgml");
362
363                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
364                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
365                 
366                 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
367         }
368
369         if (isVerbatim()) {
370                 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
371                    << "\" format=\"linespecific\">"
372                    << "</inlinegraphic>";
373         } else
374                 os << '&' << include_label << ';';
375         
376         return 0;
377 }
378
379
380 void InsetInclude::validate(LaTeXFeatures & features) const
381 {
382
383         string incfile(params_.cparams.getContents());
384         string writefile;
385
386         Buffer const * const b = bufferlist.getBuffer(getMasterFilename());
387
388         if (b && !b->tmppath.empty() && b->niceFile) {
389                 incfile = subst(incfile, '/','@');
390                 writefile = AddName(b->tmppath, incfile);
391         } else
392                 writefile = getFileName();
393
394         if (IsLyXFilename(getFileName()))
395                 writefile = ChangeExtension(writefile, ".sgml");
396
397         features.IncludedFiles[include_label] = writefile;
398
399         if (isVerbatim())
400                 features.verbatim = true;
401
402         // Here we must do the fun stuff...
403         // Load the file in the include if it needs
404         // to be loaded:
405         if (loadIfNeeded()) {
406                 // a file got loaded
407                 Buffer const * const tmp = bufferlist.getBuffer(getFileName());
408                 if (tmp)
409                         tmp->validate(features);
410         }
411 }
412
413
414 vector<string> const InsetInclude::getLabelList() const
415 {
416         vector<string> l;
417
418         if (loadIfNeeded()) {
419                 Buffer * tmp = bufferlist.getBuffer(getFileName());
420                 tmp->setParentName("");
421                 l = tmp->getLabelList();
422                 tmp->setParentName(getMasterFilename());
423         }
424
425         return l;
426 }
427
428
429 vector<pair<string,string> > const InsetInclude::getKeys() const
430 {
431         vector<pair<string,string> > keys;
432         
433         if (loadIfNeeded()) {
434                 Buffer * tmp = bufferlist.getBuffer(getFileName());
435                 tmp->setParentName("");
436                 keys = tmp->getBibkeyList();
437                 tmp->setParentName(getMasterFilename());
438         }
439         
440         return keys;
441 }