2 * \file LaTeXPackages.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
10 * \author André Pönitz
12 * Full author contact details are available in file CREDITS.
17 #include "LaTeXPackages.h"
19 #include "support/convert.h"
20 #include "support/debug.h"
21 #include "support/FileName.h"
22 #include "support/filetools.h"
23 #include "support/gettext.h"
24 #include "support/Lexer.h"
25 #include "support/lstrings.h"
26 #include "support/Package.h"
28 #include "frontends/alert.h"
32 using namespace lyx::support;
37 LaTeXPackages::Packages LaTeXPackages::packages_;
40 void LaTeXPackages::getAvailable(bool retry)
43 support::FileName const real_file = libFileSearch("", "packages.lst");
45 if (real_file.empty())
48 lex.setFile(real_file);
53 // Make sure that we are clean
56 bool finished = false;
57 string lstformat = "1";
59 while (lex.isOK() && !finished) {
65 string const p = lex.getString();
66 // Parse optional version info
68 string const v = trim(lex.getString());
69 if (p == "!!fileformat") {
73 packages_.insert(make_pair(p, v));
77 // Check if the pkglist has current format.
78 // Reconfigure once and re-parse if not.
79 if (lstformat != "2") {
80 // If we have already reconfigured, check if there is an outdated config file
81 // which produces the outdated lstformat
83 // check if we have an outdated chkconfig.ltx file in user dir
84 support::FileName chkconfig = fileSearch(addPath(package().user_support().absFileName(), ""),
85 "chkconfig.ltx", string(), must_exist);
86 if (chkconfig.empty()) {
87 // nothing found. So we can only warn
88 frontend::Alert::warning(_("Invalid package list format!"),
89 _("The format of your LaTeX packages list is wrong. Please file a bug report."));
92 // Found. Try to rename and warn.
93 support::FileName chkconfig_bak;
94 chkconfig_bak.set(chkconfig.absFileName() + ".bak");
95 if (chkconfig.renameTo(chkconfig_bak))
97 frontend::Alert::warning(_("Outdated configuration script detected!"),
98 _("We have detected an outdated script 'chkconfig.ltx' in your user directory.\n"
99 "The script has been renamed to 'chkconfig.ltx.bak'.\n"
100 "If you did not copy the script there by purpose, you can safely delete it."));
103 frontend::Alert::warning(_("Outdated configuration script detected!"),
104 bformat(_("We have detected an outdated script 'chkconfig.ltx' in your user directory\n"
106 "Please delete or update this file!"), from_utf8(chkconfig.absFileName())));
110 package().reconfigureUserLyXDir("");
116 bool LaTeXPackages::isAvailable(string const & name)
118 if (packages_.empty())
121 if (suffixIs(n, ".sty"))
122 n.erase(name.length() - 4);
123 for (auto const & package : packages_) {
124 if (package.first == n)
131 bool LaTeXPackages::isAvailableAtLeastFrom(string const & name,
132 int const y, int const m, int const d)
134 if (packages_.empty())
137 // required date as int (yyyymmdd)
138 int const req_date = (y * 10000) + (m * 100) + d;
139 for (auto const & package : packages_) {
140 if (package.first == name && !package.second.empty()) {
141 if (!isStrInt(package.second)) {
142 LYXERR0("Warning: Invalid date of package "
143 << package.first << " (" << package.second << ")");
146 // required date not newer than available date
147 return req_date <= convert<int>(package.second);