]> git.lyx.org Git - features.git/commitdiff
Rename three remaining .C files
authorBo Peng <bpeng@lyx.org>
Thu, 26 Apr 2007 05:18:04 +0000 (05:18 +0000)
committerBo Peng <bpeng@lyx.org>
Thu, 26 Apr 2007 05:18:04 +0000 (05:18 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18026 a592a061-630c-0410-9148-cb99ea01b6c8

development/scons/scons_manifest.py
src/insets/ExternalSupport.C [deleted file]
src/insets/ExternalSupport.cpp [new file with mode: 0644]
src/insets/ExternalTemplate.C [deleted file]
src/insets/ExternalTemplate.cpp [new file with mode: 0644]
src/insets/ExternalTransforms.C [deleted file]
src/insets/ExternalTransforms.cpp [new file with mode: 0644]
src/insets/Makefile.am

index 557d7219031106f6f6b630c8fed56222025419de..692c5b72c63fe964e345ca193f8ef4c564b82cd8 100644 (file)
@@ -375,9 +375,9 @@ src_insets_header_files = Split('''
 
 
 src_insets_files = Split('''
-    ExternalSupport.C
-    ExternalTemplate.C
-    ExternalTransforms.C
+    ExternalSupport.cpp
+    ExternalTemplate.cpp
+    ExternalTransforms.cpp
     Inset.cpp
     InsetBase.cpp
     InsetBibitem.cpp
diff --git a/src/insets/ExternalSupport.C b/src/insets/ExternalSupport.C
deleted file mode 100644 (file)
index aba7818..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/**
- * \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 <config.h>
-
-#include "ExternalSupport.h"
-#include "ExternalTemplate.h"
-#include "ExternalTransforms.h"
-#include "InsetExternal.h"
-
-#include "Buffer.h"
-#include "Converter.h"
-#include "debug.h"
-#include "Exporter.h"
-#include "Format.h"
-#include "Mover.h"
-
-#include "support/filetools.h"
-#include "support/Forkedcall.h"
-#include "support/lstrings.h"
-#include "support/lyxalgo.h"
-#include "support/lyxlib.h"
-#include "support/os.h"
-#include "support/Package.h"
-
-#include <boost/filesystem/operations.hpp>
-
-using std::endl;
-using std::string;
-using std::vector;
-
-using boost::filesystem::is_directory;
-
-
-namespace lyx {
-
-using support::FileName;
-
-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)
-{
-       formats.edit(buffer, params.filename,
-                    formats.getFormatFromFile(params.filename));
-}
-
-
-namespace {
-
-string const subst_path(string const & input,
-                       string const & placeholder,
-                       string const & path,
-                       bool use_latex_path,
-                       support::latex_path_extension ext = support::PROTECT_EXTENSION,
-                       support::latex_path_dots dots = support::LEAVE_DOTS)
-{
-       if (input.find(placeholder) == string::npos)
-               return input;
-       // Don't use external_path here when use_latex_path is false, as the
-       // path will be compared with another one in internal style later
-       // in Converters::move.
-       string const path2 = use_latex_path ?
-               support::latex_path(path, ext, dots) : path;
-       return support::subst(input, placeholder, path2);
-}
-
-} // namespace anon
-
-
-string const doSubstitution(InsetExternalParams const & params,
-                           Buffer const & buffer, string const & s,
-                           bool use_latex_path,
-                           bool external_in_tmpdir,
-                           Substitute what)
-{
-       Buffer const * m_buffer = buffer.getMasterBuffer();
-       string const parentpath = external_in_tmpdir ?
-               m_buffer->temppath() :
-               buffer.filePath();
-       string const filename = external_in_tmpdir ?
-               params.filename.mangledFilename() :
-               params.filename.outputFilename(parentpath);
-       string const basename = support::changeExtension(
-                       support::onlyFilename(filename), string());
-       string const absname = support::makeAbsPath(filename, parentpath).absFilename();
-
-       string result = s;
-       if (what != ALL_BUT_PATHS) {
-               string const filepath = support::onlyPath(filename);
-               string const abspath = support::onlyPath(absname);
-               string const masterpath = external_in_tmpdir ?
-                       m_buffer->temppath() :
-                       m_buffer->filePath();
-               // FIXME UNICODE
-               string relToMasterPath = support::onlyPath(
-                               to_utf8(support::makeRelPath(from_utf8(absname),
-                                                            from_utf8(masterpath))));
-               if (relToMasterPath == "./")
-                       relToMasterPath.clear();
-               // FIXME UNICODE
-               string relToParentPath = support::onlyPath(
-                               to_utf8(support::makeRelPath(from_utf8(absname),
-                                                            from_utf8(parentpath))));
-               if (relToParentPath == "./")
-                       relToParentPath.clear();
-
-               result = subst_path(result, "$$FPath", filepath,
-                                   use_latex_path,
-                                   support::PROTECT_EXTENSION,
-                                   support::ESCAPE_DOTS);
-               result = subst_path(result, "$$AbsPath", abspath,
-                                   use_latex_path,
-                                   support::PROTECT_EXTENSION,
-                                   support::ESCAPE_DOTS);
-               result = subst_path(result, "$$RelPathMaster",
-                                   relToMasterPath, use_latex_path,
-                                   support::PROTECT_EXTENSION,
-                                   support::ESCAPE_DOTS);
-               result = subst_path(result, "$$RelPathParent",
-                                   relToParentPath, use_latex_path,
-                                   support::PROTECT_EXTENSION,
-                                   support::ESCAPE_DOTS);
-               if (support::absolutePath(filename)) {
-                       result = subst_path(result, "$$AbsOrRelPathMaster",
-                                           abspath, use_latex_path,
-                                           support::PROTECT_EXTENSION,
-                                           support::ESCAPE_DOTS);
-                       result = subst_path(result, "$$AbsOrRelPathParent",
-                                           abspath, use_latex_path,
-                                           support::PROTECT_EXTENSION,
-                                           support::ESCAPE_DOTS);
-               } else {
-                       result = subst_path(result, "$$AbsOrRelPathMaster",
-                                           relToMasterPath, use_latex_path,
-                                           support::PROTECT_EXTENSION,
-                                           support::ESCAPE_DOTS);
-                       result = subst_path(result, "$$AbsOrRelPathParent",
-                                           relToParentPath, use_latex_path,
-                                           support::PROTECT_EXTENSION,
-                                           support::ESCAPE_DOTS);
-               }
-       }
-
-       if (what == PATHS)
-               return result;
-
-       result = subst_path(result, "$$FName", filename, use_latex_path,
-                           support::EXCLUDE_EXTENSION);
-       result = subst_path(result, "$$Basename", basename, use_latex_path,
-                           support::PROTECT_EXTENSION, support::ESCAPE_DOTS);
-       result = subst_path(result, "$$Extension",
-                       '.' + support::getExtension(filename), use_latex_path);
-       result = subst_path(result, "$$Tempname", params.tempname().absFilename(), use_latex_path);
-       result = subst_path(result, "$$Sysdir",
-                               support::package().system_support().absFilename(), use_latex_path);
-
-       // Handle the $$Contents(filename) syntax
-       if (support::contains(result, "$$Contents(\"")) {
-               // Since use_latex_path may be true we must extract the file
-               // name from s instead of result and do the substitutions
-               // again, this time with use_latex_path false.
-               string::size_type const spos = s.find("$$Contents(\"");
-               string::size_type const send = s.find("\")", spos);
-               string const file_template = s.substr(spos + 12, send - (spos + 12));
-               string const file = doSubstitution(params, buffer,
-                                                  file_template, false,
-                                                  external_in_tmpdir, what);
-               string contents;
-
-               FileName const absfile(
-                       support::makeAbsPath(file, m_buffer->temppath()));
-               if (support::isFileReadable(absfile))
-                       contents = support::getFileContents(absfile);
-
-               string::size_type const pos = result.find("$$Contents(\"");
-               string::size_type const end = result.find("\")", pos);
-               result.replace(pos, end + 2, contents);
-       }
-
-       return result;
-}
-
-
-namespace {
-
-/** update the file represented by the template.
-    If \p external_in_tmpdir == true, then the generated file is
-    placed in the buffer's temporary directory.
-*/
-void updateExternal(InsetExternalParams const & params,
-                   string const & format,
-                   Buffer const & buffer,
-                   ExportData & exportdata,
-                    bool external_in_tmpdir,
-                    bool dryrun)
-{
-       Template const * const et_ptr = getTemplatePtr(params);
-       if (!et_ptr)
-               return; // FAILURE
-       Template const & et = *et_ptr;
-
-       if (!et.automaticProduction)
-               return; // NOT_NEEDED
-
-       Template::Formats::const_iterator cit = et.formats.find(format);
-       if (cit == et.formats.end())
-               return; // FAILURE
-
-       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
-
-       if (from_format == "*") {
-               if (params.filename.empty())
-                       return; // NOT_NEEDED
-
-               // Try and ascertain the file format from its contents.
-               from_format = formats.getFormatFromFile(params.filename);
-               if (from_format.empty())
-                       return; // FAILURE
-
-       }
-
-       string const to_format = outputFormat.updateFormat;
-       if (to_format.empty())
-               return; // NOT_NEEDED
-
-       // The master buffer. This is useful when there are multiple levels
-       // of include files
-       Buffer const * m_buffer = buffer.getMasterBuffer();
-
-       // We copy the source file to the temp dir and do the conversion
-       // there if necessary
-       FileName const temp_file(
-               support::makeAbsPath(params.filename.mangledFilename(),
-                                    m_buffer->temppath()));
-       if (!params.filename.empty() && !is_directory(params.filename.toFilesystemEncoding())) {
-               unsigned long const from_checksum = support::sum(params.filename);
-               unsigned long const temp_checksum = support::sum(temp_file);
-
-               if (from_checksum != temp_checksum) {
-                       Mover const & mover = getMover(from_format);
-                       if (!mover.copy(params.filename, temp_file)) {
-                               LYXERR(Debug::EXTERNAL)
-                                       << "external::updateExternal. "
-                                       << "Unable to copy "
-                                       << params.filename << " to " << temp_file << endl;
-                               return; // FAILURE
-                       }
-               }
-       }
-
-       // the generated file (always in the temp dir)
-       string const to_file = doSubstitution(params, buffer,
-                                             outputFormat.updateResult,
-                                             false, true);
-       FileName const abs_to_file(
-               support::makeAbsPath(to_file, m_buffer->temppath()));
-
-       if (!dryrun) {
-               // Record the referenced files for the exporter.
-               // The exporter will copy them to the export dir.
-               typedef Template::Format::FileMap FileMap;
-               FileMap::const_iterator rit  = outputFormat.referencedFiles.begin();
-               FileMap::const_iterator rend = outputFormat.referencedFiles.end();
-               for (; rit != rend; ++rit) {
-                       vector<string>::const_iterator fit  = rit->second.begin();
-                       vector<string>::const_iterator fend = rit->second.end();
-                       for (; fit != fend; ++fit) {
-                               FileName const source(support::makeAbsPath(
-                                               doSubstitution(params, buffer, *fit,
-                                                              false, true),
-                                               m_buffer->temppath()));
-                               // The path of the referenced file is never the
-                               // temp path, but the filename may be the mangled
-                               // or the real name. Therefore we substitute the
-                               // paths and names separately.
-                               string file = support::subst(*fit, "$$FName",
-                                               "$$FPath$$Basename$$Extension");
-                               file = doSubstitution(params, buffer, file, false, false,
-                                                     PATHS);
-                               file = doSubstitution(params, buffer, file,
-                                                     false, external_in_tmpdir,
-                                                     ALL_BUT_PATHS);
-                               // if file is a relative name, it is interpreted
-                               // relative to the master document.
-                               exportdata.addExternalFile(rit->first, source, file);
-                       }
-               }
-       }
-
-       // 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(temp_file, abs_to_file) < 0)
-               return; // SUCCESS
-
-       // FIXME (Abdel 12/08/06): Is there a need to show these errors?
-       ErrorList el;
-       bool const success =
-               theConverters().convert(&buffer, temp_file, abs_to_file,
-                                  params.filename, from_format, to_format, el,
-                                  Converters::try_default | Converters::try_cache);
-
-       if (!success)
-               LYXERR(Debug::EXTERNAL)
-                       << "external::updateExternal. "
-                       << "Unable to convert from "
-                       << from_format << " to " << to_format << endl;
-
-       // return success
-}
-
-
-string const substituteCommands(InsetExternalParams const & params,
-                               string const & input, string const & format);
-
-string const substituteOptions(InsetExternalParams const & params,
-                              string const & input, string const & format);
-
-} // namespace anon
-
-
-int writeExternal(InsetExternalParams const & params,
-                 string const & format,
-                 Buffer const & buffer, odocstream & os,
-                 ExportData & exportdata,
-                 bool external_in_tmpdir,
-                 bool dryrun)
-{
-       Template const * const et_ptr = getTemplatePtr(params);
-       if (!et_ptr)
-               return 0;
-       Template const & et = *et_ptr;
-
-       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;
-       }
-
-       if (!dryrun || support::contains(cit->second.product, "$$Contents"))
-               updateExternal(params, format, buffer, exportdata,
-                              external_in_tmpdir, dryrun);
-
-       bool const use_latex_path = format == "LaTeX";
-       string str = doSubstitution(params, buffer, cit->second.product,
-                                   use_latex_path, external_in_tmpdir);
-       str = substituteCommands(params, str, format);
-       str = substituteOptions(params, str, format);
-       // FIXME UNICODE
-       os << from_utf8(str);
-       return int(lyx::count(str.begin(), str.end(),'\n'));
-}
-
-namespace {
-
-// Empty template, specialised below.
-template <typename TransformType>
-string const substituteIt(string const &,
-                         TransformID,
-                         string const &,
-                         Template::Format const &,
-                         InsetExternalParams const &);
-
-
-template <>
-string const substituteIt<TransformCommand>(string const & input,
-                                           TransformID id,
-                                           string const & /* formatname */,
-                                           Template::Format const & format,
-                                           InsetExternalParams const & params)
-{
-       typedef std::map<TransformID, TransformStore> Transformers;
-       Transformers::const_iterator it = format.command_transformers.find(id);
-       if (it == format.command_transformers.end())
-               return input;
-
-       TransformStore const & store = it->second;
-
-       TransformCommand::ptr_type ptr;
-       if (id == Rotate)
-               ptr = store.getCommandTransformer(params.rotationdata);
-       else if (id == Resize)
-               ptr = store.getCommandTransformer(params.resizedata);
-
-       if (!ptr.get())
-               return input;
-
-       string result =
-               support::subst(input, ptr->front_placeholder(), ptr->front());
-       return support::subst(result, ptr->back_placeholder(),  ptr->back());
-}
-
-
-template <>
-string const substituteIt<TransformOption>(string const & input,
-                                          TransformID id,
-                                          string const & fname,
-                                          Template::Format const & format,
-                                          InsetExternalParams const & params)
-{
-       typedef std::map<TransformID, TransformStore> Transformers;
-       Transformers::const_iterator it = format.option_transformers.find(id);
-       if (it == format.option_transformers.end())
-               return input;
-
-       TransformStore const & store = it->second;
-
-       TransformOption::ptr_type ptr;
-       switch (id) {
-       case Clip:
-               ptr = store.getOptionTransformer(params.clipdata);
-               break;
-       case Extra:
-               ptr = store.getOptionTransformer(params.extradata.get(fname));
-               break;
-       case Rotate:
-               ptr = store.getOptionTransformer(params.rotationdata);
-               break;
-       case Resize:
-               ptr = store.getOptionTransformer(params.resizedata);
-               break;
-       }
-
-       if (!ptr.get())
-               return input;
-
-       return support::subst(input, ptr->placeholder(), ptr->option());
-}
-
-
-template <typename TransformerType>
-string const transformIt(InsetExternalParams const & params,
-                        string const & s, string const & formatname)
-{
-       Template const * const et = getTemplatePtr(params);
-       if (!et || et->transformIds.empty())
-               return s;
-
-       Template::Formats::const_iterator fit = et->formats.find(formatname);
-       if (fit == et->formats.end())
-               return s;
-
-       string result = s;
-       Template::Format const & format =  fit->second;
-
-       typedef vector<TransformID> TransformsIDs;
-       TransformsIDs::const_iterator it  = et->transformIds.begin();
-       TransformsIDs::const_iterator end = et->transformIds.end();
-       for (; it != end; ++it) {
-               result = substituteIt<TransformerType>(result, *it, formatname,
-                                                      format, params);
-       }
-       return result;
-}
-
-
-string const substituteCommands(InsetExternalParams const & params,
-                               string const & input, string const & format)
-{
-       return transformIt<TransformCommand>(params, input, format);
-}
-
-
-string const substituteOption(InsetExternalParams const & params,
-                             string const & input, string const & format)
-{
-       string opt = transformIt<TransformOption>(params, input, format);
-
-       if (format == "LaTeX" || format == "PDFLaTeX")
-               return sanitizeLatexOption(opt);
-       if (format == "DocBook")
-               return sanitizeDocBookOption(opt);
-       return opt;
-}
-
-
-string const substituteOptions(InsetExternalParams const & params,
-                              string const & input, string const & format)
-{
-       string output = input;
-
-       Template const * const et = getTemplatePtr(params);
-       if (!et || et->transformIds.empty())
-               return output;
-
-       Template::Formats::const_iterator fit = et->formats.find(format);
-       if (fit == et->formats.end() || fit->second.options.empty())
-               return output;
-
-       typedef vector<Template::Option> Options;
-       Options const & options = fit->second.options;
-       Options::const_iterator it  = options.begin();
-       Options::const_iterator end = options.end();
-       for (; it != end; ++it) {
-               string const opt = substituteOption(params, it->option, format);
-               string const placeholder = "$$" + it->name;
-               output = support::subst(output, placeholder, opt);
-       }
-
-       return output;
-}
-
-} // namespace anon
-
-} // namespace external
-
-} // namespace lyx
diff --git a/src/insets/ExternalSupport.cpp b/src/insets/ExternalSupport.cpp
new file mode 100644 (file)
index 0000000..673959c
--- /dev/null
@@ -0,0 +1,530 @@
+/**
+ * \file ExternalSupport.cpp
+ * 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 <config.h>
+
+#include "ExternalSupport.h"
+#include "ExternalTemplate.h"
+#include "ExternalTransforms.h"
+#include "InsetExternal.h"
+
+#include "Buffer.h"
+#include "Converter.h"
+#include "debug.h"
+#include "Exporter.h"
+#include "Format.h"
+#include "Mover.h"
+
+#include "support/filetools.h"
+#include "support/Forkedcall.h"
+#include "support/lstrings.h"
+#include "support/lyxalgo.h"
+#include "support/lyxlib.h"
+#include "support/os.h"
+#include "support/Package.h"
+
+#include <boost/filesystem/operations.hpp>
+
+using std::endl;
+using std::string;
+using std::vector;
+
+using boost::filesystem::is_directory;
+
+
+namespace lyx {
+
+using support::FileName;
+
+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)
+{
+       formats.edit(buffer, params.filename,
+                    formats.getFormatFromFile(params.filename));
+}
+
+
+namespace {
+
+string const subst_path(string const & input,
+                       string const & placeholder,
+                       string const & path,
+                       bool use_latex_path,
+                       support::latex_path_extension ext = support::PROTECT_EXTENSION,
+                       support::latex_path_dots dots = support::LEAVE_DOTS)
+{
+       if (input.find(placeholder) == string::npos)
+               return input;
+       // Don't use external_path here when use_latex_path is false, as the
+       // path will be compared with another one in internal style later
+       // in Converters::move.
+       string const path2 = use_latex_path ?
+               support::latex_path(path, ext, dots) : path;
+       return support::subst(input, placeholder, path2);
+}
+
+} // namespace anon
+
+
+string const doSubstitution(InsetExternalParams const & params,
+                           Buffer const & buffer, string const & s,
+                           bool use_latex_path,
+                           bool external_in_tmpdir,
+                           Substitute what)
+{
+       Buffer const * m_buffer = buffer.getMasterBuffer();
+       string const parentpath = external_in_tmpdir ?
+               m_buffer->temppath() :
+               buffer.filePath();
+       string const filename = external_in_tmpdir ?
+               params.filename.mangledFilename() :
+               params.filename.outputFilename(parentpath);
+       string const basename = support::changeExtension(
+                       support::onlyFilename(filename), string());
+       string const absname = support::makeAbsPath(filename, parentpath).absFilename();
+
+       string result = s;
+       if (what != ALL_BUT_PATHS) {
+               string const filepath = support::onlyPath(filename);
+               string const abspath = support::onlyPath(absname);
+               string const masterpath = external_in_tmpdir ?
+                       m_buffer->temppath() :
+                       m_buffer->filePath();
+               // FIXME UNICODE
+               string relToMasterPath = support::onlyPath(
+                               to_utf8(support::makeRelPath(from_utf8(absname),
+                                                            from_utf8(masterpath))));
+               if (relToMasterPath == "./")
+                       relToMasterPath.clear();
+               // FIXME UNICODE
+               string relToParentPath = support::onlyPath(
+                               to_utf8(support::makeRelPath(from_utf8(absname),
+                                                            from_utf8(parentpath))));
+               if (relToParentPath == "./")
+                       relToParentPath.clear();
+
+               result = subst_path(result, "$$FPath", filepath,
+                                   use_latex_path,
+                                   support::PROTECT_EXTENSION,
+                                   support::ESCAPE_DOTS);
+               result = subst_path(result, "$$AbsPath", abspath,
+                                   use_latex_path,
+                                   support::PROTECT_EXTENSION,
+                                   support::ESCAPE_DOTS);
+               result = subst_path(result, "$$RelPathMaster",
+                                   relToMasterPath, use_latex_path,
+                                   support::PROTECT_EXTENSION,
+                                   support::ESCAPE_DOTS);
+               result = subst_path(result, "$$RelPathParent",
+                                   relToParentPath, use_latex_path,
+                                   support::PROTECT_EXTENSION,
+                                   support::ESCAPE_DOTS);
+               if (support::absolutePath(filename)) {
+                       result = subst_path(result, "$$AbsOrRelPathMaster",
+                                           abspath, use_latex_path,
+                                           support::PROTECT_EXTENSION,
+                                           support::ESCAPE_DOTS);
+                       result = subst_path(result, "$$AbsOrRelPathParent",
+                                           abspath, use_latex_path,
+                                           support::PROTECT_EXTENSION,
+                                           support::ESCAPE_DOTS);
+               } else {
+                       result = subst_path(result, "$$AbsOrRelPathMaster",
+                                           relToMasterPath, use_latex_path,
+                                           support::PROTECT_EXTENSION,
+                                           support::ESCAPE_DOTS);
+                       result = subst_path(result, "$$AbsOrRelPathParent",
+                                           relToParentPath, use_latex_path,
+                                           support::PROTECT_EXTENSION,
+                                           support::ESCAPE_DOTS);
+               }
+       }
+
+       if (what == PATHS)
+               return result;
+
+       result = subst_path(result, "$$FName", filename, use_latex_path,
+                           support::EXCLUDE_EXTENSION);
+       result = subst_path(result, "$$Basename", basename, use_latex_path,
+                           support::PROTECT_EXTENSION, support::ESCAPE_DOTS);
+       result = subst_path(result, "$$Extension",
+                       '.' + support::getExtension(filename), use_latex_path);
+       result = subst_path(result, "$$Tempname", params.tempname().absFilename(), use_latex_path);
+       result = subst_path(result, "$$Sysdir",
+                               support::package().system_support().absFilename(), use_latex_path);
+
+       // Handle the $$Contents(filename) syntax
+       if (support::contains(result, "$$Contents(\"")) {
+               // Since use_latex_path may be true we must extract the file
+               // name from s instead of result and do the substitutions
+               // again, this time with use_latex_path false.
+               string::size_type const spos = s.find("$$Contents(\"");
+               string::size_type const send = s.find("\")", spos);
+               string const file_template = s.substr(spos + 12, send - (spos + 12));
+               string const file = doSubstitution(params, buffer,
+                                                  file_template, false,
+                                                  external_in_tmpdir, what);
+               string contents;
+
+               FileName const absfile(
+                       support::makeAbsPath(file, m_buffer->temppath()));
+               if (support::isFileReadable(absfile))
+                       contents = support::getFileContents(absfile);
+
+               string::size_type const pos = result.find("$$Contents(\"");
+               string::size_type const end = result.find("\")", pos);
+               result.replace(pos, end + 2, contents);
+       }
+
+       return result;
+}
+
+
+namespace {
+
+/** update the file represented by the template.
+    If \p external_in_tmpdir == true, then the generated file is
+    placed in the buffer's temporary directory.
+*/
+void updateExternal(InsetExternalParams const & params,
+                   string const & format,
+                   Buffer const & buffer,
+                   ExportData & exportdata,
+                    bool external_in_tmpdir,
+                    bool dryrun)
+{
+       Template const * const et_ptr = getTemplatePtr(params);
+       if (!et_ptr)
+               return; // FAILURE
+       Template const & et = *et_ptr;
+
+       if (!et.automaticProduction)
+               return; // NOT_NEEDED
+
+       Template::Formats::const_iterator cit = et.formats.find(format);
+       if (cit == et.formats.end())
+               return; // FAILURE
+
+       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
+
+       if (from_format == "*") {
+               if (params.filename.empty())
+                       return; // NOT_NEEDED
+
+               // Try and ascertain the file format from its contents.
+               from_format = formats.getFormatFromFile(params.filename);
+               if (from_format.empty())
+                       return; // FAILURE
+
+       }
+
+       string const to_format = outputFormat.updateFormat;
+       if (to_format.empty())
+               return; // NOT_NEEDED
+
+       // The master buffer. This is useful when there are multiple levels
+       // of include files
+       Buffer const * m_buffer = buffer.getMasterBuffer();
+
+       // We copy the source file to the temp dir and do the conversion
+       // there if necessary
+       FileName const temp_file(
+               support::makeAbsPath(params.filename.mangledFilename(),
+                                    m_buffer->temppath()));
+       if (!params.filename.empty() && !is_directory(params.filename.toFilesystemEncoding())) {
+               unsigned long const from_checksum = support::sum(params.filename);
+               unsigned long const temp_checksum = support::sum(temp_file);
+
+               if (from_checksum != temp_checksum) {
+                       Mover const & mover = getMover(from_format);
+                       if (!mover.copy(params.filename, temp_file)) {
+                               LYXERR(Debug::EXTERNAL)
+                                       << "external::updateExternal. "
+                                       << "Unable to copy "
+                                       << params.filename << " to " << temp_file << endl;
+                               return; // FAILURE
+                       }
+               }
+       }
+
+       // the generated file (always in the temp dir)
+       string const to_file = doSubstitution(params, buffer,
+                                             outputFormat.updateResult,
+                                             false, true);
+       FileName const abs_to_file(
+               support::makeAbsPath(to_file, m_buffer->temppath()));
+
+       if (!dryrun) {
+               // Record the referenced files for the exporter.
+               // The exporter will copy them to the export dir.
+               typedef Template::Format::FileMap FileMap;
+               FileMap::const_iterator rit  = outputFormat.referencedFiles.begin();
+               FileMap::const_iterator rend = outputFormat.referencedFiles.end();
+               for (; rit != rend; ++rit) {
+                       vector<string>::const_iterator fit  = rit->second.begin();
+                       vector<string>::const_iterator fend = rit->second.end();
+                       for (; fit != fend; ++fit) {
+                               FileName const source(support::makeAbsPath(
+                                               doSubstitution(params, buffer, *fit,
+                                                              false, true),
+                                               m_buffer->temppath()));
+                               // The path of the referenced file is never the
+                               // temp path, but the filename may be the mangled
+                               // or the real name. Therefore we substitute the
+                               // paths and names separately.
+                               string file = support::subst(*fit, "$$FName",
+                                               "$$FPath$$Basename$$Extension");
+                               file = doSubstitution(params, buffer, file, false, false,
+                                                     PATHS);
+                               file = doSubstitution(params, buffer, file,
+                                                     false, external_in_tmpdir,
+                                                     ALL_BUT_PATHS);
+                               // if file is a relative name, it is interpreted
+                               // relative to the master document.
+                               exportdata.addExternalFile(rit->first, source, file);
+                       }
+               }
+       }
+
+       // 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(temp_file, abs_to_file) < 0)
+               return; // SUCCESS
+
+       // FIXME (Abdel 12/08/06): Is there a need to show these errors?
+       ErrorList el;
+       bool const success =
+               theConverters().convert(&buffer, temp_file, abs_to_file,
+                                  params.filename, from_format, to_format, el,
+                                  Converters::try_default | Converters::try_cache);
+
+       if (!success)
+               LYXERR(Debug::EXTERNAL)
+                       << "external::updateExternal. "
+                       << "Unable to convert from "
+                       << from_format << " to " << to_format << endl;
+
+       // return success
+}
+
+
+string const substituteCommands(InsetExternalParams const & params,
+                               string const & input, string const & format);
+
+string const substituteOptions(InsetExternalParams const & params,
+                              string const & input, string const & format);
+
+} // namespace anon
+
+
+int writeExternal(InsetExternalParams const & params,
+                 string const & format,
+                 Buffer const & buffer, odocstream & os,
+                 ExportData & exportdata,
+                 bool external_in_tmpdir,
+                 bool dryrun)
+{
+       Template const * const et_ptr = getTemplatePtr(params);
+       if (!et_ptr)
+               return 0;
+       Template const & et = *et_ptr;
+
+       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;
+       }
+
+       if (!dryrun || support::contains(cit->second.product, "$$Contents"))
+               updateExternal(params, format, buffer, exportdata,
+                              external_in_tmpdir, dryrun);
+
+       bool const use_latex_path = format == "LaTeX";
+       string str = doSubstitution(params, buffer, cit->second.product,
+                                   use_latex_path, external_in_tmpdir);
+       str = substituteCommands(params, str, format);
+       str = substituteOptions(params, str, format);
+       // FIXME UNICODE
+       os << from_utf8(str);
+       return int(lyx::count(str.begin(), str.end(),'\n'));
+}
+
+namespace {
+
+// Empty template, specialised below.
+template <typename TransformType>
+string const substituteIt(string const &,
+                         TransformID,
+                         string const &,
+                         Template::Format const &,
+                         InsetExternalParams const &);
+
+
+template <>
+string const substituteIt<TransformCommand>(string const & input,
+                                           TransformID id,
+                                           string const & /* formatname */,
+                                           Template::Format const & format,
+                                           InsetExternalParams const & params)
+{
+       typedef std::map<TransformID, TransformStore> Transformers;
+       Transformers::const_iterator it = format.command_transformers.find(id);
+       if (it == format.command_transformers.end())
+               return input;
+
+       TransformStore const & store = it->second;
+
+       TransformCommand::ptr_type ptr;
+       if (id == Rotate)
+               ptr = store.getCommandTransformer(params.rotationdata);
+       else if (id == Resize)
+               ptr = store.getCommandTransformer(params.resizedata);
+
+       if (!ptr.get())
+               return input;
+
+       string result =
+               support::subst(input, ptr->front_placeholder(), ptr->front());
+       return support::subst(result, ptr->back_placeholder(),  ptr->back());
+}
+
+
+template <>
+string const substituteIt<TransformOption>(string const & input,
+                                          TransformID id,
+                                          string const & fname,
+                                          Template::Format const & format,
+                                          InsetExternalParams const & params)
+{
+       typedef std::map<TransformID, TransformStore> Transformers;
+       Transformers::const_iterator it = format.option_transformers.find(id);
+       if (it == format.option_transformers.end())
+               return input;
+
+       TransformStore const & store = it->second;
+
+       TransformOption::ptr_type ptr;
+       switch (id) {
+       case Clip:
+               ptr = store.getOptionTransformer(params.clipdata);
+               break;
+       case Extra:
+               ptr = store.getOptionTransformer(params.extradata.get(fname));
+               break;
+       case Rotate:
+               ptr = store.getOptionTransformer(params.rotationdata);
+               break;
+       case Resize:
+               ptr = store.getOptionTransformer(params.resizedata);
+               break;
+       }
+
+       if (!ptr.get())
+               return input;
+
+       return support::subst(input, ptr->placeholder(), ptr->option());
+}
+
+
+template <typename TransformerType>
+string const transformIt(InsetExternalParams const & params,
+                        string const & s, string const & formatname)
+{
+       Template const * const et = getTemplatePtr(params);
+       if (!et || et->transformIds.empty())
+               return s;
+
+       Template::Formats::const_iterator fit = et->formats.find(formatname);
+       if (fit == et->formats.end())
+               return s;
+
+       string result = s;
+       Template::Format const & format =  fit->second;
+
+       typedef vector<TransformID> TransformsIDs;
+       TransformsIDs::const_iterator it  = et->transformIds.begin();
+       TransformsIDs::const_iterator end = et->transformIds.end();
+       for (; it != end; ++it) {
+               result = substituteIt<TransformerType>(result, *it, formatname,
+                                                      format, params);
+       }
+       return result;
+}
+
+
+string const substituteCommands(InsetExternalParams const & params,
+                               string const & input, string const & format)
+{
+       return transformIt<TransformCommand>(params, input, format);
+}
+
+
+string const substituteOption(InsetExternalParams const & params,
+                             string const & input, string const & format)
+{
+       string opt = transformIt<TransformOption>(params, input, format);
+
+       if (format == "LaTeX" || format == "PDFLaTeX")
+               return sanitizeLatexOption(opt);
+       if (format == "DocBook")
+               return sanitizeDocBookOption(opt);
+       return opt;
+}
+
+
+string const substituteOptions(InsetExternalParams const & params,
+                              string const & input, string const & format)
+{
+       string output = input;
+
+       Template const * const et = getTemplatePtr(params);
+       if (!et || et->transformIds.empty())
+               return output;
+
+       Template::Formats::const_iterator fit = et->formats.find(format);
+       if (fit == et->formats.end() || fit->second.options.empty())
+               return output;
+
+       typedef vector<Template::Option> Options;
+       Options const & options = fit->second.options;
+       Options::const_iterator it  = options.begin();
+       Options::const_iterator end = options.end();
+       for (; it != end; ++it) {
+               string const opt = substituteOption(params, it->option, format);
+               string const placeholder = "$$" + it->name;
+               output = support::subst(output, placeholder, opt);
+       }
+
+       return output;
+}
+
+} // namespace anon
+
+} // namespace external
+
+} // namespace lyx
diff --git a/src/insets/ExternalTemplate.C b/src/insets/ExternalTemplate.C
deleted file mode 100644 (file)
index b0a044d..0000000
+++ /dev/null
@@ -1,567 +0,0 @@
-/**
- * \file ExternalTemplate.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 <config.h>
-
-#include "ExternalTemplate.h"
-
-#include "debug.h"
-#include "LyXLex.h"
-
-#include "support/filetools.h"
-#include "support/lstrings.h"
-#include "support/Package.h"
-#include "support/Path.h"
-
-using std::endl;
-using std::for_each;
-using std::string;
-using std::ostream;
-using std::vector;
-
-namespace lyx {
-namespace external {
-
-
-typedef Translator<TransformID, string> TransformIDTranslator;
-
-static TransformIDTranslator const initIDTranslator()
-{
-       TransformIDTranslator translator(TransformID(-1), "");
-       translator.addPair(Rotate, "Rotate");
-       translator.addPair(Resize, "Resize");
-       translator.addPair(Clip,   "Clip");
-       translator.addPair(Extra,  "Extra");
-       return translator;
-}
-
-static TransformIDTranslator const & transformIDTranslator()
-{
-       static TransformIDTranslator const translator = initIDTranslator();
-       return translator;
-}
-
-// We have to have dummy default commands for security reasons!
-Template::Template()
-       : inputFormat("*")
-{}
-
-
-Template::Format::Format()
-{}
-
-
-TemplateManager::TemplateManager()
-{
-       readTemplates(support::package().user_support());
-       if (lyxerr.debugging(Debug::EXTERNAL)) {
-               dumpPreambleDefs(lyxerr);
-               lyxerr << '\n';
-               dumpTemplates(lyxerr);
-       }
-}
-
-
-class dumpPreambleDef {
-public:
-       typedef TemplateManager::PreambleDefs::value_type value_type;
-
-       dumpPreambleDef(ostream & o) : ost(o) {}
-
-       void operator()(value_type const & vt) {
-               ost << "PreambleDef " << vt.first << '\n'
-                   << vt.second
-                   << "PreambleDefEnd" << endl;
-       }
-
-private:
-       ostream & ost;
-};
-
-
-class dumpTemplate {
-public:
-       typedef TemplateManager::Templates::value_type value_type;
-
-       dumpTemplate(ostream & o) : ost(o) {}
-
-       void operator()(value_type const & vt) {
-               Template const & et = vt.second;
-
-               ost << "Template " << et.lyxName << '\n'
-                   << "\tGuiName " << et.guiName << '\n'
-                   << "\tHelpText\n"
-                   << et.helpText
-                   << "\tHelpTextEnd\n"
-                   << "\tInputFormat " << et.inputFormat << '\n'
-                   << "\tFileFilter " << et.fileRegExp << '\n'
-                   << "\tAutomaticProduction " << et.automaticProduction << '\n';
-
-               typedef vector<TransformID> IDs;
-               IDs::const_iterator it  = et.transformIds.begin();
-               IDs::const_iterator end = et.transformIds.end();
-               for (; it != end; ++it) {
-                       ost << "\tTransform "
-                           << transformIDTranslator().find(*it) << '\n';
-               }
-
-               et.dumpFormats(ost);
-               ost << "TemplateEnd" << endl;
-
-       }
-
-private:
-       ostream & ost;
-};
-
-class dumpFormat {
-public:
-       typedef Template::Formats::value_type value_type;
-
-       dumpFormat(ostream & o) : ost(o) {}
-
-       void operator()(value_type const & vt) const {
-               Template::Format const & ft = vt.second;
-               ost << "\tFormat " << vt.first << '\n'
-                   << "\t\tProduct " << ft.product << '\n'
-                   << "\t\tUpdateFormat " << ft.updateFormat << '\n'
-                   << "\t\tUpdateResult " << ft.updateResult << '\n';
-
-               vector<string>::const_iterator qit = ft.requirements.begin();
-               vector<string>::const_iterator qend = ft.requirements.end();
-               for (; qit != qend; ++qit) {
-                       lyxerr << "req:" << *qit << std::endl;
-                       ost << "\t\tRequirement " << *qit << '\n';
-               }
-
-               typedef vector<Template::Option> Options;
-               Options::const_iterator oit  = ft.options.begin();
-               Options::const_iterator oend = ft.options.end();
-               for (; oit != oend; ++oit) {
-                       ost << "\t\tOption "
-                           << oit->name
-                           << ": "
-                           << oit->option
-                           << '\n';
-               }
-
-               vector<string>::const_iterator pit  = ft.preambleNames.begin();
-               vector<string>::const_iterator pend = ft.preambleNames.end();
-               for (; pit != pend; ++pit) {
-                       ost << "\t\tPreamble " << *pit << '\n';
-               }
-
-               typedef Template::Format::FileMap FileMap;
-               FileMap::const_iterator rit  = ft.referencedFiles.begin();
-               FileMap::const_iterator rend = ft.referencedFiles.end();
-               for (; rit != rend; ++rit) {
-                       vector<string>::const_iterator fit  = rit->second.begin();
-                       vector<string>::const_iterator fend = rit->second.end();
-                       for (; fit != fend; ++fit) {
-                               ost << "\t\tReferencedFile " << rit->first
-                                   << " \"" << *fit << "\"\n";
-                       }
-               }
-
-               ost << "\tFormatEnd\n";
-       }
-private:
-       ostream & ost;
-};
-
-
-void Template::dumpFormats(ostream & os) const
-{
-       for_each(formats.begin(), formats.end(), dumpFormat(os));
-}
-
-
-void TemplateManager::dumpPreambleDefs(ostream & os) const
-{
-       for_each(preambledefs.begin(), preambledefs.end(), dumpPreambleDef(os));
-}
-
-
-void TemplateManager::dumpTemplates(ostream & os) const
-{
-       for_each(templates.begin(), templates.end(), dumpTemplate(os));
-}
-
-
-TemplateManager & TemplateManager::get()
-{
-       static TemplateManager externalTemplateManager;
-       return externalTemplateManager;
-}
-
-
-TemplateManager::Templates const &
-TemplateManager::getTemplates() const
-{
-       return templates;
-}
-
-
-Template const *
-TemplateManager::getTemplateByName(string const & name) const
-{
-       Templates::const_iterator it = templates.find(name);
-       return (it == templates.end()) ? 0 : &it->second;
-}
-
-
-string const
-TemplateManager::getPreambleDefByName(string const & name) const
-{
-       string const trimmed_name = support::trim(name);
-       if (trimmed_name.empty())
-               return string();
-
-       PreambleDefs::const_iterator it = preambledefs.find(trimmed_name);
-       if (it == preambledefs.end())
-               return string();
-
-       return it->second;
-}
-
-
-void TemplateManager::readTemplates(support::FileName const & path)
-{
-       support::Path p(path);
-
-       enum TemplateTags {
-               TM_PREAMBLEDEF = 1,
-               TM_PREAMBLEDEF_END,
-               TM_TEMPLATE,
-               TM_TEMPLATE_END
-       };
-
-       keyword_item templatetags[] = {
-               { "preambledef", TM_PREAMBLEDEF },
-               { "preambledefend", TM_PREAMBLEDEF_END },
-               { "template", TM_TEMPLATE },
-               { "templateend", TM_TEMPLATE_END }
-       };
-
-       LyXLex lex(templatetags, TM_TEMPLATE_END);
-
-       support::FileName const filename = support::libFileSearch("", "external_templates");
-       if (filename.empty() || !lex.setFile(filename)) {
-               lex.printError("external::TemplateManager::readTemplates: "
-                              "No template file");
-               return;
-       }
-
-       char const * const preamble_end_tag =
-               templatetags[TM_PREAMBLEDEF_END-1].tag;
-
-       while (lex.isOK()) {
-               switch (lex.lex()) {
-               case TM_PREAMBLEDEF: {
-                       lex.next();
-                       string const name = lex.getString();
-                       preambledefs[name] = lex.getLongString(preamble_end_tag);
-               }
-               break;
-
-               case TM_TEMPLATE: {
-                       lex.next();
-                       string const name = lex.getString();
-                       Template & tmp = templates[name];
-                       tmp.lyxName = name;
-                       tmp.readTemplate(lex);
-               }
-               break;
-
-               case TM_TEMPLATE_END:
-                       lex.printError("Warning: End outside Template.");
-               break;
-
-               case TM_PREAMBLEDEF_END:
-                       lex.printError("Warning: End outside PreambleDef.");
-               break;
-               }
-       }
-}
-
-
-namespace {
-
-void add(vector<TransformID> & ids, string const & name)
-{
-       TransformID id = transformIDTranslator().find(name);
-       if (int(id) == -1) {
-               lyxerr << "external::Template::readTemplate\n"
-                      << "Transform " << name << " is not recognized"
-                      << std::endl;
-       } else {
-               ids.push_back(id);
-       }
-}
-
-} // namespace anon
-
-
-void Template::readTemplate(LyXLex & lex)
-{
-       enum TemplateOptionTags {
-               TO_GUINAME = 1,
-               TO_HELPTEXT,
-               TO_INPUTFORMAT,
-               TO_FILTER,
-               TO_AUTOMATIC,
-               TO_TRANSFORM,
-               TO_FORMAT,
-               TO_END
-       };
-
-       keyword_item templateoptiontags[] = {
-               { "automaticproduction", TO_AUTOMATIC },
-               { "filefilter", TO_FILTER },
-               { "format", TO_FORMAT },
-               { "guiname", TO_GUINAME },
-               { "helptext", TO_HELPTEXT },
-               { "inputformat", TO_INPUTFORMAT },
-               { "templateend", TO_END },
-               { "transform", TO_TRANSFORM }
-       };
-
-       pushpophelper pph(lex, templateoptiontags, TO_END);
-
-       while (lex.isOK()) {
-               switch (lex.lex()) {
-               case TO_GUINAME:
-                       lex.next(true);
-                       guiName = lex.getString();
-                       break;
-
-               case TO_HELPTEXT:
-                       helpText = lex.getLongString("HelpTextEnd");
-                       break;
-
-               case TO_INPUTFORMAT:
-                       lex.next(true);
-                       inputFormat = lex.getString();
-                       break;
-
-               case TO_FILTER:
-                       lex.next(true);
-                       fileRegExp = lex.getString();
-                       break;
-
-               case TO_AUTOMATIC:
-                       lex.next();
-                       automaticProduction = lex.getBool();
-                       break;
-
-               case TO_TRANSFORM:
-                       lex.next(true);
-                       add(transformIds, lex.getString());
-                       break;
-
-               case TO_FORMAT:
-                       lex.next(true);
-                       formats[lex.getString()].readFormat(lex);
-                       break;
-
-               case TO_END:
-                       return;
-
-               default:
-                       lex.printError("external::Template::readTemplate: "
-                                      "Wrong tag: $$Token");
-                       BOOST_ASSERT(false);
-                       break;
-               }
-       }
-}
-
-
-namespace {
-
-void transform_not_found(std::ostream & os, string const & transform)
-{
-       os << "external::Format::readFormat. Transformation \""
-          << transform << "\" is unrecognized." << std::endl;
-}
-
-
-void transform_class_not_found(std::ostream & os, string const & tclass)
-{
-       os << "external::Format::readFormat. Transformation class \""
-          << tclass << "\" is unrecognized." << std::endl;
-}
-
-
-void setCommandFactory(Template::Format & format, string const & transform,
-                      string const & transformer_class)
-{
-       bool class_found = false;
-       if (transform == "Resize" && transformer_class == "ResizeLatexCommand") {
-               class_found = true;
-               ResizeCommandFactory factory = ResizeLatexCommand::factory;
-               format.command_transformers[Resize] =
-                       TransformStore(Resize, factory);
-
-       } else if (transform == "Rotate" &&
-                  transformer_class == "RotationLatexCommand") {
-               class_found = true;
-               RotationCommandFactory factory = RotationLatexCommand::factory;
-               format.command_transformers[Rotate] =
-                       TransformStore(Rotate, factory);
-
-       } else
-               transform_not_found(lyxerr, transform);
-
-       if (!class_found)
-               transform_class_not_found(lyxerr, transformer_class);
-}
-
-
-void setOptionFactory(Template::Format & format, string const & transform,
-               string const & transformer_class)
-{
-       bool class_found = false;
-       if (transform == "Clip" && transformer_class == "ClipLatexOption") {
-               class_found = true;
-               ClipOptionFactory factory = ClipLatexOption::factory;
-               format.option_transformers[Clip] =
-                               TransformStore(Clip, factory);
-
-       } else if (transform == "Extra" && transformer_class == "ExtraOption") {
-               class_found = true;
-               ExtraOptionFactory factory = ExtraOption::factory;
-               format.option_transformers[Extra] =
-                       TransformStore(Extra, factory);
-
-       } else if (transform == "Resize" &&
-                  transformer_class == "ResizeLatexOption") {
-               class_found = true;
-               ResizeOptionFactory factory = ResizeLatexOption::factory;
-               format.option_transformers[Resize] =
-                       TransformStore(Resize, factory);
-
-       } else if (transform == "Rotate" &&
-                  transformer_class == "RotationLatexOption") {
-               class_found = true;
-               RotationOptionFactory factory = RotationLatexOption::factory;
-               format.option_transformers[Rotate] =
-                       TransformStore(Rotate, factory);
-
-       } else
-               transform_not_found(lyxerr, transform);
-
-       if (!class_found)
-               transform_class_not_found(lyxerr, transformer_class);
-}
-
-} // namespace anon
-
-
-void Template::Format::readFormat(LyXLex & lex)
-{
-       enum FormatTags {
-               FO_PRODUCT = 1,
-               FO_UPDATEFORMAT,
-               FO_UPDATERESULT,
-               FO_REQUIREMENT,
-               FO_OPTION,
-               FO_PREAMBLE,
-               FO_TRANSFORMCOMMAND,
-               FO_TRANSFORMOPTION,
-               FO_REFERENCEDFILE,
-               FO_END
-       };
-
-       keyword_item formattags[] = {
-               { "formatend", FO_END },
-               { "option", FO_OPTION },
-               { "preamble", FO_PREAMBLE },
-               { "product", FO_PRODUCT },
-               { "referencedfile", FO_REFERENCEDFILE },
-               { "requirement", FO_REQUIREMENT },
-               { "transformcommand", FO_TRANSFORMCOMMAND },
-               { "transformoption", FO_TRANSFORMOPTION },
-               { "updateformat", FO_UPDATEFORMAT },
-               { "updateresult", FO_UPDATERESULT }
-       };
-
-       pushpophelper pph(lex, formattags, FO_END);
-
-       while (lex.isOK()) {
-               switch (lex.lex()) {
-               case FO_PRODUCT:
-                       lex.next(true);
-                       product = lex.getString();
-                       break;
-
-               case FO_UPDATEFORMAT:
-                       lex.next(true);
-                       updateFormat = lex.getString();
-                       break;
-
-               case FO_UPDATERESULT:
-                       lex.next(true);
-                       updateResult = lex.getString();
-                       break;
-
-               case FO_REQUIREMENT:
-                       lex.next(true);
-                       requirements.push_back(lex.getString());
-                       break;
-
-               case FO_PREAMBLE:
-                       lex.next(true);
-                       preambleNames.push_back(lex.getString());
-                       break;
-
-               case FO_TRANSFORMCOMMAND: {
-                       lex.next(true);
-                       string const name = lex.getString();
-                       lex.next(true);
-                       setCommandFactory(*this, name, lex.getString());
-                       break;
-               }
-
-               case FO_TRANSFORMOPTION: {
-                       lex.next(true);
-                       string const name = lex.getString();
-                       lex.next(true);
-                       setOptionFactory(*this, name, lex.getString());
-                       break;
-               }
-
-               case FO_OPTION: {
-                       lex.next(true);
-                       string const name = lex.getString();
-                       lex.next(true);
-                       string const opt = lex.getString();
-                       options.push_back(Option(name, opt));
-                       break;
-               }
-
-               case FO_REFERENCEDFILE: {
-                       lex.next(true);
-                       string const format = lex.getString();
-                       lex.next(true);
-                       string const file = lex.getString();
-                       referencedFiles[format].push_back(file);
-                       break;
-               }
-
-               case FO_END:
-                       return;
-               }
-       }
-}
-
-} // namespace external
-} // namespace lyx
diff --git a/src/insets/ExternalTemplate.cpp b/src/insets/ExternalTemplate.cpp
new file mode 100644 (file)
index 0000000..faace7b
--- /dev/null
@@ -0,0 +1,567 @@
+/**
+ * \file ExternalTemplate.cpp
+ * 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 <config.h>
+
+#include "ExternalTemplate.h"
+
+#include "debug.h"
+#include "LyXLex.h"
+
+#include "support/filetools.h"
+#include "support/lstrings.h"
+#include "support/Package.h"
+#include "support/Path.h"
+
+using std::endl;
+using std::for_each;
+using std::string;
+using std::ostream;
+using std::vector;
+
+namespace lyx {
+namespace external {
+
+
+typedef Translator<TransformID, string> TransformIDTranslator;
+
+static TransformIDTranslator const initIDTranslator()
+{
+       TransformIDTranslator translator(TransformID(-1), "");
+       translator.addPair(Rotate, "Rotate");
+       translator.addPair(Resize, "Resize");
+       translator.addPair(Clip,   "Clip");
+       translator.addPair(Extra,  "Extra");
+       return translator;
+}
+
+static TransformIDTranslator const & transformIDTranslator()
+{
+       static TransformIDTranslator const translator = initIDTranslator();
+       return translator;
+}
+
+// We have to have dummy default commands for security reasons!
+Template::Template()
+       : inputFormat("*")
+{}
+
+
+Template::Format::Format()
+{}
+
+
+TemplateManager::TemplateManager()
+{
+       readTemplates(support::package().user_support());
+       if (lyxerr.debugging(Debug::EXTERNAL)) {
+               dumpPreambleDefs(lyxerr);
+               lyxerr << '\n';
+               dumpTemplates(lyxerr);
+       }
+}
+
+
+class dumpPreambleDef {
+public:
+       typedef TemplateManager::PreambleDefs::value_type value_type;
+
+       dumpPreambleDef(ostream & o) : ost(o) {}
+
+       void operator()(value_type const & vt) {
+               ost << "PreambleDef " << vt.first << '\n'
+                   << vt.second
+                   << "PreambleDefEnd" << endl;
+       }
+
+private:
+       ostream & ost;
+};
+
+
+class dumpTemplate {
+public:
+       typedef TemplateManager::Templates::value_type value_type;
+
+       dumpTemplate(ostream & o) : ost(o) {}
+
+       void operator()(value_type const & vt) {
+               Template const & et = vt.second;
+
+               ost << "Template " << et.lyxName << '\n'
+                   << "\tGuiName " << et.guiName << '\n'
+                   << "\tHelpText\n"
+                   << et.helpText
+                   << "\tHelpTextEnd\n"
+                   << "\tInputFormat " << et.inputFormat << '\n'
+                   << "\tFileFilter " << et.fileRegExp << '\n'
+                   << "\tAutomaticProduction " << et.automaticProduction << '\n';
+
+               typedef vector<TransformID> IDs;
+               IDs::const_iterator it  = et.transformIds.begin();
+               IDs::const_iterator end = et.transformIds.end();
+               for (; it != end; ++it) {
+                       ost << "\tTransform "
+                           << transformIDTranslator().find(*it) << '\n';
+               }
+
+               et.dumpFormats(ost);
+               ost << "TemplateEnd" << endl;
+
+       }
+
+private:
+       ostream & ost;
+};
+
+class dumpFormat {
+public:
+       typedef Template::Formats::value_type value_type;
+
+       dumpFormat(ostream & o) : ost(o) {}
+
+       void operator()(value_type const & vt) const {
+               Template::Format const & ft = vt.second;
+               ost << "\tFormat " << vt.first << '\n'
+                   << "\t\tProduct " << ft.product << '\n'
+                   << "\t\tUpdateFormat " << ft.updateFormat << '\n'
+                   << "\t\tUpdateResult " << ft.updateResult << '\n';
+
+               vector<string>::const_iterator qit = ft.requirements.begin();
+               vector<string>::const_iterator qend = ft.requirements.end();
+               for (; qit != qend; ++qit) {
+                       lyxerr << "req:" << *qit << std::endl;
+                       ost << "\t\tRequirement " << *qit << '\n';
+               }
+
+               typedef vector<Template::Option> Options;
+               Options::const_iterator oit  = ft.options.begin();
+               Options::const_iterator oend = ft.options.end();
+               for (; oit != oend; ++oit) {
+                       ost << "\t\tOption "
+                           << oit->name
+                           << ": "
+                           << oit->option
+                           << '\n';
+               }
+
+               vector<string>::const_iterator pit  = ft.preambleNames.begin();
+               vector<string>::const_iterator pend = ft.preambleNames.end();
+               for (; pit != pend; ++pit) {
+                       ost << "\t\tPreamble " << *pit << '\n';
+               }
+
+               typedef Template::Format::FileMap FileMap;
+               FileMap::const_iterator rit  = ft.referencedFiles.begin();
+               FileMap::const_iterator rend = ft.referencedFiles.end();
+               for (; rit != rend; ++rit) {
+                       vector<string>::const_iterator fit  = rit->second.begin();
+                       vector<string>::const_iterator fend = rit->second.end();
+                       for (; fit != fend; ++fit) {
+                               ost << "\t\tReferencedFile " << rit->first
+                                   << " \"" << *fit << "\"\n";
+                       }
+               }
+
+               ost << "\tFormatEnd\n";
+       }
+private:
+       ostream & ost;
+};
+
+
+void Template::dumpFormats(ostream & os) const
+{
+       for_each(formats.begin(), formats.end(), dumpFormat(os));
+}
+
+
+void TemplateManager::dumpPreambleDefs(ostream & os) const
+{
+       for_each(preambledefs.begin(), preambledefs.end(), dumpPreambleDef(os));
+}
+
+
+void TemplateManager::dumpTemplates(ostream & os) const
+{
+       for_each(templates.begin(), templates.end(), dumpTemplate(os));
+}
+
+
+TemplateManager & TemplateManager::get()
+{
+       static TemplateManager externalTemplateManager;
+       return externalTemplateManager;
+}
+
+
+TemplateManager::Templates const &
+TemplateManager::getTemplates() const
+{
+       return templates;
+}
+
+
+Template const *
+TemplateManager::getTemplateByName(string const & name) const
+{
+       Templates::const_iterator it = templates.find(name);
+       return (it == templates.end()) ? 0 : &it->second;
+}
+
+
+string const
+TemplateManager::getPreambleDefByName(string const & name) const
+{
+       string const trimmed_name = support::trim(name);
+       if (trimmed_name.empty())
+               return string();
+
+       PreambleDefs::const_iterator it = preambledefs.find(trimmed_name);
+       if (it == preambledefs.end())
+               return string();
+
+       return it->second;
+}
+
+
+void TemplateManager::readTemplates(support::FileName const & path)
+{
+       support::Path p(path);
+
+       enum TemplateTags {
+               TM_PREAMBLEDEF = 1,
+               TM_PREAMBLEDEF_END,
+               TM_TEMPLATE,
+               TM_TEMPLATE_END
+       };
+
+       keyword_item templatetags[] = {
+               { "preambledef", TM_PREAMBLEDEF },
+               { "preambledefend", TM_PREAMBLEDEF_END },
+               { "template", TM_TEMPLATE },
+               { "templateend", TM_TEMPLATE_END }
+       };
+
+       LyXLex lex(templatetags, TM_TEMPLATE_END);
+
+       support::FileName const filename = support::libFileSearch("", "external_templates");
+       if (filename.empty() || !lex.setFile(filename)) {
+               lex.printError("external::TemplateManager::readTemplates: "
+                              "No template file");
+               return;
+       }
+
+       char const * const preamble_end_tag =
+               templatetags[TM_PREAMBLEDEF_END-1].tag;
+
+       while (lex.isOK()) {
+               switch (lex.lex()) {
+               case TM_PREAMBLEDEF: {
+                       lex.next();
+                       string const name = lex.getString();
+                       preambledefs[name] = lex.getLongString(preamble_end_tag);
+               }
+               break;
+
+               case TM_TEMPLATE: {
+                       lex.next();
+                       string const name = lex.getString();
+                       Template & tmp = templates[name];
+                       tmp.lyxName = name;
+                       tmp.readTemplate(lex);
+               }
+               break;
+
+               case TM_TEMPLATE_END:
+                       lex.printError("Warning: End outside Template.");
+               break;
+
+               case TM_PREAMBLEDEF_END:
+                       lex.printError("Warning: End outside PreambleDef.");
+               break;
+               }
+       }
+}
+
+
+namespace {
+
+void add(vector<TransformID> & ids, string const & name)
+{
+       TransformID id = transformIDTranslator().find(name);
+       if (int(id) == -1) {
+               lyxerr << "external::Template::readTemplate\n"
+                      << "Transform " << name << " is not recognized"
+                      << std::endl;
+       } else {
+               ids.push_back(id);
+       }
+}
+
+} // namespace anon
+
+
+void Template::readTemplate(LyXLex & lex)
+{
+       enum TemplateOptionTags {
+               TO_GUINAME = 1,
+               TO_HELPTEXT,
+               TO_INPUTFORMAT,
+               TO_FILTER,
+               TO_AUTOMATIC,
+               TO_TRANSFORM,
+               TO_FORMAT,
+               TO_END
+       };
+
+       keyword_item templateoptiontags[] = {
+               { "automaticproduction", TO_AUTOMATIC },
+               { "filefilter", TO_FILTER },
+               { "format", TO_FORMAT },
+               { "guiname", TO_GUINAME },
+               { "helptext", TO_HELPTEXT },
+               { "inputformat", TO_INPUTFORMAT },
+               { "templateend", TO_END },
+               { "transform", TO_TRANSFORM }
+       };
+
+       pushpophelper pph(lex, templateoptiontags, TO_END);
+
+       while (lex.isOK()) {
+               switch (lex.lex()) {
+               case TO_GUINAME:
+                       lex.next(true);
+                       guiName = lex.getString();
+                       break;
+
+               case TO_HELPTEXT:
+                       helpText = lex.getLongString("HelpTextEnd");
+                       break;
+
+               case TO_INPUTFORMAT:
+                       lex.next(true);
+                       inputFormat = lex.getString();
+                       break;
+
+               case TO_FILTER:
+                       lex.next(true);
+                       fileRegExp = lex.getString();
+                       break;
+
+               case TO_AUTOMATIC:
+                       lex.next();
+                       automaticProduction = lex.getBool();
+                       break;
+
+               case TO_TRANSFORM:
+                       lex.next(true);
+                       add(transformIds, lex.getString());
+                       break;
+
+               case TO_FORMAT:
+                       lex.next(true);
+                       formats[lex.getString()].readFormat(lex);
+                       break;
+
+               case TO_END:
+                       return;
+
+               default:
+                       lex.printError("external::Template::readTemplate: "
+                                      "Wrong tag: $$Token");
+                       BOOST_ASSERT(false);
+                       break;
+               }
+       }
+}
+
+
+namespace {
+
+void transform_not_found(std::ostream & os, string const & transform)
+{
+       os << "external::Format::readFormat. Transformation \""
+          << transform << "\" is unrecognized." << std::endl;
+}
+
+
+void transform_class_not_found(std::ostream & os, string const & tclass)
+{
+       os << "external::Format::readFormat. Transformation class \""
+          << tclass << "\" is unrecognized." << std::endl;
+}
+
+
+void setCommandFactory(Template::Format & format, string const & transform,
+                      string const & transformer_class)
+{
+       bool class_found = false;
+       if (transform == "Resize" && transformer_class == "ResizeLatexCommand") {
+               class_found = true;
+               ResizeCommandFactory factory = ResizeLatexCommand::factory;
+               format.command_transformers[Resize] =
+                       TransformStore(Resize, factory);
+
+       } else if (transform == "Rotate" &&
+                  transformer_class == "RotationLatexCommand") {
+               class_found = true;
+               RotationCommandFactory factory = RotationLatexCommand::factory;
+               format.command_transformers[Rotate] =
+                       TransformStore(Rotate, factory);
+
+       } else
+               transform_not_found(lyxerr, transform);
+
+       if (!class_found)
+               transform_class_not_found(lyxerr, transformer_class);
+}
+
+
+void setOptionFactory(Template::Format & format, string const & transform,
+               string const & transformer_class)
+{
+       bool class_found = false;
+       if (transform == "Clip" && transformer_class == "ClipLatexOption") {
+               class_found = true;
+               ClipOptionFactory factory = ClipLatexOption::factory;
+               format.option_transformers[Clip] =
+                               TransformStore(Clip, factory);
+
+       } else if (transform == "Extra" && transformer_class == "ExtraOption") {
+               class_found = true;
+               ExtraOptionFactory factory = ExtraOption::factory;
+               format.option_transformers[Extra] =
+                       TransformStore(Extra, factory);
+
+       } else if (transform == "Resize" &&
+                  transformer_class == "ResizeLatexOption") {
+               class_found = true;
+               ResizeOptionFactory factory = ResizeLatexOption::factory;
+               format.option_transformers[Resize] =
+                       TransformStore(Resize, factory);
+
+       } else if (transform == "Rotate" &&
+                  transformer_class == "RotationLatexOption") {
+               class_found = true;
+               RotationOptionFactory factory = RotationLatexOption::factory;
+               format.option_transformers[Rotate] =
+                       TransformStore(Rotate, factory);
+
+       } else
+               transform_not_found(lyxerr, transform);
+
+       if (!class_found)
+               transform_class_not_found(lyxerr, transformer_class);
+}
+
+} // namespace anon
+
+
+void Template::Format::readFormat(LyXLex & lex)
+{
+       enum FormatTags {
+               FO_PRODUCT = 1,
+               FO_UPDATEFORMAT,
+               FO_UPDATERESULT,
+               FO_REQUIREMENT,
+               FO_OPTION,
+               FO_PREAMBLE,
+               FO_TRANSFORMCOMMAND,
+               FO_TRANSFORMOPTION,
+               FO_REFERENCEDFILE,
+               FO_END
+       };
+
+       keyword_item formattags[] = {
+               { "formatend", FO_END },
+               { "option", FO_OPTION },
+               { "preamble", FO_PREAMBLE },
+               { "product", FO_PRODUCT },
+               { "referencedfile", FO_REFERENCEDFILE },
+               { "requirement", FO_REQUIREMENT },
+               { "transformcommand", FO_TRANSFORMCOMMAND },
+               { "transformoption", FO_TRANSFORMOPTION },
+               { "updateformat", FO_UPDATEFORMAT },
+               { "updateresult", FO_UPDATERESULT }
+       };
+
+       pushpophelper pph(lex, formattags, FO_END);
+
+       while (lex.isOK()) {
+               switch (lex.lex()) {
+               case FO_PRODUCT:
+                       lex.next(true);
+                       product = lex.getString();
+                       break;
+
+               case FO_UPDATEFORMAT:
+                       lex.next(true);
+                       updateFormat = lex.getString();
+                       break;
+
+               case FO_UPDATERESULT:
+                       lex.next(true);
+                       updateResult = lex.getString();
+                       break;
+
+               case FO_REQUIREMENT:
+                       lex.next(true);
+                       requirements.push_back(lex.getString());
+                       break;
+
+               case FO_PREAMBLE:
+                       lex.next(true);
+                       preambleNames.push_back(lex.getString());
+                       break;
+
+               case FO_TRANSFORMCOMMAND: {
+                       lex.next(true);
+                       string const name = lex.getString();
+                       lex.next(true);
+                       setCommandFactory(*this, name, lex.getString());
+                       break;
+               }
+
+               case FO_TRANSFORMOPTION: {
+                       lex.next(true);
+                       string const name = lex.getString();
+                       lex.next(true);
+                       setOptionFactory(*this, name, lex.getString());
+                       break;
+               }
+
+               case FO_OPTION: {
+                       lex.next(true);
+                       string const name = lex.getString();
+                       lex.next(true);
+                       string const opt = lex.getString();
+                       options.push_back(Option(name, opt));
+                       break;
+               }
+
+               case FO_REFERENCEDFILE: {
+                       lex.next(true);
+                       string const format = lex.getString();
+                       lex.next(true);
+                       string const file = lex.getString();
+                       referencedFiles[format].push_back(file);
+                       break;
+               }
+
+               case FO_END:
+                       return;
+               }
+       }
+}
+
+} // namespace external
+} // namespace lyx
diff --git a/src/insets/ExternalTransforms.C b/src/insets/ExternalTransforms.C
deleted file mode 100644 (file)
index 2f8d08e..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/**
- * \file ExternalTransforms.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Angus Leeming
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "ExternalTransforms.h"
-
-#include "debug.h"
-
-#include "support/lstrings.h"
-#include "support/lyxlib.h" // float_equal
-#include "support/convert.h"
-#include "support/Translator.h"
-
-#include <boost/regex.hpp>
-
-#include <cmath> // std::abs
-#include <sstream>
-
-
-namespace lyx {
-namespace external {
-
-using support::float_equal;
-using std::string;
-
-
-string const ExtraData::get(string const & id) const
-{
-       std::map<string, string>::const_iterator it = data_.find(id);
-       return it == data_.end() ? string() : it->second;
-}
-
-
-void ExtraData::set(string const & id, string const & data)
-{
-       data_[id] = data;
-}
-
-
-bool ResizeData::no_resize() const
-{
-       return !usingScale() && width.zero() && height.zero();
-}
-
-
-bool ResizeData::usingScale() const
-{
-       return (!scale.empty() && !float_equal(convert<double>(scale), 0.0, 0.05));
-}
-
-
-bool RotationData::no_rotation() const
-{
-       return (angle.empty() || std::abs(convert<double>(angle)) < 0.1);
-}
-
-
-string const RotationData::adjAngle() const
-{
-       // Ensure that angle lies in the range -360 < angle < 360
-       double rotAngle = convert<double>(angle);
-       if (std::abs(rotAngle) > 360.0) {
-               rotAngle -= 360.0 * floor(rotAngle / 360.0);
-               return convert<string>(rotAngle);
-       }
-       return angle;
-}
-
-
-namespace {
-
-typedef Translator<RotationData::OriginType, string> OriginTranslator;
-OriginTranslator const & originTranslator();
-
-} // namespace anon
-
-
-void RotationData::origin(string const & o)
-{
-       origin_ = originTranslator().find(o);
-}
-
-
-string const RotationData::originString() const
-{
-       return originTranslator().find(origin_);
-}
-
-
-string const ResizeLatexCommand::front_impl() const
-{
-       if (data.no_resize())
-               return string();
-
-       std::ostringstream os;
-       if (data.usingScale()) {
-               double const scl = convert<double>(data.scale) / 100.0;
-               os << "\\scalebox{" << scl << "}[" << scl << "]{";
-       } else {
-               string width  = "!";
-               string height = "!";
-               if (data.keepAspectRatio) {
-                       if (data.width.inPixels(10) > data.height.inPixels(10))
-                               width = data.width.asLatexString();
-                       else
-                               height = data.height.asLatexString();
-               } else {
-                       if (!data.width.zero())
-                               width = data.width.asLatexString();
-                       if (!data.height.zero())
-                               height = data.height.asLatexString();
-               }
-
-               os << "\\resizebox{"
-                  << width << "}{"
-                  << height << "}{";
-       }
-       return os.str();
-}
-
-
-string const ResizeLatexCommand::back_impl() const
-{
-       if (data.no_resize())
-               return string();
-
-       return "}";
-}
-
-
-namespace {
-
-std::ostream & operator<<(std::ostream & os, RotationData::OriginType type)
-{
-       switch (type) {
-       case RotationData::DEFAULT:
-       case RotationData::CENTER:
-               break;
-       case RotationData::TOPLEFT:
-       case RotationData::TOPCENTER:
-       case RotationData::TOPRIGHT:
-               os << 't';
-               break;
-       case RotationData::BOTTOMLEFT:
-       case RotationData::BOTTOMCENTER:
-       case RotationData::BOTTOMRIGHT:
-               os << 'b';
-               break;
-       case RotationData::BASELINELEFT:
-       case RotationData::BASELINECENTER:
-       case RotationData::BASELINERIGHT:
-               os << 'B';
-               break;
-       }
-
-       switch (type) {
-       case RotationData::DEFAULT:
-               break;
-       case RotationData::TOPLEFT:
-       case RotationData::BOTTOMLEFT:
-       case RotationData::BASELINELEFT:
-               os << 'l';
-               break;
-       case RotationData::CENTER:
-       case RotationData::TOPCENTER:
-       case RotationData::BOTTOMCENTER:
-       case RotationData::BASELINECENTER:
-               os << 'c';
-               break;
-       case RotationData::TOPRIGHT:
-       case RotationData::BOTTOMRIGHT:
-       case RotationData::BASELINERIGHT:
-               os << 'r';
-               break;
-       }
-
-       return os;
-}
-
-} // namespace anon
-
-
-string const RotationLatexCommand::front_impl() const
-{
-       if (data.no_rotation())
-               return string();
-
-       std::ostringstream os;
-       os << "\\rotatebox";
-
-       if (data.origin() != RotationData::DEFAULT)
-               os << "[origin=" << data.origin() << ']';
-
-       os << '{' << data.angle << "}{";
-       return os.str();
-}
-
-
-string const RotationLatexCommand::back_impl() const
-{
-       if (data.no_rotation())
-               return string();
-
-       return "}";
-}
-
-
-string const  ClipLatexOption::option_impl() const
-{
-       if (!data.clip || data.bbox.empty())
-               return string();
-
-       std::ostringstream os;
-       if (!data.bbox.empty())
-               os << "bb=" << data.bbox << ',';
-       if (data.clip)
-               os << "clip,";
-       return os.str();
-}
-
-
-string const ResizeLatexOption::option_impl() const
-{
-       if (data.no_resize())
-               return string();
-
-       std::ostringstream os;
-       if (data.usingScale()) {
-               double const scl = convert<double>(data.scale);
-               if (!float_equal(scl, 100.0, 0.05))
-                       os << "scale=" << scl / 100.0 << ',';
-               return os.str();
-       }
-
-       if (!data.width.zero())
-               os << "width=" << data.width.asLatexString() << ',';
-       if (!data.height.zero())
-               os << "height=" << data.height.asLatexString() << ',';
-       if (data.keepAspectRatio)
-               os << "keepaspectratio,";
-
-       return os.str();
-}
-
-
-string const RotationLatexOption ::option_impl() const
-{
-       if (data.no_rotation())
-               return string();
-
-       std::ostringstream os;
-       os << "angle=" << data.angle << ',';
-
-       if (data.origin() != RotationData::DEFAULT)
-               os << "origin=" << data.origin() << ',';
-
-       return os.str();
-}
-
-
-string const sanitizeDocBookOption(string const & input)
-{
-       return input;
-}
-
-
-string const sanitizeLatexOption(string const & input)
-{
-       string::const_iterator begin = input.begin();
-       string::const_iterator end   = input.end();
-       string::const_iterator it = begin;
-
-       // Strip any leading commas
-       // "[,,,,foo..." -> "foo..." ("foo..." may be empty)
-       string output;
-       boost::smatch what;
-       static boost::regex const front("^( *[[],*)(.*)$");
-
-       regex_match(it, end, what, front, boost::match_partial);
-       if (!what[0].matched) {
-               lyxerr << "Unable to sanitize LaTeX \"Option\": "
-                      << input << '\n';
-               return string();
-       }
-       it =  what[1].second;
-
-       // Replace any consecutive commas with a single one
-       // "foo,,,,bar" -> "foo,bar"
-       // with iterator now pointing to 'b'
-       static boost::regex const commas("([^,]*)(,,*)(.*)$");
-       for (; it != end;) {
-               regex_match(it, end, what, commas, boost::match_partial);
-               if (!what[0].matched) {
-                       output += string(it, end);
-                       break;
-               }
-               output += what.str(1) + ",";
-               it = what[3].first;
-       }
-
-       // Strip any trailing commas
-       // "...foo,,,]" -> "...foo" ("...foo,,," may be empty)
-       static boost::regex const back("^(.*[^,])?,*[]] *$");
-       regex_match(output, what, back);
-       if (!what[0].matched) {
-               lyxerr << "Unable to sanitize LaTeX \"Option\": "
-                      << output << '\n';
-               return string();
-       }
-       output = what.str(1);
-
-       // Remove any surrounding whitespace
-       output = support::trim(output);
-
-       // If the thing is empty, leave it so, else wrap it in square brackets.
-       return output.empty() ? output : "[" + output + "]";
-}
-
-
-namespace {
-
-template <typename Factory, typename Data, typename Transformer>
-void extractIt(boost::any const & any_factory,
-              Data const & data, Transformer & transformer)
-{
-       if (any_factory.type() != typeid(Factory))
-               return;
-
-       Factory factory = boost::any_cast<Factory>(any_factory);
-       if (!factory.empty())
-               transformer = factory(data);
-}
-
-} // namespace anon
-
-
-TransformCommand::ptr_type
-TransformStore::getCommandTransformer(RotationData const & data) const
-{
-       TransformCommand::ptr_type ptr;
-       if (id == Rotate)
-               extractIt<RotationCommandFactory>(any_factory, data, ptr);
-       return ptr;
-}
-
-
-TransformCommand::ptr_type
-TransformStore::getCommandTransformer(ResizeData const & data) const
-{
-       TransformCommand::ptr_type ptr;
-       if (id == Resize)
-               extractIt<ResizeCommandFactory>(any_factory, data, ptr);
-       return ptr;
-}
-
-
-TransformOption::ptr_type
-TransformStore::getOptionTransformer(RotationData const & data) const
-{
-       TransformOption::ptr_type ptr;
-       if (id == Rotate)
-               extractIt<RotationOptionFactory>(any_factory, data, ptr);
-       return ptr;
-}
-
-
-TransformOption::ptr_type
-TransformStore::getOptionTransformer(ResizeData const & data) const
-{
-       TransformOption::ptr_type ptr;
-       if (id == Resize)
-               extractIt<ResizeOptionFactory>(any_factory, data, ptr);
-       return ptr;
-}
-
-
-TransformOption::ptr_type
-TransformStore::getOptionTransformer(ClipData const & data) const
-{
-       TransformOption::ptr_type ptr;
-       if (id == Clip)
-               extractIt<ClipOptionFactory>(any_factory, data, ptr);
-       return ptr;
-}
-
-
-
-TransformOption::ptr_type
-TransformStore::getOptionTransformer(string const & data) const
-{
-       TransformOption::ptr_type ptr;
-       if (id == Extra)
-               extractIt<ExtraOptionFactory>(any_factory, data, ptr);
-       return ptr;
-}
-
-
-namespace {
-
-OriginTranslator const initOriginTranslator()
-{
-       OriginTranslator translator(RotationData::DEFAULT, "default");
-       translator.addPair(RotationData::TOPLEFT,        "topleft");
-       translator.addPair(RotationData::BOTTOMLEFT,     "bottomleft");
-       translator.addPair(RotationData::BASELINELEFT,   "baselineleft");
-       translator.addPair(RotationData::CENTER,         "center");
-       translator.addPair(RotationData::TOPCENTER,      "topcenter");
-       translator.addPair(RotationData::BOTTOMCENTER,   "bottomcenter");
-       translator.addPair(RotationData::BASELINECENTER, "baselinecenter");
-       translator.addPair(RotationData::TOPRIGHT,       "topright");
-       translator.addPair(RotationData::BOTTOMRIGHT,    "bottomright");
-       translator.addPair(RotationData::BASELINERIGHT,  "baselineright");
-       return translator;
-}
-
-
-OriginTranslator const & originTranslator()
-{
-       static OriginTranslator const translator = initOriginTranslator();
-       return translator;
-}
-
-} // namespace anon
-
-} // namespace external
-} // namespace lyx
diff --git a/src/insets/ExternalTransforms.cpp b/src/insets/ExternalTransforms.cpp
new file mode 100644 (file)
index 0000000..de25277
--- /dev/null
@@ -0,0 +1,434 @@
+/**
+ * \file ExternalTransforms.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "ExternalTransforms.h"
+
+#include "debug.h"
+
+#include "support/lstrings.h"
+#include "support/lyxlib.h" // float_equal
+#include "support/convert.h"
+#include "support/Translator.h"
+
+#include <boost/regex.hpp>
+
+#include <cmath> // std::abs
+#include <sstream>
+
+
+namespace lyx {
+namespace external {
+
+using support::float_equal;
+using std::string;
+
+
+string const ExtraData::get(string const & id) const
+{
+       std::map<string, string>::const_iterator it = data_.find(id);
+       return it == data_.end() ? string() : it->second;
+}
+
+
+void ExtraData::set(string const & id, string const & data)
+{
+       data_[id] = data;
+}
+
+
+bool ResizeData::no_resize() const
+{
+       return !usingScale() && width.zero() && height.zero();
+}
+
+
+bool ResizeData::usingScale() const
+{
+       return (!scale.empty() && !float_equal(convert<double>(scale), 0.0, 0.05));
+}
+
+
+bool RotationData::no_rotation() const
+{
+       return (angle.empty() || std::abs(convert<double>(angle)) < 0.1);
+}
+
+
+string const RotationData::adjAngle() const
+{
+       // Ensure that angle lies in the range -360 < angle < 360
+       double rotAngle = convert<double>(angle);
+       if (std::abs(rotAngle) > 360.0) {
+               rotAngle -= 360.0 * floor(rotAngle / 360.0);
+               return convert<string>(rotAngle);
+       }
+       return angle;
+}
+
+
+namespace {
+
+typedef Translator<RotationData::OriginType, string> OriginTranslator;
+OriginTranslator const & originTranslator();
+
+} // namespace anon
+
+
+void RotationData::origin(string const & o)
+{
+       origin_ = originTranslator().find(o);
+}
+
+
+string const RotationData::originString() const
+{
+       return originTranslator().find(origin_);
+}
+
+
+string const ResizeLatexCommand::front_impl() const
+{
+       if (data.no_resize())
+               return string();
+
+       std::ostringstream os;
+       if (data.usingScale()) {
+               double const scl = convert<double>(data.scale) / 100.0;
+               os << "\\scalebox{" << scl << "}[" << scl << "]{";
+       } else {
+               string width  = "!";
+               string height = "!";
+               if (data.keepAspectRatio) {
+                       if (data.width.inPixels(10) > data.height.inPixels(10))
+                               width = data.width.asLatexString();
+                       else
+                               height = data.height.asLatexString();
+               } else {
+                       if (!data.width.zero())
+                               width = data.width.asLatexString();
+                       if (!data.height.zero())
+                               height = data.height.asLatexString();
+               }
+
+               os << "\\resizebox{"
+                  << width << "}{"
+                  << height << "}{";
+       }
+       return os.str();
+}
+
+
+string const ResizeLatexCommand::back_impl() const
+{
+       if (data.no_resize())
+               return string();
+
+       return "}";
+}
+
+
+namespace {
+
+std::ostream & operator<<(std::ostream & os, RotationData::OriginType type)
+{
+       switch (type) {
+       case RotationData::DEFAULT:
+       case RotationData::CENTER:
+               break;
+       case RotationData::TOPLEFT:
+       case RotationData::TOPCENTER:
+       case RotationData::TOPRIGHT:
+               os << 't';
+               break;
+       case RotationData::BOTTOMLEFT:
+       case RotationData::BOTTOMCENTER:
+       case RotationData::BOTTOMRIGHT:
+               os << 'b';
+               break;
+       case RotationData::BASELINELEFT:
+       case RotationData::BASELINECENTER:
+       case RotationData::BASELINERIGHT:
+               os << 'B';
+               break;
+       }
+
+       switch (type) {
+       case RotationData::DEFAULT:
+               break;
+       case RotationData::TOPLEFT:
+       case RotationData::BOTTOMLEFT:
+       case RotationData::BASELINELEFT:
+               os << 'l';
+               break;
+       case RotationData::CENTER:
+       case RotationData::TOPCENTER:
+       case RotationData::BOTTOMCENTER:
+       case RotationData::BASELINECENTER:
+               os << 'c';
+               break;
+       case RotationData::TOPRIGHT:
+       case RotationData::BOTTOMRIGHT:
+       case RotationData::BASELINERIGHT:
+               os << 'r';
+               break;
+       }
+
+       return os;
+}
+
+} // namespace anon
+
+
+string const RotationLatexCommand::front_impl() const
+{
+       if (data.no_rotation())
+               return string();
+
+       std::ostringstream os;
+       os << "\\rotatebox";
+
+       if (data.origin() != RotationData::DEFAULT)
+               os << "[origin=" << data.origin() << ']';
+
+       os << '{' << data.angle << "}{";
+       return os.str();
+}
+
+
+string const RotationLatexCommand::back_impl() const
+{
+       if (data.no_rotation())
+               return string();
+
+       return "}";
+}
+
+
+string const  ClipLatexOption::option_impl() const
+{
+       if (!data.clip || data.bbox.empty())
+               return string();
+
+       std::ostringstream os;
+       if (!data.bbox.empty())
+               os << "bb=" << data.bbox << ',';
+       if (data.clip)
+               os << "clip,";
+       return os.str();
+}
+
+
+string const ResizeLatexOption::option_impl() const
+{
+       if (data.no_resize())
+               return string();
+
+       std::ostringstream os;
+       if (data.usingScale()) {
+               double const scl = convert<double>(data.scale);
+               if (!float_equal(scl, 100.0, 0.05))
+                       os << "scale=" << scl / 100.0 << ',';
+               return os.str();
+       }
+
+       if (!data.width.zero())
+               os << "width=" << data.width.asLatexString() << ',';
+       if (!data.height.zero())
+               os << "height=" << data.height.asLatexString() << ',';
+       if (data.keepAspectRatio)
+               os << "keepaspectratio,";
+
+       return os.str();
+}
+
+
+string const RotationLatexOption ::option_impl() const
+{
+       if (data.no_rotation())
+               return string();
+
+       std::ostringstream os;
+       os << "angle=" << data.angle << ',';
+
+       if (data.origin() != RotationData::DEFAULT)
+               os << "origin=" << data.origin() << ',';
+
+       return os.str();
+}
+
+
+string const sanitizeDocBookOption(string const & input)
+{
+       return input;
+}
+
+
+string const sanitizeLatexOption(string const & input)
+{
+       string::const_iterator begin = input.begin();
+       string::const_iterator end   = input.end();
+       string::const_iterator it = begin;
+
+       // Strip any leading commas
+       // "[,,,,foo..." -> "foo..." ("foo..." may be empty)
+       string output;
+       boost::smatch what;
+       static boost::regex const front("^( *[[],*)(.*)$");
+
+       regex_match(it, end, what, front, boost::match_partial);
+       if (!what[0].matched) {
+               lyxerr << "Unable to sanitize LaTeX \"Option\": "
+                      << input << '\n';
+               return string();
+       }
+       it =  what[1].second;
+
+       // Replace any consecutive commas with a single one
+       // "foo,,,,bar" -> "foo,bar"
+       // with iterator now pointing to 'b'
+       static boost::regex const commas("([^,]*)(,,*)(.*)$");
+       for (; it != end;) {
+               regex_match(it, end, what, commas, boost::match_partial);
+               if (!what[0].matched) {
+                       output += string(it, end);
+                       break;
+               }
+               output += what.str(1) + ",";
+               it = what[3].first;
+       }
+
+       // Strip any trailing commas
+       // "...foo,,,]" -> "...foo" ("...foo,,," may be empty)
+       static boost::regex const back("^(.*[^,])?,*[]] *$");
+       regex_match(output, what, back);
+       if (!what[0].matched) {
+               lyxerr << "Unable to sanitize LaTeX \"Option\": "
+                      << output << '\n';
+               return string();
+       }
+       output = what.str(1);
+
+       // Remove any surrounding whitespace
+       output = support::trim(output);
+
+       // If the thing is empty, leave it so, else wrap it in square brackets.
+       return output.empty() ? output : "[" + output + "]";
+}
+
+
+namespace {
+
+template <typename Factory, typename Data, typename Transformer>
+void extractIt(boost::any const & any_factory,
+              Data const & data, Transformer & transformer)
+{
+       if (any_factory.type() != typeid(Factory))
+               return;
+
+       Factory factory = boost::any_cast<Factory>(any_factory);
+       if (!factory.empty())
+               transformer = factory(data);
+}
+
+} // namespace anon
+
+
+TransformCommand::ptr_type
+TransformStore::getCommandTransformer(RotationData const & data) const
+{
+       TransformCommand::ptr_type ptr;
+       if (id == Rotate)
+               extractIt<RotationCommandFactory>(any_factory, data, ptr);
+       return ptr;
+}
+
+
+TransformCommand::ptr_type
+TransformStore::getCommandTransformer(ResizeData const & data) const
+{
+       TransformCommand::ptr_type ptr;
+       if (id == Resize)
+               extractIt<ResizeCommandFactory>(any_factory, data, ptr);
+       return ptr;
+}
+
+
+TransformOption::ptr_type
+TransformStore::getOptionTransformer(RotationData const & data) const
+{
+       TransformOption::ptr_type ptr;
+       if (id == Rotate)
+               extractIt<RotationOptionFactory>(any_factory, data, ptr);
+       return ptr;
+}
+
+
+TransformOption::ptr_type
+TransformStore::getOptionTransformer(ResizeData const & data) const
+{
+       TransformOption::ptr_type ptr;
+       if (id == Resize)
+               extractIt<ResizeOptionFactory>(any_factory, data, ptr);
+       return ptr;
+}
+
+
+TransformOption::ptr_type
+TransformStore::getOptionTransformer(ClipData const & data) const
+{
+       TransformOption::ptr_type ptr;
+       if (id == Clip)
+               extractIt<ClipOptionFactory>(any_factory, data, ptr);
+       return ptr;
+}
+
+
+
+TransformOption::ptr_type
+TransformStore::getOptionTransformer(string const & data) const
+{
+       TransformOption::ptr_type ptr;
+       if (id == Extra)
+               extractIt<ExtraOptionFactory>(any_factory, data, ptr);
+       return ptr;
+}
+
+
+namespace {
+
+OriginTranslator const initOriginTranslator()
+{
+       OriginTranslator translator(RotationData::DEFAULT, "default");
+       translator.addPair(RotationData::TOPLEFT,        "topleft");
+       translator.addPair(RotationData::BOTTOMLEFT,     "bottomleft");
+       translator.addPair(RotationData::BASELINELEFT,   "baselineleft");
+       translator.addPair(RotationData::CENTER,         "center");
+       translator.addPair(RotationData::TOPCENTER,      "topcenter");
+       translator.addPair(RotationData::BOTTOMCENTER,   "bottomcenter");
+       translator.addPair(RotationData::BASELINECENTER, "baselinecenter");
+       translator.addPair(RotationData::TOPRIGHT,       "topright");
+       translator.addPair(RotationData::BOTTOMRIGHT,    "bottomright");
+       translator.addPair(RotationData::BASELINERIGHT,  "baselineright");
+       return translator;
+}
+
+
+OriginTranslator const & originTranslator()
+{
+       static OriginTranslator const translator = initOriginTranslator();
+       return translator;
+}
+
+} // namespace anon
+
+} // namespace external
+} // namespace lyx
index ac92f3ed329c51d3f2487b78883c9c0632a165b5..aab94712b13374e96451bf6950c8fff7b7494fc1 100644 (file)
@@ -14,11 +14,11 @@ AM_CPPFLAGS += $(PCH_FLAGS) -I$(srcdir)/.. $(BOOST_INCLUDES)
 libinsets_la_SOURCES = \
        MailInset.cpp \
        MailInset.h \
-       ExternalSupport.C \
+       ExternalSupport.cpp \
        ExternalSupport.h \
-       ExternalTemplate.C \
+       ExternalTemplate.cpp \
        ExternalTemplate.h \
-       ExternalTransforms.C \
+       ExternalTransforms.cpp \
        ExternalTransforms.h \
        RenderBase.h \
        RenderButton.cpp \