Here comes my long promised fix for bug 2637 (graphics files with ' in the
name can't be previewed).
My first idea was to copy the graphics file to the buffer temp dir, using
the same mangled name that will be used when running latex, and then
running the conversion chain on that file.
The advantage of that would be that we can reuse the conversion results (png
format in the common case) for pdflatex.
I did not do that in the end, because the preview conversion runs in the
background, and so we could easily get a race condition when view->pdflatex
is started before the conversion is complete.
Therefore I simply added one additional copy step to the conversion chain,
and did not use the original file name for the temp file name anymore.
This will go in tomorrow unless I get objections.
Georg
Log:
Fix bug 2637
* src/graphics/GraphicsCacheItem.C
(CacheItem::Impl::convertToDisplayFormat): Don't derive the temp
file name from the original file name. This ensures that it is
composed of valid characters only.
* src/graphics/GraphicsConverter.C: remove example script, since it
will get out of date.
(build_script): Copy the original file to a temp file before the
conversion chain starts. This avoids problems with converters that
can't handle ' in filenames.
Index: src/graphics/GraphicsCacheItem.C
===================================================================
--- src/graphics/GraphicsCacheItem.C (Revision 14417)
+++ src/graphics/GraphicsCacheItem.C (Arbeitskopie)
@@ -426,12 +426,10 @@ void CacheItem::Impl::convertToDisplayFo
}
lyxerr[Debug::GRAPHICS] << "\tConverting it to " << to << " format." << endl;
- // Take only the filename part of the file, without path or extension.
- string const temp = changeExtension(onlyFilename(filename), string());
// Add some stuff to create a uniquely named temporary file.
// This file is deleted in loadImage after it is loaded into memory.
- string const to_file_base = tempName(string(), temp);
+ string const to_file_base = tempName(string(), "CacheItem");
remove_loaded_file_ = true;
// Remove the temp file, we only want the name...
Index: src/graphics/GraphicsConverter.C
===================================================================
--- src/graphics/GraphicsConverter.C (Revision 14417)
+++ src/graphics/GraphicsConverter.C (Arbeitskopie)
@@ -33,6 +33,7 @@ namespace support = lyx::support;
using support::changeExtension;
using support::Forkedcall;
using support::ForkedCallQueue;
+using support::getExtension;
using support::libFileSearch;
using support::libScriptSearch;
using support::onlyPath;
@@ -265,7 +266,6 @@ string const move_file(string const & fr
<< "try:\n"
<< " os.rename(fromfile, tofile)\n"
<< "except:\n"
- << " import shutil\n"
<< " try:\n"
<< " shutil.copy(fromfile, tofile)\n"
<< " except:\n"
@@ -276,50 +276,6 @@ string const move_file(string const & fr
}
-/*
-A typical script looks like:
-
-#!/usr/bin/env python -tt
-import os, sys
-
-def unlinkNoThrow(file):
- ''' remove a file, do not throw if error occurs '''
- try:
- os.unlink(file)
- except:
- pass
-
-infile = '/home/username/Figure3a.eps'
-infile_base = '/home/username/Figure3a'
-outfile = '/tmp/lyx_tmpdir12992hUwBqt/gconvert0129929eUBPm.pdf'
-
-if os.system(r'epstopdf ' + '"' + infile + '"' + ' --output ' + '"' + outfile + '"' + '') != 0:
- unlinkNoThrow(outfile)
- sys.exit(1)
-
-if not os.path.isfile(outfile):
- if os.path.isfile(outfile + '.0'):
- os.rename(outfile + '.0', outfile)
- import glob
- for file in glob.glob(outfile + '.?'):
- unlinkNoThrow(file)
- else:
- sys.exit(1)
-
-fromfile = outfile
-tofile = '/tmp/lyx_tmpdir12992hUwBqt/Figure3a129927ByaCl.ppm'
-
-try:
- os.rename(fromfile, tofile)
-except:
- import shutil
- try:
- shutil.copy(fromfile, tofile)
- except:
- sys.exit(1)
- unlinkNoThrow(fromfile)
-
-*/
bool build_script(string const & from_file,
string const & to_file_base,
string const & from_format,
@@ -334,7 +290,7 @@ bool build_script(string const & from_fi
return false;
script << "#!/usr/bin/env python -tt\n"
- "import os, sys\n\n"
+ "import os, shutil, sys\n\n"
"def unlinkNoThrow(file):\n"
" ''' remove a file, do not throw if an error occurs '''\n"
" try:\n"
@@ -361,7 +317,15 @@ bool build_script(string const & from_fi
string const to_base = tempName(string(), tmp);
unlink(to_base);
- string outfile = from_file;
+ // Create a copy of the file in case the original name contains
+ // problematic characters like ' or ". We can work around that problem
+ // in python, but the converters might be shell scripts and have more
+ // troubles with it.
+ string outfile = changeExtension(to_base, getExtension(from_file));
+ script << "infile = '"
+ << subst(subst(from_file, "\\", "\\\\"), "'", "\\'") << "'\n"
+ "outfile = " << quoteName(outfile) << "\n"
+ "shutil.copy(infile, outfile)\n";
// The conversion commands may contain these tokens that need to be
// changed to infile, infile_base, outfile respectively.
@@ -413,9 +377,8 @@ bool build_script(string const & from_fi
" else:\n"
" sys.exit(1)\n\n";
- // Delete the infile, if it isn't the original, from_file.
- if (infile != from_file)
- script << "unlinkNoThrow(infile)\n\n";
+ // Delete the infile
+ script << "unlinkNoThrow(infile)\n\n";
}
// Move the final outfile to to_file