X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FFormat.cpp;h=1ae3960163de695bcb9457bf14bec40842ecf342;hb=55a3dd7b346d29a52ba305a4558e9e380ef50f47;hp=7e82f9a3b073756f4eadaed6ebc4bc702f9ed9d7;hpb=455ac11cfc239621c2603f56257a24abece4373a;p=lyx.git diff --git a/src/Format.cpp b/src/Format.cpp index 7e82f9a3b0..1ae3960163 100644 --- a/src/Format.cpp +++ b/src/Format.cpp @@ -23,9 +23,14 @@ #include "support/gettext.h" #include "support/lstrings.h" #include "support/os.h" +#include "support/Path.h" #include "support/Systemcall.h" +#include "support/textutils.h" +#include "support/Translator.h" #include +#include +#include // FIXME: Q_WS_MACX is not available, it's in Qt #ifdef USE_MACOSX_PACKAGING @@ -66,30 +71,43 @@ public: : extension_(extension) {} bool operator()(Format const & f) const { - return f.extension() == extension_; + return f.hasExtension(extension_); } private: string extension_; }; + +class FormatPrettyNameEqual : public unary_function { +public: + FormatPrettyNameEqual(string const & prettyname) + : prettyname_(prettyname) {} + bool operator()(Format const & f) const + { + return f.prettyname() == prettyname_; + } +private: + string prettyname_; +}; + } //namespace anon + bool operator<(Format const & a, Format const & b) { - // use the compare_ascii_no_case instead of compare_no_case, - // because in turkish, 'i' is not the lowercase version of 'I', - // and thus turkish locale breaks parsing of tags. - - return compare_ascii_no_case(a.prettyname(), b.prettyname()) < 0; + return _(a.prettyname()) < _(b.prettyname()); } Format::Format(string const & n, string const & e, string const & p, string const & s, string const & v, string const & ed, int flags) - : name_(n), extension_(e), prettyname_(p), shortcut_(s), viewer_(v), + : name_(n), prettyname_(p), shortcut_(s), viewer_(v), editor_(ed), flags_(flags) -{} +{ + extension_list_ = getVectorFromString(e, ","); + LYXERR(Debug::GRAPHICS, "New Format: n=" << n << ", flags=" << flags); +} bool Format::dummy() const @@ -98,11 +116,24 @@ bool Format::dummy() const } +string const Format::extensions() const +{ + return getStringFromVector(extension_list_, ", "); +} + + +bool Format::hasExtension(string const & e) const +{ + return (find(extension_list_.begin(), extension_list_.end(), e) + != extension_list_.end()); +} + + bool Format::isChildFormat() const { if (name_.empty()) return false; - return isdigit(name_[name_.length() - 1]); + return isDigitASCII(name_[name_.length() - 1]); } @@ -112,6 +143,12 @@ string const Format::parentFormat() const } +void Format::setExtensions(string const & e) +{ + extension_list_ = getVectorFromString(e, ","); +} + + // This method should return a reference, and throw an exception // if the format named name cannot be found (Lgb) Format const * Formats::getFormat(string const & name) const @@ -132,11 +169,26 @@ string Formats::getFormatFromFile(FileName const & filename) const return string(); string const format = filename.guessFormatFromContents(); + string const ext = getExtension(filename.absFileName()); + if ((format == "gzip" || format == "zip" || format == "compress") + && !ext.empty()) { + string const & fmt_name = formats.getFormatFromExtension(ext); + if (!fmt_name.empty()) { + Format const * p_format = formats.getFormat(fmt_name); + if (p_format && p_format->zippedNative()) + return p_format->name(); + } + } if (!format.empty()) return format; // try to find a format from the file extension. - string const ext = getExtension(filename.absFileName()); + return getFormatFromExtension(ext); +} + + +string Formats::getFormatFromExtension(string const & ext) const +{ if (!ext.empty()) { // this is ambigous if two formats have the same extension, // but better than nothing @@ -153,6 +205,45 @@ string Formats::getFormatFromFile(FileName const & filename) const } +string Formats::getFormatFromPrettyName(string const & prettyname) const +{ + if (!prettyname.empty()) { + Formats::const_iterator cit = + find_if(formatlist.begin(), formatlist.end(), + FormatPrettyNameEqual(prettyname)); + if (cit != formats.end()) + return cit->name(); + } + return string(); +} + + +/// Used to store last timestamp of file and whether it is (was) zipped +struct ZippedInfo { + bool zipped; + std::time_t timestamp; + ZippedInfo(bool zipped, std::time_t timestamp) + : zipped(zipped), timestamp(timestamp) { } +}; + + +/// Mapping absolute pathnames of files to their ZippedInfo metadata. +static std::map zipped_; + + +bool Formats::isZippedFile(support::FileName const & filename) const { + string const & fname = filename.absFileName(); + time_t timestamp = filename.lastModified(); + map::iterator it = zipped_.find(fname); + if (it != zipped_.end() && it->second.timestamp == timestamp) + return it->second.zipped; + string const & format = getFormatFromFile(filename); + bool zipped = (format == "gzip" || format == "zip"); + zipped_.insert(pair(fname, ZippedInfo(zipped, timestamp))); + return zipped; +} + + static string fixCommand(string const & cmd, string const & ext, os::auto_open_mode mode) { @@ -204,7 +295,7 @@ void Formats::add(string const & name) } -void Formats::add(string const & name, string const & extension, +void Formats::add(string const & name, string const & extensions, string const & prettyname, string const & shortcut, string const & viewer, string const & editor, int flags) @@ -213,10 +304,10 @@ void Formats::add(string const & name, string const & extension, find_if(formatlist.begin(), formatlist.end(), FormatNamesEqual(name)); if (it == formatlist.end()) - formatlist.push_back(Format(name, extension, prettyname, + formatlist.push_back(Format(name, extensions, prettyname, shortcut, viewer, editor, flags)); else - *it = Format(name, extension, prettyname, shortcut, viewer, + *it = Format(name, extensions, prettyname, shortcut, viewer, editor, flags); } @@ -259,27 +350,6 @@ void Formats::setEditor(string const & name, string const & command) } -bool Formats::viewURL(docstring const & url) { - Format const * format = getFormat("html"); - if (!format) - return false; - - string command = libScriptSearch(format->viewer()); - - if (!contains(command, token_from_format)) - command += ' ' + token_from_format; - command = subst(command, token_from_format, quoteName(to_utf8(url))); - - LYXERR(Debug::FILES, "Executing command: " << command); - - Systemcall one; - one.startscript(Systemcall::DontWait, command); - - // we can't report any sort of error, since we aren't waiting - return true; -} - - bool Formats::view(Buffer const & buffer, FileName const & filename, string const & format_name) const { @@ -304,7 +374,7 @@ bool Formats::view(Buffer const & buffer, FileName const & filename, } // viewer is 'auto' if (format->viewer() == "auto") { - if (os::autoOpenFile(filename.absFileName(), os::VIEW)) + if (os::autoOpenFile(filename.absFileName(), os::VIEW, buffer.filePath())) return true; else { Alert::error(_("Cannot view file"), @@ -331,15 +401,16 @@ bool Formats::view(Buffer const & buffer, FileName const & filename, if (!contains(command, token_from_format)) command += ' ' + token_from_format; - command = subst(command, token_from_format, quoteName(filename.toFilesystemEncoding())); + command = subst(command, token_from_format, quoteName(onlyFileName(filename.toFilesystemEncoding()))); command = subst(command, token_path_format, quoteName(onlyPath(filename.toFilesystemEncoding()))); command = subst(command, token_socket_format, quoteName(theServerSocket().address())); LYXERR(Debug::FILES, "Executing command: " << command); // FIXME UNICODE utf8 can be wrong for files buffer.message(_("Executing command: ") + from_utf8(command)); + PathChanger p(filename.onlyPath()); Systemcall one; - one.startscript(Systemcall::DontWait, command); + one.startscript(Systemcall::DontWait, command, buffer.filePath()); // we can't report any sort of error, since we aren't waiting return true; @@ -380,10 +451,10 @@ bool Formats::edit(Buffer const & buffer, FileName const & filename, prettyName(format_name))); return false; } - + // editor is 'auto' if (format->editor() == "auto") { - if (os::autoOpenFile(filename.absFileName(), os::EDIT)) + if (os::autoOpenFile(filename.absFileName(), os::EDIT, buffer.filePath())) return true; else { Alert::error(_("Cannot edit file"), @@ -406,7 +477,7 @@ bool Formats::edit(Buffer const & buffer, FileName const & filename, buffer.message(_("Executing command: ") + from_utf8(command)); Systemcall one; - one.startscript(Systemcall::DontWait, command); + one.startscript(Systemcall::DontWait, command, buffer.filePath()); // we can't report any sort of error, since we aren't waiting return true; @@ -433,8 +504,53 @@ string const Formats::extension(string const & name) const } +string const Formats::extensions(string const & name) const +{ + Format const * format = getFormat(name); + if (format) + return format->extensions(); + else + return name; +} + + +namespace { +typedef Translator FlavorTranslator; + +FlavorTranslator initFlavorTranslator() +{ + FlavorTranslator f(OutputParams::LATEX, "latex"); + f.addPair(OutputParams::DVILUATEX, "dviluatex"); + f.addPair(OutputParams::LUATEX, "luatex"); + f.addPair(OutputParams::PDFLATEX, "pdflatex"); + f.addPair(OutputParams::XETEX, "xetex"); + f.addPair(OutputParams::XML, "docbook-xml"); + f.addPair(OutputParams::HTML, "xhtml"); + f.addPair(OutputParams::TEXT, "text"); + return f; +} +FlavorTranslator const & flavorTranslator() +{ + static FlavorTranslator translator = initFlavorTranslator(); + return translator; +} +} + + +std::string flavor2format(OutputParams::FLAVOR flavor) +{ + return flavorTranslator().find(flavor); +} + + +/* Not currently needed, but I'll leave the code in case it is. +OutputParams::FLAVOR format2flavor(std::string fmt) +{ + return flavorTranslator().find(fmt); +} */ + Formats formats; Formats system_formats;