示例#1
0
QStringList texFileList(QString const & filename)
{
	QStringList list;
	FileName const file = libFileSearch(QString(), filename);
	if (file.empty())
		return list;

	// FIXME Unicode.
	vector<docstring> doclist = 
		getVectorFromString(file.fileContents("UTF-8"), from_ascii("\n"));

	// Normalise paths like /foo//bar ==> /foo/bar
	QSet<QString> set;
	for (size_t i = 0; i != doclist.size(); ++i) {
		QString file = toqstr(doclist[i]);
		file.replace("\r", "");
		while (file.contains("//"))
			file.replace("//", "/");
		if (!file.isEmpty())
			set.insert(file);
	}

	// remove duplicates
	return QList<QString>::fromSet(set);
}
示例#2
0
void LaTeXFeatures::getAvailable()
{
	Lexer lex;
	support::FileName const real_file = libFileSearch("", "packages.lst");

	if (real_file.empty())
		return;

	lex.setFile(real_file);

	if (!lex.isOK())
		return;

	// Make sure that we are clean
	packages_.clear();

	bool finished = false;
	// Parse config-file
	while (lex.isOK() && !finished) {
		switch (lex.lex()) {
		case Lexer::LEX_FEOF:
			finished = true;
			break;
		default:
			packages_.insert(lex.getString());
		}
	}
}
示例#3
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;
}
示例#4
0
// Much of this is borrowed from LayoutFileList::read()
bool ModuleList::read()
{
	FileName const real_file = libFileSearch("", "lyxmodules.lst");
	LYXERR(Debug::TCLASS, "Reading modules from `" << real_file << '\'');

	if (real_file.empty()) {
		LYXERR0("unable to find modules file `lyxmodules.lst'.\n"
			<< "No modules will be available.");
		return false;
	}

	Lexer lex;
	if (!lex.setFile(real_file)) {
		LYXERR0("lyxlex was not able to set file: "
			<< real_file << ".\nNo modules will be available.");
		return false;
	}

	if (!lex.isOK()) {
		LYXERR0("unable to open modules file  `"
			<< to_utf8(makeDisplayPath(real_file.absFileName(), 1000))
			<< "'\nNo modules will be available.");
		return false;
	}

	bool finished = false;
	// Parse modules files
	LYXERR(Debug::TCLASS, "Starting parsing of lyxmodules.lst");
	while (lex.isOK() && !finished) {
		LYXERR(Debug::TCLASS, "\tline by line");
		switch (lex.lex()) {
		case Lexer::LEX_FEOF:
			finished = true;
			break;
		default:
			string const modname = lex.getString();
			LYXERR(Debug::TCLASS, "Module name: " << modname);
			if (!lex.next())
				break;
			string const fname = lex.getString();
			LYXERR(Debug::TCLASS, "Filename: " << fname);
			if (!lex.next(true))
				break;
			string const desc = lex.getString();
			LYXERR(Debug::TCLASS, "Description: " << desc);
			//FIXME Add packages
			if (!lex.next())
				break;
			string str = lex.getString();
			LYXERR(Debug::TCLASS, "Packages: " << str);
			vector<string> pkgs;
			while (!str.empty()) {
				string p;
				str = split(str, p, ',');
				pkgs.push_back(p);
			}
			if (!lex.next())
				break;
			str = lex.getString();
			LYXERR(Debug::TCLASS, "Required: " << str);
			vector<string> req;
			while (!str.empty()) {
				string p;
				str = split(str, p, '|');
				req.push_back(p);
			}
			if (!lex.next())
				break;
			str = lex.getString();
			LYXERR(Debug::TCLASS, "Excluded: " << str);
			vector<string> exc;
			while (!str.empty()) {
				string p;
				str = split(str, p, '|');
				exc.push_back(p);
			}
			if (!lex.next())
				break;
			string const catgy = lex.getString();
			LYXERR(Debug::TCLASS, "Category: " << catgy);
			if (!lex.next())
				break;
			bool const local = lex.getString() == "true";
			LYXERR(Debug::TCLASS, "Local: " << local);
			// This code is run when we have
			// modName, fname, desc, pkgs, req, exc, catgy, and local
			addLayoutModule(modname, fname, desc, pkgs, req, exc, catgy, local);
		} // end switch
	} //end while

	LYXERR(Debug::TCLASS, "End of parsing of lyxmodules.lst");

	if (!theModuleList.empty())
		sort(theModuleList.begin(), theModuleList.end(), ModuleSorter());
	return true;
}