From: Bo Peng Date: Thu, 26 Apr 2007 05:18:04 +0000 (+0000) Subject: Rename three remaining .C files X-Git-Tag: 1.6.10~10052 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=bcc90ce1c9cfaa7c93cb0610632d71b79c1bbf9d;p=lyx.git Rename three remaining .C files git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18026 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/development/scons/scons_manifest.py b/development/scons/scons_manifest.py index 557d721903..692c5b72c6 100644 --- a/development/scons/scons_manifest.py +++ b/development/scons/scons_manifest.py @@ -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 index aba7818440..0000000000 --- a/src/insets/ExternalSupport.C +++ /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 - -#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 - -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::const_iterator fit = rit->second.begin(); - vector::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 -string const substituteIt(string const &, - TransformID, - string const &, - Template::Format const &, - InsetExternalParams const &); - - -template <> -string const substituteIt(string const & input, - TransformID id, - string const & /* formatname */, - Template::Format const & format, - InsetExternalParams const & params) -{ - typedef std::map 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(string const & input, - TransformID id, - string const & fname, - Template::Format const & format, - InsetExternalParams const & params) -{ - typedef std::map 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 -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 TransformsIDs; - TransformsIDs::const_iterator it = et->transformIds.begin(); - TransformsIDs::const_iterator end = et->transformIds.end(); - for (; it != end; ++it) { - result = substituteIt(result, *it, formatname, - format, params); - } - return result; -} - - -string const substituteCommands(InsetExternalParams const & params, - string const & input, string const & format) -{ - return transformIt(params, input, format); -} - - -string const substituteOption(InsetExternalParams const & params, - string const & input, string const & format) -{ - string opt = transformIt(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 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 index 0000000000..673959cf05 --- /dev/null +++ b/src/insets/ExternalSupport.cpp @@ -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 + +#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 + +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::const_iterator fit = rit->second.begin(); + vector::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 +string const substituteIt(string const &, + TransformID, + string const &, + Template::Format const &, + InsetExternalParams const &); + + +template <> +string const substituteIt(string const & input, + TransformID id, + string const & /* formatname */, + Template::Format const & format, + InsetExternalParams const & params) +{ + typedef std::map 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(string const & input, + TransformID id, + string const & fname, + Template::Format const & format, + InsetExternalParams const & params) +{ + typedef std::map 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 +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 TransformsIDs; + TransformsIDs::const_iterator it = et->transformIds.begin(); + TransformsIDs::const_iterator end = et->transformIds.end(); + for (; it != end; ++it) { + result = substituteIt(result, *it, formatname, + format, params); + } + return result; +} + + +string const substituteCommands(InsetExternalParams const & params, + string const & input, string const & format) +{ + return transformIt(params, input, format); +} + + +string const substituteOption(InsetExternalParams const & params, + string const & input, string const & format) +{ + string opt = transformIt(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 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 index b0a044d94f..0000000000 --- a/src/insets/ExternalTemplate.C +++ /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 - -#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 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 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::const_iterator qit = ft.requirements.begin(); - vector::const_iterator qend = ft.requirements.end(); - for (; qit != qend; ++qit) { - lyxerr << "req:" << *qit << std::endl; - ost << "\t\tRequirement " << *qit << '\n'; - } - - typedef vector 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::const_iterator pit = ft.preambleNames.begin(); - vector::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::const_iterator fit = rit->second.begin(); - vector::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 & 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 index 0000000000..faace7b244 --- /dev/null +++ b/src/insets/ExternalTemplate.cpp @@ -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 + +#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 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 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::const_iterator qit = ft.requirements.begin(); + vector::const_iterator qend = ft.requirements.end(); + for (; qit != qend; ++qit) { + lyxerr << "req:" << *qit << std::endl; + ost << "\t\tRequirement " << *qit << '\n'; + } + + typedef vector 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::const_iterator pit = ft.preambleNames.begin(); + vector::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::const_iterator fit = rit->second.begin(); + vector::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 & 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 index 2f8d08e391..0000000000 --- a/src/insets/ExternalTransforms.C +++ /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 - -#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 - -#include // std::abs -#include - - -namespace lyx { -namespace external { - -using support::float_equal; -using std::string; - - -string const ExtraData::get(string const & id) const -{ - std::map::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(scale), 0.0, 0.05)); -} - - -bool RotationData::no_rotation() const -{ - return (angle.empty() || std::abs(convert(angle)) < 0.1); -} - - -string const RotationData::adjAngle() const -{ - // Ensure that angle lies in the range -360 < angle < 360 - double rotAngle = convert(angle); - if (std::abs(rotAngle) > 360.0) { - rotAngle -= 360.0 * floor(rotAngle / 360.0); - return convert(rotAngle); - } - return angle; -} - - -namespace { - -typedef Translator 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(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(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 -void extractIt(boost::any const & any_factory, - Data const & data, Transformer & transformer) -{ - if (any_factory.type() != typeid(Factory)) - return; - - Factory factory = boost::any_cast(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(any_factory, data, ptr); - return ptr; -} - - -TransformCommand::ptr_type -TransformStore::getCommandTransformer(ResizeData const & data) const -{ - TransformCommand::ptr_type ptr; - if (id == Resize) - extractIt(any_factory, data, ptr); - return ptr; -} - - -TransformOption::ptr_type -TransformStore::getOptionTransformer(RotationData const & data) const -{ - TransformOption::ptr_type ptr; - if (id == Rotate) - extractIt(any_factory, data, ptr); - return ptr; -} - - -TransformOption::ptr_type -TransformStore::getOptionTransformer(ResizeData const & data) const -{ - TransformOption::ptr_type ptr; - if (id == Resize) - extractIt(any_factory, data, ptr); - return ptr; -} - - -TransformOption::ptr_type -TransformStore::getOptionTransformer(ClipData const & data) const -{ - TransformOption::ptr_type ptr; - if (id == Clip) - extractIt(any_factory, data, ptr); - return ptr; -} - - - -TransformOption::ptr_type -TransformStore::getOptionTransformer(string const & data) const -{ - TransformOption::ptr_type ptr; - if (id == Extra) - extractIt(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 index 0000000000..de25277845 --- /dev/null +++ b/src/insets/ExternalTransforms.cpp @@ -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 + +#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 + +#include // std::abs +#include + + +namespace lyx { +namespace external { + +using support::float_equal; +using std::string; + + +string const ExtraData::get(string const & id) const +{ + std::map::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(scale), 0.0, 0.05)); +} + + +bool RotationData::no_rotation() const +{ + return (angle.empty() || std::abs(convert(angle)) < 0.1); +} + + +string const RotationData::adjAngle() const +{ + // Ensure that angle lies in the range -360 < angle < 360 + double rotAngle = convert(angle); + if (std::abs(rotAngle) > 360.0) { + rotAngle -= 360.0 * floor(rotAngle / 360.0); + return convert(rotAngle); + } + return angle; +} + + +namespace { + +typedef Translator 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(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(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 +void extractIt(boost::any const & any_factory, + Data const & data, Transformer & transformer) +{ + if (any_factory.type() != typeid(Factory)) + return; + + Factory factory = boost::any_cast(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(any_factory, data, ptr); + return ptr; +} + + +TransformCommand::ptr_type +TransformStore::getCommandTransformer(ResizeData const & data) const +{ + TransformCommand::ptr_type ptr; + if (id == Resize) + extractIt(any_factory, data, ptr); + return ptr; +} + + +TransformOption::ptr_type +TransformStore::getOptionTransformer(RotationData const & data) const +{ + TransformOption::ptr_type ptr; + if (id == Rotate) + extractIt(any_factory, data, ptr); + return ptr; +} + + +TransformOption::ptr_type +TransformStore::getOptionTransformer(ResizeData const & data) const +{ + TransformOption::ptr_type ptr; + if (id == Resize) + extractIt(any_factory, data, ptr); + return ptr; +} + + +TransformOption::ptr_type +TransformStore::getOptionTransformer(ClipData const & data) const +{ + TransformOption::ptr_type ptr; + if (id == Clip) + extractIt(any_factory, data, ptr); + return ptr; +} + + + +TransformOption::ptr_type +TransformStore::getOptionTransformer(string const & data) const +{ + TransformOption::ptr_type ptr; + if (id == Extra) + extractIt(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/Makefile.am b/src/insets/Makefile.am index ac92f3ed32..aab94712b1 100644 --- a/src/insets/Makefile.am +++ b/src/insets/Makefile.am @@ -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 \