From: Bo Peng Date: Mon, 10 Sep 2007 03:54:02 +0000 (+0000) Subject: Embedding: prepare to read/write manifest in .lyx file X-Git-Tag: 1.6.10~8406 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=3189e7b5dd438876016091463b8e66b134295fb5;p=lyx.git 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 --- diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 404efdf6fb..76cce2c544 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -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 diff --git a/src/EmbeddedFiles.cpp b/src/EmbeddedFiles.cpp index 2680f4d563..155ed86ac7 100644 --- a/src/EmbeddedFiles.cpp +++ b/src/EmbeddedFiles.cpp @@ -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 > 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; - - if (version != 1) { - lyxerr << "This version of LyX can only read LyX manifest version 1" << endl; - return is; - } + int line = -1; + int begin_manifest_line = -1; - getline(is, tmp); - if (tmp != "") { - lyxerr << "Invalid manifest file, lacking " << endl; - return is; - } - // manifest file may be messed up, be carefully - while (is.good()) { - getline(is, tmp); - if (tmp != "") - break; + file_list_.clear(); + string filename = ""; + string inzipName = ""; + bool status = ""; + + while (lex.isOK()) { + lex.next(); + string const token = lex.getString(); + + if (token.empty()) + continue; - 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 != "") { - lyxerr << "Invalid manifest file, lacking " << endl; + if (token == "\\end_manifest") break; - } - files.registerFile(fname, embed); - }; - // the last line must be - if (tmp != "") { - lyxerr << "Invalid manifest file, lacking " << endl; - return is; + ++line; + if (token == "\\begin_manifest") { + begin_manifest_line = line; + continue; + } + + LYXERR(Debug::PARSER) << "Handling document manifest token: `" + << token << '\'' << endl; + + 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)); + } + } + if (begin_manifest_line) { + docstring const s = _("\\begin_manifest is missing"); + errorList.push_back(ErrorItem(_("Manifest error"), + s, -1, 0, 0)); } - return is; + 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 << "\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 << "\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' - << "\n"; + from_utf8(buffer_->filePath()))) << '\n' + << "\\inzipName " << it->inzipName() << '\n' + << "\\status " << (it->embedded() ? "true" : "false") << '\n'; } - os << "\n"; - return os; } + } diff --git a/src/EmbeddedFiles.h b/src/EmbeddedFiles.h index df8915e6bb..58b1a08b1a 100644 --- a/src/EmbeddedFiles.h +++ b/src/EmbeddedFiles.h @@ -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 diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp index a54de14c98..70cfe9767d 100644 --- a/src/insets/InsetGraphics.cpp +++ b/src/insets/InsetGraphics.cpp @@ -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()); }