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;
35 static unsigned int seed = 1000;
37 std::ostringstream ost;
38 ost << "file" << ++seed;
40 // Needed if we use lyxstring.
41 return ost.str().c_str();
45 InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & bf)
46 : InsetCommand(p), master(&bf)
48 flag = InsetInclude::INCLUDE;
50 include_label = unique_id();
54 InsetInclude::~InsetInclude()
59 Inset * InsetInclude::Clone(Buffer const & buffer) const
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.
69 ii->setVisibleSpace(isVerbVisibleSpace());
75 void InsetInclude::Edit(BufferView * bv, int, int, unsigned int)
77 bv->owner()->getDialogs()->showInclude(this);
81 void InsetInclude::Write(Buffer const *, ostream & os) const
83 os << "Include " << getCommand() << "\n";
87 void InsetInclude::Read(Buffer const * buf, LyXLex & lex)
89 InsetCommand::Read(buf, lex);
91 if (getCmdName() == "include")
93 else if (getCmdName() == "input")
95 else if (contains(getCmdName(), "verbatim")) {
97 if (getCmdName() == "verbatiminput*")
98 setVisibleSpace(true);
103 bool InsetInclude::display() const
109 string const InsetInclude::getScreenLabel() const
115 temp += _("Verbatim Input");
116 if (isVerbVisibleSpace()) temp += '*';
117 } else temp += _("Include");
120 if (getContents().empty()) {
123 temp+= getContents();
129 string const InsetInclude::getFileName() const
131 return MakeAbsPath(getContents(),
132 OnlyPath(getMasterFilename()));
136 string const InsetInclude::getMasterFilename() const
138 return master->fileName();
142 bool InsetInclude::loadIfNeeded() const
144 if (isNoLoad() || isVerb()) return false;
145 if (!IsLyXFilename(getFileName())) return false;
147 if (bufferlist.exists(getFileName())) return true;
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;
156 int InsetInclude::Latex(Buffer const * buffer, ostream & os,
157 bool /*fragile*/, bool /*fs*/) const
159 string incfile(getContents());
161 // Do nothing if no file name has been specified
165 if (loadIfNeeded()) {
166 Buffer * tmp = bufferlist.getBuffer(getFileName());
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)
174 << textclasslist.NameOfClass(buffer->params.textclass)
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, '/','@');
185 incfile = subst(incfile, ':', '$');
187 writefile = AddName(buffer->tmppath, incfile);
189 writefile = getFileName();
190 writefile = ChangeExtension(writefile, ".tex");
191 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
192 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
194 tmp->markDepClean(buffer->tmppath);
196 tmp->makeLaTeXFile(writefile,
197 OnlyPath(getMasterFilename()),
198 buffer->niceFile, true);
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 << '}';
208 os << '\\' << getCmdName() << '{'
209 << ChangeExtension(incfile, ".tex")
213 // \include don't want extension and demands that the
214 // file really have .tex
215 os << '\\' << getCmdName() << '{'
216 << ChangeExtension(incfile, string())
224 int InsetInclude::Ascii(Buffer const *, std::ostream & os, int) const
227 os << GetFileContents(getFileName());
232 int InsetInclude::Linuxdoc(Buffer const * buffer, ostream & os) const
234 string incfile(getContents());
236 // Do nothing if no file name has been specified
240 if (loadIfNeeded()) {
241 Buffer * tmp = bufferlist.getBuffer(getFileName());
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);
249 writefile = getFileName();
251 if (IsLyXFilename(getFileName()))
252 writefile = ChangeExtension(writefile, ".sgml");
254 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
255 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
257 tmp->makeLinuxDocFile(writefile, buffer->niceFile, true);
261 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
262 << "\" format=\"linespecific\">"
263 << "</inlinegraphic>";
265 os << '&' << include_label << ';';
271 int InsetInclude::DocBook(Buffer const * buffer, ostream & os) const
273 string incfile(getContents());
275 // Do nothing if no file name has been specified
279 if (loadIfNeeded()) {
280 Buffer * tmp = bufferlist.getBuffer(getFileName());
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);
288 writefile = getFileName();
289 if (IsLyXFilename(getFileName()))
290 writefile = ChangeExtension(writefile, ".sgml");
292 lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
293 lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
295 tmp->makeDocBookFile(writefile, buffer->niceFile, true);
299 os << "<inlinegraphic fileref=\"" << '&' << include_label << ';'
300 << "\" format=\"linespecific\">"
301 << "</inlinegraphic>";
303 os << '&' << include_label << ';';
309 void InsetInclude::Validate(LaTeXFeatures & features) const
312 string incfile(getContents());
313 string writefile; // = ChangeExtension(getFileName(), ".sgml");
315 if (!master->tmppath.empty() && !master->niceFile) {
316 incfile = subst(incfile, '/','@');
317 writefile = AddName(master->tmppath, incfile);
319 writefile = getFileName();
320 // Use the relative path.
321 //writefile = incfile;
323 if (IsLyXFilename(getFileName()))
324 writefile = ChangeExtension(writefile, ".sgml");
326 features.IncludedFiles[include_label] = writefile;
329 features.verbatim = true;
331 // Here we must do the fun stuff...
332 // Load the file in the include if it needs
334 if (loadIfNeeded()) {
336 Buffer * tmp = bufferlist.getBuffer(getFileName());
337 tmp->validate(features);
342 vector<string> const InsetInclude::getLabelList() const
346 if (loadIfNeeded()) {
347 Buffer * tmp = bufferlist.getBuffer(getFileName());
348 tmp->setParentName("");
349 l = tmp->getLabelList();
350 tmp->setParentName(getMasterFilename());
357 vector<pair<string,string> > const InsetInclude::getKeys() const
359 vector<pair<string,string> > keys;
361 if (loadIfNeeded()) {
362 Buffer * tmp = bufferlist.getBuffer(getFileName());
363 tmp->setParentName("");
364 keys = tmp->getBibkeyList();
365 tmp->setParentName(getMasterFilename());