10 #include "frontends/Dialogs.h"
12 #include "insetinclude.h"
14 #include "bufferlist.h"
15 #include "BufferView.h"
17 #include "support/filetools.h"
20 #include "LaTeXFeatures.h"
22 #include "support/FileInfo.h"
23 #include "support/lstrings.h"
31 extern BufferList bufferlist;
35 string const unique_id()
37 static unsigned int seed = 1000;
40 ost << "file" << ++seed;
42 // Needed if we use lyxstring.
43 return ost.str().c_str();
49 InsetInclude::InsetInclude(Params const & p)
50 : params_(p), include_label(unique_id())
54 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b)
57 params_.masterFilename_ = b.fileName();
58 include_label = unique_id();
62 InsetInclude::~InsetInclude()
68 InsetInclude::Params const & InsetInclude::params() const
74 bool InsetInclude::Params::operator==(Params const & o) const
76 if (cparams == o.cparams && flag == o.flag &&
77 noload == o.noload && masterFilename_ == o.masterFilename_)
84 bool InsetInclude::Params::operator!=(Params const & o) const
90 void InsetInclude::set(Params const & p)
97 switch (params_.flag) {
102 command="verbatiminput";
108 command="verbatiminput*";
112 params_.cparams.setCmdName(command);
116 Inset * InsetInclude::clone(Buffer const & buffer, bool) const
119 p.masterFilename_ = buffer.fileName();
121 return new InsetInclude(p);
125 void InsetInclude::edit(BufferView * bv, int, int, unsigned int)
127 bv->owner()->getDialogs()->showInclude(this);
131 void InsetInclude::edit(BufferView * bv, bool)
137 void InsetInclude::write(Buffer const *, ostream & os) const
139 os << "Include " << params_.cparams.getCommand() << "\n";
143 void InsetInclude::read(Buffer const *, LyXLex & lex)
145 params_.cparams.read(lex);
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")) {
154 if (params_.cparams.getCmdName() == "verbatiminput*")
155 params_.flag = VERBAST;
160 bool InsetInclude::display() const
162 return !(params_.flag == INPUT);
166 string const InsetInclude::getScreenLabel(Buffer const *) const
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;
179 if (params_.cparams.getContents().empty())
182 temp += params_.cparams.getContents();
188 string const InsetInclude::getRelFileBaseName() const
190 return OnlyFilename(ChangeExtension(params_.cparams.getContents(), string()));
194 string const InsetInclude::getFileName() const
196 return MakeAbsPath(params_.cparams.getContents(),
197 OnlyPath(getMasterFilename()));
201 string const InsetInclude::getMasterFilename() const
203 return params_.masterFilename_;
207 bool InsetInclude::loadIfNeeded() const
209 if (params_.noload || isVerbatim())
212 if (!IsLyXFilename(getFileName()))
215 if (bufferlist.exists(getFileName()))
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;
225 int InsetInclude::latex(Buffer const * buffer, ostream & os,
226 bool /*fragile*/, bool /*fs*/) const
228 string incfile(params_.cparams.getContents());
230 // Do nothing if no file name has been specified
234 if (loadIfNeeded()) {
235 Buffer * tmp = bufferlist.getBuffer(getFileName());
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)
249 // write it to a file (so far the complete file)
250 string writefile = ChangeExtension(getFileName(), ".tex");
252 if (!buffer->tmppath.empty()
253 && !buffer->niceFile) {
254 incfile = subst(incfile, '/','@');
256 incfile = subst(incfile, ':', '$');
258 writefile = AddName(buffer->tmppath, incfile);
260 writefile = getFileName();
261 writefile = ChangeExtension(writefile, ".tex");
262 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
263 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
265 tmp->markDepClean(buffer->tmppath);
267 tmp->makeLaTeXFile(writefile,
268 OnlyPath(getMasterFilename()),
269 buffer->niceFile, true);
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 << '}';
279 os << '\\' << params_.cparams.getCmdName() << '{'
280 << ChangeExtension(incfile, ".tex")
284 // \include don't want extension and demands that the
285 // file really have .tex
286 os << '\\' << params_.cparams.getCmdName() << '{'
287 << ChangeExtension(incfile, string())
295 int InsetInclude::ascii(Buffer const *, std::ostream & os, int) const
298 os << GetFileContents(getFileName());
303 int InsetInclude::linuxdoc(Buffer const * buffer, ostream & os) const
305 string incfile(params_.cparams.getContents());
307 // Do nothing if no file name has been specified
311 if (loadIfNeeded()) {
312 Buffer * tmp = bufferlist.getBuffer(getFileName());
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);
320 writefile = getFileName();
322 if (IsLyXFilename(getFileName()))
323 writefile = ChangeExtension(writefile, ".sgml");
325 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
326 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
328 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
332 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
333 << "\" format=\"linespecific\">"
334 << "</inlinegraphic>";
336 os << '&' << include_label << ';';
342 int InsetInclude::docbook(Buffer const * buffer, ostream & os) const
344 string incfile(params_.cparams.getContents());
346 // Do nothing if no file name has been specified
350 if (loadIfNeeded()) {
351 Buffer * tmp = bufferlist.getBuffer(getFileName());
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);
359 writefile = getFileName();
360 if (IsLyXFilename(getFileName()))
361 writefile = ChangeExtension(writefile, ".sgml");
363 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
364 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
366 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
370 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
371 << "\" format=\"linespecific\">"
372 << "</inlinegraphic>";
374 os << '&' << include_label << ';';
380 void InsetInclude::validate(LaTeXFeatures & features) const
383 string incfile(params_.cparams.getContents());
386 Buffer const * const b = bufferlist.getBuffer(getMasterFilename());
388 if (b && !b->tmppath.empty() && b->niceFile) {
389 incfile = subst(incfile, '/','@');
390 writefile = AddName(b->tmppath, incfile);
392 writefile = getFileName();
394 if (IsLyXFilename(getFileName()))
395 writefile = ChangeExtension(writefile, ".sgml");
397 features.IncludedFiles[include_label] = writefile;
400 features.verbatim = true;
402 // Here we must do the fun stuff...
403 // Load the file in the include if it needs
405 if (loadIfNeeded()) {
407 Buffer const * const tmp = bufferlist.getBuffer(getFileName());
409 tmp->validate(features);
414 vector<string> const InsetInclude::getLabelList() const
418 if (loadIfNeeded()) {
419 Buffer * tmp = bufferlist.getBuffer(getFileName());
420 tmp->setParentName("");
421 l = tmp->getLabelList();
422 tmp->setParentName(getMasterFilename());
429 vector<pair<string,string> > const InsetInclude::getKeys() const
431 vector<pair<string,string> > keys;
433 if (loadIfNeeded()) {
434 Buffer * tmp = bufferlist.getBuffer(getFileName());
435 tmp->setParentName("");
436 keys = tmp->getBibkeyList();
437 tmp->setParentName(getMasterFilename());