First, a summary of the problem, since it has been discussed a while ago:

1. LyX interprets relative filenames relative to the document that contains
the filename. LaTeX interprets relative filenames relative to the master
document.

2. A filename in the .tex output of LyX should be absolute if it was
absolute in the .lyx file.

3. A filename in the .tex output of LyX should be relative if it was
relative in the .lyx file.


2. is no problem and works right now. 3. does not work in certain cases.

A possible solution is to define a variable that contains the correct path
in all cases:


Georg Baum wrote:

> Am Mittwoch, 24. März 2004 16:02 schrieb Angus Leeming:
>> It's a bit clumsy, but I'm happy to conceed it's needed.
> 
> It is clumsy, but I have been annoyed often enough by programs like
> powerpoint that change paths from relative to absolute and break things
> that I know I don't want lyx to behave like that.
> 
>> As for naming, why not
>> 
>> /home/angus/parent.lyx
>> /home/angus/foo/child.lyx
>> /home/angus/foo/bar/image.fig
>> 
>> image.fig would have:
>> 
>> $$Basename --- "image"
> 
> This is nice: The meaning is closer to the shell command "basename"
> 
>> $$Extension --- ".fig"
>> $$AbsPath --- "/home/angus/"
>> $$RelPath_Parent --- "bar/"
>> $$RelPath_Master --- "foo/bar/"
> 
> IMHO we still need a bit of magic, otherwise we are not able to preserve
> absolute file names. For example:
> 
> $$AbsPathOrRelPath_Parent --- "bar/"
> $$AbsPathOrRelPath_Master --- "foo/bar/"
> 
> for "filename image.fig" in parent.lyx and
> 
> $$AbsPathOrRelPath_Parent --- "/home/angus/foo/bar/"
> $$AbsPathOrRelPath_Master --- "/home/angus/foo/bar/"
> 
> for "filename /home/angus/foo/bar/image.fig" in parent.lyx.
> 
> $$RelPath_Parent and $$RelPath_Master are not needed for the current
> templates, but are maybe useful for something I can't imagine right now.


Here is a patch that implements this with one small change: use
$$AbsOrRelPath_Parent instead of $$AbsPathOrRelPath_Parent (otherwise
substitution would not work properly).

Is this ok?

What remains to be done is the documentation of the variables in
Customization.lyx. I could do this, but is there a 1.4 version of the
documentation yet?


Georg
Index: lib/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/lib/ChangeLog,v
retrieving revision 1.578
diff -u -r1.578 ChangeLog
--- lib/ChangeLog	2004/04/01 08:09:14	1.578
+++ lib/ChangeLog	2004/04/05 15:36:44
@@ -1,3 +1,8 @@
+2004-04-05  Georg Baum  <[EMAIL PROTECTED]>
+
+	* external_templates: use some new variables instead of $$Basename
+	(needed to fix bug #605)
+
 2004-04-01  Jürgen Spitzmüller  <[EMAIL PROTECTED]>
 
 	* help/ and contents is gone (outdated).
Index: lib/external_templates
===================================================================
RCS file: /cvs/lyx/lyx-devel/lib/external_templates,v
retrieving revision 1.22
diff -u -r1.22 external_templates
--- lib/external_templates	2004/01/05 16:49:34	1.22
+++ lib/external_templates	2004/04/05 15:21:25
@@ -35,14 +35,14 @@
 
 
 Template RasterImage
-	GuiName "Bitmap: $$Basename"
+	GuiName "Bitmap: $$AbsOrRelPath_Parent$$Basename"
 	HelpText
 		A bitmap file.
 		This template uses Gimp for editing.
 	HelpTextEnd
 	InputFormat "*"
 	FileFilter "*.{gif,png,jpg,bmp,pbm,ppm,tga,tif,xpm,xbm}"
-	EditCommand "gimp $$FName"
+	EditCommand "gimp $$Absname"
 	AutomaticProduction true
 	Transform Rotate
 	Transform Resize
@@ -54,9 +54,9 @@
 		TransformOption Clip   ClipLatexOption
 		TransformOption Extra  ExtraOption
 		Option Arg "[$$Extra,$$Rotate,$$Resize,$$Clip]"
-		Product "\\includegraphics$$Arg{$$Basename}"
+		Product "\\includegraphics$$Arg{$$AbsOrRelPath_Master$$Basename}"
 		UpdateFormat eps
-		UpdateResult "$$Basename.eps"
+		UpdateResult "$$AbsPath$$Basename.eps"
 		Requirement "graphicx"
 	FormatEnd
 	Format PDFLaTeX
@@ -65,20 +65,20 @@
 		TransformOption Clip   ClipLatexOption
 		TransformOption Extra  ExtraOption
 		Option Arg "[$$Extra,$$Rotate,$$Resize,$$Clip]"
-		Product "\\includegraphics$$Arg{$$Basename}"
+		Product "\\includegraphics$$Arg{$$AbsOrRelPath_Master$$Basename}"
 		UpdateFormat png
-		UpdateResult "$$Basename.png"
+		UpdateResult "$$AbsPath$$Basename.png"
 		Requirement "graphicx"
 	FormatEnd
 	Format Ascii
-		Product "$$Contents(\"$$Basename.asc\")"
+		Product "$$Contents(\"$$AbsPath$$Basename.asc\")"
 		UpdateFormat asciiimage
-		UpdateResult "$$Basename.asc"
+		UpdateResult "$$AbsPath$$Basename.asc"
 	FormatEnd
 	Format DocBook
-		Product "<graphic fileref=\"$$Basename.eps\"></graphic>"
+		Product "<graphic fileref=\"$$AbsOrRelPath_Master$$Basename.eps\"></graphic>"
 		UpdateFormat eps
-		UpdateResult "$$Basename.eps"
+		UpdateResult "$$AbsPath$$Basename.eps"
 	FormatEnd
 	Format LinuxDoc
 		Product "[Bitmap: $$FName]"
@@ -87,23 +87,23 @@
 
 
 Template XFig
-	GuiName "XFig: $$Basename"
+	GuiName "XFig: $$AbsOrRelPath_Parent$$Basename"
 	HelpText
 		An XFig figure.
 		This template uses XFig for editing.
 	HelpTextEnd
 	InputFormat fig
 	FileFilter "*.fig"
-	EditCommand "xfig $$FName"
+	EditCommand "xfig $$Absname"
 	AutomaticProduction true
 	Transform Rotate
 	Transform Resize
 	Format LaTeX
 		TransformCommand Rotate RotationLatexCommand
 		TransformCommand Resize ResizeLatexCommand
-		Product "$$RotateFront$$ResizeFront\\input{$$Basename.pstex_t}$$ResizeBack$$RotateBack"
+		Product "$$RotateFront$$ResizeFront\\input{$$AbsOrRelPath_Master$$Basename.pstex_t}$$ResizeBack$$RotateBack"
 		UpdateFormat pstex
-		UpdateResult "$$Basename.pstex_t"
+		UpdateResult "$$AbsPath$$Basename.pstex_t"
 		Requirement "graphicx"
 		Preamble WarnNotFound
 		Preamble InputOrWarn
@@ -111,22 +111,22 @@
 	Format PDFLaTeX
 		TransformCommand Rotate RotationLatexCommand
 		TransformCommand Resize ResizeLatexCommand
-		Product "$$RotateFront$$ResizeFront\\input{$$Basename.pdftex_t}$$ResizeBack$$RotateBack"
+		Product "$$RotateFront$$ResizeFront\\input{$$AbsOrRelPath_Master$$Basename.pdftex_t}$$ResizeBack$$RotateBack"
 		UpdateFormat pdftex
-		UpdateResult "$$Basename.pdftex_t"
+		UpdateResult "$$AbsPath$$Basename.pdftex_t"
 		Requirement "graphicx"
 		Preamble WarnNotFound
 		Preamble InputOrWarn
 	FormatEnd
 	Format Ascii
-		Product "$$Contents(\"$$Basename.asc\")"
+		Product "$$Contents(\"$$AbsPath$$Basename.asc\")"
 		UpdateFormat asciixfig
-		UpdateResult "$$Basename.asc"
+		UpdateResult "$$AbsPath$$Basename.asc"
 	FormatEnd
 	Format DocBook
-		Product "<graphic fileref=\"$$Basename.eps\"></graphic>"
+		Product "<graphic fileref=\"$$AbsOrRelPath_Master$$Basename.eps\"></graphic>"
 		UpdateFormat eps
-		UpdateResult "$$Basename.eps"
+		UpdateResult "$$AbsPath$$Basename.eps"
 	FormatEnd
 	Format LinuxDoc
 		Product "[XFig: $$FName]"
@@ -135,7 +135,7 @@
 
 
 Template ChessDiagram
-	GuiName "Chess: $$Basename"
+	GuiName "Chess: $$AbsOrRelPath_Parent$$Basename"
 	HelpText
 		A chess position diagram.
 		This template will use XBoard to edit the position.
@@ -157,19 +157,19 @@
 	HelpTextEnd
 	InputFormat fen
 	FileFilter "*.fen"
-	EditCommand "xboard -lpf $$FName -mode EditPosition"
+	EditCommand "xboard -lpf $$Absname -mode EditPosition"
 	AutomaticProduction true
 	Format LaTeX
-		Product "\\loadgame{$$FPath$$Basename}\\showboard"
+		Product "\\loadgame{$$AbsOrRelPath_Master$$Basename}\\showboard"
 		Requirement "chess"
 	FormatEnd
 	Format Ascii
-		Product "$$Contents(\"$$Basename.asc\")"
+		Product "$$Contents(\"$$AbsPath$$Basename.asc\")"
 		UpdateFormat asciichess
-		UpdateResult "$$Basename.asc"
+		UpdateResult "$$AbsPath$$Basename.asc"
 	FormatEnd
 	Format DocBook
-		Product "[Chess: $$Basename]"
+		Product "[Chess: $$AbsOrRelPath_Master$$Basename]"
 	FormatEnd
 	Format LinuxDoc
 		Product "[Chess: $$FName]"
Index: src/insets/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/ChangeLog,v
retrieving revision 1.992
diff -u -r1.992 ChangeLog
--- src/insets/ChangeLog	2004/04/05 09:36:26	1.992
+++ src/insets/ChangeLog	2004/04/05 15:21:53
@@ -1,3 +1,12 @@
+2004-04-05  Georg Baum  <[EMAIL PROTECTED]>
+
+	* ExternalSupport.C (doSubstitution): add new variables $$AbsPath,
+	$$RelPath_Master, $$RelPath_Parent, $$Extension,
+	$$AbsOrRelPath_Master and $$AbsOrRelPath_Parent. Change the meaning
+	of $$Basename
+	* ExternalSupport.C (updateExternal): use absolute and output
+	filename where appropriate
+
 2004-05-04  Angus Leeming  <[EMAIL PROTECTED]>
 
 	* insetbibitem.C:
Index: src/insets/ExternalSupport.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/ExternalSupport.C,v
retrieving revision 1.5
diff -u -r1.5 ExternalSupport.C
--- src/insets/ExternalSupport.C	2004/03/25 10:12:43	1.5
+++ src/insets/ExternalSupport.C	2004/04/05 15:21:53
@@ -78,12 +78,40 @@
 			    string const & filename)
 {
 	string result;
-	string const basename = support::ChangeExtension(filename, string());
+	string const basename = support::ChangeExtension(
+			support::OnlyFilename(filename), string());
+	string const absname = support::MakeAbsPath(filename, buffer.filePath());
 	string const filepath = support::OnlyPath(filename);
+	string const abspath = support::OnlyPath(absname);
+	Buffer const * m_buffer = buffer.getMasterBuffer();
+	string relToMasterPath = support::OnlyPath(
+			support::MakeRelPath(absname, m_buffer->filePath()));
+	if (relToMasterPath == "./")
+		relToMasterPath.clear();
+	string relToParentPath = support::OnlyPath(
+			support::MakeRelPath(absname, buffer.filePath()));
+	if (relToParentPath == "./")
+		relToParentPath.clear();
 
 	result = support::subst(s, "$$FName", filename);
 	result = support::subst(result, "$$Basename", basename);
+	result = support::subst(result, "$$Extension",
+			'.' + support::GetExtension(filename));
 	result = support::subst(result, "$$FPath", filepath);
+	result = support::subst(result, "$$AbsPath", abspath);
+	result = support::subst(result, "$$RelPath_Master", relToMasterPath);
+	result = support::subst(result, "$$RelPath_Parent", relToParentPath);
+	if (support::AbsolutePath(filename)) {
+		result = support::subst(result, "$$AbsOrRelPath_Master",
+		                        abspath);
+		result = support::subst(result, "$$AbsOrRelPath_Parent",
+		                        abspath);
+	} else {
+		result = support::subst(result, "$$AbsOrRelPath_Master",
+		                        relToMasterPath);
+		result = support::subst(result, "$$AbsOrRelPath_Parent",
+		                        relToParentPath);
+	}
 	result = support::subst(result, "$$Tempname", params.tempname());
 	result = support::subst(result, "$$Sysdir", support::system_lyxdir());
 
@@ -96,7 +124,7 @@
 		string contents;
 
 		string const filepath = support::IsFileReadable(file) ?
-			buffer.filePath() : buffer.getMasterBuffer()->temppath();
+			buffer.filePath() : m_buffer->temppath();
 		support::Path p(filepath);
 
 		if (support::IsFileReadable(file))
@@ -139,16 +167,17 @@
 	if (from_format.empty())
 		return; // NOT_NEEDED
 
-	string from_file = params.filename.absFilename();
+	string abs_from_file = params.filename.absFilename();
 
 	if (from_format == "*") {
-		if (from_file.empty())
+		if (abs_from_file.empty())
 			return; // NOT_NEEDED
 
 		// Try and ascertain the file format from its contents.
-		from_format = support::getExtFromContents(from_file);
+		from_format = support::getExtFromContents(abs_from_file);
 		if (from_format.empty())
 			return; // FAILURE
+
 	}
 
 	string const to_format = outputFormat.updateFormat;
@@ -163,24 +192,32 @@
 		return; // FAILURE
 	}
 
+	string from_file = params.filename.outputFilename(buffer.filePath());
+
 	// The master buffer. This is useful when there are multiple levels
 	// of include files
 	Buffer const * m_buffer = buffer.getMasterBuffer();
 
-	if (external_in_tmpdir && !from_file.empty()) {
+	if (external_in_tmpdir && !abs_from_file.empty()) {
 		// We are running stuff through LaTeX
 		string const temp_file =
 			support::MakeAbsPath(params.filename.mangledFilename(),
 					     m_buffer->temppath());
-		unsigned long const from_checksum = support::sum(from_file);
+		unsigned long const from_checksum = support::sum(abs_from_file);
 		unsigned long const temp_checksum = support::sum(temp_file);
 
 		if (from_checksum != temp_checksum) {
-			if (!support::copy(from_file, temp_file))
+			if (!support::copy(abs_from_file, temp_file)) {
+				lyxerr[Debug::EXTERNAL]
+					<< "external::updateExternal. "
+					<< "Unable to copy "
+					<< abs_from_file << " to " << temp_file << endl;
 				return; // FAILURE
+			}
 		}
 
 		from_file = temp_file;
+		abs_from_file = temp_file;
 	}
 
 	string const to_file = doSubstitution(params, buffer,
@@ -194,13 +231,13 @@
 
 	// Do we need to perform the conversion?
 	// Yes if to_file does not exist or if from_file is newer than to_file
-	if (support::compare_timestamps(from_file, abs_to_file) < 0)
+	if (support::compare_timestamps(abs_from_file, abs_to_file) < 0)
 		return; // SUCCESS
 
 	string const to_file_base =
 		support::ChangeExtension(to_file, string());
 	/* bool const success = */
-		converters.convert(&buffer, from_file, to_file_base,
+		converters.convert(&buffer, abs_from_file, to_file_base,
 				   from_format, to_format);
 	// return success
 }

Reply via email to