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 }