10 #include "frontends/Dialogs.h"
12 #include "insetinclude.h"
14 #include "bufferlist.h"
16 #include "support/filetools.h"
19 #include "LaTeXFeatures.h"
21 #include "support/FileInfo.h"
30 extern BufferList bufferlist;
34 string const unique_id()
36 static unsigned int seed = 1000;
38 std::ostringstream ost;
39 ost << "file" << ++seed;
41 // Needed if we use lyxstring.
42 return ost.str().c_str();
48 InsetInclude::InsetInclude(Params const & p)
49 : params_(p), include_label(unique_id())
53 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b)
56 params_.masterFilename_ = b.fileName();
57 include_label = unique_id();
61 InsetInclude::~InsetInclude()
67 InsetInclude::Params const & InsetInclude::params() const
73 bool InsetInclude::Params::operator==(Params const & o) const
75 if (cparams == o.cparams && flag == o.flag &&
76 noload == o.noload && masterFilename_ == o.masterFilename_)
83 bool InsetInclude::Params::operator!=(Params const & o) const
89 void InsetInclude::set(Params const & p)
96 switch (params_.flag) {
101 command="verbatiminput";
107 command="verbatiminput*";
111 params_.cparams.setCmdName(command);
115 Inset * InsetInclude::Clone(Buffer const & buffer) const
118 p.masterFilename_ = buffer.fileName();
120 return new InsetInclude(p);
124 void InsetInclude::Edit(BufferView * bv, int, int, unsigned int)
126 bv->owner()->getDialogs()->showInclude(this);
130 void InsetInclude::Write(Buffer const *, ostream & os) const
132 os << "Include " << params_.cparams.getCommand() << "\n";
136 void InsetInclude::Read(Buffer const *, LyXLex & lex)
138 params_.cparams.Read(lex);
140 if (params_.cparams.getCmdName() == "include")
141 params_.flag = INCLUDE;
142 else if (params_.cparams.getCmdName() == "input")
143 params_.flag = INPUT;
144 /* FIXME: is this logic necessary now ? */
145 else if (contains(params_.cparams.getCmdName(), "verbatim")) {
147 if (params_.cparams.getCmdName() == "verbatiminput*")
148 params_.flag = VERBAST;
153 bool InsetInclude::display() const
155 return !(params_.flag == INPUT);
159 string const InsetInclude::getScreenLabel() const
163 switch (params_.flag) {
164 case INPUT: temp += _("Input"); break;
165 case VERB: temp += _("Verbatim Input"); break;
166 case VERBAST: temp += _("Verbatim Input*"); break;
167 case INCLUDE: temp += _("Include"); break;
172 if (params_.cparams.getContents().empty())
175 temp += params_.cparams.getContents();
181 string const InsetInclude::getRelFileBaseName() const
183 return OnlyFilename(ChangeExtension(params_.cparams.getContents(), string()));
187 string const InsetInclude::getFileName() const
189 return MakeAbsPath(params_.cparams.getContents(),
190 OnlyPath(getMasterFilename()));
194 string const InsetInclude::getMasterFilename() const
196 return params_.masterFilename_;
200 bool InsetInclude::loadIfNeeded() const
202 if (params_.noload || isVerbatim())
205 if (!IsLyXFilename(getFileName()))
208 if (bufferlist.exists(getFileName()))
211 // the readonly flag can/will be wrong, not anymore I think.
212 FileInfo finfo(getFileName());
213 bool const ro = !finfo.writable();
214 return bufferlist.readFile(getFileName(), ro) != 0;
218 int InsetInclude::Latex(Buffer const * buffer, ostream & os,
219 bool /*fragile*/, bool /*fs*/) const
221 string incfile(params_.cparams.getContents());
223 // Do nothing if no file name has been specified
227 if (loadIfNeeded()) {
228 Buffer * tmp = bufferlist.getBuffer(getFileName());
230 // FIXME: this should be a GUI warning
231 if (tmp->params.textclass != buffer->params.textclass) {
232 lyxerr << "WARNING: Included file `"
233 << MakeDisplayPath(getFileName())
234 << "' has textclass `"
235 << textclasslist.NameOfClass(tmp->params.textclass)
236 << "' while parent file has textclass `"
237 << textclasslist.NameOfClass(buffer->params.textclass)
242 // write it to a file (so far the complete file)
243 string writefile = ChangeExtension(getFileName(), ".tex");
245 if (!buffer->tmppath.empty()
246 && !buffer->niceFile) {
247 incfile = subst(incfile, '/','@');
249 incfile = subst(incfile, ':', '$');
251 writefile = AddName(buffer->tmppath, incfile);
253 writefile = getFileName();
254 writefile = ChangeExtension(writefile, ".tex");
255 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
256 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
258 tmp->markDepClean(buffer->tmppath);
260 tmp->makeLaTeXFile(writefile,
261 OnlyPath(getMasterFilename()),
262 buffer->niceFile, true);
266 os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
267 } else if (params_.flag == INPUT) {
268 // \input wants file with extension (default is .tex)
269 if (!IsLyXFilename(getFileName())) {
270 os << '\\' << params_.cparams.getCmdName() << '{' << incfile << '}';
272 os << '\\' << params_.cparams.getCmdName() << '{'
273 << ChangeExtension(incfile, ".tex")
277 // \include don't want extension and demands that the
278 // file really have .tex
279 os << '\\' << params_.cparams.getCmdName() << '{'
280 << ChangeExtension(incfile, string())
288 int InsetInclude::Ascii(Buffer const *, std::ostream & os, int) const
291 os << GetFileContents(getFileName());
296 int InsetInclude::Linuxdoc(Buffer const * buffer, ostream & os) const
298 string incfile(params_.cparams.getContents());
300 // Do nothing if no file name has been specified
304 if (loadIfNeeded()) {
305 Buffer * tmp = bufferlist.getBuffer(getFileName());
307 // write it to a file (so far the complete file)
308 string writefile = ChangeExtension(getFileName(), ".sgml");
309 if (!buffer->tmppath.empty() && !buffer->niceFile) {
310 incfile = subst(incfile, '/','@');
311 writefile = AddName(buffer->tmppath, incfile);
313 writefile = getFileName();
315 if (IsLyXFilename(getFileName()))
316 writefile = ChangeExtension(writefile, ".sgml");
318 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
319 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
321 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
325 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
326 << "\" format=\"linespecific\">"
327 << "</inlinegraphic>";
329 os << '&' << include_label << ';';
335 int InsetInclude::DocBook(Buffer const * buffer, ostream & os) const
337 string incfile(params_.cparams.getContents());
339 // Do nothing if no file name has been specified
343 if (loadIfNeeded()) {
344 Buffer * tmp = bufferlist.getBuffer(getFileName());
346 // write it to a file (so far the complete file)
347 string writefile = ChangeExtension(getFileName(), ".sgml");
348 if (!buffer->tmppath.empty() && !buffer->niceFile) {
349 incfile = subst(incfile, '/','@');
350 writefile = AddName(buffer->tmppath, incfile);
352 writefile = getFileName();
353 if (IsLyXFilename(getFileName()))
354 writefile = ChangeExtension(writefile, ".sgml");
356 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
357 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
359 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
363 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
364 << "\" format=\"linespecific\">"
365 << "</inlinegraphic>";
367 os << '&' << include_label << ';';
373 void InsetInclude::Validate(LaTeXFeatures & features) const
376 string incfile(params_.cparams.getContents());
379 Buffer const * const b = bufferlist.getBuffer(getMasterFilename());
381 if (b && !b->tmppath.empty() && b->niceFile) {
382 incfile = subst(incfile, '/','@');
383 writefile = AddName(b->tmppath, incfile);
385 writefile = getFileName();
387 if (IsLyXFilename(getFileName()))
388 writefile = ChangeExtension(writefile, ".sgml");
390 features.IncludedFiles[include_label] = writefile;
393 features.verbatim = true;
395 // Here we must do the fun stuff...
396 // Load the file in the include if it needs
398 if (loadIfNeeded()) {
400 Buffer const * const tmp = bufferlist.getBuffer(getFileName());
402 tmp->validate(features);
407 vector<string> const InsetInclude::getLabelList() const
411 if (loadIfNeeded()) {
412 Buffer * tmp = bufferlist.getBuffer(getFileName());
413 tmp->setParentName("");
414 l = tmp->getLabelList();
415 tmp->setParentName(getMasterFilename());
422 vector<pair<string,string> > const InsetInclude::getKeys() const
424 vector<pair<string,string> > keys;
426 if (loadIfNeeded()) {
427 Buffer * tmp = bufferlist.getBuffer(getFileName());
428 tmp->setParentName("");
429 keys = tmp->getBibkeyList();
430 tmp->setParentName(getMasterFilename());