Finally I found time to investigate a bit further:

Jean-Marc Lasgouttes wrote:

>>>>>> "Georg" == Georg Baum <[EMAIL PROTECTED]> writes:
> 
> Georg> Not much. The stuff related to #605 is
> 
> Georg> s/buffer\.temppath()/buffer.getMasterBuffer()->temppath()/g
> 
> Georg> in ExternalSupport.C.
> 
> But how do you deal with normal export? If file foo1.lyx includes
> dir/foo2.lyx and foo2.lyx has an external inset bar.dat, the name
> should be exported in latex as dir/bar.dat, shouldn't it?
> 
> From my cursory looking at the sources, we cannot do that directly in
> doSubstitution, since there are cases where we want $$FName as plain
> bar.dat.
> 
> It seems to me that it is necessary to add a bool to doSubstitution
> telling wether relative file names should relative to buffer or master
> buffer.

I changed the input file name for doSubstitution() in writeExternal(). This 
works now for the RasterImage template, but I am not sure wether it is 
correct: We assume that $$FName is used as argument to some LaTeX input 
command, but this does not need to be the case.
I believe the only way to do it correctly is to define a new variable:

$$FName:
The filename exactly as the user entered it (absolute or relative to the 
file that contains the template).

$$LatexName:
The filename in a way suitable for a LaTeX include command (absolute or 
relative to the master file)

Angus, what do you think?

> Georg> It is easy to start with the #605 part. Sould I separate this
> Georg> out?
> 
> I guess it would be a good idea.

See attached. It is the ported 605 stuff + the above mentioned insetexternal 
changes + copying included .tex files to the temp dir.
Apart from the question metioned above it is ready for applying.

Georg
Index: src/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/ChangeLog,v
retrieving revision 1.1829
diff -u -r1.1829 ChangeLog
--- src/ChangeLog	2004/03/11 16:09:32	1.1829
+++ src/ChangeLog	2004/03/15 18:34:46
@@ -1,3 +1,16 @@
+2003-02-12  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
+
+	* buffer.C (makeLaTeXFile): if the main latex file that is
+	processed is usually a subdocument of some master, then pretend
+	for a while that it is actually the master
+
+2003-02-10  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
+
+	* buffer.C (getLabelList):
+	(getBibkeyList): use getMasterBuffer()
+	(getMasterBuffer): new method. Returns the main document in the
+	case where one is using included documents.
+
 
 2004-03-11  André Pönitz  <[EMAIL PROTECTED]>
 
Index: src/buffer.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/buffer.C,v
retrieving revision 1.559
diff -u -r1.559 buffer.C
--- src/buffer.C	2004/03/11 17:16:24	1.559
+++ src/buffer.C	2004/03/15 18:34:48
@@ -857,6 +882,9 @@
 	// [EMAIL PROTECTED] is set when the actual parameter
 	// original_path is set. This is done for usual tex-file, but not
 	// for nice-latex-file. (Matthias 250696)
+	// Note that [EMAIL PROTECTED] is only needed for something the user does
+	// in the preamble, included .tex files or ERT, files included by
+	// LyX work without it.
 	if (output_preamble) {
 		if (!runparams.nice) {
 			// code for usual, NOT nice-latex-file
@@ -895,8 +923,22 @@
 		texrow().newline();
 	}
 
+	// if we are doing a real file with body, even if this is the
+	// child of some other buffer, let's cut the link here.
+	// This happens for example if only a child document is printed.
+	string save_parentname;
+	if (output_preamble) {
+		save_parentname = params().parentname;
+		params().parentname.erase();
+	}
+
+	// the real stuff
 	latexParagraphs(*this, paragraphs(), os, texrow(), runparams);
 
+	// Restore the parenthood if needed
+	if (output_preamble)
+		params().parentname = save_parentname;
+
 	// add this just in case after all the paragraphs
 	os << endl;
 	texrow().newline();
@@ -1164,13 +1213,10 @@
 {
 	/// if this is a child document and the parent is already loaded
 	/// Use the parent's list instead  [ale990407]
-	if (!params().parentname.empty()
-	    && bufferlist.exists(params().parentname)) {
-		Buffer const * tmp = bufferlist.getBuffer(params().parentname);
-		if (tmp) {
-			tmp->getLabelList(list);
-			return;
-		}
+	Buffer const * tmp = getMasterBuffer();
+	if (tmp != this) {
+		tmp->getLabelList(list);
+		return;
 	}
 
 	for (inset_iterator it = inset_const_iterator_begin();
@@ -1186,13 +1232,10 @@
 {
 	/// if this is a child document and the parent is already loaded
 	/// use the parent's list instead  [ale990412]
-	if (!params().parentname.empty() &&
-	    bufferlist.exists(params().parentname)) {
-		Buffer const * tmp = bufferlist.getBuffer(params().parentname);
-		if (tmp) {
-			tmp->fillWithBibKeys(keys);
-			return;
-		}
+	Buffer const * tmp = getMasterBuffer();
+	if (tmp != this) {
+		tmp->fillWithBibKeys(keys);
+		return;
 	}
 
 	for (inset_iterator it = inset_const_iterator_begin();
@@ -1473,6 +1516,19 @@
 void Buffer::setParentName(string const & name)
 {
 	params().parentname = name;
+}
+
+
+Buffer const * Buffer::getMasterBuffer() const
+{
+	if (!params().parentname.empty()
+	    && bufferlist.exists(params().parentname)) {
+		Buffer const * buf = bufferlist.getBuffer(params().parentname);
+		if (buf)
+			return buf->getMasterBuffer();
+	}
+
+	return this;
 }
 
 
Index: src/buffer.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/buffer.h,v
retrieving revision 1.180
diff -u -r1.180 buffer.h
--- src/buffer.h	2004/03/11 17:16:25	1.180
+++ src/buffer.h	2004/03/15 18:34:48
@@ -207,6 +207,11 @@
 	/// Name of the document's parent
 	void setParentName(std::string const &);
 
+	/** Get the document's master (or \c this if this is not a
+	    child document)
+	 */
+	Buffer const * getMasterBuffer() const;
+
 	/// Is buffer read-only?
 	bool isReadonly() const;
 
Index: src/insets/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/ChangeLog,v
retrieving revision 1.975
diff -u -r1.975 ChangeLog
--- src/insets/ChangeLog	2004/03/10 08:50:46	1.975
+++ src/insets/ChangeLog	2004/03/15 18:35:20
@@ -1,3 +1,28 @@
+2004-03-15  Georg Baum  <[EMAIL PROTECTED]>
+
+	* ExternalSupport.C: use the master buffer's temp dir
+	* ExternalSupport.C (writeExternal): make relative filename relative
+	to the master file
+	* insetinclude.C (latex): return relative filename
+	* insetinclude.C (masterFilename): new function
+	* insetinclude.C (linuxdoc, docbook): simplify logic (IsLyXFilename()
+	is always true if loadIfNeeded() returns true)
+	* insetgraphics.C (latex): make relative filename relative to the
+	master file
+	* insetgraphics.C: use the master buffer's temp dir
+
+2003-02-10  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
+
+	* insetinclude.C (loadIfNeeded): when the child buffer is loaded,
+	set its parent to the current buffer.
+	(latex): use the tmppath of the master buffer, not just the parent
+	buffer (makes a difference with more than one level of include
+	insets). If the file name is relative write in the .tex file a
+	name relative to the master buffer directory.
+
+	* insetinclude.C: rename masterFilename to parentFilename (this
+	points to the direct parent)
+
 2004-03-09  Alfredo Braunstein  <[EMAIL PROTECTED]>
 
 	* insetcollapsable.[Ch] (metrics, draw): implemented an inlined-Open 
Index: src/insets/ExternalSupport.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/ExternalSupport.C,v
retrieving revision 1.4
diff -u -r1.4 ExternalSupport.C
--- src/insets/ExternalSupport.C	2003/10/13 02:10:45	1.4
+++ src/insets/ExternalSupport.C	2004/03/15 18:35:20
@@ -96,7 +96,7 @@
 		string contents;
 
 		string const filepath = support::IsFileReadable(file) ?
-			buffer.filePath() : buffer.temppath();
+			buffer.filePath() : buffer.getMasterBuffer()->temppath();
 		support::Path p(filepath);
 
 		if (support::IsFileReadable(file))
@@ -167,7 +184,7 @@
 		// We are running stuff through LaTeX
 		string const temp_file =
 			support::MakeAbsPath(params.filename.mangledFilename(),
-					     buffer.temppath());
+					     buffer.getMasterBuffer()->temppath());
 		unsigned long const from_checksum = support::sum(from_file);
 		unsigned long const temp_checksum = support::sum(temp_file);
 
@@ -184,7 +210,9 @@
 					      from_file);
 
 	string const abs_to_file =
-		support::MakeAbsPath(to_file, buffer.filePath());
+		support::MakeAbsPath(to_file, external_in_tmpdir
+			? buffer.getMasterBuffer()->temppath()
+			: buffer.filePath());
 
 	// Do we need to perform the conversion?
 	// Yes if to_file does not exist or if from_file is newer than to_file
@@ -230,12 +260,14 @@
 
 	updateExternal(params, format, buffer, external_in_tmpdir);
 
-	string from_file = params.filename.outputFilename(buffer.filePath());
+	// a relative filename should be relative to the master buffer
+	string from_file = params.filename.outputFilename(
+				buffer.getMasterBuffer()->filePath());
 	if (external_in_tmpdir && !from_file.empty()) {
 		// We are running stuff through LaTeX
 		from_file =
 			support::MakeAbsPath(params.filename.mangledFilename(),
-					     buffer.temppath());
+			                     buffer.getMasterBuffer()->temppath());
 	}
 
 	string str = doSubstitution(params, buffer, cit->second.product,
Index: src/insets/insetgraphics.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/insetgraphics.C,v
retrieving revision 1.237
diff -u -r1.237 insetgraphics.C
--- src/insets/insetgraphics.C	2004/02/25 12:00:53	1.237
+++ src/insets/insetgraphics.C	2004/03/15 18:35:22
@@ -434,10 +435,15 @@
 	// we move it to a temp dir or uncompress it.
 	string temp_file = orig_file;
 
+	// We place all temporary files in the master buffer's temp dir.
+	// This is possible because we use mangled file names.
+	// This is necessary for DVI export.
+	string const temp_path = buf.getMasterBuffer()->temppath();
+
 	if (zipped) {
 		CopyStatus status;
 		boost::tie(status, temp_file) =
-			copyToDirIfNeeded(orig_file, buf.temppath());
+			copyToDirIfNeeded(orig_file, temp_path);
 
 		if (status == FAILURE)
 			return orig_file;
@@ -465,7 +471,7 @@
 	bool conversion_needed = true;
 	CopyStatus status;
 	boost::tie(status, temp_file) =
-			copyToDirIfNeeded(orig_file, buf.temppath());
+			copyToDirIfNeeded(orig_file, temp_path);
 
 	if (status == FAILURE)
 		return orig_file;
@@ -523,6 +529,10 @@
 int InsetGraphics::latex(Buffer const & buf, ostream & os,
 			 OutputParams const & runparams) const
 {
+	// The master buffer. This is useful when there are multiple levels
+	// of include files
+	Buffer const * m_buffer = buf.getMasterBuffer();
+
 	// If there is no file specified or not existing,
 	// just output a message about it in the latex output.
 	lyxerr[Debug::GRAPHICS]
@@ -576,19 +586,23 @@
 		<< "\n\tafter = " << after << endl;
 
 
+	string latex_str = before + '{';
 	// "nice" means that the buffer is exported to LaTeX format but not
 	//        run through the LaTeX compiler.
 	if (runparams.nice) {
-		os << before <<'{' << relative_file << '}' << after;
-		return 1;
-	}
+		// a relative filename should be relative to the master
+		// buffer.
+		latex_str += params().filename.outputFilename(m_buffer->filePath());
+	} else if (file_exists) {
+		// Make the filename relative to the lyx file
+		// and remove the extension so the LaTeX will use whatever
+		// is appropriate (when there are several versions in
+		// different formats)
+		latex_str += os::external_path(prepareFile(buf, runparams));
+	} else
+		latex_str += relative_file + " not found!";
 
-	// Make the filename relative to the lyx file
-	// and remove the extension so the LaTeX will use whatever is
-	// appropriate (when there are several versions in different formats)
-	string const latex_str = message.empty() ?
-		(before + '{' + os::external_path(prepareFile(buf, runparams)) + '}' + after) :
-		(before + '{' + relative_file + " not found!}" + after);
+	latex_str += '}' + after;
 	os << latex_str;
 
 	lyxerr[Debug::GRAPHICS] << "InsetGraphics::latex outputting:\n"
Index: src/insets/insetinclude.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/insetinclude.C,v
retrieving revision 1.184
diff -u -r1.184 insetinclude.C
--- src/insets/insetinclude.C	2004/02/25 12:00:53	1.184
+++ src/insets/insetinclude.C	2004/03/15 18:35:22
@@ -40,6 +40,7 @@
 #include "support/filename.h"
 #include "support/filetools.h"
 #include "support/lstrings.h" // contains
+#include "support/lyxlib.h"
 #include "support/tostr.h"
 
 #include <boost/bind.hpp>
@@ -46,9 +47,11 @@
 #include "support/std_sstream.h"
 
 using lyx::support::AddName;
+using lyx::support::AbsolutePath;
 using lyx::support::bformat;
 using lyx::support::ChangeExtension;
 using lyx::support::contains;
+using lyx::support::copy;
 using lyx::support::FileInfo;
 using lyx::support::FileName;
 using lyx::support::GetFileContents;
@@ -58,9 +62,11 @@
 using lyx::support::IsLyXFilename;
 using lyx::support::MakeAbsPath;
 using lyx::support::MakeDisplayPath;
+using lyx::support::MakeRelPath;
 using lyx::support::OnlyFilename;
 using lyx::support::OnlyPath;
 using lyx::support::subst;
+using lyx::support::sum;
 
 using std::endl;
 using std::string;
@@ -187,6 +193,12 @@
 
 string const masterFilename(Buffer const & buffer)
 {
+	return buffer.getMasterBuffer()->fileName();
+}
+
+
+string const parentFilename(Buffer const & buffer)
+{
 	return buffer.fileName();
 }
 
@@ -195,7 +207,7 @@
 			      InsetCommandParams const & params)
 {
 	return MakeAbsPath(params.getContents(),
-			   OnlyPath(masterFilename(buffer)));
+			   OnlyPath(parentFilename(buffer)));
 }
 
 
@@ -282,15 +294,19 @@
 	if (!IsLyXFilename(included_file))
 		return false;
 
-	if (bufferlist.exists(included_file))
-		return true;
-
-	// the readonly flag can/will be wrong, not anymore I think.
-	FileInfo finfo(included_file);
-	if (!finfo.isOK())
-		return false;
-	return loadLyXFile(bufferlist.newBuffer(included_file),
-			   included_file);
+	Buffer * buf = bufferlist.getBuffer(included_file);
+	if (!buf) {
+		// the readonly flag can/will be wrong, not anymore I think.
+		FileInfo finfo(included_file);
+		if (!finfo.isOK())
+			return false;
+		buf = bufferlist.newBuffer(included_file);
+		if (!loadLyXFile(buf, included_file))
+			return false;
+	}
+	if (buf)
+		buf->setParentName(parentFilename(buffer));
+	return buf != 0;
 }
 
 
@@ -307,37 +323,67 @@
 		return 0;
 
 	string const included_file = includedFilename(buffer, params_);
+	Buffer const * const m_buffer = buffer.getMasterBuffer();
+
+	// if incfile is relative, make it relative to the master
+	// buffer directory.
+	if (!AbsolutePath(incfile)) {
+		incfile = MakeRelPath(included_file,
+		                      m_buffer->filePath());
+	}
+
+	// write it to a file (so far the complete file)
+	string writefile = ChangeExtension(included_file, ".tex");
+
+	if (!runparams.nice) {
+		incfile = FileName(writefile).mangledFilename();
+		writefile = MakeAbsPath(incfile, m_buffer->temppath());
+	}
+	lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
+	lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
 
 	if (loadIfNeeded(buffer, params_)) {
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 
-		if (tmp->params().textclass != buffer.params().textclass) {
+		if (tmp->params().textclass != m_buffer->params().textclass) {
 			string text = bformat(_("Included file `%1$s'\n"
 			                        "has textclass `%2$s'\n"
 			                        "while parent file has textclass `%3$s'."),
 			                      MakeDisplayPath(included_file),
 			                      tmp->params().getLyXTextClass().name(),
-			                      buffer.params().getLyXTextClass().name());
+			                      m_buffer->params().getLyXTextClass().name());
 			Alert::warning(_("Different textclasses"), text);
 			//return 0;
 		}
 
-		// write it to a file (so far the complete file)
-		string writefile = ChangeExtension(included_file, ".tex");
+		tmp->markDepClean(m_buffer->temppath());
 
-		if (!runparams.nice) {
-			incfile = FileName(writefile).mangledFilename();
-			writefile = MakeAbsPath(incfile, buffer.temppath());
-		}
-
-		lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
-		lyxerr[Debug::LATEX] << "writefile:" << writefile << endl;
-
-		tmp->markDepClean(buffer.temppath());
-
+#ifdef WITH_WARNINGS
+#warning Second argument is irrelevant!
+// since only_body is true, makeLaTeXFile will not look at second
+// argument. Should we set it to string(), or should makeLaTeXFile
+// make use of it somehow? (JMarc 20031002)
+#endif
 		tmp->makeLaTeXFile(writefile,
 				   OnlyPath(masterFilename(buffer)),
 				   runparams, false);
+	} else if (!runparams.nice) {
+		// Copy the file to the temp dir, so that .aux files etc.
+		// are not created in the original dir. Files included by
+		// this file will be found via [EMAIL PROTECTED], see ../buffer.C.
+		unsigned long const checksum_in  = sum(included_file);
+		unsigned long const checksum_out = sum(writefile);
+
+		if (checksum_in != checksum_out) {
+			if (!copy(included_file, writefile)) {
+				lyxerr[Debug::LATEX]
+					<< bformat(_("Could not copy the file\n%1$s\n"
+					             "into the temporary directory."),
+					           included_file)
+					<< endl;
+				return 0;
+			}
+		}
 	}
 
 	if (isVerbatim(params_)) {
@@ -387,15 +435,12 @@
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 
 		// write it to a file (so far the complete file)
-		string writefile;
-		if (IsLyXFilename(included_file))
-			writefile = ChangeExtension(included_file, ".sgml");
-		else
-			writefile = included_file;
+		string writefile = ChangeExtension(included_file, ".sgml");
 
 		if (!runparams.nice) {
 			incfile = FileName(writefile).mangledFilename();
-			writefile = MakeAbsPath(incfile, buffer.temppath());
+			writefile = MakeAbsPath(incfile,
+			                        buffer.getMasterBuffer()->temppath());
 		}
 
 		lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
@@ -431,15 +477,12 @@
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 
 		// write it to a file (so far the complete file)
-		string writefile;
-		if (IsLyXFilename(included_file))
-			writefile = ChangeExtension(included_file, ".sgml");
-		else
-			writefile = included_file;
+		string writefile = ChangeExtension(included_file, ".sgml");
 
 		if (!runparams.nice) {
 			incfile = FileName(writefile).mangledFilename();
-			writefile = MakeAbsPath(incfile, buffer.temppath());
+			writefile = MakeAbsPath(incfile,
+			                        buffer.getMasterBuffer()->temppath());
 		}
 
 		lyxerr[Debug::LATEX] << "incfile:" << incfile << endl;
@@ -471,7 +515,8 @@
 
 	if (!features.nice() && !isVerbatim(params_)) {
 		incfile = FileName(writefile).mangledFilename();
-		writefile = MakeAbsPath(incfile, buffer.temppath());
+		writefile = MakeAbsPath(incfile,
+			                buffer.getMasterBuffer()->temppath());
 	}
 
 	features.includeFile(include_label, writefile);
@@ -504,7 +548,7 @@
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 		tmp->setParentName("");
 		tmp->getLabelList(list);
-		tmp->setParentName(masterFilename(buffer));
+		tmp->setParentName(parentFilename(buffer));
 	}
 }
 
@@ -517,7 +561,7 @@
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 		tmp->setParentName("");
 		tmp->fillWithBibKeys(keys);
-		tmp->setParentName(masterFilename(buffer));
+		tmp->setParentName(parentFilename(buffer));
 	}
 }
 

Reply via email to