]> git.lyx.org Git - lyx.git/blob - src/LaTeXPackages.cpp
Avoid full metrics computation with Update:FitCursor
[lyx.git] / src / LaTeXPackages.cpp
1 /**
2  * \file LaTeXPackages.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author José Matos
7  * \author Lars Gullik Bjønnes
8  * \author Jean-Marc Lasgouttes
9  * \author Jürgen Vigna
10  * \author André Pönitz
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #include <config.h>
16
17 #include "LaTeXPackages.h"
18
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"
27
28 #include "frontends/alert.h"
29
30
31 using namespace std;
32 using namespace lyx::support;
33
34
35 namespace lyx {
36
37 LaTeXPackages::Packages LaTeXPackages::packages_;
38
39
40 void LaTeXPackages::getAvailable(bool retry)
41 {
42         Lexer lex;
43         support::FileName const real_file = libFileSearch("", "packages.lst");
44
45         if (real_file.empty())
46                 return;
47
48         lex.setFile(real_file);
49
50         if (!lex.isOK())
51                 return;
52
53         // Make sure that we are clean
54         packages_.clear();
55
56         bool finished = false;
57         string lstformat = "1";
58         // Parse config-file
59         while (lex.isOK() && !finished) {
60                 switch (lex.lex()) {
61                 case Lexer::LEX_FEOF:
62                         finished = true;
63                         break;
64                 default: {
65                         string const p = lex.getString();
66                         // Parse optional version info
67                         lex.eatLine();
68                         string const v = trim(lex.getString());
69                         if (p == "!!fileformat") {
70                                 lstformat = v;
71                                 continue;
72                         }
73                         packages_.insert(make_pair(p, v));
74                 }
75                 }
76         }
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
82                 if (retry) {
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."));
90                                 return;
91                         }
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))
96                                 // renaming succeeded
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."));
101                         else {
102                                 // renaming failed
103                                 frontend::Alert::warning(_("Outdated configuration script detected!"),
104                                         bformat(_("We have detected an outdated script 'chkconfig.ltx' in your user directory\n"
105                                           "(%1$s).\n"
106                                           "Please delete or update this file!"), from_utf8(chkconfig.absFileName())));
107                                 return;
108                         }
109                 }
110                 package().reconfigureUserLyXDir("");
111                 getAvailable(true);
112         }
113 }
114
115
116 bool LaTeXPackages::isAvailable(string const & name)
117 {
118         if (packages_.empty())
119                 getAvailable();
120         string n = name;
121         if (suffixIs(n, ".sty"))
122                 n.erase(name.length() - 4);
123         for (auto const & package : packages_) {
124                 if (package.first == n)
125                         return true;
126         }
127         return false;
128 }
129
130
131 bool LaTeXPackages::isAvailableAtLeastFrom(string const & name,
132                                            int const y, int const m, int const d)
133 {
134         if (packages_.empty())
135                 getAvailable();
136
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 << ")");
144                                 continue;
145                         }
146                         // required date not newer than available date
147                         return req_date <= convert<int>(package.second);
148                 }
149         }
150         return false;
151 }
152
153 } // namespace lyx