if not modules then modules = { } end modules ['mtx-tools'] = {
version = 1.002,
comment = "companion to mtxrun.lua",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local find, format, sub, rep, gsub, lower = string.find, string.format, string.sub, string.rep, string.gsub, string.lower
local helpinfo = [[
mtx-tools
Some File Related Goodies
1.01
remove utf bomb if present
remove indeed
glob directory into xml
glob pattern (default: *)
url attribute (no processing)
the root of the globbed path (default: .)
output filename (console by default)
recurse into subdirecories
take pathpart of given pattern
set name attributes to full path name
lowercase names
show unicode characters in given string
show unicode characters in given file
glob pattern (default: *)
recurse into subdirecories
downcase indeed
]]
local application = logs.application {
name = "mtx-tools",
banner = "Some File Related Goodies 1.01",
helpinfo = helpinfo,
}
local report = application.report
local writeln = (logs and logs.writer) or (texio and texio.write_nl) or print
scripts = scripts or { }
scripts.tools = scripts.tools or { }
local bomb_1, bomb_2 = "^\254\255", "^\239\187\191"
function scripts.tools.disarmutfbomb()
local force, done = environment.argument("force"), false
local files = environment.files
for i=1,#files do
local name = files[i]
if lfs.isfile(name) then
local data = io.loaddata(name)
if not data then
-- just skip
elseif find(data,bomb_1) then
report("file '%s' has a 2 character utf bomb",name)
if force then
io.savedata(name,(gsub(data,bomb_1,"")))
end
done = true
elseif find(data,bomb_2) then
report("file '%s' has a 3 character utf bomb",name)
if force then
io.savedata(name,(gsub(data,bomb_2,"")))
end
done = true
else
-- report("file '%s' has no utf bomb",name)
end
end
end
if done and not force then
report("use --force to do a real disarming")
end
end
function scripts.tools.downcase()
local pattern = environment.argument('pattern') or "*"
local recurse = environment.argument('recurse')
local force = environment.argument('force')
local n = 0
if recurse and not find(pattern,"^%*%*%/") then
pattern = "**/*" .. pattern
end
dir.glob(pattern,function(name)
local basename = file.basename(name)
if lower(basename) ~= basename then
n = n + 1
local low = lower(name)
if n == 1 then
report()
end
report("%a renamed to %a",name,low)
if force then
os.rename(name,low)
end
end
end)
if n > 0 then
report()
if force then
report("%s files renamed",n)
else
report("use --force to do a real rename (%s files involved)",n)
end
else
report("nothing to do")
end
end
function scripts.tools.dirtoxml()
local join, removesuffix, suffixonly, date = file.join, file.removesuffix, file.suffixonly, os.date
local xmlns = "http://www.pragma-ade.com/rlg/xmldir.rng"
local timestamp = "%Y-%m-%d %H:%M"
local pattern = environment.argument('pattern') or ".*"
local url = environment.argument('url') or "no-url"
local root = environment.argument('root') or "."
local outputfile = environment.argument('output')
local recurse = environment.argument('recurse') or false
local stripname = environment.argument('stripname')
local longname = environment.argument('longname')
local function flush(list,result,n,path)
n, result = n or 1, result or { }
local d = rep(" ",n)
for name, attr in table.sortedhash(list) do
local mode = attr.mode
if mode == "file" then
result[#result+1] = format("%s",d,(longname and path and join(path,name)) or name)
result[#result+1] = format("%s %s",d,removesuffix(name))
result[#result+1] = format("%s %s",d,suffixonly(name))
result[#result+1] = format("%s %s",d,attr.size)
result[#result+1] = format("%s %s",d,sub(attr.permissions,7,9))
result[#result+1] = format("%s %s",d,date(timestamp,attr.modification))
result[#result+1] = format("%s",d)
elseif mode == "directory" then
result[#result+1] = format("%s",d,name)
flush(attr.list,result,n+1,(path and join(path,name)) or name)
result[#result+1] = format("%s",d)
end
end
end
if not pattern or pattern == "" then
report('provide --pattern=')
return
end
if stripname then
pattern = file.dirname(pattern)
end
local luapattern = string.topattern(pattern,true)
lfs.chdir(root)
local list = dir.collectpattern(root,luapattern,recurse)
if list[outputfile] then
list[outputfile] = nil
end
local result = { "" }
result[#result+1] = format("",url,root,pattern,luapattern,xmlns,date(timestamp))
flush(list,result)
result[#result+1] = ""
result = table.concat(result,"\n")
if not outputfile or outputfile == "" then
writeln(result)
else
io.savedata(outputfile,result)
end
end
local function showstring(s)
if not characters or not characters.data then
require("char-def")
end
local d = characters.data
local f = string.formatters["%U %s %-30s %c"]
for c in string.utfvalues(s) do
local cs = d[c]
print(f(c,cs.category or "",cs.description or "",c))
end
end
function scripts.tools.showstring()
local files = environment.files
for i=1,#files do
showstring(files[i])
end
end
function scripts.tools.showfile()
local files = environment.files
for i=1,#files do
showstring(io.loaddata(files[i]) or "")
end
end
if environment.argument("disarmutfbomb") then
scripts.tools.disarmutfbomb()
elseif environment.argument("dirtoxml") then
scripts.tools.dirtoxml()
elseif environment.argument("downcase") then
scripts.tools.downcase()
elseif environment.argument("exporthelp") then
application.export(environment.argument("exporthelp"),environment.files[1])
elseif environment.argument("showstring") then
scripts.tools.showstring()
elseif environment.argument("showfile") then
scripts.tools.showfile()
else
application.help()
end