mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 19:07:45 +00:00
Embedding: prepare to read/write manifest in .lyx file
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@20186 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
17112f655d
commit
3189e7b5dd
@ -669,12 +669,6 @@ bool Buffer::readFile(FileName const & filename)
|
||||
fs::exists(lyxfile.toFilesystemEncoding())) {
|
||||
params().embedded = true;
|
||||
fname = lyxfile;
|
||||
// read manifest file
|
||||
ifstream is(manifest.toFilesystemEncoding().c_str());
|
||||
is >> pimpl_->embedded_files;
|
||||
is.close();
|
||||
LYXERR(Debug::FILES) << filename << " is a embedded file. Its manifest is:\n"
|
||||
<< pimpl_->embedded_files;
|
||||
}
|
||||
}
|
||||
// The embedded lyx file can also be compressed, for backward compatibility
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "debug.h"
|
||||
#include "gettext.h"
|
||||
#include "Format.h"
|
||||
#include "Lexer.h"
|
||||
#include "ErrorList.h"
|
||||
|
||||
#include "frontends/alert.h"
|
||||
|
||||
@ -244,7 +246,7 @@ bool EmbeddedFiles::enable(bool flag)
|
||||
|
||||
|
||||
void EmbeddedFiles::registerFile(string const & filename,
|
||||
bool embed, Inset const * inset)
|
||||
bool embed, Inset const * inset, string const & inzipName)
|
||||
{
|
||||
// filename can be relative or absolute, translate to absolute filename
|
||||
string abs_filename = makeAbsPath(filename, buffer_->filePath()).absFilename();
|
||||
@ -257,18 +259,12 @@ void EmbeddedFiles::registerFile(string const & filename,
|
||||
// find this filename, keep the original embedding status
|
||||
if (it != file_list_.end()) {
|
||||
it->addInset(inset);
|
||||
// if the file is embedded, the embedded file should have exist
|
||||
// check for this to ensure that our logic is correct
|
||||
if (it->embedded())
|
||||
BOOST_ASSERT(fs::exists(it->embeddedFile(buffer_)));
|
||||
it->validate();
|
||||
return;
|
||||
}
|
||||
// try to be more careful
|
||||
file_list_.push_back(EmbeddedFile(abs_filename,
|
||||
getInzipName(abs_filename), embed, inset));
|
||||
// validate if things are OK
|
||||
BOOST_ASSERT(fs::exists(file_list_.back().availableFile(buffer_)));
|
||||
getInzipName(abs_filename, inzipName), embed, inset));
|
||||
}
|
||||
|
||||
|
||||
@ -287,10 +283,6 @@ void EmbeddedFiles::update()
|
||||
|
||||
for (InsetIterator it = inset_iterator_begin(buffer_->inset()); it; ++it)
|
||||
it->registerEmbeddedFiles(*buffer_, *this);
|
||||
|
||||
LYXERR(Debug::FILES) << "Manifest updated: " << endl
|
||||
<< *this
|
||||
<< "End Manifest" << endl;
|
||||
}
|
||||
|
||||
|
||||
@ -298,17 +290,11 @@ bool EmbeddedFiles::write(DocFileName const & filename)
|
||||
{
|
||||
// file in the temporary path has the content
|
||||
string const content = FileName(addName(buffer_->temppath(),
|
||||
onlyFilename(filename.toFilesystemEncoding()))).toFilesystemEncoding();
|
||||
"content.lyx")).toFilesystemEncoding();
|
||||
|
||||
// get a file list and write a manifest file
|
||||
vector<pair<string, string> > filenames;
|
||||
string const manifest = FileName(
|
||||
addName(buffer_->temppath(), "manifest.txt")).toFilesystemEncoding();
|
||||
|
||||
// write a manifest file
|
||||
ofstream os(manifest.c_str());
|
||||
os << *this;
|
||||
os.close();
|
||||
// add content.lyx to filenames
|
||||
filenames.push_back(make_pair(content, "content.lyx"));
|
||||
// prepare list of embedded file
|
||||
EmbeddedFileList::iterator it = file_list_.begin();
|
||||
EmbeddedFileList::iterator it_end = file_list_.end();
|
||||
@ -321,9 +307,6 @@ bool EmbeddedFiles::write(DocFileName const & filename)
|
||||
filenames.push_back(make_pair(file, it->inzipName()));
|
||||
}
|
||||
}
|
||||
// add filename (.lyx) and manifest to filenames
|
||||
filenames.push_back(make_pair(content, onlyFilename(filename.toFilesystemEncoding())));
|
||||
filenames.push_back(make_pair(manifest, "manifest.txt"));
|
||||
// write a zip file with all these files. Write to a temp file first, to
|
||||
// avoid messing up the original file in case something goes terribly wrong.
|
||||
DocFileName zipfile(addName(buffer_->temppath(),
|
||||
@ -380,11 +363,13 @@ bool EmbeddedFiles::updateFromExternalFile() const
|
||||
}
|
||||
|
||||
|
||||
string const EmbeddedFiles::getInzipName(string const & abs_filename)
|
||||
string const EmbeddedFiles::getInzipName(string const & abs_filename, string const & name)
|
||||
{
|
||||
// register a new one, using relative file path as inzip_name
|
||||
string inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
|
||||
from_utf8(buffer_->fileName())));
|
||||
string inzip_name = name;
|
||||
if (name.empty())
|
||||
inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
|
||||
from_utf8(buffer_->filePath())));
|
||||
// if inzip_name is an absolute path, use filename only to avoid
|
||||
// leaking of filesystem information in inzip_name
|
||||
// The second case covers cases '../path/file' and '.'
|
||||
@ -413,81 +398,74 @@ string const EmbeddedFiles::getInzipName(string const & abs_filename)
|
||||
}
|
||||
|
||||
|
||||
istream & operator>> (istream & is, EmbeddedFiles & files)
|
||||
bool EmbeddedFiles::readManifest(Lexer & lex, ErrorList & errorList)
|
||||
{
|
||||
files.clear();
|
||||
string tmp;
|
||||
getline(is, tmp);
|
||||
// get version
|
||||
istringstream itmp(tmp);
|
||||
int version;
|
||||
itmp.ignore(string("# LyX manifest version ").size());
|
||||
itmp >> version;
|
||||
int line = -1;
|
||||
int begin_manifest_line = -1;
|
||||
|
||||
if (version != 1) {
|
||||
lyxerr << "This version of LyX can only read LyX manifest version 1" << endl;
|
||||
return is;
|
||||
}
|
||||
file_list_.clear();
|
||||
string filename = "";
|
||||
string inzipName = "";
|
||||
bool status = "";
|
||||
|
||||
getline(is, tmp);
|
||||
if (tmp != "<manifest>") {
|
||||
lyxerr << "Invalid manifest file, lacking <manifest>" << endl;
|
||||
return is;
|
||||
}
|
||||
// manifest file may be messed up, be carefully
|
||||
while (is.good()) {
|
||||
getline(is, tmp);
|
||||
if (tmp != "<file>")
|
||||
while (lex.isOK()) {
|
||||
lex.next();
|
||||
string const token = lex.getString();
|
||||
|
||||
if (token.empty())
|
||||
continue;
|
||||
|
||||
if (token == "\\end_manifest")
|
||||
break;
|
||||
|
||||
string fname;
|
||||
getline(is, fname);
|
||||
string inzip_name;
|
||||
getline(is, inzip_name);
|
||||
getline(is, tmp);
|
||||
istringstream itmp(tmp);
|
||||
int embed;
|
||||
itmp >> embed;
|
||||
|
||||
getline(is, tmp);
|
||||
if (tmp != "</file>") {
|
||||
lyxerr << "Invalid manifest file, lacking </file>" << endl;
|
||||
break;
|
||||
++line;
|
||||
if (token == "\\begin_manifest") {
|
||||
begin_manifest_line = line;
|
||||
continue;
|
||||
}
|
||||
|
||||
LYXERR(Debug::PARSER) << "Handling document manifest token: `"
|
||||
<< token << '\'' << endl;
|
||||
|
||||
files.registerFile(fname, embed);
|
||||
};
|
||||
// the last line must be </manifest>
|
||||
if (tmp != "</manifest>") {
|
||||
lyxerr << "Invalid manifest file, lacking </manifest>" << endl;
|
||||
return is;
|
||||
if (token == "\\filename")
|
||||
lex >> filename;
|
||||
else if (token == "\\inzipName")
|
||||
lex >> inzipName;
|
||||
else if (token == "\\status") {
|
||||
lex >> status;
|
||||
registerFile(filename, status, NULL, inzipName);
|
||||
filename = "";
|
||||
inzipName = "";
|
||||
} else {
|
||||
docstring const s = _("\\begin_file is missing");
|
||||
errorList.push_back(ErrorItem(_("Manifest error"),
|
||||
s, -1, 0, 0));
|
||||
}
|
||||
}
|
||||
return is;
|
||||
if (begin_manifest_line) {
|
||||
docstring const s = _("\\begin_manifest is missing");
|
||||
errorList.push_back(ErrorItem(_("Manifest error"),
|
||||
s, -1, 0, 0));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ostream & operator<< (ostream & os, EmbeddedFiles const & files)
|
||||
void EmbeddedFiles::writeManifest(ostream & os) const
|
||||
{
|
||||
// store a version so that operator >> can read later versions
|
||||
// using version information.
|
||||
os << "# lyx manifest version 1\n";
|
||||
os << "<manifest>\n";
|
||||
EmbeddedFiles::EmbeddedFileList::const_iterator it = files.begin();
|
||||
EmbeddedFiles::EmbeddedFileList::const_iterator it_end = files.end();
|
||||
EmbeddedFiles::EmbeddedFileList::const_iterator it = begin();
|
||||
EmbeddedFiles::EmbeddedFileList::const_iterator it_end = end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!it->valid())
|
||||
continue;
|
||||
// use differnt lines to make reading easier.
|
||||
os << "<file>\n"
|
||||
// save the relative path
|
||||
// save the relative path
|
||||
os << "\\filename "
|
||||
<< to_utf8(makeRelPath(from_utf8(it->absFilename()),
|
||||
from_utf8(files.buffer_->filePath()))) << '\n'
|
||||
<< it->inzipName() << '\n'
|
||||
<< it->embedded() << '\n'
|
||||
<< "</file>\n";
|
||||
from_utf8(buffer_->filePath()))) << '\n'
|
||||
<< "\\inzipName " << it->inzipName() << '\n'
|
||||
<< "\\status " << (it->embedded() ? "true" : "false") << '\n';
|
||||
}
|
||||
os << "</manifest>\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -107,6 +107,8 @@ embedded file (check path == temppath()), if so, save filename() instead.
|
||||
namespace lyx {
|
||||
|
||||
class Buffer;
|
||||
class Lexer;
|
||||
class ErrorList;
|
||||
|
||||
class EmbeddedFile : public support::DocFileName
|
||||
{
|
||||
@ -186,10 +188,12 @@ public:
|
||||
/* \param filename filename to add
|
||||
* \param embed embedding status. For a new file item, this is always true.
|
||||
* If the file already exists, this parameter is ignored.
|
||||
* \param pit paragraph id.
|
||||
* \param inset Inset pointer
|
||||
* \param inzipName suggested inzipname
|
||||
*/
|
||||
void registerFile(std::string const & filename, bool embed = false,
|
||||
Inset const * inset = NULL);
|
||||
Inset const * inset = NULL,
|
||||
std::string const & inzipName = std::string());
|
||||
|
||||
/// scan the buffer and get a list of EmbeddedFile
|
||||
void update();
|
||||
@ -214,12 +218,11 @@ public:
|
||||
/// update all files from external, used when enable embedding
|
||||
bool updateFromExternalFile() const;
|
||||
///
|
||||
friend std::istream & operator>> (std::istream & is, EmbeddedFiles &);
|
||||
|
||||
friend std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
|
||||
bool readManifest(Lexer & lex, ErrorList & errorList);
|
||||
void writeManifest(std::ostream & os) const;
|
||||
private:
|
||||
/// get a unique inzip name
|
||||
std::string const getInzipName(std::string const & name);
|
||||
/// get a unique inzip name, a suggestion can be given.
|
||||
std::string const getInzipName(std::string const & name, std::string const & inzipName);
|
||||
/// list of embedded files
|
||||
EmbeddedFileList file_list_;
|
||||
///
|
||||
@ -227,9 +230,5 @@ private:
|
||||
};
|
||||
|
||||
|
||||
std::istream & operator>> (std::istream & is, EmbeddedFiles &);
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -285,11 +285,14 @@ void InsetGraphics::read(Buffer const & buf, Lexer & lex)
|
||||
|
||||
// InsetGraphics is read, with filename in params_. We do not know if this file actually
|
||||
// exists or is embedded so we need to get the 'availableFile' from buf.embeddedFiles()
|
||||
EmbeddedFiles::EmbeddedFileList::const_iterator it = buf.embeddedFiles().find(params_.filename.toFilesystemEncoding());
|
||||
if (it != buf.embeddedFiles().end())
|
||||
// using available file, embedded or external, depending on file availability and
|
||||
// embedding status.
|
||||
params_.filename = DocFileName(it->availableFile(&buf));
|
||||
if (buf.embeddedFiles().enabled()) {
|
||||
EmbeddedFiles::EmbeddedFileList::const_iterator it =
|
||||
buf.embeddedFiles().find(params_.filename.toFilesystemEncoding());
|
||||
if (it != buf.embeddedFiles().end())
|
||||
// using available file, embedded or external, depending on file availability and
|
||||
// embedding status.
|
||||
params_.filename = DocFileName(it->availableFile(&buf));
|
||||
}
|
||||
graphic_->update(params().as_grfxParams());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user