Hello, with the attached patch lyx loads all external_template definitions from 1. user_lyxdir 2. build_lyxdir 3. system_lyxdir
If there are template or preamble definitions with the same name from different sources then lyx prints a warning message to the console and the first definition (in the above order) is used.
objections? good night Bernhard
Index: src/insets/ExternalTemplate.cpp =================================================================== --- src/insets/ExternalTemplate.cpp (revision 18994) +++ src/insets/ExternalTemplate.cpp (working copy) @@ -251,43 +251,67 @@ { "templateend", TM_TEMPLATE_END } }; - Lexer lex(templatetags, TM_TEMPLATE_END); + std::map<std::string, std::string> preamble_sources; + std::map<std::string, std::string> template_sources; + std::vector<std::pair<std::string, support::FileName> > files; + std::vector<std::pair<std::string, support::FileName> >::iterator it; + support::libFileSearch(files, "", "external_templates"); + for (it = files.begin(); it != files.end(); ++it) { + Lexer 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; - } + if (!lex.setFile(it->second)) { + lex.printError("external::TemplateManager::readTemplates: " + "Set template file failed"); + continue; + } - char const * const preamble_end_tag = - templatetags[TM_PREAMBLEDEF_END-1].tag; + 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; + while (lex.isOK()) { + switch (lex.lex()) { + case TM_PREAMBLEDEF: { + lex.next(); + string const name = lex.getString(); + if (preambledefs.find(name) != preambledefs.end()) { + lyxerr << "External template preamble definition \"" << name << "\" from " + << preamble_sources[name] << " overwrites definition in " + << it->first << '\n'; + lex.getLongString(preamble_end_tag); + } else { + preambledefs[name] = lex.getLongString(preamble_end_tag); + } + preamble_sources[name] = it->first; + } + 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: { + lex.next(); + string const name = lex.getString(); + // remove an existing template (user template overwrites system template) + if (templates.find(name) != templates.end()) { + lyxerr << "External template definition \"" << name << "\" from " + << template_sources[name] << " overwrites definition in " + << it->first << '\n'; + Template tmp; + tmp.readTemplate(lex); + } else { + Template & tmp = templates[name]; + tmp.lyxName = name; + tmp.readTemplate(lex); + } + template_sources[name] = it->first; + } + break; - case TM_TEMPLATE_END: - lex.printError("Warning: End outside Template."); - break; + case TM_TEMPLATE_END: + lex.printError("Warning: End outside Template."); + break; - case TM_PREAMBLEDEF_END: - lex.printError("Warning: End outside PreambleDef."); - break; + case TM_PREAMBLEDEF_END: + lex.printError("Warning: End outside PreambleDef."); + break; + } } } } Index: src/support/filetools.cpp =================================================================== --- src/support/filetools.cpp (revision 18994) +++ src/support/filetools.cpp (working copy) @@ -299,6 +299,31 @@ } +// Search the file name.ext in the subdirectory dir of +// 1) user_lyxdir +// 2) build_lyxdir (if not empty) +// 3) system_lyxdir +void libFileSearch(std::vector<std::pair<std::string, support::FileName> > &files, + string const & dir, string const & name, string const & ext) +{ + FileName fullname = fileSearch(addPath(package().user_support().absFilename(), dir), + name, ext); + if (!fullname.empty()) + files.push_back(std::pair<std::string, support::FileName>("user_lyxdir", fullname)); + + if (!package().build_support().empty()) { + fullname = fileSearch(addPath(package().build_support().absFilename(), dir), + name, ext); + if (!fullname.empty()) + files.push_back(std::pair<std::string, support::FileName>("build_lyxdir", fullname)); + } + + fullname = fileSearch(addPath(package().system_support().absFilename(), dir), name, ext); + if (!fullname.empty()) + files.push_back(std::pair<std::string, support::FileName>("system_lyxdir", fullname)); +} + + FileName const i18nLibFileSearch(string const & dir, string const & name, string const & ext) { Index: src/support/filetools.h =================================================================== --- src/support/filetools.h (revision 18994) +++ src/support/filetools.h (working copy) @@ -108,6 +108,20 @@ std::string const & name, std::string const & ext = std::string()); +/** Returns the path of all library data files. + Search the file name.ext in the subdirectory dir of + -# user_lyxdir + -# build_lyxdir (if not empty) + -# system_lyxdir + The third parameter `ext' is optional. + The files argument is filled with the filenames of + the existing files in these directories. +*/ +void libFileSearch(std::vector<std::pair<std::string, support::FileName> > &files, + std::string const & dir, + std::string const & name, + std::string const & ext = std::string()); + /** Same as libFileSearch(), but tries first to find an internationalized version of the file by prepending $LANG_ to the name