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