From 1e8ce6117746cf80d0e495c797c12092d641f9f0 Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Tue, 7 Oct 2003 20:25:10 +0000 Subject: [PATCH] * Rename InsetExternal::Params as InsetExternalParams. Consistent with other Params structs. Allows it to be forward delclared. * Unclutter insetexternal.[Ch] by moving helper functions to new files ExternalSupport.[Ch]. * Fix export to LaTeX and PDFLaTeX without breaking use of the temp dir. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7874 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/factory.C | 2 +- src/frontends/controllers/ChangeLog | 5 + src/frontends/controllers/ControlExternal.C | 23 +- src/frontends/controllers/ControlExternal.h | 16 +- src/frontends/qt2/ChangeLog | 4 + src/frontends/qt2/QExternal.C | 5 +- src/frontends/xforms/FormExternal.C | 5 +- src/insets/ExternalSupport.C | 254 ++++++++++++++++ src/insets/ExternalSupport.h | 56 ++++ src/insets/Makefile.am | 2 + src/insets/insetexternal.C | 320 ++++---------------- src/insets/insetexternal.h | 155 +++++----- 12 files changed, 483 insertions(+), 364 deletions(-) create mode 100644 src/insets/ExternalSupport.C create mode 100644 src/insets/ExternalSupport.h diff --git a/src/factory.C b/src/factory.C index f02653dfbd..6c728827d2 100644 --- a/src/factory.C +++ b/src/factory.C @@ -225,7 +225,7 @@ InsetOld * createInset(FuncRequest const & cmd) } else if (name == "external") { Buffer const & buffer = *cmd.view()->buffer(); - InsetExternal::Params iep; + InsetExternalParams iep; InsetExternalMailer::string2params(cmd.argument, buffer, iep); InsetExternal * inset = new InsetExternal; diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index b5fa09f7f9..242c3fe6bd 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,8 @@ +2003-10-07 Angus Leeming + + * ControlExternal.[Ch]: InsetExternal::Params -> InsetExternalParams. + (getTemplatePtr): removed. Use function in ExternalSupport. + 2003-10-07 Martin Vermeer * ControlBox.C: diff --git a/src/frontends/controllers/ControlExternal.C b/src/frontends/controllers/ControlExternal.C index a7834b6cf7..adb866aa57 100644 --- a/src/frontends/controllers/ControlExternal.C +++ b/src/frontends/controllers/ControlExternal.C @@ -18,6 +18,8 @@ #include "helper_funcs.h" #include "lyxrc.h" +#include "insets/insetexternal.h" +#include "insets/ExternalSupport.h" #include "insets/ExternalTemplate.h" @@ -34,7 +36,7 @@ ControlExternal::ControlExternal(Dialog & parent) bool ControlExternal::initialiseParams(string const & data) { - params_.reset(new InsetExternal::Params); + params_.reset(new InsetExternalParams); InsetExternalMailer::string2params(data, kernel().buffer(), *params_); return true; } @@ -54,14 +56,14 @@ void ControlExternal::dispatchParams() } -void ControlExternal::setParams(InsetExternal::Params const & p) +void ControlExternal::setParams(InsetExternalParams const & p) { BOOST_ASSERT(params_.get()); *params_ = p; } -InsetExternal::Params const & ControlExternal::params() const +InsetExternalParams const & ControlExternal::params() const { BOOST_ASSERT(params_.get()); return *params_; @@ -121,18 +123,6 @@ external::Template ControlExternal::getTemplate(int i) const } -namespace { - -external::Template const * getTemplatePtr(InsetExternal::Params const & params) -{ - external::TemplateManager const & etm = - external::TemplateManager::get(); - return etm.getTemplateByName(params.templatename()); -} - -} // namespace anon - - string const ControlExternal::Browse(string const & input) const { string const title = _("Select external file"); @@ -141,7 +131,8 @@ string const ControlExternal::Browse(string const & input) const /// Determine the template file extension string pattern = "*"; - external::Template const * const et_ptr = getTemplatePtr(params()); + external::Template const * const et_ptr = + external::getTemplatePtr(params()); if (et_ptr) pattern = et_ptr->fileRegExp; diff --git a/src/frontends/controllers/ControlExternal.h b/src/frontends/controllers/ControlExternal.h index 2903e43f75..48c3386b22 100644 --- a/src/frontends/controllers/ControlExternal.h +++ b/src/frontends/controllers/ControlExternal.h @@ -14,15 +14,21 @@ #ifndef CONTROLEXTERNAL_H #define CONTROLEXTERNAL_H - #include "Dialog.h" -#include "insets/insetexternal.h" + #include +#include +#include + + +class InsetExternalParams; namespace lyx { namespace external { + class Template; + } // namespace external } // namespace lyx @@ -41,9 +47,9 @@ public: virtual bool isBufferDependent() const { return true; } /// - InsetExternal::Params const & params() const; + InsetExternalParams const & params() const; /// - void setParams(InsetExternal::Params const &); + void setParams(InsetExternalParams const &); /// void editExternal(); @@ -57,7 +63,7 @@ public: std::string const Browse(std::string const &) const; private: /// - boost::scoped_ptr params_; + boost::scoped_ptr params_; }; #endif // CONTROLEXTERNAL_H diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index 3706ea4213..58ebe47d7c 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,7 @@ +2003-10-07 Angus Leeming + + * QExternal.C: InsetExternal::Params -> InsetExternalParams. + 2003-10-06 Michael Schmitt * QDelimiterDialog.h: diff --git a/src/frontends/qt2/QExternal.C b/src/frontends/qt2/QExternal.C index cbbf8db32f..06e0c0bb7d 100644 --- a/src/frontends/qt2/QExternal.C +++ b/src/frontends/qt2/QExternal.C @@ -15,6 +15,7 @@ #include "qt_helpers.h" #include "insets/ExternalTemplate.h" +#include "insets/insetexternal.h" #include "support/lstrings.h" #include "support/tostr.h" @@ -64,7 +65,7 @@ void QExternal::build_dialog() void QExternal::update_contents() { - InsetExternal::Params const & params = controller().params(); + InsetExternalParams const & params = controller().params(); string const name = params.filename.outputFilename(kernel().bufferFilepath()); @@ -104,7 +105,7 @@ string const QExternal::helpText() const void QExternal::apply() { - InsetExternal::Params params = controller().params(); + InsetExternalParams params = controller().params(); params.filename.set(fromqstr(dialog_->fileED->text()), kernel().bufferFilepath()); diff --git a/src/frontends/xforms/FormExternal.C b/src/frontends/xforms/FormExternal.C index 6e47c0ad87..fac2058fd0 100644 --- a/src/frontends/xforms/FormExternal.C +++ b/src/frontends/xforms/FormExternal.C @@ -22,6 +22,7 @@ #include "xformsBC.h" #include "insets/ExternalTemplate.h" +#include "insets/insetexternal.h" #include "support/lstrings.h" #include "support/tostr.h" @@ -43,7 +44,7 @@ FormExternal::FormExternal(Dialog & parent) void FormExternal::apply() { - InsetExternal::Params params = controller().params(); + InsetExternalParams params = controller().params(); string const buffer_path = kernel().bufferFilepath(); params.filename.set(getString(dialog_->input_filename), buffer_path); @@ -123,7 +124,7 @@ void FormExternal::build() void FormExternal::update() { - InsetExternal::Params const & params = controller().params(); + InsetExternalParams const & params = controller().params(); string const buffer_path = kernel().bufferFilepath(); string const name = params.filename.outputFilename(buffer_path); diff --git a/src/insets/ExternalSupport.C b/src/insets/ExternalSupport.C new file mode 100644 index 0000000000..0ae746b574 --- /dev/null +++ b/src/insets/ExternalSupport.C @@ -0,0 +1,254 @@ +/** + * \file ExternalSupport.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Asger Alstrup Nielsen + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "ExternalSupport.h" +#include "insetexternal.h" + +#include "buffer.h" +#include "converter.h" +#include "debug.h" +#include "ExternalTemplate.h" + +#include "support/filetools.h" +#include "support/forkedcall.h" +#include "support/lstrings.h" +#include "support/lyxalgo.h" +#include "support/lyxlib.h" +#include "support/path.h" +#include "support/path_defines.h" + +#include "support/std_ostream.h" + + +namespace support = lyx::support; + +using std::endl; +using std::string; +using std::ostream; + + +namespace lyx { +namespace external { + +Template const * getTemplatePtr(InsetExternalParams const & params) +{ + TemplateManager const & etm = TemplateManager::get(); + return etm.getTemplateByName(params.templatename()); +} + + +void editExternal(InsetExternalParams const & params, Buffer const & buffer) +{ + external::Template const * const et_ptr = + external::getTemplatePtr(params); + if (!et_ptr) + return; + external::Template const & et = *et_ptr; + + if (et.editCommand.empty()) + return; + + string const command = doSubstitution(params, buffer, et.editCommand); + + support::Path p(buffer.filePath()); + support::Forkedcall call; + if (lyxerr.debugging(Debug::EXTERNAL)) { + lyxerr << "Executing '" << command << "' in '" + << buffer.filePath() << '\'' << endl; + } + call.startscript(support::Forkedcall::DontWait, command); +} + + +namespace { + +string const doSubstitution(InsetExternalParams const & params, + Buffer const & buffer, string const & s, + string const & filename) +{ + string result; + string const basename = support::ChangeExtension(filename, string()); + string const filepath = support::OnlyPath(filename); + + result = support::subst(s, "$$FName", filename); + result = support::subst(result, "$$Basename", basename); + result = support::subst(result, "$$FPath", filepath); + result = support::subst(result, "$$Tempname", params.tempname()); + result = support::subst(result, "$$Sysdir", support::system_lyxdir()); + + // Handle the $$Contents(filename) syntax + if (support::contains(result, "$$Contents(\"")) { + + string::size_type const pos = result.find("$$Contents(\""); + string::size_type const end = result.find("\")", pos); + string const file = result.substr(pos + 12, end - (pos + 12)); + string contents; + + string const filepath = support::IsFileReadable(file) ? + buffer.filePath() : buffer.temppath(); + support::Path p(filepath); + + if (support::IsFileReadable(file)) + contents = support::GetFileContents(file); + + result = support::subst(result, + ("$$Contents(\"" + file + "\")").c_str(), + contents); + } + + return result; +} + +/** update the file represented by the template. + If \param external_in_tmpdir == true, then the generated file is + place in the buffer's temporary directory. +*/ +void updateExternal(InsetExternalParams const & params, + string const & format, + Buffer const & buffer, + bool external_in_tmpdir) +{ + external::Template const * const et_ptr = + external::getTemplatePtr(params); + if (!et_ptr) + return; // FAILURE + external::Template const & et = *et_ptr; + + if (!et.automaticProduction) + return; // NOT_NEEDED + + external::Template::Formats::const_iterator cit = + et.formats.find(format); + if (cit == et.formats.end()) + return; // FAILURE + + external::Template::Format const & outputFormat = cit->second; + if (outputFormat.updateResult.empty()) + return; // NOT_NEEDED + + string from_format = et.inputFormat; + if (from_format.empty()) + return; // NOT_NEEDED + + string from_file = params.filename.absFilename(); + + if (from_format == "*") { + if (from_file.empty()) + return; // NOT_NEEDED + + // Try and ascertain the file format from its contents. + from_format = support::getExtFromContents(from_file); + if (from_format.empty()) + return; // FAILURE + } + + string const to_format = outputFormat.updateFormat; + if (to_format.empty()) + return; // NOT_NEEDED + + if (!converters.isReachable(from_format, to_format)) { + lyxerr[Debug::EXTERNAL] + << "InsetExternal::updateExternal. " + << "Unable to convert from " + << from_format << " to " << to_format << endl; + return; // FAILURE + } + + if (external_in_tmpdir && !from_file.empty()) { + // We are running stuff through LaTeX + string const temp_file = + support::MakeAbsPath(params.filename.mangledFilename(), + buffer.temppath()); + unsigned long const from_checksum = support::sum(from_file); + unsigned long const temp_checksum = support::sum(temp_file); + + if (from_checksum != temp_checksum) { + if (!support::copy(from_file, temp_file)) + return; // FAILURE + } + + from_file = temp_file; + } + + string const to_file = doSubstitution(params, buffer, + outputFormat.updateResult, + from_file); + + string const abs_to_file = + support::MakeAbsPath(to_file, buffer.filePath()); + + // Do we need to perform the conversion? + // Yes if to_file does not exist or if from_file is newer than to_file + if (support::compare_timestamps(from_file, abs_to_file) < 0) + return; // SUCCESS + + string const to_file_base = + support::ChangeExtension(to_file, string()); + /* bool const success = */ + converters.convert(&buffer, from_file, to_file_base, + from_format, to_format); + // return success +} + +} // namespace anon + + +int writeExternal(InsetExternalParams const & params, + string const & format, + Buffer const & buffer, ostream & os, + bool external_in_tmpdir) +{ + external::Template const * const et_ptr = + external::getTemplatePtr(params); + if (!et_ptr) + return 0; + external::Template const & et = *et_ptr; + + external::Template::Formats::const_iterator cit = + et.formats.find(format); + if (cit == et.formats.end()) { + lyxerr[Debug::EXTERNAL] + << "External template format '" << format + << "' not specified in template " + << params.templatename() << endl; + return 0; + } + + updateExternal(params, format, buffer, external_in_tmpdir); + + 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()); + } + + string const str = doSubstitution(params, buffer, cit->second.product, + from_file); + os << str; + return int(lyx::count(str.begin(), str.end(),'\n') + 1); +} + + +/// Substitute meta-variables in this string +string const doSubstitution(InsetExternalParams const & params, + Buffer const & buffer, string const & s) +{ + string const buffer_path = buffer.filePath(); + string const filename = params.filename.outputFilename(buffer_path); + return doSubstitution(params, buffer, s, filename); +} + +} // namespace external +} // namespace lyx diff --git a/src/insets/ExternalSupport.h b/src/insets/ExternalSupport.h new file mode 100644 index 0000000000..3d9e98801e --- /dev/null +++ b/src/insets/ExternalSupport.h @@ -0,0 +1,56 @@ +// -*- C++ -*- +/** + * \file ExternalSupport.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Asger Alstrup Nielsen + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef EXTERNALSUPPORT_H +#define EXTERNALSUPPORT_H + +#include +#include + +class Buffer; +class InsetExternalParams; + +namespace lyx { +namespace external { + +class Template; + +/// A shorthand, helper function +Template const * getTemplatePtr(InsetExternalParams const & params); + + +/// Invoke the external editor. +void editExternal(InsetExternalParams const & params, + Buffer const & buffer); + + +/// Substitute meta-variables in string s, making use of params and buffer. +std::string const doSubstitution(InsetExternalParams const & params, + Buffer const & buffer, + std::string const & s); + + +/** Write the output for a specific file format + and generate any external data files. + If \param external_in_tmpdir == true, then the generated file is + place in the buffer's temporary directory. +*/ +int writeExternal(InsetExternalParams const &, + std::string const & format, + Buffer const &, + std::ostream &, + bool external_in_tmpdir = false); + +} // namespace external +} // namespace lyx + +#endif // NOT EXTERNALSUPPORT_H diff --git a/src/insets/Makefile.am b/src/insets/Makefile.am index dd9c775da9..ba50877fb6 100644 --- a/src/insets/Makefile.am +++ b/src/insets/Makefile.am @@ -13,6 +13,8 @@ EXTRA_DIST = \ libinsets_la_SOURCES = \ mailinset.C \ mailinset.h \ + ExternalSupport.C \ + ExternalSupport.h \ ExternalTemplate.C \ ExternalTemplate.h \ renderers.C \ diff --git a/src/insets/insetexternal.C b/src/insets/insetexternal.C index 3bc0558883..d0eb36403b 100644 --- a/src/insets/insetexternal.C +++ b/src/insets/insetexternal.C @@ -12,34 +12,30 @@ #include "insetexternal.h" #include "insets/renderers.h" +#include "insets/ExternalSupport.h" +#include "insets/ExternalTemplate.h" #include "buffer.h" #include "BufferView.h" -#include "converter.h" #include "debug.h" -#include "ExternalTemplate.h" #include "funcrequest.h" #include "gettext.h" #include "LaTeXFeatures.h" #include "latexrunparams.h" #include "lyxlex.h" #include "lyxrc.h" -#include "support/std_sstream.h" #include "frontends/lyx_gui.h" -#include "support/filetools.h" -#include "support/forkedcall.h" #include "support/lstrings.h" -#include "support/lyxalgo.h" #include "support/lyxlib.h" -#include "support/path.h" -#include "support/path_defines.h" #include "support/tostr.h" #include "support/translator.h" #include +#include "support/std_sstream.h" + namespace support = lyx::support; namespace external = lyx::external; @@ -54,10 +50,13 @@ using std::vector; namespace lyx { namespace graphics { + /// The translator between the DisplayType and the corresponding lyx string. extern Translator displayTranslator; -} -} + +} // namespace graphics +} // namespace lyx + namespace { @@ -65,33 +64,13 @@ lyx::graphics::DisplayType const defaultDisplayType = lyx::graphics::NoDisplay; unsigned int defaultLyxScale = 100; -/// Substitute meta-variables in string s, makeing use of params and buffer. -string const doSubstitution(InsetExternal::Params const & params, - Buffer const & buffer, string const & s); - -/// Invoke the external editor. -void editExternal(InsetExternal::Params const & params, Buffer const & buffer); - - -external::Template const * getTemplatePtr(string const & name) -{ - external::TemplateManager const & etm = - external::TemplateManager::get(); - return etm.getTemplateByName(name); -} - - -external::Template const * getTemplatePtr(InsetExternal::Params const & params) -{ - external::TemplateManager const & etm = - external::TemplateManager::get(); - return etm.getTemplateByName(params.templatename()); -} - } // namespace anon -InsetExternal::TempName::TempName() +namespace lyx { +namespace external { + +TempName::TempName() { tempname_ = support::tempName(string(), "lyxext"); support::unlink(tempname_); @@ -100,40 +79,43 @@ InsetExternal::TempName::TempName() } -InsetExternal::TempName::TempName(InsetExternal::TempName const &) +TempName::TempName(TempName const &) { tempname_ = TempName()(); } -InsetExternal::TempName::~TempName() +TempName::~TempName() { support::unlink(tempname_); } -InsetExternal::TempName & -InsetExternal::TempName::operator=(InsetExternal::TempName const & other) +TempName & +TempName::operator=(TempName const & other) { if (this != &other) tempname_ = TempName()(); return *this; } +} // namespace external +} // namespace lyx + -InsetExternal::Params::Params() +InsetExternalParams::InsetExternalParams() : display(defaultDisplayType), lyxscale(defaultLyxScale) {} -void InsetExternal::Params::settemplate(string const & name) +void InsetExternalParams::settemplate(string const & name) { templatename_ = name; } -void InsetExternal::Params::write(Buffer const & buffer, ostream & os) const +void InsetExternalParams::write(Buffer const & buffer, ostream & os) const { os << "External\n" << "\ttemplate " << templatename() << '\n'; @@ -144,7 +126,8 @@ void InsetExternal::Params::write(Buffer const & buffer, ostream & os) const << '\n'; if (display != defaultDisplayType) - os << "\tdisplay " << lyx::graphics::displayTranslator.find(display) + os << "\tdisplay " + << lyx::graphics::displayTranslator.find(display) << '\n'; if (lyxscale != defaultLyxScale) @@ -152,7 +135,7 @@ void InsetExternal::Params::write(Buffer const & buffer, ostream & os) const } -bool InsetExternal::Params::read(Buffer const & buffer, LyXLex & lex) +bool InsetExternalParams::read(Buffer const & buffer, LyXLex & lex) { enum ExternalTags { EX_TEMPLATE = 1, @@ -216,21 +199,16 @@ bool InsetExternal::Params::read(Buffer const & buffer, LyXLex & lex) break; } - if (!found_end) { - lex.printError("ExternalInset::read: " - "Missing \\end_inset."); - } + if (!found_end) + lex.printError("ExternalInset::read: Missing \\end_inset."); // This is a trick to make sure that the data are self-consistent. settemplate(templatename_); - lyxerr[Debug::EXTERNAL] - << "InsetExternal::Params::read: " - << "template: '" << templatename() - << "' filename: '" << filename.absFilename() - << "' display: '" << display - << "' scale: '" << lyxscale - << '\'' << endl; + if (lyxerr.debugging(Debug::EXTERNAL)) { + lyxerr << "InsetExternalParams::read:\n"; + write(buffer, lyxerr); + } return !read_error; } @@ -247,10 +225,10 @@ InsetExternal::InsetExternal(InsetExternal const & other) params_(other.params_), renderer_(other.renderer_->clone()) { - GraphicRenderer * ptr = dynamic_cast(renderer_.get()); - if (ptr) { + GraphicRenderer * ptr = + dynamic_cast(renderer_.get()); + if (ptr) ptr->connect(boost::bind(&InsetExternal::statusChanged, this)); - } } @@ -268,7 +246,7 @@ InsetExternal::~InsetExternal() void InsetExternal::statusChanged() { - BufferView * bv = renderer_->view(); + BufferView * const bv = renderer_->view(); if (bv) bv->updateInset(this); } @@ -282,9 +260,9 @@ dispatch_result InsetExternal::localDispatch(FuncRequest const & cmd) BOOST_ASSERT(cmd.view()); Buffer const & buffer = *cmd.view()->buffer(); - InsetExternal::Params p; + InsetExternalParams p; InsetExternalMailer::string2params(cmd.argument, buffer, p); - editExternal(p, buffer); + external::editExternal(p, buffer); return DISPATCHED_NOUPDATE; } @@ -292,7 +270,7 @@ dispatch_result InsetExternal::localDispatch(FuncRequest const & cmd) BOOST_ASSERT(cmd.view()); Buffer const & buffer = *cmd.view()->buffer(); - InsetExternal::Params p; + InsetExternalParams p; InsetExternalMailer::string2params(cmd.argument, buffer, p); setParams(p, buffer); cmd.view()->updateInset(this); @@ -329,17 +307,16 @@ void InsetExternal::draw(PainterInfo & pi, int x, int y) const namespace { -lyx::graphics::Params get_grfx_params(InsetExternal::Params const & eparams) +lyx::graphics::Params get_grfx_params(InsetExternalParams const & eparams) { lyx::graphics::Params gparams; gparams.filename = eparams.filename.absFilename(); gparams.scale = eparams.lyxscale; - gparams.display = eparams.display; + gparams.display = eparams.display; if (gparams.display == lyx::graphics::DefaultDisplay) gparams.display = lyxrc.display_graphics; - // Override the above if we're not using a gui if (!lyx_gui::use_gui) gparams.display = lyx::graphics::NoDisplay; @@ -348,32 +325,34 @@ lyx::graphics::Params get_grfx_params(InsetExternal::Params const & eparams) } -string const getScreenLabel(InsetExternal::Params const & params, +string const getScreenLabel(InsetExternalParams const & params, Buffer const & buffer) { - external::Template const * const ptr = getTemplatePtr(params); + external::Template const * const ptr = + external::getTemplatePtr(params); if (!ptr) return support::bformat(_("External template %1$s is not installed"), params.templatename()); - return doSubstitution(params, buffer, ptr->guiName); + return external::doSubstitution(params, buffer, ptr->guiName); } } // namespace anon -InsetExternal::Params const & InsetExternal::params() const +InsetExternalParams const & InsetExternal::params() const { return params_; } -void InsetExternal::setParams(Params const & p, Buffer const & buffer) +void InsetExternal::setParams(InsetExternalParams const & p, + Buffer const & buffer) { // The stored params; what we would like to happen in an ideal world. params_ = p; // We display the inset as a button by default. - bool display_button = (!getTemplatePtr(params_) || + bool display_button = (!external::getTemplatePtr(params_) || params_.filename.empty() || params_.display == lyx::graphics::NoDisplay); @@ -410,38 +389,12 @@ void InsetExternal::write(Buffer const & buffer, ostream & os) const void InsetExternal::read(Buffer const & buffer, LyXLex & lex) { - Params params; + InsetExternalParams params; if (params.read(buffer, lex)) setParams(params, buffer); } -int InsetExternal::write(string const & format, - Buffer const & buf, ostream & os, - bool external_in_tmpdir) const -{ - external::Template const * const et_ptr = getTemplatePtr(params_); - if (!et_ptr) - return 0; - external::Template const & et = *et_ptr; - - external::Template::Formats::const_iterator cit = - et.formats.find(format); - if (cit == et.formats.end()) { - lyxerr[Debug::EXTERNAL] - << "External template format '" << format - << "' not specified in template " - << params_.templatename() << endl; - return 0; - } - - updateExternal(format, buf, external_in_tmpdir); - string const str = doSubstitution(params_, buf, cit->second.product); - os << str; - return int(lyx::count(str.begin(), str.end(),'\n') + 1); -} - - int InsetExternal::latex(Buffer const & buf, ostream & os, LatexRunParams const & runparams) const { @@ -455,7 +408,8 @@ int InsetExternal::latex(Buffer const & buf, ostream & os, // If the template has specified a PDFLaTeX output, then we try and // use that. if (runparams.flavor == LatexRunParams::PDFLATEX) { - external::Template const * const et_ptr = getTemplatePtr(params_); + external::Template const * const et_ptr = + external::getTemplatePtr(params_); if (!et_ptr) return 0; external::Template const & et = *et_ptr; @@ -463,39 +417,43 @@ int InsetExternal::latex(Buffer const & buf, ostream & os, external::Template::Formats::const_iterator cit = et.formats.find("PDFLaTeX"); if (cit != et.formats.end()) - return write("PDFLaTeX", buf, os, external_in_tmpdir); + return external::writeExternal(params_, "PDFLaTeX", + buf, os, external_in_tmpdir); } - return write("LaTeX", buf, os, external_in_tmpdir); + return external::writeExternal(params_, "LaTeX", + buf, os, external_in_tmpdir); } int InsetExternal::ascii(Buffer const & buf, ostream & os, int) const { - return write("Ascii", buf, os); + return external::writeExternal(params_, "Ascii", buf, os); } int InsetExternal::linuxdoc(Buffer const & buf, ostream & os) const { - return write("LinuxDoc", buf, os); + return external::writeExternal(params_, "LinuxDoc", buf, os); } int InsetExternal::docbook(Buffer const & buf, ostream & os, bool) const { - return write("DocBook", buf, os); + return external::writeExternal(params_, "DocBook", buf, os); } void InsetExternal::validate(LaTeXFeatures & features) const { - external::Template const * const et_ptr = getTemplatePtr(params_); + external::Template const * const et_ptr = + external::getTemplatePtr(params_); if (!et_ptr) return; external::Template const & et = *et_ptr; - external::Template::Formats::const_iterator cit = et.formats.find("LaTeX"); + external::Template::Formats::const_iterator cit = + et.formats.find("LaTeX"); if (cit == et.formats.end()) return; @@ -514,152 +472,6 @@ void InsetExternal::validate(LaTeXFeatures & features) const } -void InsetExternal::updateExternal(string const & format, - Buffer const & buf, - bool external_in_tmpdir) const -{ - external::Template const * const et_ptr = getTemplatePtr(params_); - if (!et_ptr) - return; - external::Template const & et = *et_ptr; - - if (!et.automaticProduction) - return; - - external::Template::Formats::const_iterator cit = - et.formats.find(format); - if (cit == et.formats.end()) - return; - - external::Template::Format const & outputFormat = cit->second; - if (outputFormat.updateResult.empty()) - return; - - string from_format = et.inputFormat; - if (from_format.empty()) - return; - - string from_file = params_.filename.absFilename(); - - if (from_format == "*") { - if (from_file.empty()) - return; - - // Try and ascertain the file format from its contents. - from_format = support::getExtFromContents(from_file); - if (from_format.empty()) - return; - } - - string const to_format = outputFormat.updateFormat; - if (to_format.empty()) - return; - - if (!converters.isReachable(from_format, to_format)) { - lyxerr[Debug::EXTERNAL] - << "InsetExternal::updateExternal. " - << "Unable to convert from " - << from_format << " to " << to_format << endl; - return; - } - - if (external_in_tmpdir && !from_file.empty()) { - // We are running stuff through LaTeX - string const temp_file = - support::MakeAbsPath(params_.filename.mangledFilename(), - buf.temppath()); - unsigned long const from_checksum = support::sum(from_file); - unsigned long const temp_checksum = support::sum(temp_file); - - // Nothing to do... - if (from_checksum == temp_checksum) - return; - - // Cannot proceed... - if (!support::copy(from_file, temp_file)) - return; - from_file = temp_file; - } - - string const to_file = doSubstitution(params_, buf, - outputFormat.updateResult); - string const abs_to_file = support::MakeAbsPath(to_file, buf.filePath()); - - // Do we need to perform the conversion? - // Yes if to_file does not exist or if from_file is newer than to_file - if (support::compare_timestamps(from_file, abs_to_file) < 0) - return; - - string const to_filebase = support::ChangeExtension(to_file, string()); - converters.convert(&buf, from_file, to_filebase, from_format, to_format); -} - - -namespace { - -/// Substitute meta-variables in this string -string const doSubstitution(InsetExternal::Params const & params, - Buffer const & buffer, string const & s) -{ - string result; - string const buffer_path = buffer.filePath(); - string const filename = params.filename.outputFilename(buffer_path); - string const basename = support::ChangeExtension(filename, string()); - string const filepath = support::OnlyPath(filename); - - result = support::subst(s, "$$FName", filename); - result = support::subst(result, "$$Basename", basename); - result = support::subst(result, "$$FPath", filepath); - result = support::subst(result, "$$Tempname", params.tempname()); - result = support::subst(result, "$$Sysdir", support::system_lyxdir()); - - // Handle the $$Contents(filename) syntax - if (support::contains(result, "$$Contents(\"")) { - - string::size_type const pos = result.find("$$Contents(\""); - string::size_type const end = result.find("\")", pos); - string const file = result.substr(pos + 12, end - (pos + 12)); - string contents; - - string const filepath = support::IsFileReadable(file) ? - buffer.filePath() : buffer.temppath(); - support::Path p(filepath); - - if (support::IsFileReadable(file)) - contents = support::GetFileContents(file); - - result = support::subst(result, - ("$$Contents(\"" + file + "\")").c_str(), - contents); - } - - return result; -} - - -void editExternal(InsetExternal::Params const & params, Buffer const & buffer) -{ - external::Template const * const et_ptr = getTemplatePtr(params); - if (!et_ptr) - return; - external::Template const & et = *et_ptr; - - if (et.editCommand.empty()) - return; - - string const command = doSubstitution(params, buffer, et.editCommand); - - support::Path p(buffer.filePath()); - support::Forkedcall call; - if (lyxerr.debugging(Debug::EXTERNAL)) { - lyxerr << "Executing '" << command << "' in '" - << buffer.filePath() << '\'' << endl; - } - call.startscript(support::Forkedcall::DontWait, command); -} - -} // namespace anon - string const InsetExternalMailer::name_("external"); InsetExternalMailer::InsetExternalMailer(InsetExternal & inset) @@ -675,9 +487,9 @@ string const InsetExternalMailer::inset2string(Buffer const & buffer) const void InsetExternalMailer::string2params(string const & in, Buffer const & buffer, - InsetExternal::Params & params) + InsetExternalParams & params) { - params = InsetExternal::Params(); + params = InsetExternalParams(); if (in.empty()) return; @@ -709,7 +521,7 @@ void InsetExternalMailer::string2params(string const & in, string const -InsetExternalMailer::params2string(InsetExternal::Params const & params, +InsetExternalMailer::params2string(InsetExternalParams const & params, Buffer const & buffer) { ostringstream data; diff --git a/src/insets/insetexternal.h b/src/insets/insetexternal.h index 9e955d1b76..024a2319ce 100644 --- a/src/insets/insetexternal.h +++ b/src/insets/insetexternal.h @@ -22,108 +22,104 @@ #include -class RenderInset; +/** No two InsetExternalParams variables can have the same temporary file. + * This struct has copy-semantics but the copy constructor + * and assignment operator simply call the default constructor. + * Use of this struct enables us to use the compiler-generated + * copy constructor and assignment operator for the + * InsetExternalParams struct. + */ +namespace lyx { +namespace external { + +struct TempName { + TempName(); + TempName(TempName const &); + ~TempName(); + TempName & operator=(TempName const &); + std::string const & operator()() const { return tempname_; } +private: + std::string tempname_; +}; -/// -class InsetExternal : public InsetOld, public boost::signals::trackable -{ - /** No two Params variables can have the same temporary file. - * This struct has copy-semantics but the copy constructor - * and assignment operator simply call the default constructor. - * Use of this struct enables us to use the compiler-generated - * copy constructor and assignment operator for the Params struct. - */ - struct TempName { - TempName(); - TempName(TempName const &); - ~TempName(); - TempName & operator=(TempName const &); - std::string const & operator()() const { return tempname_; } - private: - std::string tempname_; - }; +} // namespace external +} // namespace lyx -public: - /// hold parameters settable from the GUI - struct Params { - Params(); - void write(Buffer const &, std::ostream &) const; - bool read(Buffer const &, LyXLex &); +/// hold parameters settable from the GUI +struct InsetExternalParams { + InsetExternalParams(); - /// The name of the tempfile used for manipulations. - std::string const & tempname() const { return tempname_(); } + void write(Buffer const &, std::ostream &) const; + bool read(Buffer const &, LyXLex &); - /// the current template used - void settemplate(std::string const &); - std::string const & templatename() const { return templatename_; } + /// The name of the tempfile used for manipulations. + std::string const & tempname() const { return tempname_(); } - /// the filename - lyx::support::FileName filename; - /// how the inset is displayed by LyX - lyx::graphics::DisplayType display; - /// The scale of the displayed graphic (If shown). - unsigned int lyxscale; + /// The template currently in use. + void settemplate(std::string const &); + std::string const & templatename() const { return templatename_; } - private: - TempName tempname_; - std::string templatename_; - }; + /// The external file. + lyx::support::FileName filename; + /// How the inset is to be displayed by LyX. + lyx::graphics::DisplayType display; + /// The scale of the displayed graphic (if shown). + unsigned int lyxscale; +private: + lyx::external::TempName tempname_; + std::string templatename_; +}; + + +class RenderInset; + +/// +class InsetExternal : public InsetOld, public boost::signals::trackable +{ +public: InsetExternal(); /// InsetExternal(InsetExternal const &); /// virtual ~InsetExternal(); /// + virtual std::auto_ptr clone() const; + /// virtual dispatch_result localDispatch(FuncRequest const & cmd); + + /// + virtual InsetOld::Code lyxCode() const { return EXTERNAL_CODE; } + /// + virtual EDITABLE editable() const { return IS_EDITABLE; } + /// void metrics(MetricsInfo &, Dimension &) const; /// void draw(PainterInfo & pi, int x, int y) const; /// - virtual EDITABLE editable() const { return IS_EDITABLE; } - /// virtual void write(Buffer const &, std::ostream &) const; /// virtual void read(Buffer const &, LyXLex & lex); - /** returns the number of rows (\n's) of generated tex code. - fragile == true means, that the inset should take care about - fragile commands by adding a \protect before. - If the free_spc (freespacing) variable is set, then this inset - is in a free-spacing paragraph. - */ + /// \returns the number of rows (\n's) of generated code. virtual int latex(Buffer const &, std::ostream &, LatexRunParams const &) const; - /// write ASCII output to the ostream + /// virtual int ascii(Buffer const &, std::ostream &, int linelen) const; - /// write LinuxDoc output to the ostream + /// virtual int linuxdoc(Buffer const &, std::ostream &) const; - /// write DocBook output to the ostream - virtual int docbook(Buffer const &, std::ostream &, bool mixcont) const; + /// + virtual int docbook(Buffer const &, std::ostream &, + bool mixcont) const; - /// Updates needed features for this inset. + /// Update needed features for this inset. virtual void validate(LaTeXFeatures & features) const; - /// returns LyX code associated with the inset. Used for TOC, ...) - virtual InsetOld::Code lyxCode() const { return EXTERNAL_CODE; } - /// - virtual std::auto_ptr clone() const; - - /// return a copy of our current params - Params const & params() const; - - /// Set the inset parameters. - virtual void setParams(Params const &, Buffer const &); - - /** update the file represented by the template. - If \param external_in_tmpdir == true, then the generated file is - place in the buffer's temporary directory. - */ - void updateExternal(std::string const &, Buffer const &, - bool external_in_tmpdir) const; + InsetExternalParams const & params() const; + void setParams(InsetExternalParams const &, Buffer const &); private: /** This method is connected to the graphics loader, so we are @@ -131,17 +127,8 @@ private: */ void statusChanged(); - /** Write the output for a specific file format - and generate any external data files. - If \param external_in_tmpdir == true, then the generated file is - place in the buffer's temporary directory. - */ - int write(std::string const & format, Buffer const &, std::ostream &, - bool external_in_tmpdir = false) const; - - /// the current params - Params params_; - + /// The current params + InsetExternalParams params_; /// The thing that actually draws the image on LyX's screen. boost::scoped_ptr renderer_; }; @@ -161,10 +148,10 @@ public: virtual std::string const inset2string(Buffer const &) const; /// static void string2params(std::string const &, Buffer const &, - InsetExternal::Params &); + InsetExternalParams &); /// - static std::string const params2string(InsetExternal::Params const &, - Buffer const &); + static std::string const params2string(InsetExternalParams const &, + Buffer const &); private: /// static std::string const name_; -- 2.39.2