1if not modules then modules = { } end modules ['file-mod'] = {
2 version = 1.001,
3 comment = "companion to file-mod.mkvi",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11
12
13
14
15
20
21local format, find, concat, tonumber = string.format, string.find, table.concat, tonumber
22local sortedhash = table.sortedhash
23local basename = file.basename
24
25local trace_modules = false trackers .register("modules.loading", function(v) trace_modules = v end)
26local permit_unprefixed = false directives.register("modules.permitunprefixed", function(v) permit_unprefixed = v end)
27
28local report = logs.reporter("modules")
29
30local commands = commands
31local context = context
32local implement = interfaces.implement
33
34local findbyscheme = resolvers.finders.byscheme
35local iterator = utilities.parsers.iterator
36
37
38
39local prefixes = {
40 "m",
41 "p",
42 "s",
43 "x",
44
45 "t",
46}
47
48
49
50local suffixes = CONTEXTLMTXMODE > 0 and
51{
52 "mklx",
53 "mkxl",
54 "mkvi",
55 "mkiv",
56 "tex",
57 "cld",
58 "lua",
59}
60 or
61{
62 "mkvi",
63 "mkiv",
64 "tex",
65 "cld",
66 "lua",
67}
68
69local modstatus = { }
70local missing = false
71
72local function usemodule(name,hasscheme)
73 local foundname
74 if hasscheme then
75
76
77 local fullname = file.addsuffix(name,"tex")
78 if trace_modules then
79 report("checking url %a",fullname)
80 end
81 foundname = resolvers.findtexfile(fullname) or ""
82 elseif file.suffix(name) ~= "" then
83 if trace_modules then
84 report("checking file %a",name)
85 end
86 foundname = findbyscheme("any",name) or ""
87 else
88 for i=1,#suffixes do
89 local fullname = file.addsuffix(name,suffixes[i])
90 if trace_modules then
91 report("checking file %a",fullname)
92 end
93 foundname = findbyscheme("any",fullname) or ""
94 if foundname ~= "" then
95 break
96 end
97 end
98 end
99 if foundname ~= "" then
100 if trace_modules then
101 report("loading file %a",foundname)
102 end
103 context.startreadingfile()
104 resolvers.jobs.usefile(foundname,true)
105
106 context.stopreadingfile()
107 return true
108 else
109 return false
110 end
111end
112
113function environment.usemodules(prefix,askedname,truename)
114 local truename = truename or environment.truefilename(askedname) or askedname
115 if truename and truename ~= "" then
116 local hasprefix = prefix and prefix ~= ""
117 local hashname = ((hasprefix and prefix) or "*") .. "-" .. truename
118 local status = modstatus[hashname] or false
119 if status == 0 then
120
121 elseif status == 1 then
122 status = status + 1
123 else
124 if trace_modules then
125 report("locating, prefix %a, askedname %a, truename %a",prefix,askedname,truename)
126 end
127 local hasscheme = url.hasscheme(truename)
128 if hasscheme then
129
130 if usemodule(truename,true) then
131 status = 1
132 else
133 status = 0
134 end
135 elseif hasprefix then
136 if usemodule(prefix .. "-" .. truename) then
137 status = 1
138 else
139 status = 0
140 end
141 else
142 for i=1,#prefixes do
143
144 local thename = prefixes[i] .. "-" .. truename
145 if usemodule(thename) then
146 status = 1
147 break
148 end
149 end
150 if status then
151
152 elseif find(truename,"-",1,true) and usemodule(truename) then
153
154 report("using user prefixed file %a",truename)
155 status = 1
156 elseif permit_unprefixed and usemodule(truename) then
157 report("using unprefixed file %a",truename)
158 status = 1
159 else
160 status = 0
161 end
162 end
163 end
164 if status == 0 then
165 missing = true
166 report("%a is not found",askedname)
167 elseif status == 1 then
168 report("%a is loaded",trace_modules and truename or askedname)
169 else
170 report("%a is already loaded",trace_modules and truename or askedname)
171 end
172 modstatus[hashname] = status
173 end
174end
175
176statistics.register("loaded tex modules", function()
177 if next(modstatus) then
178 local t, f, nt, nf = { }, { }, 0, 0
179 for k, v in sortedhash(modstatus) do
180 local b = basename(k)
181 if v == 0 then
182 nf = nf + 1
183 f[nf] = b
184 else
185 nt = nt + 1
186 t[nt] = b
187 end
188 end
189 if nf == 0 then
190 return format("%s requested, all found (%s)",nt,concat(t," "))
191 elseif nt == 0 then
192 return format("%s requested, all missing (%s)",nf,concat(f," "))
193 else
194 return format("%s requested, %s found (%s), %s missing (%s)",nt+nf,nt,concat(t," "),nf,concat(f," "))
195 end
196 else
197 return nil
198 end
199end)
200
201logs.registerfinalactions(function()
202 logs.startfilelogging(report,"used modules")
203 for k, v in sortedhash(modstatus) do
204 report(v == 0 and "missing: %s" or "loaded : %s",basename(k))
205 end
206 logs.stopfilelogging()
207 if missing and logs.loggingerrors() then
208 logs.starterrorlogging(report,"missing modules")
209 for k, v in sortedhash(modstatus) do
210 if v == 0 then
211 report("%w%s",6,basename(k))
212 end
213 end
214 logs.stoperrorlogging()
215 end
216end)
217
218
219
220local lpegmatch = lpeg.match
221local splitter = lpeg.tsplitter(lpeg.S(". "),tonumber)
222
223function environment.comparedversion(one,two)
224 if not two or two == "" then
225 one, two = environment.version, one
226 elseif one == "" then
227 one = environment.version
228 end
229 one = lpegmatch(splitter,one)
230 two = lpegmatch(splitter,two)
231 one = (one[1] or 0) * 10000 + (one[2] or 0) * 100 + (one[3] or 0)
232 two = (two[1] or 0) * 10000 + (two[2] or 0) * 100 + (two[3] or 0)
233 if one < two then
234 return -1
235 elseif one > two then
236 return 1
237 else
238 return 0
239 end
240end
241
242environment.comparedversion = comparedversion
243
244
245function environment.useluamodule(list)
246 for filename in iterator(list) do
247 environment.loadluafile(filename)
248 end
249end
250
251implement {
252 name = "usemodules",
253 actions = environment.usemodules,
254 arguments = "2 strings",
255}
256
257implement {
258 name = "doifelseolderversion",
259 actions = function(one,two) commands.doifelse(comparedversion(one,two) >= 0) end,
260 arguments = "2 strings"
261}
262
263implement {
264 name = "useluamodule",
265 actions = environment.useluamodule,
266 arguments = "string"
267}
268
269implement {
270 name = "loadluamodule",
271 actions = function(name) dofile(resolvers.findctxfile(name)) end,
272 arguments = "string"
273}
274
275 |