1if not modules then modules = { } end modules ['file-res'] = {
2 version = 1.001,
3 comment = "companion to supp-fil.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local tonumber = tonumber
10local format, find = string.format, string.find
11local isfile = lfs.isfile
12local is_qualified_path = file.is_qualified_path
13local hasscheme, urlescape = url.hasscheme, url.escape
14
15local trace_files = false trackers.register("resolvers.readfile", function(v) trace_files = v end)
16local trace_details = false trackers.register("resolvers.readfile.details", function(v) trace_details = v end)
17local report_files = logs.reporter("files","readfile")
18
19resolvers.maxreadlevel = 2
20
21directives.register("resolvers.maxreadlevel", function(v)
22
23 resolvers.maxreadlevel = v == false and 0 or tonumber(v) or 2
24end)
25
26local finders, loaders, openers = resolvers.finders, resolvers.loaders, resolvers.openers
27
28local found = { }
29
30local function readfilename(specification,backtrack,treetoo)
31 if trace_details then
32 report_files(table.serialize(specification,"specification"))
33 end
34 local name = specification.filename
35 local fnd = name and found[name]
36 if not fnd then
37 local names
38 local suffix = file.suffix(name)
39 if suffix ~= "" then
40 names = { name }
41 else
42 local defaultsuffixes = resolvers.defaultsuffixes
43 names = { }
44 for i=1,#defaultsuffixes do
45 names[i] = name .. "." .. defaultsuffixes[i]
46 end
47 if trace_files then
48 report_files("locating: %s, using default suffixes: %a",name,defaultsuffixes)
49 end
50 end
51 for i=1,#names do
52 local fname = names[i]
53 if isfile(fname) then
54 if trace_files then
55 report_files("found local: %s",name)
56 end
57 fnd = fname
58 break
59 end
60 end
61 if not fnd and backtrack then
62 local path = environment.arguments.runpath and environment.arguments.path or ""
63 for i=1,#names do
64 local fname = names[i]
65 for i=1,backtrack,1 do
66 fname = "../" .. fname
67 local pname = path and (path ~= "") and (path .. "/" .. fname) or fname
68 if isfile(pname) then
69 if trace_files then
70 report_files("found by backtracking: %s",pname)
71 end
72 fnd = pname
73 break
74 elseif trace_files then
75 report_files("not found by backtracking: %s",pname)
76 end
77 end
78 if fnd then
79 break
80 end
81 end
82 end
83 if not fnd then
84 local paths = resolvers.getextrapaths()
85 if paths then
86 for i=1,#paths do
87 for i=1,#names do
88 local fname = paths[i] .. "/" .. names[i]
89 if isfile(fname) then
90 if trace_files then
91 report_files("found on extra path: %s",fname)
92 end
93 fnd = fname
94 break
95 end
96 end
97 if fnd then
98 break
99 end
100 end
101 end
102 end
103 if not fnd and treetoo then
104 fnd = resolvers.findtexfile(name) or ""
105 if trace_files then
106 if fnd ~= "" then
107 report_files("found by tree lookup: %s",fnd)
108 else
109 report_files("not found by tree lookup: %s",name)
110 end
111 end
112 end
113 found[name] = fnd
114 elseif trace_files then
115 if fnd ~= "" then
116 report_files("already found: %s",fnd)
117 else
118 report_files("already not found: %s",name)
119 end
120 end
121 return fnd or ""
122end
123
124
125
126function resolvers.finders.original(specification)
127 return specification.path
128end
129
130function finders.job(specification) return readfilename(specification,false, false) end
131function finders.loc(specification) return readfilename(specification,resolvers.maxreadlevel,false) end
132function finders.sys(specification) return readfilename(specification,false, true ) end
133function finders.fix(specification) return readfilename(specification,resolvers.maxreadlevel,false) end
134function finders.set(specification) return readfilename(specification,false, false) end
135function finders.any(specification) return readfilename(specification,resolvers.maxreadlevel,true ) end
136
137openers.job = openers.file loaders.job = loaders.file
138openers.loc = openers.file loaders.loc = loaders.file
139openers.sys = openers.file loaders.sys = loaders.file
140openers.fix = openers.file loaders.fix = loaders.file
141openers.set = openers.file loaders.set = loaders.file
142openers.any = openers.file loaders.any = loaders.file
143
144local function getreadfilename(scheme,path,name)
145 local fullname
146 if hasscheme(name) or is_qualified_path(name) then
147 fullname = name
148 else
149 if not find(name,"%",1,true) then
150 name = urlescape(name)
151 end
152 fullname = ((path == "") and format("%s:///%s",scheme,name)) or format("%s:///%s/%s",scheme,path,name)
153 end
154 return resolvers.findtexfile(fullname) or ""
155end
156
157resolvers.getreadfilename = getreadfilename
158
159
160
161local implement = interfaces.implement
162
163implement {
164 name = "getreadfilename",
165 actions = { getreadfilename, context },
166 arguments = "3 strings",
167}
168
169implement {
170 name = "locfilename",
171 actions = { getreadfilename, context },
172 arguments = { "'loc'","'.'", "string" },
173}
174
175implement {
176 name = "doifelselocfile",
177 actions = { getreadfilename, isfile, commands.doifelse },
178 arguments = { "'loc'","'.'", "string" },
179}
180 |