mtx-tools.lua /size: 8257 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mtx-tools
'
]
=
{
2
version
=
1
.
002
,
3
comment
=
"
companion to mtxrun.lua
"
,
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
local
find
,
format
,
sub
,
rep
,
gsub
,
lower
=
string
.
find
,
string
.
format
,
string
.
sub
,
string
.
rep
,
string
.
gsub
,
string
.
lower
10 11
local
helpinfo
=
[[
12<?xml version="1.0"?> 13<application> 14 <metadata> 15 <entry name="name">mtx-tools</entry> 16 <entry name="detail">Some File Related Goodies</entry> 17 <entry name="version">1.01</entry> 18 </metadata> 19 <flags> 20 <category name="basic"> 21 <subcategory> 22 <flag name="disarmutfbomb"><short>remove utf bomb if present</short></flag> 23 <flag name="force"><short>remove indeed</short></flag> 24 </subcategory> 25 <subcategory> 26 <flag name="dirtoxml"><short>glob directory into xml</short></flag> 27 <flag name="pattern"><short>glob pattern (default: *)</short></flag> 28 <flag name="url"><short>url attribute (no processing)</short></flag> 29 <flag name="root"><short>the root of the globbed path (default: .)</short></flag> 30 <flag name="output"><short>output filename (console by default)</short></flag> 31 <flag name="recurse"><short>recurse into subdirecories</short></flag> 32 <flag name="stripname"><short>take pathpart of given pattern</short></flag> 33 <flag name="longname"><short>set name attributes to full path name</short></flag> 34 <flag name="downcase"><short>lowercase names</short></flag> 35 </subcategory> 36 <subcategory> 37 <flag name="showstring"><short>show unicode characters in given string</short></flag> 38 <flag name="showfile"><short>show unicode characters in given file</short></flag> 39 </subcategory> 40 <subcategory> 41 <flag name="pattern"><short>glob pattern (default: *)</short></flag> 42 <flag name="recurse"><short>recurse into subdirecories</short></flag> 43 <flag name="force"><short>downcase indeed</short></flag> 44 </subcategory> 45 </category> 46 </flags> 47</application> 48
]]
49 50
local
application
=
logs
.
application
{
51
name
=
"
mtx-tools
"
,
52
banner
=
"
Some File Related Goodies 1.01
"
,
53
helpinfo
=
helpinfo
,
54
}
55 56
local
report
=
application
.
report
57
local
writeln
=
(
logs
and
logs
.
writer
)
or
(
texio
and
texio
.
write_nl
)
or
print
58 59
scripts
=
scripts
or
{
}
60
scripts
.
tools
=
scripts
.
tools
or
{
}
61 62
local
bomb_1
,
bomb_2
=
"
^\254\255
"
,
"
^\239\187\191
"
63 64
function
scripts
.
tools
.
disarmutfbomb
(
)
65
local
force
,
done
=
environment
.
argument
(
"
force
"
)
,
false
66
local
files
=
environment
.
files
67
for
i
=
1
,
#
files
do
68
local
name
=
files
[
i
]
69
if
lfs
.
isfile
(
name
)
then
70
local
data
=
io
.
loaddata
(
name
)
71
if
not
data
then
72
-- just skip
73
elseif
find
(
data
,
bomb_1
)
then
74
report
(
"
file '%s' has a 2 character utf bomb
"
,
name
)
75
if
force
then
76
io
.
savedata
(
name
,
(
gsub
(
data
,
bomb_1
,
"
"
)
)
)
77
end
78
done
=
true
79
elseif
find
(
data
,
bomb_2
)
then
80
report
(
"
file '%s' has a 3 character utf bomb
"
,
name
)
81
if
force
then
82
io
.
savedata
(
name
,
(
gsub
(
data
,
bomb_2
,
"
"
)
)
)
83
end
84
done
=
true
85
else
86
-- report("file '%s' has no utf bomb",name)
87
end
88
end
89
end
90
if
done
and
not
force
then
91
report
(
"
use --force to do a real disarming
"
)
92
end
93
end
94 95
function
scripts
.
tools
.
downcase
(
)
96
local
pattern
=
environment
.
argument
(
'
pattern
'
)
or
"
*
"
97
local
recurse
=
environment
.
argument
(
'
recurse
'
)
98
local
force
=
environment
.
argument
(
'
force
'
)
99
local
n
=
0
100
if
recurse
and
not
find
(
pattern
,
"
^%*%*%/
"
)
then
101
pattern
=
"
**/*
"
.
.
pattern
102
end
103
dir
.
glob
(
pattern
,
function
(
name
)
104
local
basename
=
file
.
basename
(
name
)
105
if
lower
(
basename
)
~
=
basename
then
106
n
=
n
+
1
107
local
low
=
lower
(
name
)
108
if
n
=
=
1
then
109
report
(
)
110
end
111
report
(
"
%a renamed to %a
"
,
name
,
low
)
112
if
force
then
113
os
.
rename
(
name
,
low
)
114
end
115
end
116
end
)
117
if
n
>
0
then
118
report
(
)
119
if
force
then
120
report
(
"
%s files renamed
"
,
n
)
121
else
122
report
(
"
use --force to do a real rename (%s files involved)
"
,
n
)
123
end
124
else
125
report
(
"
nothing to do
"
)
126
end
127
end
128 129
function
scripts
.
tools
.
dirtoxml
(
)
130 131
local
join
,
removesuffix
,
suffixonly
,
date
=
file
.
join
,
file
.
removesuffix
,
file
.
suffixonly
,
os
.
date
132 133
local
xmlns
=
"
http://www.pragma-ade.com/rlg/xmldir.rng
"
134
local
timestamp
=
"
%Y-%m-%d %H:%M
"
135 136
local
pattern
=
environment
.
argument
(
'
pattern
'
)
or
"
.*
"
137
local
url
=
environment
.
argument
(
'
url
'
)
or
"
no-url
"
138
local
root
=
environment
.
argument
(
'
root
'
)
or
"
.
"
139
local
outputfile
=
environment
.
argument
(
'
output
'
)
140 141
local
recurse
=
environment
.
argument
(
'
recurse
'
)
or
false
142
local
stripname
=
environment
.
argument
(
'
stripname
'
)
143
local
longname
=
environment
.
argument
(
'
longname
'
)
144 145
local
function
flush
(
list
,
result
,
n
,
path
)
146
n
,
result
=
n
or
1
,
result
or
{
}
147
local
d
=
rep
(
"
"
,
n
)
148
for
name
,
attr
in
table
.
sortedhash
(
list
)
do
149
local
mode
=
attr
.
mode
150
if
mode
=
=
"
file
"
then
151
result
[
#
result
+
1
]
=
format
(
"
%s<file name='%s'>
"
,
d
,
(
longname
and
path
and
join
(
path
,
name
)
)
or
name
)
152
result
[
#
result
+
1
]
=
format
(
"
%s <base>%s</base>
"
,
d
,
removesuffix
(
name
)
)
153
result
[
#
result
+
1
]
=
format
(
"
%s <type>%s</type>
"
,
d
,
suffixonly
(
name
)
)
154
result
[
#
result
+
1
]
=
format
(
"
%s <size>%s</size>
"
,
d
,
attr
.
size
)
155
result
[
#
result
+
1
]
=
format
(
"
%s <permissions>%s</permissions>
"
,
d
,
sub
(
attr
.
permissions
,
7
,
9
)
)
156
result
[
#
result
+
1
]
=
format
(
"
%s <date>%s</date>
"
,
d
,
date
(
timestamp
,
attr
.
modification
)
)
157
result
[
#
result
+
1
]
=
format
(
"
%s</file>
"
,
d
)
158
elseif
mode
=
=
"
directory
"
then
159
result
[
#
result
+
1
]
=
format
(
"
%s<directory name='%s'>
"
,
d
,
name
)
160
flush
(
attr
.
list
,
result
,
n
+
1
,
(
path
and
join
(
path
,
name
)
)
or
name
)
161
result
[
#
result
+
1
]
=
format
(
"
%s</directory>
"
,
d
)
162
end
163
end
164
end
165 166
if
not
pattern
or
pattern
=
=
"
"
then
167
report
(
'
provide --pattern=
'
)
168
return
169
end
170 171
if
stripname
then
172
pattern
=
file
.
dirname
(
pattern
)
173
end
174 175
local
luapattern
=
string
.
topattern
(
pattern
,
true
)
176 177
lfs
.
chdir
(
root
)
178 179
local
list
=
dir
.
collectpattern
(
root
,
luapattern
,
recurse
)
180 181
if
list
[
outputfile
]
then
182
list
[
outputfile
]
=
nil
183
end
184 185
local
result
=
{
"
<?xml version='1.0'?>
"
}
186
result
[
#
result
+
1
]
=
format
(
"
<files url=%q root=%q pattern=%q luapattern=%q xmlns='%s' timestamp='%s'>
"
,
url
,
root
,
pattern
,
luapattern
,
xmlns
,
date
(
timestamp
)
)
187
flush
(
list
,
result
)
188
result
[
#
result
+
1
]
=
"
</files>
"
189 190
result
=
table
.
concat
(
result
,
"
\n
"
)
191 192
if
not
outputfile
or
outputfile
=
=
"
"
then
193
writeln
(
result
)
194
else
195
io
.
savedata
(
outputfile
,
result
)
196
end
197 198
end
199 200
local
function
showstring
(
s
)
201
if
not
characters
or
not
characters
.
data
then
202
require
(
"
char-def
"
)
203
end
204
local
d
=
characters
.
data
205
local
f
=
string
.
formatters
[
"
%U %s %-30s %c
"
]
206
for
c
in
string
.
utfvalues
(
s
)
do
207
local
cs
=
d
[
c
]
208
print
(
f
(
c
,
cs
.
category
or
"
"
,
cs
.
description
or
"
"
,
c
)
)
209
end
210
end
211 212
function
scripts
.
tools
.
showstring
(
)
213
local
files
=
environment
.
files
214
for
i
=
1
,
#
files
do
215
showstring
(
files
[
i
]
)
216
end
217
end
218 219
function
scripts
.
tools
.
showfile
(
)
220
local
files
=
environment
.
files
221
for
i
=
1
,
#
files
do
222
showstring
(
io
.
loaddata
(
files
[
i
]
)
or
"
"
)
223
end
224
end
225 226
if
environment
.
argument
(
"
disarmutfbomb
"
)
then
227
scripts
.
tools
.
disarmutfbomb
(
)
228
elseif
environment
.
argument
(
"
dirtoxml
"
)
then
229
scripts
.
tools
.
dirtoxml
(
)
230
elseif
environment
.
argument
(
"
downcase
"
)
then
231
scripts
.
tools
.
downcase
(
)
232
elseif
environment
.
argument
(
"
exporthelp
"
)
then
233
application
.
export
(
environment
.
argument
(
"
exporthelp
"
)
,
environment
.
files
[
1
]
)
234
elseif
environment
.
argument
(
"
showstring
"
)
then
235
scripts
.
tools
.
showstring
(
)
236
elseif
environment
.
argument
(
"
showfile
"
)
then
237
scripts
.
tools
.
showfile
(
)
238
else
239
application
.
help
(
)
240
end
241