mtx-ctan.lua /size: 9467 b    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mtx-ctan
'
]
=
{
2
version
=
1
.
00
,
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
-- This is just an experiment. Some day I want to be able to install fonts this way
10
-- but maybe fetching tex live packages is also an option (I need to check if there
11
-- is an api for that ... in wintertime). Normally fonts come from the web but I had
12
-- to fetch newcm from ctan, so ...
13
--
14
-- mtxrun --script ctan --packages --pattern=computermodern
15 16
-- http://www.ctan.org/json/2.0/packages
17
-- http://www.ctan.org/json/2.0/pkg/name
18
-- http://www.ctan.org/json/2.0/topics : key details
19
-- http://www.ctan.org/json/2.0/topic/name : key details
20
-- http://www.ctan.org/json/2.0/topic/name?ref=true : key details packages
21 22
local
lower
,
find
,
gsub
=
string
.
lower
,
string
.
find
,
string
.
gsub
23
local
write_nl
=
(
logs
and
logs
.
writer
)
or
(
texio
and
texio
.
write_nl
)
or
print
24
local
xmlconvert
,
xmltext
,
xmlattr
,
xmlcollected
=
xml
.
convert
,
xml
.
text
,
xml
.
attribute
,
xml
.
collected
25 26
local
helpinfo
=
[[
27<?xml version="1.0"?> 28<application> 29 <metadata> 30 <entry name="name">mtx-ctan</entry> 31 <entry name="detail">Dealing with CTAN</entry> 32 <entry name="version">1.00</entry> 33 </metadata> 34 <flags> 35 <category name="basic"> 36 <subcategory> 37 <flag name="packages"><short>list available packages</short></flag> 38 <flag name="topics"><short>list available topics</short></flag> 39 <flag name="detail"><short>show details about package</short></flag> 40 <flag name="pattern" value="string"><short>use this pattern, otherwise first argument</short></flag> 41 </subcategory> 42 </category> 43 </flags> 44</application> 45
]]
46 47
local
application
=
logs
.
application
{
48
name
=
"
mtx-ctan
"
,
49
banner
=
"
Dealing with CTAN
"
,
50
helpinfo
=
helpinfo
,
51
}
52 53
local
report
=
application
.
report
54 55
scripts
=
scripts
or
{
}
56
scripts
.
ctan
=
scripts
.
ctan
or
{
}
57 58
local
okay
,
json
=
pcall
(
require
,
"
util-jsn
"
)
59
local
okay
,
curl
=
pcall
(
require
,
"
libs-imp-curl
"
)
60
pcall
(
require
,
"
char-ini
"
)
61 62
local
jsontolua
=
json
and
json
.
tolua
63
local
shaped
=
characters
and
characters
.
shaped
or
lower
64 65
-- local ignore = {
66
-- "latex",
67
-- "plain",
68
-- "xetex",
69
-- }
70 71
-- what is the url to fetch a zip
72 73
-- We cannot use the socket library because we don't compile that massive amount of
74
-- ssl code into lua(meta)tex. aybe some day one fo these small embedded libraries
75
-- makes sense but there are so many changes in all that security stuff that it
76
-- defeats long term stability of the ecosystem anyway ... just like some of my old
77
-- devices suddenly are no longer accessible with modern browsers I expect it to
78
-- happen everywhere. I'm not sure why ctan can't support http because I see no
79
-- added value in the 's' here.
80 81
local
ctanurl
=
"
https://www.ctan.org/
"
.
.
(
json
and
"
json
"
or
"
xml
"
)
.
.
"
/2.0/
"
82 83
local
fetched
=
curl
and
84 85
function
(
str
)
86
local
data
,
message
=
curl
.
fetch
{
87
url
=
ctanurl
.
.
str
,
88
sslverifyhost
=
false
,
89
sslverifypeer
=
false
,
90
}
91
if
not
data
then
92
report
(
"
some error: %s
"
,
message
)
93
end
94
return
data
95
end
96 97
or
98 99
function
(
str
)
100
-- So, no redirect to http, which means that we cannot use the built in socket
101
-- library. What if the client is happy with http?
102
local
data
=
os
.
resultof
(
"
curl -sS
"
.
.
ctanurl
.
.
str
)
103
-- print(data)
104
return
data
105
end
106 107
-- for j=1,#ignore do
108
-- if find(str,ignore[j]) then
109
-- return false
110
-- end
111
-- end
112 113
local
function
strfound
(
pattern
,
str
)
114
if
not
pattern
then
115
return
true
116
else
117
local
str
=
lower
(
shaped
(
str
)
)
118
if
find
(
str
,
pattern
)
then
119
return
true
120
else
121
str
=
gsub
(
str
,
"
[^a-zA-Z0-9]
"
,
"
"
)
122
if
find
(
str
,
pattern
)
then
123
return
true
124
else
125
return
false
126
end
127
end
128
end
129
end
130 131
local
function
showresult
(
found
)
132
if
#
found
>
2
then
133
utilities
.
formatters
.
formatcolumns
(
found
)
134
report
(
"
"
)
135
for
k
=
1
,
#
found
do
136
report
(
found
[
k
]
)
137
end
138
report
(
"
"
)
139
end
140
end
141 142
local
function
checkedpattern
(
pattern
)
143
if
pattern
then
144
return
lower
(
shaped
(
pattern
)
)
145
end
146
end
147 148
local
validdata
=
json
and
149 150
function
(
data
)
151
if
data
then
152
data
=
jsontolua
(
data
)
153
if
type
(
data
)
=
=
"
table
"
then
154
return
data
155
else
156
report
(
"
unable to handle this json data
"
)
157
end
158
else
159
report
(
"
unable to fetch packages
"
)
160
end
161
end
162 163
or
164 165
function
(
data
)
166
if
data
then
167
data
=
xmlconvert
(
data
)
168
if
data
.
error
then
169
report
(
"
unable to handle this json data
"
)
170
else
171
return
data
172
end
173
else
174
report
(
"
unable to fetch packages
"
)
175
end
176
end
177 178
scripts
.
ctan
.
details
=
json
and
179 180
function
(
name
)
181
if
name
then
182
local
data
=
validdata
(
fetched
(
"
pkg/
"
.
.
name
)
)
183
if
data
then
184
report
(
"
"
)
185
-- report("key : %s",data.key or "-")
186
report
(
"
name : %s
"
,
data
.
name
or
"
-
"
)
187
report
(
"
caption : %s
"
,
data
.
caption
or
"
-
"
)
188
report
(
"
path : %s
"
,
data
.
ctan
.
path
or
"
-
"
)
189
report
(
"
"
)
190
end
191
end
192
end
193 194
or
195 196
function
(
name
)
197
if
name
then
198
local
data
=
validdata
(
fetched
(
"
pkg/
"
.
.
name
)
)
199
report
(
"
"
)
200
-- report("key : %s",data.key or "-")
201
report
(
"
name : %s
"
,
xmltext
(
data
,
"
/entry/name
"
)
)
202
report
(
"
caption : %s
"
,
xmltext
(
data
,
"
/entry/caption
"
)
)
203
report
(
"
path : %s
"
,
xmlattr
(
data
,
"
/entry/ctan
"
,
"
path
"
)
)
204
report
(
"
"
)
205
end
206
end
207 208
scripts
.
ctan
.
packages
=
json
and
209 210
function
(
pattern
)
211
local
data
=
validdata
(
fetched
(
"
packages
"
)
)
212
if
data
then
213
local
found
=
{
214
{
"
key
"
,
"
name
"
,
"
caption
"
}
,
215
{
"
"
,
"
"
,
"
"
}
,
216
}
217
pattern
=
checkedpattern
(
pattern
)
218
for
i
=
1
,
#
data
do
219
local
entry
=
data
[
i
]
220
if
strfound
(
pattern
,
entry
.
caption
)
then
221
found
[
#
found
+
1
]
=
{
entry
.
key
,
entry
.
name
,
entry
.
caption
}
222
end
223
end
224
showresult
(
found
)
225
end
226
end
227 228
or
229 230
function
(
pattern
)
231
local
data
=
validdata
(
fetched
(
"
packages
"
)
)
232
if
data
then
233
local
found
=
{
234
{
"
key
"
,
"
name
"
,
"
caption
"
}
,
235
{
"
"
,
"
"
,
"
"
}
,
236
}
237
pattern
=
checkedpattern
(
pattern
)
238
for
c
in
xmlcollected
(
data
,
"
/packages/package
"
)
do
239
local
at
=
c
.
at
240
if
strfound
(
pattern
,
at
.
caption
)
then
241
found
[
#
found
+
1
]
=
{
at
.
key
,
at
.
name
,
at
.
caption
}
242
end
243
end
244
showresult
(
found
)
245
end
246
end
247 248
scripts
.
ctan
.
topics
=
json
and
249 250
function
(
pattern
)
251
local
data
=
validdata
(
fetched
(
"
topics
"
)
)
252
if
data
then
253
local
found
=
{
254
{
"
key
"
,
"
details
"
}
,
255
{
"
"
,
"
"
}
,
256
}
257
pattern
=
checkedpattern
(
pattern
)
258
for
i
=
1
,
#
data
do
259
local
entry
=
data
[
i
]
260
if
strfound
(
pattern
,
entry
.
details
)
then
261
found
[
#
found
+
1
]
=
{
entry
.
key
or
entry
.
name
,
entry
.
details
}
-- inconsistency between json and xml
262
end
263
end
264
showresult
(
found
)
265
end
266
end
267 268
or
269 270
function
(
pattern
)
271
local
data
=
validdata
(
fetched
(
"
topics
"
)
)
272
if
data
then
273
local
found
=
{
274
{
"
name
"
,
"
details
"
}
,
275
{
"
"
,
"
"
}
,
276
}
277
pattern
=
checkedpattern
(
pattern
)
278
for
c
in
xmlcollected
(
data
,
"
/topics/topic
"
)
do
279
local
at
=
c
.
at
280
if
strfound
(
pattern
,
at
.
caption
)
then
281
found
[
#
found
+
1
]
=
{
at
.
key
or
at
.
name
,
at
.
details
}
-- inconsistency between json and xml
282
end
283
end
284
showresult
(
found
)
285
end
286
end
287 288
local
function
whatever
(
)
289
report
(
"
"
)
290
report
(
"
using %s interface
"
,
json
and
"
json
"
or
"
xml
"
)
291
report
(
"
using curl %s
"
,
curl
and
"
library
"
or
"
binary
"
)
292
report
(
"
"
)
293
end
294 295
if
environment
.
argument
(
"
packages
"
)
then
296
whatever
(
)
297
scripts
.
ctan
.
packages
(
environment
.
argument
(
"
pattern
"
)
or
environment
.
files
[
1
]
)
298
elseif
environment
.
argument
(
"
topics
"
)
then
299
whatever
(
)
300
scripts
.
ctan
.
topics
(
environment
.
argument
(
"
pattern
"
)
or
environment
.
files
[
1
]
)
301
elseif
environment
.
argument
(
"
details
"
)
then
302
whatever
(
)
303
scripts
.
ctan
.
details
(
environment
.
files
[
1
]
)
304
elseif
environment
.
argument
(
"
exporthelp
"
)
then
305
application
.
export
(
environment
.
argument
(
"
exporthelp
"
)
,
environment
.
files
[
1
]
)
306
else
307
application
.
help
(
)
308
end
309 310
-- scripts.ctan.packages(environment.argument("pattern") or environment.files[1])
311
-- scripts.ctan.packages("font")
312
-- scripts.ctan.details("tex")
313
-- scripts.ctan.details("ipaex")
314 315
-- scripts.ctan.packages("Półtawskiego")
316
-- scripts.ctan.packages("Poltawskiego")
317 318
-- scripts.ctan.topics("font")
319
-- scripts.ctan.topics()
320