This is the promised fix for bugs 605, 1231, and 1244. It is work in
progress, the html export is not fixed yet.


What this patch does:

- maintain a list of included graphics files for the exporter, so that they
can be copied for dvi output.

- use always relative filenames for graphics if running latex in the
tempdir. Use the name the user gave (relative or absolute) otherwise.

- require always a file extension for included graphics. LyX needs it,
because it must display and convert the included image. This is no
disadvantage for the latex output, because there the extension is always
omitted. To make this work, a trick from the UK TeX FAQ had to be applied.
This is a file format change.

- copy included .tex files into the temp dir rather than referencing them
through [EMAIL PROTECTED] This is a preparation for html export.

- put every included material into the master buffer's temp dir. This works
because we use mangled filenames and is needed for the dvi export.

- the only difference between 'nice' and 'unnice' latex export for graphics
is now that in the former case the files are not converted and the above
mentioned filename differences.


Open questions:

- The ExportData struct is rather a hack because it circumvents the
const'ness of runparams. How to do this properly?
- Does the \lyxdot trick work on other platforms than unix?
- the test for format 229 in lyx2lyx is not nice. How to do it better? Also
note that the addition of graphics extensions from format 229 to 230 fails
if lyx2lyx is used as a filter.
- where to put copyToDirIfNeeded() (now used both by graphics and include
inset)?
- usage of boost::filesystem::path can probably be improved in the exporter.


If the overall direction is ok, I'll continue with the html export.


Georg
Index: development/FORMAT
===================================================================
RCS file: /cvs/lyx/lyx-devel/development/FORMAT,v
retrieving revision 1.22
diff -u -r1.22 FORMAT
--- development/FORMAT	2004/01/07 14:36:42	1.22
+++ development/FORMAT	2004/02/27 17:21:34
@@ -1,6 +1,12 @@
 LyX file-format changes
 -----------------------
 
+2004-02-27  Georg Baum  <[EMAIL PROTECTED]>
+
+	* format incremented to 230.
+	* insetgraphics does not allow filenames without extension anymore.
+	The complete filename has to be given.
+
 2003-12-29  Jürgen Spitzmüller  <[EMAIL PROTECTED]>
 
 	* format incremented to 229.
Index: lib/lyx2lyx/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/lib/lyx2lyx/ChangeLog,v
retrieving revision 1.21
diff -u -r1.21 ChangeLog
--- lib/lyx2lyx/ChangeLog	2004/02/04 18:11:44	1.21
+++ lib/lyx2lyx/ChangeLog	2004/02/27 17:21:44
@@ -1,3 +1,9 @@
+2004-02-27  Georg Baum  <[EMAIL PROTECTED]>
+
+	* lyx2lyx: up the format to 230.
+	* lyxconvert_229.py: new file, convert graphics filename
+	* lyxrevert_230.py: new file (bare bone, no conversion needed)
+
 2004-02-04  José Matos  <[EMAIL PROTECTED]>
 	* lyxconvert_210.py: add two new transforms:
 	remove_empty_insets and remove_formula_latex
Index: lib/lyx2lyx/lyx2lyx
===================================================================
RCS file: /cvs/lyx/lyx-devel/lib/lyx2lyx/lyx2lyx,v
retrieving revision 1.21
diff -u -r1.21 lyx2lyx
--- lib/lyx2lyx/lyx2lyx	2003/12/29 15:49:49	1.21
+++ lib/lyx2lyx/lyx2lyx	2004/02/27 17:21:44
@@ -40,7 +40,7 @@
 
 format = re.compile(r"(\d)[\.,]?(\d\d)")
 fileformat = re.compile(r"\\lyxformat\s*(\S*)")
-lst_ft = [210, 215, 216, 217,  218, 220, 221, 223, 224, 225, 226, 227, 228, 229]
+lst_ft = [210, 215, 216, 217,  218, 220, 221, 223, 224, 225, 226, 227, 228, 229, 230]
 
 def usage():
     print """Usage: lyx2lyx [options] [file]
@@ -187,7 +187,10 @@
     end = lst_ft.index(opt.end)
 
     for fmt in lst_ft[start:end]:
-        __import__(mode + str(fmt)).convert(header,body)
+	if mode + str(fmt) == "lyxconvert_229":
+            __import__(mode + str(fmt)).convert(header,body,opt.input)
+	else:
+            __import__(mode + str(fmt)).convert(header,body)
 
     set_comment(header, version)
     set_format(header, opt.end)
Index: src/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/ChangeLog,v
retrieving revision 1.1817
diff -u -r1.1817 ChangeLog
--- src/ChangeLog	2004/02/27 14:21:00	1.1817
+++ src/ChangeLog	2004/02/27 17:22:20
@@ -1,3 +1,19 @@
+2004-02-27  Georg Baum  <[EMAIL PROTECTED]>
+
+	* buffer.C: increment format to 230.
+	* LaTeXFeatures.C, lyx_sty.[Ch]: add \lyxdot macro
+	* exporter.C: copy included graphics when exporting as DVI
+	* outputparams.h: add ExportData struct. Contains currently the
+	included grpahics file names
+	* Makefile.am: add boost_filesystem lib
+
+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-02-25  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
 	* BufferView_pimpl.C (workAreaDispatch): allow also
Index: src/LaTeXFeatures.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/LaTeXFeatures.C,v
retrieving revision 1.103
diff -u -r1.103 LaTeXFeatures.C
--- src/LaTeXFeatures.C	2004/01/21 17:52:05	1.103
+++ src/LaTeXFeatures.C	2004/02/27 17:22:21
@@ -370,6 +370,9 @@
 	if (isRequired("lyxgreyedout"))
 		macros << lyxgreyedout_def;
 
+	if (isRequired("lyxdot"))
+		macros << lyxdot_def << '\n';
+
 	// floats
 	getFloatDefinitions(macros);
 
Index: src/Makefile.am
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/Makefile.am,v
retrieving revision 1.204
diff -u -r1.204 Makefile.am
--- src/Makefile.am	2004/01/13 15:25:50	1.204
+++ src/Makefile.am	2004/02/27 17:22:22
@@ -22,9 +22,10 @@
 
 if USE_INCLUDED_BOOST
 BOOST_LIBS = ../boost/libs/regex/src/libboostregex.la \
-	../boost/libs/signals/src/libboostsignals.la
+	../boost/libs/signals/src/libboostsignals.la \
+	../boost/libs/filesystem/src/libboostfilesystem.la
 else
-BOOST_LIBS = -lboost_regex -lboost_signals
+BOOST_LIBS = -lboost_regex -lboost_signals -lboost_filesystem
 endif
 
 OTHERLIBS = $(BOOST_LIBS) $(INTLLIBS) $(AIKSAURUS_LIBS) @LIBS@
Index: src/buffer.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/buffer.C,v
retrieving revision 1.555
diff -u -r1.555 buffer.C
--- src/buffer.C	2004/02/25 12:00:47	1.555
+++ src/buffer.C	2004/02/27 17:22:26
@@ -133,7 +133,7 @@
 
 namespace {
 
-const int LYX_FORMAT = 229;
+const int LYX_FORMAT = 230;
 
 } // namespace anon
 
@@ -857,6 +882,8 @@
 	// [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 or ERT, files included by LyX work without it.
 	if (output_preamble) {
 		if (!runparams.nice) {
 			// code for usual, NOT nice-latex-file
@@ -1164,13 +1197,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 +1216,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 +1500,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.178
diff -u -r1.178 buffer.h
--- src/buffer.h	2004/02/25 12:00:48	1.178
+++ src/buffer.h	2004/02/27 17:22:26
@@ -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/exporter.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/exporter.C,v
retrieving revision 1.51
diff -u -r1.51 exporter.C
--- src/exporter.C	2004/02/25 12:00:48	1.51
+++ src/exporter.C	2004/02/27 17:22:28
@@ -22,6 +22,7 @@
 #include "buffer_funcs.h"
 #include "bufferparams.h"
 #include "converter.h"
+#include "debug.h"
 #include "format.h"
 #include "gettext.h"
 #include "lyxrc.h"
@@ -29,7 +30,9 @@
 #include "outputparams.h"
 #include "frontends/Alert.h"
 
+#include "support/FileInfo.h"
 #include "support/filetools.h"
+#include "support/lyxlib.h"
 
 using lyx::support::AddName;
 using lyx::support::bformat;
@@ -53,6 +56,43 @@
 	return v;
 }
 
+
+bool checkOverwrite(string const & filename)
+{
+	if (lyx::support::FileInfo(filename, true).exist()) {
+		string text = bformat(_("The file %1$s already exists.\n\n"
+					"Do you want to over-write that file?"),
+		                      MakeDisplayPath(filename));
+		int const ret = Alert::prompt(_("Over-write file?"),
+		                              text, 0, 1,
+		                              _("&Over-write"), _("&Cancel"));
+		if (ret == 1)
+			return false;
+		// erase file to make sure that this question is not asked
+		// again
+		//unlink(filename);
+	}
+	return true;
+}
+
+
+void copyFile(string const & sourceFile, string const & destFile)
+{
+	if (!checkOverwrite(destFile))
+		return;
+        lyxerr[Debug::GRAPHICS]
+		<< bformat(_("About to copy file\n%1$s\n"
+		             "to\n%2$s."),
+		           sourceFile, destFile)
+		<< std::endl;
+
+	if (!lyx::support::copy(sourceFile, destFile))
+		Alert::error(_("Couldn't copy file"),
+		             bformat(_("Copying %1$s to %2$s failed."),
+		                     MakeDisplayPath(sourceFile),
+		                     MakeDisplayPath(destFile)));
+}
+
 } //namespace anon
 
 
@@ -60,9 +100,11 @@
 		      bool put_in_tempdir, string & result_file)
 {
 	string backend_format;
+	ExportData exportdata;
 	OutputParams runparams;
 	runparams.flavor = OutputParams::LATEX;
 	runparams.linelen = lyxrc.ascii_linelen;
+	runparams.exportdata = &exportdata;
 	vector<string> backends = Backends(*buffer);
 	if (find(backends.begin(), backends.end(), format) == backends.end()) {
 		for (vector<string>::const_iterator it = backends.begin();
@@ -122,14 +164,23 @@
 				backend_format, format, result_file))
 		return false;
 
-	if (!put_in_tempdir)
+	if (!put_in_tempdir) {
 		buffer->message(_("Document exported as ")
 				      + formats.prettyName(format)
 				      + _(" to file `")
 				      + MakeDisplayPath(result_file) +'\'');
+		if (format == "dvi") {
+			// We need to copy included graphics to the result
+			// dir, because the dvi format does not contain them.
+			string const source = buffer->temppath();
+			string const dest = lyx::support::OnlyPath(result_file);
+			for (std::list<boost::filesystem::path>::const_iterator it = exportdata.files.begin();
+					it != exportdata.files.end(); ++it) {
+				copyFile(it->string(), AddName(dest, it->string()));
+			}
+		}
+	}
+
 	return true;
 }
 
Index: src/lyx_sty.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/lyx_sty.C,v
retrieving revision 1.16
diff -u -r1.16 lyx_sty.C
--- src/lyx_sty.C	2003/12/29 13:55:42	1.16
+++ src/lyx_sty.C	2004/02/27 17:22:32
@@ -126,3 +126,10 @@
 string const lyxgreyedout_def =
 	"%% The greyedout annotation environment\n"
 	"\\newenvironment{lyxgreyedout}{\\color[gray]{0.8}}{}\n";
+
+// We want to omit the file extension for includegraphics, but this does not
+// work when the filename contains other dots.
+// Idea from http://www.tex.ac.uk/cgi-bin/texfaq2html?label=unkgrfextn
+string const lyxdot_def =
+	"%% A simple dot to overcome graphicx limitations\n"
+	"\\newcommand{\\lyxdot}{.}\n";
Index: src/lyx_sty.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/lyx_sty.h,v
retrieving revision 1.17
diff -u -r1.17 lyx_sty.h
--- src/lyx_sty.h	2003/12/29 13:55:42	1.17
+++ src/lyx_sty.h	2004/02/27 17:22:32
@@ -52,5 +52,7 @@
 extern std::string const tabularnewline_def;
 ///
 extern std::string const lyxgreyedout_def;
+///
+extern std::string const lyxdot_def;
 
 #endif // LYX_STY_H
Index: src/outputparams.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/outputparams.h,v
retrieving revision 1.1
diff -u -r1.1 outputparams.h
--- src/outputparams.h	2003/11/05 12:06:03	1.1
+++ src/outputparams.h	2004/02/27 17:22:38
@@ -12,6 +12,18 @@
 #ifndef OUTPUTPARAMS_H
 #define OUTPUTPARAMS_H
 
+#include <boost/filesystem/path.hpp>
+#include <list>
+
+/* This is a hack: Make it possible to add files to constant OutputParams
+ * instances. */
+struct ExportData {
+	/** Generated files that might need to be copied to the destination
+	 *  dir
+	 */
+	std::list<boost::filesystem::path> files;
+};
+
 struct OutputParams {
         enum FLAVOR {
                 LATEX,
@@ -21,7 +33,7 @@
         OutputParams() : flavor(LATEX), nice(false),
 			   moving_arg(false), free_spacing(false),
 			   use_babel(false), mixed_content(false),
-			   linelen(0) {}
+			   linelen(0), exportdata(0) {}
 
 	/** The latex that we export depends occasionally on what is to
 	    compile the file.
@@ -59,6 +71,9 @@
 	/** Line lenght to use with ascii export.
 	 */
 	int linelen;
+
+	ExportData *exportdata;
+
 };
 
 #endif // LATEXRUNPARAMS_H
Index: src/insets/ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/ChangeLog,v
retrieving revision 1.971
diff -u -r1.971 ChangeLog
--- src/insets/ChangeLog	2004/02/27 08:33:24	1.971
+++ src/insets/ChangeLog	2004/02/27 17:23:29
@@ -1,3 +1,27 @@
+2004-02-27  Georg Baum  <[EMAIL PROTECTED]>
+
+	* ExternalSupport.C: use the master buffer's temp dir
+	* ExternalSupport.C (writeExternal): return relative filename
+	* insetexternal.C, insetgraphics.C (latex): add file to
+	runparams.exportdata (needed for DVI export)
+	* insetinclude.C (latex): return relative filename
+	* insetinclude.C: set parent filename of tmp buffers
+	* insetgraphics.C: require file extension (file format change!)
+	* insetgraphics.C (copyToDirIfNeeded): handle files with double
+	extensions (.eps.gz, .eps.bb etc)
+
+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.[Ch]: rename masterFilename to parentFilename (this
+	points to the direct parent)
+
 2004-02-27  Alfredo Braunstein  <[EMAIL PROTECTED]>
 
 	* insetlabel.[Ch]: remove them
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/02/27 17:23:29
@@ -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 +167,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);
 
@@ -233,9 +233,10 @@
 	string from_file = params.filename.outputFilename(buffer.filePath());
 	if (external_in_tmpdir && !from_file.empty()) {
 		// We are running stuff through LaTeX
-		from_file =
-			support::MakeAbsPath(params.filename.mangledFilename(),
-					     buffer.temppath());
+		// We need to return the filename relative to the temp dir
+		// if we export to DVI because the converted files are
+		// afterwards copied into the directory of the exported file.
+		from_file = params.filename.mangledFilename();
 	}
 
 	string str = doSubstitution(params, buffer, cit->second.product,
Index: src/insets/insetexternal.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/insets/insetexternal.C,v
retrieving revision 1.143
diff -u -r1.143 insetexternal.C
--- src/insets/insetexternal.C	2004/02/25 12:00:53	1.143
+++ src/insets/insetexternal.C	2004/02/27 17:23:31
@@ -682,6 +682,8 @@
 		return 1;
 	}
 
+	runparams.exportdata->files.push_back(params_.filename.outputFilename(buf.filePath()));
+
 	// "nice" means that the buffer is exported to LaTeX format but not
 	// run through the LaTeX compiler.
 	// If we're running through the LaTeX compiler, we should write the
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/02/27 17:23:34
@@ -71,6 +71,7 @@
 #include "frontends/Alert.h"
 #include "frontends/LyXView.h"
 
+#include "support/FileInfo.h"
 #include "support/filetools.h"
 #include "support/lyxalgo.h" // lyx::count
 #include "support/lyxlib.h" // float_equal
@@ -93,6 +94,7 @@
 using lyx::support::getExtFromContents;
 using lyx::support::IsFileReadable;
 using lyx::support::LibFileSearch;
+using lyx::support::MakeRelPath;
 using lyx::support::rtrim;
 using lyx::support::Systemcall;
 using lyx::support::unzipFile;
@@ -347,28 +349,36 @@
 };
 
 
+/*!
+ * copy the file \p basename_in + \p ext to the temporary directory
+ * \p dir. \p ext needs to be separate for zipped and .bb files, because
+ * otherwise the mangled filename would be *_eps.gz instead of *.eps.gz and
+ * *_eps.bb instead of *.eps.bb.
+ * For other files \p ext should be empty.
+ */
 std::pair<CopyStatus, string> const
-copyToDirIfNeeded(string const & file_in, string const & dir)
+copyToDirIfNeeded(string const & basename_in, string const & dir,
+                  string const & ext = string())
 {
 	using support::rtrim;
 
+	string const file_in = basename_in + ext;
 	BOOST_ASSERT(AbsolutePath(file_in));
 
 	string const only_path = support::OnlyPath(file_in);
 	if (rtrim(support::OnlyPath(file_in) , "/") == rtrim(dir, "/"))
 		return std::make_pair(IDENTICAL_PATHS, file_in);
 
-	string mangled;
-	if (support::zippedFile(file_in)) {
-		string const ext = GetExtension(file_in);
-		string const unzipped = support::unzippedFileName(file_in);
-		mangled = FileName(unzipped).mangledFilename();
-		mangled += "." + ext;
-	} else
-		mangled = FileName(file_in).mangledFilename();
+	string const mangled = FileName(basename_in).mangledFilename() + ext;
 
 	string const file_out = support::MakeAbsPath(mangled, dir);
 
+	lyxerr[Debug::GRAPHICS]
+		<< bformat(_("About to copy file\n%1$s\n"
+		             "to\n%2$s."),
+		           file_in, file_out)
+		<< std::endl;
+
 	unsigned long const checksum_in  = support::sum(file_in);
 	unsigned long const checksum_out = support::sum(file_out);
 
@@ -405,52 +415,91 @@
 string const InsetGraphics::prepareFile(Buffer const & buf,
 					OutputParams const & runparams) const
 {
-	string orig_file = params().filename.absFilename();
-	string const rel_file = params().filename.relFilename(buf.filePath());
-
-	// LaTeX can cope if the graphics file doesn't exist, so just return the
-	// filename.
-	if (!IsFileReadable(orig_file)) {
-		lyxerr[Debug::GRAPHICS]
-			<< "InsetGraphics::prepareFile\n"
-			<< "No file '" << orig_file << "' can be found!" << endl;
-		return rel_file;
-	}
+	string const abs_orig_file = params().filename.absFilename();
+	string const rel_orig_file = params().filename.relFilename(buf.filePath());
+	string const orig_file = params().filename.outputFilename(buf.filePath());
+
+	// We assume that abs_orig_file exists (the caller checks this)
+
+	// How we handle filenames:
+	// - Use relative filename if we are using a temp file. This is
+	//   necessary for DVI export
+	// - Otherwise, use the filename the user provided (relative or
+	//   absolute).
 
 	// If the file is compressed and we have specified that it
 	// should not be uncompressed, then just return its name and
 	// let LaTeX do the rest!
 	bool const zipped = params().filename.isZipped();
 
-	if (zipped && params().noUnzip) {
-		lyxerr[Debug::GRAPHICS]
-			<< "\tpass zipped file to LaTeX but with full path.\n";
-		// LaTeX needs an absolute path, otherwise the
-		// coresponding *.eps.bb file isn't found
-		return orig_file;
-	}
-
 	// temp_file will contain the file for LaTeX to act on if, for example,
 	// we move it to a temp dir or uncompress it.
-	string temp_file = orig_file;
+	string temp_file = abs_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();
+	string unzipped_orig_file = orig_file;
+
 	if (zipped) {
-		CopyStatus status;
-		boost::tie(status, temp_file) =
-			copyToDirIfNeeded(orig_file, buf.temppath());
-
-		if (status == FAILURE)
-			return orig_file;
-
-		orig_file = unzippedFileName(temp_file);
-		if (!IsFileReadable(orig_file)) {
-			unzipFile(temp_file);
+		if (!runparams.nice) {
+			string const unzipped_abs_orig_file =
+				unzippedFileName(abs_orig_file);
+			CopyStatus status;
+			boost::tie(status, temp_file) =
+				copyToDirIfNeeded(unzipped_abs_orig_file,
+				                  temp_path,
+				                  "." + GetExtension(abs_orig_file));
+
+			if (status == FAILURE)
+				return orig_file;
+
+			if (params().noUnzip) {
+				// LaTeX needs the bounding box file in the
+				// tmp dir
+				string bb_file;
+				boost::tie(status, bb_file) =
+					copyToDirIfNeeded(unzipped_abs_orig_file,
+					                  temp_path, ".bb");
+
+				if (status == FAILURE)
+					return orig_file;
+			}
+		}
+
+		if (params().noUnzip) {
+			lyxerr[Debug::GRAPHICS]
+				<< "\tpass zipped file to LaTeX.\n";
+			if (runparams.nice)
+				return orig_file;
+			else {
+				runparams.exportdata->files.push_back(temp_file);
+				return MakeRelPath(temp_file, temp_path);
+			}
+		}
+
+		// We only unzip the image if we run LaTeX.
+		if (runparams.nice) {
+			unzipped_orig_file = unzippedFileName(orig_file);
+		} else {
+			runparams.exportdata->files.push_back(temp_file);
+			temp_file = unzipFile(temp_file);
 			lyxerr[Debug::GRAPHICS]
-				<< "\tunzipped to " << orig_file << endl;
+				<< "\tunzipped to " << temp_file << endl;
 		}
 	}
+
+	// We won't convert the image if we don't run LaTeX.
+	// We remove the extension to enable LaTeX to determine the correct
+	// format automatically, dependent on the output format.
+	// This works only if the filename contains no dots besides the
+	// just removed one. We can fool here by replacing all dots with a
+	// macro whose definition is just a dot ;-)
+	if (runparams.nice)
+		return support::subst(RemoveExtension(unzipped_orig_file), ".", "\\lyxdot ");
 
-	string const from = getExtFromContents(orig_file);
+	string const from = getExtFromContents(temp_file);
 	string const to   = findTargetFormat(from, runparams);
 	lyxerr[Debug::GRAPHICS]
 		<< "\t we have: from " << from << " to " << to << '\n';
@@ -465,15 +514,18 @@
 	bool conversion_needed = true;
 	CopyStatus status;
 	boost::tie(status, temp_file) =
-			copyToDirIfNeeded(orig_file, buf.temppath());
+		copyToDirIfNeeded(abs_orig_file, temp_path);
 
 	if (status == FAILURE)
 		return orig_file;
 	else if (status == IDENTICAL_CONTENTS)
 		conversion_needed = false;
 
+	if (!zipped)
+		runparams.exportdata->files.push_back(temp_file);
+
 	if (from == to)
-		return stripExtensionIfPossible(temp_file, to);
+		return MakeRelPath(stripExtensionIfPossible(temp_file, to), temp_path);
 
 	string const to_file_base = RemoveExtension(temp_file);
 	string const to_file = ChangeExtension(to_file_base, to);
@@ -484,9 +536,9 @@
 	    support::compare_timestamps(temp_file, to_file) < 0) {
 		lyxerr[Debug::GRAPHICS]
 			<< bformat(_("No conversion of %1$s is needed after all"),
-				   rel_file)
+				   rel_orig_file)
 			<< std::endl;
-		return to_file_base;
+		return MakeRelPath(to_file_base, temp_path);
 	}
 
 	lyxerr[Debug::GRAPHICS]
@@ -516,7 +569,7 @@
 		}
 	}
 
-	return to_file_base;
+	return MakeRelPath(to_file_base, temp_path);
 }
 
 
@@ -529,22 +582,12 @@
 		<< "insetgraphics::latex: Filename = "
 		<< params().filename.absFilename() << endl;
 
-	string const relative_file =
-		params().filename.relFilename(buf.filePath());
-
-	// A missing (e)ps-extension is no problem for LaTeX, so
-	// we have to test three different cases
-#warning uh, but can our cache handle it ? no.
 	string const file_ = params().filename.absFilename();
-	bool const file_exists =
-		!file_.empty() &&
-		(IsFileReadable(file_) ||		// original
-		 IsFileReadable(file_ + ".eps") ||	// original.eps
-		 IsFileReadable(file_ + ".ps"));	// original.ps
+	bool const file_exists = !file_.empty() && IsFileReadable(file_);
 	string const message = file_exists ?
 		string() : string("bb = 0 0 200 100, draft, type=eps");
 	// if !message.empty() than there was no existing file
-	// "filename(.(e)ps)" found. In this case LaTeX
+	// "filename" found. In this case LaTeX
 	// draws only a rectangle with the above bb and the
 	// not found filename in it.
 	lyxerr[Debug::GRAPHICS]
@@ -575,20 +618,19 @@
 		<< "\tBefore = " << before
 		<< "\n\tafter = " << after << endl;
 
+	// 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 convertedFile;
 
 	// "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;
-	}
+	if (runparams.nice || file_exists)
+		convertedFile = os::external_path(prepareFile(buf, runparams));
+	else
+		convertedFile = params().filename.relFilename(buf.filePath()) + " 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);
+	string const latex_str = before + '{' + convertedFile + '}' + after;
 	os << latex_str;
 
 	lyxerr[Debug::GRAPHICS] << "InsetGraphics::latex outputting:\n"
@@ -650,6 +692,14 @@
 
 	features.require("graphicx");
 
+	if (features.nice()) {
+		string const filename = params().filename.isZipped() ?
+			unzippedFileName(params().filename.outputFilename(features.buffer().filePath())) :
+			params().filename.outputFilename(features.buffer().filePath());
+		if (contains(RemoveExtension(filename), "."))
+			features.require("lyxdot");
+	}
+
 	if (params().subcaption)
 		features.require("subfigure");
 }
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/02/27 17:23:35
@@ -40,14 +40,17 @@
 #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>
+#include <boost/tuple/tuple.hpp>
 
 #include "support/std_ostream.h"
 #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;
@@ -58,6 +61,7 @@
 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;
@@ -187,6 +191,12 @@
 
 string const masterFilename(Buffer const & buffer)
 {
+	return buffer.getMasterBuffer()->fileName();
+}
+
+
+string const parentFilename(Buffer const & buffer)
+{
 	return buffer.fileName();
 }
 
@@ -195,7 +205,7 @@
 			      InsetCommandParams const & params)
 {
 	return MakeAbsPath(params.getContents(),
-			   OnlyPath(masterFilename(buffer)));
+			   OnlyPath(parentFilename(buffer)));
 }
 
 
@@ -294,6 +304,65 @@
 }
 
 
+enum CopyStatus {
+	SUCCESS,
+	FAILURE,
+	IDENTICAL_PATHS,
+	IDENTICAL_CONTENTS
+};
+
+
+/*!
+ * copy the file \p basename_in + \p ext to the temporary directory
+ * \p dir. \p ext needs to be separate for zipped and .bb files, because
+ * otherwise the mangled filename would be *_eps.gz instead of *.eps.gz and
+ * *_eps.bb instead of *.eps.bb.
+ * For other files \p ext should be empty.
+ */
+std::pair<CopyStatus, string> const
+copyToDirIfNeeded(string const & basename_in, string const & dir,
+                  string const & ext = string())
+{
+	namespace support = lyx::support;
+	using support::rtrim;
+
+	string const file_in = basename_in + ext;
+	BOOST_ASSERT(AbsolutePath(file_in));
+
+	string const only_path = support::OnlyPath(file_in);
+	if (rtrim(support::OnlyPath(file_in) , "/") == rtrim(dir, "/"))
+		return std::make_pair(IDENTICAL_PATHS, file_in);
+
+	string const mangled = FileName(basename_in).mangledFilename() + ext;
+
+	string const file_out = support::MakeAbsPath(mangled, dir);
+
+	lyxerr[Debug::GRAPHICS]
+		<< bformat(_("About to copy file\n%1$s\n"
+		             "to\n%2$s."),
+		           file_in, file_out)
+		<< std::endl;
+
+	unsigned long const checksum_in  = support::sum(file_in);
+	unsigned long const checksum_out = support::sum(file_out);
+
+	if (checksum_in == checksum_out)
+		// Nothing to do...
+		return std::make_pair(IDENTICAL_CONTENTS, file_out);
+
+	bool const success = support::copy(file_in, file_out);
+	if (!success) {
+		lyxerr[Debug::GRAPHICS]
+			<< bformat(_("Could not copy the file\n%1$s\n"
+			             "into the temporary directory."),
+			           file_in)
+			<< std::endl;
+	}
+
+	CopyStatus status = success ? SUCCESS : FAILURE;
+	return std::make_pair(status, file_out);
+}
+
 } // namespace anon
 
 
@@ -307,9 +376,28 @@
 		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);
+		tmp->setParentName(parentFilename(buffer));
 
 		if (tmp->params().textclass != buffer.params().textclass) {
 			string text = bformat(_("Included file `%1$s'\n"
@@ -321,23 +409,24 @@
 			Alert::warning(_("Different textclasses"), text);
 			//return 0;
 		}
-
-		// 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, buffer.temppath());
-		}
+		tmp->markDepClean(m_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 {
+		CopyStatus status;
+		boost::tie(status, writefile) =
+				copyToDirIfNeeded(included_file, m_buffer->temppath());
+		if (status == FAILURE)
+			return 0;
 	}
 
 	if (isVerbatim(params_)) {
@@ -385,17 +474,15 @@
 
 	if (loadIfNeeded(buffer, params_)) {
 		Buffer * tmp = bufferlist.getBuffer(included_file);
+		tmp->setParentName(parentFilename(buffer));
 
 		// 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;
@@ -429,17 +516,15 @@
 
 	if (loadIfNeeded(buffer, params_)) {
 		Buffer * tmp = bufferlist.getBuffer(included_file);
+		tmp->setParentName(parentFilename(buffer));
 
 		// 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;
@@ -463,20 +548,18 @@
 void InsetInclude::validate(LaTeXFeatures & features) const
 {
 	string incfile(params_.getContents());
-	string writefile;
 
 	Buffer const & buffer = features.buffer();
 
 	string const included_file = includedFilename(buffer, params_);
+	string writefile = included_file;
 
 	if (IsLyXFilename(included_file))
-		writefile = ChangeExtension(included_file, ".sgml");
-	else
-		writefile = included_file;
-
-	if (!features.nice() && !isVerbatim(params_)) {
+		writefile = ChangeExtension(writefile, ".sgml");
+	else 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);
@@ -490,8 +573,10 @@
 	if (loadIfNeeded(buffer, params_)) {
 		// a file got loaded
 		Buffer * const tmp = bufferlist.getBuffer(included_file);
-		if (tmp)
+		if (tmp) {
+			tmp->setParentName(parentFilename(buffer));
 			tmp->validate(features);
+		}
 	}
 }
 
@@ -504,7 +589,7 @@
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 		tmp->setParentName("");
 		tmp->getLabelList(list);
-		tmp->setParentName(masterFilename(buffer));
+		tmp->setParentName(parentFilename(buffer));
 	}
 }
 
@@ -517,7 +602,7 @@
 		Buffer * tmp = bufferlist.getBuffer(included_file);
 		tmp->setParentName("");
 		tmp->fillWithBibKeys(keys);
-		tmp->setParentName(masterFilename(buffer));
+		tmp->setParentName(parentFilename(buffer));
 	}
 }
 
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2003 José Matos <[EMAIL PROTECTED]>
# Copyright (C) 2004 Georg Baum <[EMAIL PROTECTED]>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.



import sys
import os
from parser_tools import find_token, find_token2
from string import replace, split


def convert_graphics(lines, input):
    """ Add extension to filenames of insetgraphic if necessary.
    """
    if input == sys.stdin:
        dir = ""
    else:
        dir = os.path.dirname(os.path.abspath(input.name))
    i = 0
    while 1:
        i = find_token(lines, "\\begin_inset Graphics", i)
        if i == -1:
            return

        j = find_token2(lines, "filename", i)
        if j == -1:
            return
        i = i + 1
        filename = split(lines[j])[1]
        absname = os.path.normpath(os.path.join(dir, filename))
        if os.access(absname, os.F_OK):
            continue
        if input == sys.stdin:
            sys.stderr.write("Warning: Can not convert filename if reading from 
stdin\n")
            return;
        if os.access(absname + ".ps", os.F_OK):
            lines[j] = replace(lines[j], filename, filename + ".ps")
            continue
        if os.access(absname + ".eps", os.F_OK):
            lines[j] = replace(lines[j], filename, filename + ".eps")

def convert(header, body, input):
    convert_graphics(body, input)

if __name__ == "__main__":
    pass
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2003 José Matos <[EMAIL PROTECTED]>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.



def convert(header, body):
    pass

if __name__ == "__main__":
    pass

Reply via email to