예제 #1
0
LyXModule const * ModuleList::operator[](string const & str) const
{
	LyXModuleList::const_iterator it = modlist_.begin();
	for (; it != modlist_.end(); ++it)
		if (it->getID() == str) {
			LyXModule const & mod = *it;
			return &mod;
		}
	return 0;
}
예제 #2
0
bool checkModule(string const & name, bool command)
{
	// Cache to avoid slowdown by repated searches
	static set<string> failed[2];

	// Only add the module if the command was actually defined in the LyX preamble
	if (command) {
		if (possible_textclass_commands.find('\\' + name) == possible_textclass_commands.end())
			return false;
	} else {
		if (possible_textclass_environments.find(name) == possible_textclass_environments.end())
			return false;
	}
	if (failed[command].find(name) != failed[command].end())
		return false;

	// Create list of dummy document classes if not already done.
	// This is needed since a module cannot be read on its own, only as
	// part of a document class.
	LayoutFile const & baseClass = LayoutFileList::get()[textclass.name()];
	typedef map<string, DocumentClass *> ModuleMap;
	static ModuleMap modules;
	static bool init = true;
	if (init) {
		baseClass.load();
		DocumentClassBundle & bundle = DocumentClassBundle::get();
		LyXModuleList::const_iterator const end = theModuleList.end();
		LyXModuleList::const_iterator it = theModuleList.begin();
		for (; it != end; it++) {
			string const module = it->getID();
			LayoutModuleList m;
			// FIXME this excludes all modules that depend on another one
			if (!m.moduleCanBeAdded(module, &baseClass))
				continue;
			m.push_back(module);
			modules[module] = &bundle.makeDocumentClass(baseClass, m);
		}
		init = false;
	}

	// Try to find a module that defines the command.
	// Only add it if the definition can be found in the preamble of the
	// style that corresponds to the command. This is a heuristic and
	// different from the way how we parse the builtin commands of the
	// text class (in that case we only compare the name), but it is
	// needed since it is not unlikely that two different modules define a
	// command with the same name.
	ModuleMap::iterator const end = modules.end();
	for (ModuleMap::iterator it = modules.begin(); it != end; it++) {
		string const module = it->first;
		if (!used_modules.moduleCanBeAdded(module, &baseClass))
			continue;
		if (findLayoutWithoutModule(textclass, name, command))
			continue;
		if (findInsetLayoutWithoutModule(textclass, name, command))
			continue;
		DocumentClass const * c = it->second;
		Layout const * layout = findLayoutWithoutModule(*c, name, command);
		InsetLayout const * insetlayout = layout ? 0 :
			findInsetLayoutWithoutModule(*c, name, command);
		docstring preamble;
		if (layout)
			preamble = layout->preamble();
		else if (insetlayout)
			preamble = insetlayout->preamble();
		if (preamble.empty())
			continue;
		bool add = false;
		if (command) {
			FullCommand const & cmd =
				possible_textclass_commands['\\' + name];
			if (preamble.find(cmd.def) != docstring::npos)
				add = true;
		} else {
			FullEnvironment const & env =
				possible_textclass_environments[name];
			if (preamble.find(env.beg) != docstring::npos &&
			    preamble.find(env.end) != docstring::npos)
				add = true;
		}
		if (add) {
			FileName layout_file = libFileSearch("layouts", module, "module");
			if (textclass.read(layout_file, TextClass::MODULE)) {
				used_modules.push_back(module);
				// speed up further searches:
				// the module does not need to be checked anymore.
				modules.erase(it);
				return true;
			}
		}
	}
	failed[command].insert(name);
	return false;
}