]> git.lyx.org Git - lyx.git/blob - src/insets/insetinclude.C
Make LFUN_QUOTE work for InsetText.
[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 "debug.h"
16 #include "support/filetools.h"
17 #include "lyxrc.h"
18 #include "LyXView.h"
19 #include "LaTeXFeatures.h"
20 #include "gettext.h"
21 #include "support/FileInfo.h"
22 #include "layout.h"
23 #include "lyxfunc.h"
24
25 using std::ostream;
26 using std::endl;
27 using std::vector;
28 using std::pair;
29
30 extern BufferList bufferlist;
31
32
33 static inline
34 string unique_id() {
35         static unsigned int seed = 1000;
36
37         std::ostringstream ost;
38         ost << "file" << ++seed;
39
40         // Needed if we use lyxstring.
41         return ost.str().c_str();
42 }
43
44
45 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & bf)
46         : InsetCommand(p), master(&bf)
47 {
48         flag = InsetInclude::INCLUDE;
49         noload = false;
50         include_label = unique_id();
51 }
52
53
54 InsetInclude::~InsetInclude()
55 {
56 }
57
58
59 Inset * InsetInclude::Clone(Buffer const & buffer) const
60
61         InsetInclude * ii = new InsetInclude (params(), buffer); 
62         ii->setNoLoad(isNoLoad());
63         // By default, the newly created inset is of `include' type,
64         // so we do not test this case.
65         if (isInput())
66                 ii->setInput();
67         else if (isVerb()) {
68                 ii->setVerb();
69                 ii->setVisibleSpace(isVerbVisibleSpace());
70         }
71         return ii;
72 }
73
74
75 void InsetInclude::Edit(BufferView * bv, int, int, unsigned int)
76 {
77         bv->owner()->getDialogs()->showInclude(this);
78 }
79
80
81 void InsetInclude::Write(Buffer const *, ostream & os) const
82 {
83         os << "Include " << getCommand() << "\n";
84 }
85
86
87 void InsetInclude::Read(Buffer const * buf, LyXLex & lex)
88 {
89         InsetCommand::Read(buf, lex);
90     
91         if (getCmdName() == "include")
92                 setInclude();
93         else if (getCmdName() == "input")
94                 setInput();
95         else if (contains(getCmdName(), "verbatim")) {
96                 setVerb();
97                 if (getCmdName() == "verbatiminput*")
98                         setVisibleSpace(true);
99         }
100 }
101
102
103 bool InsetInclude::display() const 
104 {
105         return !isInput();
106 }
107
108
109 string const InsetInclude::getScreenLabel() const
110 {
111         string temp;
112         if (isInput())
113                 temp += _("Input");
114         else if (isVerb()) {
115                 temp += _("Verbatim Input");
116                 if (isVerbVisibleSpace()) temp += '*';
117         } else temp += _("Include");
118         temp += ": ";
119         
120         if (getContents().empty()) {
121                 temp+= "???";
122         } else {
123                 temp+= getContents();
124         }
125         return temp;
126 }
127
128
129 string const InsetInclude::getFileName() const
130 {
131         return MakeAbsPath(getContents(), 
132                            OnlyPath(getMasterFilename()));
133 }
134
135
136 string const InsetInclude::getMasterFilename() const
137 {
138         return master->fileName();
139 }
140
141
142 bool InsetInclude::loadIfNeeded() const
143 {
144         if (isNoLoad() || isVerb()) return false;
145         if (!IsLyXFilename(getFileName())) return false;
146         
147         if (bufferlist.exists(getFileName())) return true;
148         
149         // the readonly flag can/will be wrong, not anymore I think.
150         FileInfo finfo(getFileName());
151         bool const ro = !finfo.writable();
152         return bufferlist.readFile(getFileName(), ro) != 0;
153 }
154
155
156 int InsetInclude::Latex(Buffer const * buffer, ostream & os,
157                         bool /*fragile*/, bool /*fs*/) const
158 {
159         string incfile(getContents());
160         
161         // Do nothing if no file name has been specified
162         if (incfile.empty())
163                 return 0;
164     
165         if (loadIfNeeded()) {
166                 Buffer * tmp = bufferlist.getBuffer(getFileName());
167
168                 if (tmp->params.textclass != buffer->params.textclass) {
169                         lyxerr << "ERROR: Cannot handle include file `"
170                                << MakeDisplayPath(getFileName())
171                                << "' which has textclass `"
172                                << textclasslist.NameOfClass(tmp->params.textclass)
173                                << "' instead of `"
174                                << textclasslist.NameOfClass(buffer->params.textclass)
175                                << "'." << endl;
176                         return 0;
177                 }
178                 
179                 // write it to a file (so far the complete file)
180                 string writefile = ChangeExtension(getFileName(), ".tex");
181                 if (!buffer->tmppath.empty()
182                     && !buffer->niceFile) {
183                         incfile = subst(incfile, '/','@');
184 #ifdef __EMX__
185                         incfile = subst(incfile, ':', '$');
186 #endif
187                         writefile = AddName(buffer->tmppath, incfile);
188                 } else
189                         writefile = getFileName();
190                 writefile = ChangeExtension(writefile, ".tex");
191                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
192                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
193                 
194                 tmp->markDepClean(buffer->tmppath);
195                 
196                 tmp->makeLaTeXFile(writefile,
197                                    OnlyPath(getMasterFilename()), 
198                                    buffer->niceFile, true);
199         } 
200
201         if (isVerb()) {
202                 os << '\\' << getCmdName() << '{' << incfile << '}';
203         } else if (isInput()) {
204                 // \input wants file with extension (default is .tex)
205                 if (!IsLyXFilename(getFileName())) {
206                         os << '\\' << getCmdName() << '{' << incfile << '}';
207                 } else {
208                         os << '\\' << getCmdName() << '{'
209                            << ChangeExtension(incfile, ".tex")
210                            <<  '}';
211                 }
212         } else {
213                 // \include don't want extension and demands that the
214                 // file really have .tex
215                 os << '\\' << getCmdName() << '{'
216                    << ChangeExtension(incfile, string())
217                    << '}';
218         }
219
220         return 0;
221 }
222
223
224 int InsetInclude::Ascii(Buffer const *, std::ostream & os, int) const
225 {
226         if (isVerb())
227                 os << GetFileContents(getFileName());
228         return 0;
229 }
230
231
232 int InsetInclude::Linuxdoc(Buffer const * buffer, ostream & os) const
233 {
234         string incfile(getContents());
235         
236         // Do nothing if no file name has been specified
237         if (incfile.empty())
238                 return 0;
239     
240         if (loadIfNeeded()) {
241                 Buffer * tmp = bufferlist.getBuffer(getFileName());
242
243                 // write it to a file (so far the complete file)
244                 string writefile = ChangeExtension(getFileName(), ".sgml");
245                 if (!buffer->tmppath.empty() && !buffer->niceFile) {
246                         incfile = subst(incfile, '/','@');
247                         writefile = AddName(buffer->tmppath, incfile);
248                 } else
249                         writefile = getFileName();
250
251                 if (IsLyXFilename(getFileName()))
252                         writefile = ChangeExtension(writefile, ".sgml");
253
254                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
255                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
256                 
257                 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
258         } 
259
260         if (isVerb()) {
261                 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
262                    << "\" format=\"linespecific\">"
263                    << "</inlinegraphic>";
264         } else 
265                 os << '&' << include_label << ';';
266         
267         return 0;
268 }
269
270
271 int InsetInclude::DocBook(Buffer const * buffer, ostream & os) const
272 {
273         string incfile(getContents());
274
275         // Do nothing if no file name has been specified
276         if (incfile.empty())
277                 return 0;
278     
279         if (loadIfNeeded()) {
280                 Buffer * tmp = bufferlist.getBuffer(getFileName());
281
282                 // write it to a file (so far the complete file)
283                 string writefile = ChangeExtension(getFileName(), ".sgml");
284                 if (!buffer->tmppath.empty() && !buffer->niceFile) {
285                         incfile = subst(incfile, '/','@');
286                         writefile = AddName(buffer->tmppath, incfile);
287                 } else
288                         writefile = getFileName();
289                 if (IsLyXFilename(getFileName()))
290                         writefile = ChangeExtension(writefile, ".sgml");
291
292                 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
293                 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
294                 
295                 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
296         } 
297
298         if (isVerb()) {
299                 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
300                    << "\" format=\"linespecific\">"
301                    << "</inlinegraphic>";
302         } else 
303                 os << '&' << include_label << ';';
304         
305         return 0;
306 }
307
308
309 void InsetInclude::Validate(LaTeXFeatures & features) const
310 {
311
312         string incfile(getContents());
313         string writefile; // = ChangeExtension(getFileName(), ".sgml");
314
315         if (!master->tmppath.empty() && !master->niceFile) {
316                 incfile = subst(incfile, '/','@');
317                 writefile = AddName(master->tmppath, incfile);
318         } else
319                 writefile = getFileName();
320                 // Use the relative path.
321                 //writefile = incfile;
322
323         if (IsLyXFilename(getFileName()))
324                 writefile = ChangeExtension(writefile, ".sgml");
325
326         features.IncludedFiles[include_label] = writefile;
327
328         if (isVerb())
329                 features.verbatim = true;
330
331         // Here we must do the fun stuff...
332         // Load the file in the include if it needs
333         // to be loaded:
334         if (loadIfNeeded()) {
335                 // a file got loaded
336                 Buffer * tmp = bufferlist.getBuffer(getFileName());
337                 tmp->validate(features);
338         }
339 }
340
341
342 vector<string> const InsetInclude::getLabelList() const
343 {
344         vector<string> l;
345
346         if (loadIfNeeded()) {
347                 Buffer * tmp = bufferlist.getBuffer(getFileName());
348                 tmp->setParentName(""); 
349                 l = tmp->getLabelList();
350                 tmp->setParentName(getMasterFilename());
351         }
352
353         return l;
354 }
355
356
357 vector<pair<string,string> > const InsetInclude::getKeys() const
358 {
359         vector<pair<string,string> > keys;
360         
361         if (loadIfNeeded()) {
362                 Buffer * tmp = bufferlist.getBuffer(getFileName());
363                 tmp->setParentName(""); 
364                 keys = tmp->getBibkeyList();
365                 tmp->setParentName(getMasterFilename());
366         }
367         
368         return keys;
369 }