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); }
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()); } } }
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; }
// 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; }