diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/data-pre.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/data-pre.lua | 234 |
1 files changed, 65 insertions, 169 deletions
diff --git a/Master/texmf-dist/tex/context/base/data-pre.lua b/Master/texmf-dist/tex/context/base/data-pre.lua index f2f5bddc44c..1c5016f8644 100644 --- a/Master/texmf-dist/tex/context/base/data-pre.lua +++ b/Master/texmf-dist/tex/context/base/data-pre.lua @@ -6,63 +6,61 @@ if not modules then modules = { } end modules ['data-pre'] = { license = "see context related readme files" } --- It could be interesting to hook the resolver in the file --- opener so that unresolved prefixes travel around and we --- get more abstraction. +local resolvers = resolvers +local prefixes = resolvers.prefixes --- As we use this beforehand we will move this up in the chain --- of loading. +local cleanpath = resolvers.cleanpath +local findgivenfile = resolvers.findgivenfile +local expansion = resolvers.expansion +local getenv = resolvers.getenv -- we can probably also use resolvers.expansion ---~ print(resolvers.resolve("abc env:tmp file:cont-en.tex path:cont-en.tex full:cont-en.tex rel:zapf/one/p-chars.tex")) +local basename = file.basename +local dirname = file.dirname +local joinpath = file.join -local resolvers = resolvers -local prefixes = utilities.storage.allocate() -resolvers.prefixes = prefixes - -local cleanpath, findgivenfile, expansion = resolvers.cleanpath, resolvers.findgivenfile, resolvers.expansion -local getenv = resolvers.getenv -- we can probably also use resolvers.expansion -local P, S, R, C, Cs, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.match -local joinpath, basename, dirname = file.join, file.basename, file.dirname -local getmetatable, rawset, type = getmetatable, rawset, type - --- getenv = function(...) return resolvers.getenv(...) end -- needs checking (definitions changes later on) +local isfile = lfs.isfile prefixes.environment = function(str) return cleanpath(expansion(str)) end -prefixes.relative = function(str,n) -- lfs.isfile - if io.exists(str) then - -- nothing - elseif io.exists("./" .. str) then - str = "./" .. str - else - local p = "../" - for i=1,n or 2 do - if io.exists(p .. str) then - str = p .. str - break - else - p = p .. "../" +local function relative(str,n) + if not isfile(str) then + local pstr = "./" .. str + if isfile(pstr) then + str = pstr + else + local p = "../" + for i=1,n or 2 do + local pstr = p .. str + if isfile(pstr) then + str = pstr + break + else + p = p .. "../" + end end end end return cleanpath(str) end +local function locate(str) + local fullname = findgivenfile(str) or "" + return cleanpath(fullname ~= "" and fullname or str) +end + +prefixes.relative = relative +prefixes.locate = locate + prefixes.auto = function(str) - local fullname = prefixes.relative(str) - if not lfs.isfile(fullname) then - fullname = prefixes.locate(str) + local fullname = relative(str) + if not isfile(fullname) then + fullname = locate(str) end return fullname end -prefixes.locate = function(str) - local fullname = findgivenfile(str) or "" - return cleanpath((fullname ~= "" and fullname) or str) -end - prefixes.filename = function(str) local fullname = findgivenfile(str) or "" return cleanpath(basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here @@ -89,25 +87,6 @@ prefixes.home = function(str) return cleanpath(joinpath(getenv('HOME'),str)) end -local function toppath() - local inputstack = resolvers.inputstack -- dependency, actually the code should move but it's - if not inputstack then -- more convenient to keep it here - return "." - end - local pathname = dirname(inputstack[#inputstack] or "") - if pathname == "" then - return "." - else - return pathname - end -end - -resolvers.toppath = toppath - -prefixes.toppath = function(str) - return cleanpath(joinpath(toppath(),str)) -end - prefixes.env = prefixes.environment prefixes.rel = prefixes.relative prefixes.loc = prefixes.locate @@ -116,131 +95,48 @@ prefixes.full = prefixes.locate prefixes.file = prefixes.filename prefixes.path = prefixes.pathname -function resolvers.allprefixes(separator) - local all = table.sortedkeys(prefixes) - if separator then - for i=1,#all do - all[i] = all[i] .. ":" - end - end - return all -end +-- This one assumes that inputstack is set (used in the tex loader). It is a momentary resolve +-- as the top of the input stack changes. -local function _resolve_(method,target) - local action = prefixes[method] - if action then - return action(target) - else - return method .. ":" .. target +local function toppath() + local inputstack = resolvers.inputstack -- dependency, actually the code should move but it's + if not inputstack then -- more convenient to keep it here + return "." end -end - -local resolved, abstract = { }, { } - -function resolvers.resetresolve(str) - resolved, abstract = { }, { } -end - --- todo: use an lpeg (see data-lua for !! / stripper) - --- local function resolve(str) -- use schemes, this one is then for the commandline only --- if type(str) == "table" then --- local t = { } --- for i=1,#str do --- t[i] = resolve(str[i]) --- end --- return t --- else --- local res = resolved[str] --- if not res then --- res = gsub(str,"([a-z][a-z]+):([^ \"\';,]*)",_resolve_) -- home:xx;selfautoparent:xx; etc (comma added) --- resolved[str] = res --- abstract[res] = str --- end --- return res --- end --- end - --- home:xx;selfautoparent:xx; - -local pattern = Cs((C(R("az")^2) * P(":") * C((1-S(" \"\';,"))^1) / _resolve_ + P(1))^0) - -local prefix = C(R("az")^2) * P(":") -local target = C((1-S(" \"\';,"))^1) -local notarget = (#S(";,") + P(-1)) * Cc("") - -local pattern = Cs(((prefix * (target + notarget)) / _resolve_ + P(1))^0) - -local function resolve(str) -- use schemes, this one is then for the commandline only - if type(str) == "table" then - local t = { } - for i=1,#str do - t[i] = resolve(str[i]) - end - return t + local pathname = dirname(inputstack[#inputstack] or "") + if pathname == "" then + return "." else - local res = resolved[str] - if not res then - res = lpegmatch(pattern,str) - resolved[str] = res - abstract[res] = str - end - return res + return pathname end end -local function unresolve(str) - return abstract[str] or str -end - -resolvers.resolve = resolve -resolvers.unresolve = unresolve +-- The next variant is similar but bound to explicitly registered paths. Practice should +-- show if that gives the same results as the previous one. It is meant for a project +-- stucture. -if type(os.uname) == "function" then - - for k, v in next, os.uname() do - if not prefixes[k] then - prefixes[k] = function() return v end - end +local function jobpath() + local path = resolvers.stackpath() + if not path or path == "" then + return "." + else + return path end - end -if os.type == "unix" then - - -- We need to distringuish between a prefix and something else : so we - -- have a special repath variant for linux. Also, when a new prefix is - -- defined, we need to remake the matcher. - - local pattern - - local function makepattern(t,k,v) - if t then - rawset(t,k,v) - end - local colon = P(":") - for k, v in table.sortedpairs(prefixes) do - if p then - p = P(k) + p - else - p = P(k) - end - end - pattern = Cs((p * colon + colon/";" + P(1))^0) - end +resolvers.toppath = toppath +resolvers.jobpath = jobpath - makepattern() +-- This hook sit into the resolver: - getmetatable(prefixes).__newindex = makepattern +prefixes.toppath = function(str) return cleanpath(joinpath(toppath(),str)) end -- str can be nil or empty +prefixes.jobpath = function(str) return cleanpath(joinpath(jobpath(),str)) end -- str can be nil or empty - function resolvers.repath(str) - return lpegmatch(pattern,str) - end +resolvers.setdynamic("toppath") +resolvers.setdynamic("jobpath") -else -- already the default: +-- for a while (obsolete): - function resolvers.repath(str) - return str - end +prefixes.jobfile = prefixes.jobpath -end +resolvers.setdynamic("jobfile") |