summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/l-dir.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/l-dir.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/l-dir.lua152
1 files changed, 104 insertions, 48 deletions
diff --git a/Master/texmf-dist/tex/context/base/l-dir.lua b/Master/texmf-dist/tex/context/base/l-dir.lua
index 5a726303f0c..2643f538b94 100644
--- a/Master/texmf-dist/tex/context/base/l-dir.lua
+++ b/Master/texmf-dist/tex/context/base/l-dir.lua
@@ -1,16 +1,25 @@
if not modules then modules = { } end modules ['l-dir'] = {
version = 1.001,
- comment = "companion to luat-lib.tex",
+ comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
+-- dir.expand_name will be merged with cleanpath and collapsepath
+
local type = type
-local find, gmatch = string.find, string.gmatch
+local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub
+local lpegmatch = lpeg.match
dir = dir or { }
+-- handy
+
+function dir.current()
+ return (gsub(lfs.currentdir(),"\\","/"))
+end
+
-- optimizing for no string.find (*) does not save time
local attributes = lfs.attributes
@@ -41,6 +50,35 @@ end
dir.glob_pattern = glob_pattern
+local function collect_pattern(path,patt,recurse,result)
+ local ok, scanner
+ result = result or { }
+ if path == "/" then
+ ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe
+ else
+ ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
+ end
+ if ok and type(scanner) == "function" then
+ if not find(path,"/$") then path = path .. '/' end
+ for name in scanner do
+ local full = path .. name
+ local attr = attributes(full)
+ local mode = attr.mode
+ if mode == 'file' then
+ if find(full,patt) then
+ result[name] = attr
+ end
+ elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then
+ attr.list = collect_pattern(full,patt,recurse)
+ result[name] = attr
+ end
+ end
+ end
+ return result
+end
+
+dir.collect_pattern = collect_pattern
+
local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
local pattern = Ct {
@@ -60,29 +98,48 @@ local filter = Cs ( (
)^0 )
local function glob(str,t)
- if type(str) == "table" then
- local t = t or { }
- for s=1,#str do
- glob(str[s],t)
+ if type(t) == "function" then
+ if type(str) == "table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif lfs.isfile(str) then
+ t(str)
+ else
+ local split = lpegmatch(pattern,str)
+ if split then
+ local root, path, base = split[1], split[2], split[3]
+ local recurse = find(base,"%*%*")
+ local start = root .. path
+ local result = lpegmatch(filter,start .. base)
+ glob_pattern(start,result,recurse,t)
+ end
end
- return t
- elseif lfs.isfile(str) then
- local t = t or { }
- t[#t+1] = str
- return t
else
- local split = pattern:match(str)
- if split then
+ if type(str) == "table" then
+ local t = t or { }
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif lfs.isfile(str) then
local t = t or { }
- local action = action or function(name) t[#t+1] = name end
- local root, path, base = split[1], split[2], split[3]
- local recurse = find(base,"%*%*")
- local start = root .. path
- local result = filter:match(start .. base)
- glob_pattern(start,result,recurse,action)
+ t[#t+1] = str
return t
else
- return { }
+ local split = lpegmatch(pattern,str)
+ if split then
+ local t = t or { }
+ local action = action or function(name) t[#t+1] = name end
+ local root, path, base = split[1], split[2], split[3]
+ local recurse = find(base,"%*%*")
+ local start = root .. path
+ local result = lpegmatch(filter,start .. base)
+ glob_pattern(start,result,recurse,action)
+ return t
+ else
+ return { }
+ end
end
end
end
@@ -144,11 +201,12 @@ end
local make_indeed = true -- false
-if string.find(os.getenv("PATH"),";") then
+if string.find(os.getenv("PATH"),";") then -- os.type == "windows"
function dir.mkdirs(...)
- local str, pth = "", ""
- for _, s in ipairs({...}) do
+ local str, pth, t = "", "", { ... }
+ for i=1,#t do
+ local s = t[i]
if s ~= "" then
if str ~= "" then
str = str .. "/" .. s
@@ -159,13 +217,13 @@ if string.find(os.getenv("PATH"),";") then
end
local first, middle, last
local drive = false
- first, middle, last = str:match("^(//)(//*)(.*)$")
+ first, middle, last = match(str,"^(//)(//*)(.*)$")
if first then
-- empty network path == local path
else
- first, last = str:match("^(//)/*(.-)$")
+ first, last = match(str,"^(//)/*(.-)$")
if first then
- middle, last = str:match("([^/]+)/+(.-)$")
+ middle, last = match(str,"([^/]+)/+(.-)$")
if middle then
pth = "//" .. middle
else
@@ -173,11 +231,11 @@ if string.find(os.getenv("PATH"),";") then
last = ""
end
else
- first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$")
+ first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$")
if first then
pth, drive = first .. middle, true
else
- middle, last = str:match("^(/*)(.-)$")
+ middle, last = match(str,"^(/*)(.-)$")
if not middle then
last = str
end
@@ -211,34 +269,31 @@ if string.find(os.getenv("PATH"),";") then
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
- local first, nothing, last = str:match("^(//)(//*)(.*)$")
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
+ local first, nothing, last = match(str,"^(//)(//*)(.*)$")
if first then
- first = lfs.currentdir() .. "/"
- first = first:gsub("\\","/")
+ first = dir.current() .. "/"
end
if not first then
- first, last = str:match("^(//)/*(.*)$")
+ first, last = match(str,"^(//)/*(.*)$")
end
if not first then
- first, last = str:match("^([a-zA-Z]:)(.*)$")
+ first, last = match(str,"^([a-zA-Z]:)(.*)$")
if first and not find(last,"^/") then
local d = lfs.currentdir()
if lfs.chdir(first) then
- first = lfs.currentdir()
- first = first:gsub("\\","/")
+ first = dir.current()
end
lfs.chdir(d)
end
end
if not first then
- first, last = lfs.currentdir(), str
- first = first:gsub("\\","/")
+ first, last = dir.current(), str
end
- last = last:gsub("//","/")
- last = last:gsub("/%./","/")
- last = last:gsub("^/*","")
- first = first:gsub("/*$","")
+ last = gsub(last,"//","/")
+ last = gsub(last,"/%./","/")
+ last = gsub(last,"^/*","")
+ first = gsub(first,"/*$","")
if last == "" then
return first
else
@@ -249,8 +304,9 @@ if string.find(os.getenv("PATH"),";") then
else
function dir.mkdirs(...)
- local str, pth = "", ""
- for _, s in ipairs({...}) do
+ local str, pth, t = "", "", { ... }
+ for i=1,#t do
+ local s = t[i]
if s ~= "" then
if str ~= "" then
str = str .. "/" .. s
@@ -259,7 +315,7 @@ else
end
end
end
- str = str:gsub("/+","/")
+ str = gsub(str,"/+","/")
if find(str,"^/") then
pth = "/"
for s in gmatch(str,"[^/]+") do
@@ -293,12 +349,12 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
- str = str:gsub("//","/")
- str = str:gsub("/%./","/")
+ str = gsub(str,"//","/")
+ str = gsub(str,"/%./","/")
return str
end