mtx-server-ctx-fonttest.lua /size: 31 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mtx-server-ctx-fonttest
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
Font Feature Tester
"
,
4
author
=
"
Hans Hagen
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- probably too much but who cares
10 11
dofile
(
resolvers
.
findfile
(
"
trac-lmx.lua
"
,
"
tex
"
)
)
12
dofile
(
resolvers
.
findfile
(
"
char-def.lua
"
,
"
tex
"
)
)
13 14
dofile
(
resolvers
.
findfile
(
"
font-ini.lua
"
,
"
tex
"
)
)
15
dofile
(
resolvers
.
findfile
(
"
font-log.lua
"
,
"
tex
"
)
)
16
dofile
(
resolvers
.
findfile
(
"
font-con.lua
"
,
"
tex
"
)
)
17
dofile
(
resolvers
.
findfile
(
"
font-cft.lua
"
,
"
tex
"
)
)
18
dofile
(
resolvers
.
findfile
(
"
font-enc.lua
"
,
"
tex
"
)
)
19
dofile
(
resolvers
.
findfile
(
"
font-agl.lua
"
,
"
tex
"
)
)
20
dofile
(
resolvers
.
findfile
(
"
font-cid.lua
"
,
"
tex
"
)
)
21
dofile
(
resolvers
.
findfile
(
"
font-map.lua
"
,
"
tex
"
)
)
22
dofile
(
resolvers
.
findfile
(
"
font-otr.lua
"
,
"
tex
"
)
)
23
dofile
(
resolvers
.
findfile
(
"
font-web.lua
"
,
"
tex
"
)
)
24
dofile
(
resolvers
.
findfile
(
"
font-cff.lua
"
,
"
tex
"
)
)
25
dofile
(
resolvers
.
findfile
(
"
font-ttf.lua
"
,
"
tex
"
)
)
26
dofile
(
resolvers
.
findfile
(
"
font-dsp.lua
"
,
"
tex
"
)
)
27
dofile
(
resolvers
.
findfile
(
"
font-hsh.lua
"
,
"
tex
"
)
)
28
dofile
(
resolvers
.
findfile
(
"
font-oti.lua
"
,
"
tex
"
)
)
29
dofile
(
resolvers
.
findfile
(
"
font-ott.lua
"
,
"
tex
"
)
)
30
dofile
(
resolvers
.
findfile
(
"
font-otl.lua
"
,
"
tex
"
)
)
31
-- dofile(resolvers.findfile("font-oto.lua","tex"))
32
-- dofile(resolvers.findfile("font-otj.lua","tex"))
33
dofile
(
resolvers
.
findfile
(
"
font-oup.lua
"
,
"
tex
"
)
)
34
-- dofile(resolvers.findfile("font-ots.lua","tex"))
35
-- dofile(resolvers.findfile("font-otd.lua","tex"))
36
-- dofile(resolvers.findfile("font-otc.lua","tex"))
37
-- dofile(resolvers.findfile("font-oth.lua","tex"))
38
-- dofile(resolvers.findfile("font-osd.lua","tex"))
39
-- dofile(resolvers.findfile("font-ocl.lua","tex"))
40
dofile
(
resolvers
.
findfile
(
"
font-onr.lua
"
,
"
tex
"
)
)
41 42
dofile
(
resolvers
.
findfile
(
"
font-syn.lua
"
,
"
tex
"
)
)
43
dofile
(
resolvers
.
findfile
(
"
font-mis.lua
"
,
"
tex
"
)
)
44 45
local
format
,
gsub
,
concat
,
match
,
find
=
string
.
format
,
string
.
gsub
,
table
.
concat
,
string
.
match
,
string
.
find
46 47
local
formatters
=
string
.
formatters
48 49
local
report
=
logs
.
reporter
(
"
ctx-fonttest
"
)
50 51
local
sample_line
=
"
This is a sample line!
"
52
local
tempname
=
"
mtx-server-ctx-fonttest-temp
"
53
local
temppath
=
caches
.
setfirstwritablefile
(
"
temp
"
,
"
mtx-server-ctx-fonttest
"
)
54
local
basename
=
"
mtx-server-ctx-fonttest-data.lua
"
55
local
basepath
=
temppath
56 57
local
remove_suffixes
=
{
"
tex
"
,
"
pdf
"
,
"
log
"
}
58
local
what_options
=
{
"
trace
"
,
"
basemode
"
}
59 60
for
i
=
1
,
#
remove_suffixes
do
61
os
.
remove
(
file
.
join
(
temppath
,
file
.
addsuffix
(
tempname
,
remove_suffixes
[
i
]
)
)
)
62
end
63 64
local
foolcache
=
0
65 66
local
function
makename
(
name
,
new
)
67
if
new
then
68
foolcache
=
foolcache
>
25
and
1
or
foolcache
+
1
69
end
70
return
formatters
[
"
%s-%02i
"
]
(
name
,
foolcache
)
71
end
72 73
-- nowadays i would use the more advanced template mechanism with named variables
74 75
local
process_templates
=
{
}
76 77
-- %\definedfont[name:%s*sample]
78 79
process_templates
.
default
=
formatters
[
[[
80\starttext 81 \setupdirections[bidi=one] 82 \definefontfeature[sample][analyze=yes,%s] 83 \definedfont[name:%s*none] 84 \startTEXpage[offset=3pt] 85 \detokenize{%s} 86 \blank 87 \definedfont[name:%s*sample] 88 \detokenize{%s} 89 \stopTEXpage 90\stoptext 91
]]
]
92 93
process_templates
.
cache
=
formatters
[
[[
94\starttext 95 \definedfont[name:%s] 96 \startTEXpage[offset=3pt] 97 cached: \detokenize{%s} 98 \stopTEXpage 99\stoptext 100
]]
]
101 102
process_templates
.
trace
=
formatters
[
[[
103\usemodule[fnt-20] 104 105\definefontfeature[sample][%s] 106 107\setupcolors[state=start] 108 109\setupdirections[bidi=global] 110 111\setvariables 112 [otftracker] 113 [title=Test Run, 114 font=name:%s, 115 direction=0, 116 features=sample, 117 sample={‍\detokenize{%s}}] 118
]]
]
119 120
local
javascripts
=
formatters
[
[[
121function selected_radio(name) { 122 var form = document.forms["main-form"] ; 123 var script = form.elements[name] ; 124 if (script) { 125 var n = script.length ; 126 if (n) { 127 for (var i=0; i<n; i++) { 128 if (script[i].checked) { 129 return script[i].value ; 130 } 131 } 132 } 133 } 134 return "" ; 135} 136 137function reset_valid() { 138 var fields = document.getElementsByTagName("span") ; 139 for (var i=0; i<fields.length; i++) { 140 var e = fields[i] 141 if (e) { 142 if (e.className == "valid") { 143 e.className = "" ; 144 } 145 } 146 } 147} 148 149function set_valid() { 150 var script = selected_radio("script") ; 151 var language = selected_radio("language") ; 152 if (script && language) { 153 var s = feature_hash[script] ; 154 if (s) { 155 for (l in s) { 156 var e = document.getElementById("t-l-" + l) ; 157 if (e) { 158 e.className = "valid" ; 159 } 160 } 161 var l = s[language] ; 162 if (l) { 163 for (i in l) { 164 var e = document.getElementById("t-f-" + i) ; 165 if (e) { 166 e.className = "valid" ; 167 } 168 } 169 } 170 var e = document.getElementById("t-s-" + script) ; 171 if (e) { 172 e.className = "valid" ; 173 } 174 } 175 } 176} 177 178function check_form() { 179 reset_valid() ; 180 set_valid() ; 181} 182 183function check_script() { 184 reset_valid() ; 185 set_valid() ; 186} 187 188function check_language() { 189 reset_valid() ; 190 set_valid() ; 191} 192 193function check_feature() { 194 // not needed 195} 196
]]
]
197 198
local
jitmode
=
false
-- assumes local use (one user as shared)
199 200
local
run_context_normal
=
formatters
[
"
mtxrun --path=%q --script context --once --batchmode %q
"
]
201
local
run_context_jitted
=
formatters
[
"
mtxrun --path=%q --script context --once --batchmode --jit %q
"
]
202 203
local
function
runcontext
(
temppath
,
filename
)
204
local
start
=
os
.
clock
(
)
205
local
command
=
(
jitmode
and
run_context_jitted
or
run_context_normal
)
(
temppath
,
filename
)
206
report
(
"
temppath: %s
"
,
temppath
)
207
report
(
"
filename: %s
"
,
filename
)
208
report
(
"
command: %s
"
,
command
)
209
os
.
execute
(
command
)
210
return
os
.
clock
(
)
-
start
211
end
212 213
local
function
identifyfonts
(
)
214
local
command
=
"
mtxrun --script font --reload
"
215
report
(
"
command: %s
"
,
command
)
216
os
.
execute
(
command
)
217
end
218 219
local
cache
=
{
}
220 221
local
function
showfeatures
(
f
)
222
if
f
then
223
report
(
"
processing font '%s'
"
,
f
)
224
local
features
=
cache
[
f
]
225
if
features
=
=
nil
then
226
features
=
fonts
.
helpers
.
getfeatures
(
resolvers
.
findfile
(
f
)
)
227
if
not
features
then
228
report
(
"
building cache for '%s'
"
,
f
)
229
local
usedname
=
file
.
addsuffix
(
tempname
,
"
tex
"
)
230
io
.
savedata
(
file
.
join
(
temppath
,
usedname
)
,
process_templates
.
cache
(
f
,
f
)
)
231
runcontext
(
temppath
,
usedname
)
232
features
=
fonts
.
helpers
.
getfeatures
(
f
)
233
end
234
cache
[
f
]
=
features
or
false
235
report
(
"
caching info of '%s'
"
,
f
)
236
else
237
report
(
"
using cached info of '%s'
"
,
f
)
238
end
239
if
features
then
240
local
scr
,
lan
,
fea
,
rev
=
{
}
,
{
}
,
{
}
,
{
}
241
local
function
show
(
what
)
242
local
data
=
features
[
what
]
243
if
data
and
next
(
data
)
then
244
for
f
,
ff
in
next
,
data
do
245
if
find
(
f
,
"
<
"
)
then
246
-- ignore aat for the moment
247
else
248
fea
[
f
]
=
true
249
for
s
,
ss
in
next
,
ff
do
250
if
find
(
s
,
"
%*
"
)
then
251
-- ignore *
252
else
253
scr
[
s
]
=
true
254
local
rs
=
rev
[
s
]
if
not
rs
then
rs
=
{
}
rev
[
s
]
=
rs
end
255
for
k
,
l
in
next
,
ss
do
256
if
find
(
k
,
"
%*
"
)
then
257
-- ignore *
258
else
259
lan
[
k
]
=
true
260
local
rsk
=
rs
[
k
]
if
not
rsk
then
rsk
=
{
}
rs
[
k
]
=
rsk
end
261
rsk
[
f
]
=
true
262
end
263
end
264
end
265
end
266
end
267
end
268
end
269
end
270
for
what
,
v
in
table
.
sortedhash
(
features
)
do
271
show
(
what
)
272
end
273
-- we could json this
274
local
stupid
=
{
}
275
stupid
[
#
stupid
+
1
]
=
"
var feature_hash = new Array ;
"
276
for
s
,
sr
in
next
,
rev
do
277
stupid
[
#
stupid
+
1
]
=
formatters
[
"
feature_hash['%s'] = new Array ;
"
]
(
s
)
278
for
l
,
lr
in
next
,
sr
do
279
stupid
[
#
stupid
+
1
]
=
formatters
[
"
feature_hash['%s']['%s'] = new Array ;
"
]
(
s
,
l
)
280
for
f
,
fr
in
next
,
lr
do
281
stupid
[
#
stupid
+
1
]
=
formatters
[
"
feature_hash['%s']['%s']['%s'] = true ;
"
]
(
s
,
l
,
f
)
282
end
283
end
284
end
285
-- gpos feature script languages
286
return
{
287
scripts
=
scr
,
288
languages
=
lan
,
289
features
=
fea
,
290
javascript
=
concat
(
stupid
,
"
\n
"
)
291
}
292
end
293
end
294
end
295 296
local
template_h
=
formatters
[
[[
297<tr> 298 <th>safe name&nbsp;&nbsp;&nbsp;&nbsp;</th> 299 <th>family name&nbsp;&nbsp;&nbsp;&nbsp;</th> 300 <th>style-variant-weight-width&nbsp;&nbsp;&nbsp;&nbsp;</th> 301 <th>font name&nbsp;&nbsp;&nbsp;&nbsp;</th> 302 <th>weight&nbsp;&nbsp;&nbsp;&nbsp;</th> 303 <th>filename</th> 304</tr>
]]
]
305 306
local
template_d
=
formatters
[
[[
307<tr> 308 <td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a>&nbsp;&nbsp;&nbsp;&nbsp;</td> 309 <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td> 310 <td>%s-%s-%s-%s&nbsp;&nbsp;&nbsp;&nbsp;</td> 311 <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td> 312 <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td> 313 <td>%s</td> 314</tr>
]]
]
315 316
local
function
select_font
(
)
317
local
t
=
fonts
.
names
.
list
(
"
.*
"
,
false
,
true
)
318
if
t
then
319
local
listoffonts
=
{
}
320
listoffonts
[
#
listoffonts
+
1
]
=
"
<h1>Fonts</h1><br/>
"
321
listoffonts
[
#
listoffonts
+
1
]
=
"
<table>
"
322
listoffonts
[
#
listoffonts
+
1
]
=
template_h
(
)
323
for
k
,
v
in
table
.
sortedhash
(
t
)
do
324
local
kind
=
v
.
format
325
if
kind
=
=
"
otf
"
or
kind
=
=
"
ttf
"
or
kind
=
=
"
ttc
"
then
326
local
fontname
=
v
.
fontname
327
listoffonts
[
#
listoffonts
+
1
]
=
template_d
(
328
fontname
,
329
fontname
,
330
v
.
familyname
or
"
"
,
331
t
.
variant
or
"
normal
"
,
332
t
.
weight
or
"
normal
"
,
333
t
.
width
or
"
normal
"
,
334
t
.
style
or
"
normal
"
,
335
v
.
rawname
or
fontname
,
336
v
.
fontweight
or
"
"
,
337
v
.
filename
or
"
"
338
)
339
end
340
end
341
listoffonts
[
#
listoffonts
+
1
]
=
"
</table>
"
342
return
concat
(
listoffonts
,
"
\n
"
)
343
end
344
return
"
<b>no fonts</b>
"
345
end
346 347
local
edit_template
=
formatters
[
[[
348 <textarea name='sampletext' rows='5' cols='100'>%s</textarea> 349 <br/> <br/>name:&nbsp;<input type='text' name='name' size='20' value=%q/>&nbsp;&nbsp; title:&nbsp;<input type='text' name='title' size='40' value=%q/> 350 <br/> <br/>scripts:&nbsp;%s 351 <br/> <br/>languages:&nbsp;%s 352 <br/> <br/>features:&nbsp;%s 353 <br/> <br/>options:&nbsp;%s 354
]]
]
355 356
-- <embed src="%s#toolbar=0&amp;navpanes=0&amp;scrollbar=0" width="100%%"/>
357 358
local
result_template
=
formatters
[
[[
359 <br/> <br/> 360 <embed src="%s#view=Fit&amp;toolbar=0&amp;navpanes=0&amp;scrollbar=0" width="100%%"/> 361 <br/> <br/> results:&nbsp; 362 <a href='%s' target="source">tex file</a>&nbsp;&nbsp; 363 <a href='%s' target="result">pdf file</a>&nbsp;&nbsp; 364 (runtime: %s) 365 <br/> <br/> 366
]]
]
367 368
local
main_template
=
formatters
[
[[
369 <h1>Font: %s</h1><br/> 370 %s 371 %s 372
]]
]
373 374
scripts
.
webserver
.
registerpath
(
temppath
)
375 376
local
function
get_specification
(
name
)
377
return
fonts
.
names
.
resolvedspecification
(
name
or
"
"
)
378
end
379 380
local
function
edit_font
(
currentfont
,
detail
,
tempname
,
runtime
)
381
report
(
"
entering edit mode for '%s'
"
,
currentfont
)
382
local
specification
=
get_specification
(
currentfont
)
383
if
specification
then
384
local
htmldata
=
showfeatures
(
specification
.
filename
)
385
if
htmldata
then
386
local
features
,
languages
,
scripts
,
options
=
{
}
,
{
}
,
{
}
,
{
}
387
local
sorted
=
table
.
sortedkeys
(
htmldata
.
scripts
)
388
for
k
=
1
,
#
sorted
do
389
local
v
=
sorted
[
k
]
390
local
s
=
fonts
.
handlers
.
otf
.
tables
.
scripts
[
v
]
or
v
391
if
detail
and
v
=
=
detail
.
script
then
392
scripts
[
#
scripts
+
1
]
=
formatters
[
"
<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' checked='checked'/>&nbsp;<span id='t-s-%s'>%s</span>
"
]
(
s
,
v
,
v
,
v
,
v
)
393
else
394
scripts
[
#
scripts
+
1
]
=
formatters
[
"
<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' />&nbsp;<span id='t-s-%s'>%s</span>
"
]
(
s
,
v
,
v
,
v
,
v
)
395
end
396
end
397
local
sorted
=
table
.
sortedkeys
(
htmldata
.
languages
)
398
for
k
=
1
,
#
sorted
do
399
local
v
=
sorted
[
k
]
400
local
l
=
fonts
.
handlers
.
otf
.
tables
.
languages
[
v
]
or
v
401
if
detail
and
v
=
=
detail
.
language
then
402
languages
[
#
languages
+
1
]
=
formatters
[
"
<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' checked='checked'/>&nbsp;<span id='t-l-%s'>%s</span>
"
]
(
l
,
v
,
v
,
v
,
v
)
403
else
404
languages
[
#
languages
+
1
]
=
formatters
[
"
<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' />&nbsp;<span id='t-l-%s'>%s</span>
"
]
(
l
,
v
,
v
,
v
,
v
)
405
end
406
end
407
local
sorted
=
table
.
sortedkeys
(
htmldata
.
features
)
408
for
k
=
1
,
#
sorted
do
409
local
v
=
sorted
[
k
]
410
local
f
=
fonts
.
handlers
.
otf
.
tables
.
features
[
v
]
or
v
411
if
detail
and
detail
[
"
f-
"
.
.
v
]
then
412
features
[
#
features
+
1
]
=
formatters
[
"
<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' checked='checked'/>&nbsp;<span id='t-f-%s'>%s</span>
"
]
(
f
,
v
,
v
,
v
,
v
)
413
else
414
features
[
#
features
+
1
]
=
formatters
[
"
<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' />&nbsp;<span id='t-f-%s'>%s</span>
"
]
(
f
,
v
,
v
,
v
,
v
)
415
end
416
end
417
for
k
=
1
,
#
what_options
do
418
local
v
=
what_options
[
k
]
419
if
detail
and
detail
[
"
o-
"
.
.
v
]
then
420
options
[
#
options
+
1
]
=
formatters
[
"
<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/>&nbsp;%s
"
]
(
v
,
v
,
v
)
421
else
422
options
[
#
options
+
1
]
=
formatters
[
"
<input id='o-%s' type='checkbox' name='o-%s'/>&nbsp;%s
"
]
(
v
,
v
,
v
)
423
end
424
end
425
local
e
=
edit_template
(
426
detail
and
detail
.
sampletext
or
sample_line
,
427
detail
and
detail
.
name
or
"
no name
"
,
428
detail
and
detail
.
title
or
"
"
,
429
concat
(
scripts
,
"
"
)
,
430
concat
(
languages
,
"
"
)
,
431
concat
(
features
,
"
"
)
,
432
concat
(
options
,
"
"
)
433
)
434
if
tempname
then
435
local
pdffile
,
texfile
=
file
.
replacesuffix
(
tempname
,
"
pdf
"
)
,
file
.
replacesuffix
(
tempname
,
"
tex
"
)
436
local
r
=
result_template
(
pdffile
,
texfile
,
pdffile
,
runtime
and
formatters
[
"
%0.3f
"
]
(
runtime
)
or
"
-
"
)
437
return
main_template
(
currentfont
,
e
,
r
)
,
htmldata
.
javascript
or
"
"
438
else
439
return
main_template
(
currentfont
,
e
,
"
"
)
,
htmldata
.
javascript
or
"
"
440
end
441
else
442
return
"
error, nothing set up yet
"
443
end
444
else
445
return
"
error, no info about font
"
446
end
447
end
448 449
local
function
process_font
(
currentfont
,
detail
)
-- maybe just fontname
450
local
features
=
{
451
"
mode=node
"
,
452
formatters
[
"
language=%s
"
]
(
detail
.
language
or
"
dflt
"
)
,
453
formatters
[
"
script=%s
"
]
(
detail
.
script
or
"
dflt
"
)
,
454
}
455
for
k
,
v
in
next
,
detail
do
456
local
f
=
match
(
k
,
"
^f%-(.*)$
"
)
457
if
f
then
458
features
[
#
features
+
1
]
=
formatters
[
"
%s=yes
"
]
(
f
)
459
end
460
end
461
local
variant
=
process_templates
.
default
462
if
detail
[
"
o-trace
"
]
then
463
variant
=
process_templates
.
trace
464
end
465
local
sample
=
string
.
strip
(
detail
.
sampletext
or
"
"
)
466
if
sample
=
=
"
"
then
sample
=
sample_line
end
467
report
(
"
sample text: %s
"
,
sample
)
468
dir
.
mkdirs
(
temppath
)
469
local
tempname
=
makename
(
tempname
,
true
)
470
local
usedname
=
file
.
addsuffix
(
tempname
,
"
tex
"
)
471
local
fullname
=
file
.
join
(
temppath
,
usedname
)
472
local
data
=
variant
(
concat
(
features
,
"
,
"
)
,
currentfont
,
sample
,
currentfont
,
sample
)
473
io
.
savedata
(
fullname
,
data
)
474
io
.
flush
(
)
475
local
runtime
=
runcontext
(
temppath
,
usedname
)
476
return
edit_font
(
currentfont
,
detail
,
tempname
,
runtime
)
477
end
478 479
local
tex_template
=
formatters
[
[[
480<h1>Font: %s</h1><br/> 481<pre><tt> 482%s 483</tt></pre> 484
]]
]
485 486
local
function
show_source
(
currentfont
,
detail
)
487
local
tempname
=
makename
(
tempname
)
488
if
tempname
and
tempname
~
=
"
"
then
489
local
data
=
io
.
loaddata
(
file
.
join
(
temppath
,
file
.
replacesuffix
(
tempname
,
"
tex
"
)
)
)
or
"
no source yet
"
490
return
tex_template
(
currentfont
,
data
)
491
else
492
return
"
no source file
"
493
end
494
end
495 496
local
function
show_log
(
currentfont
,
detail
)
497
local
tempname
=
makename
(
tempname
)
498
if
tempname
and
tempname
~
=
"
"
then
499
local
data
=
io
.
loaddata
(
file
.
join
(
temppath
,
file
.
replacesuffix
(
tempname
,
'
log
'
)
)
)
or
"
no log file yet
"
500
data
=
gsub
(
data
,
"
[%s%%]*begin of optionfile.-end of optionfile[%s%%]*
"
,
"
\n
"
)
501
return
tex_template
(
currentfont
,
data
)
502
else
503
return
"
no log file
"
504
end
505
end
506 507
-- much nicer would be an lmx template
508 509
local
function
show_font
(
currentfont
,
detail
)
510
local
specification
=
get_specification
(
currentfont
)
511
local
features
=
fonts
.
helpers
.
getfeatures
(
specification
.
filename
)
512
local
result
=
{
}
513
result
[
#
result
+
1
]
=
formatters
[
"
<h1>Font: %s</h1><br/>
"
]
(
currentfont
)
514
result
[
#
result
+
1
]
=
"
<table>
"
515
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>fontname </td><td style='width:20em'>%s</td>
"
]
(
specification
.
fontname
or
"
-
"
)
516
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>designsize </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
designsize
or
"
-
"
)
517
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>fullname </td><td style='width:20em'>%s</td>
"
]
(
specification
.
fullname
or
"
-
"
)
518
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>minimumsize</td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
minsize
or
"
-
"
)
519
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>filename </td><td style='width:20em'>%s</td>
"
]
(
specification
.
fontfile
or
"
-
"
)
520
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>maximumsize</td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
maxsize
or
"
-
"
)
521
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>rawname </td><td style='width:20em'>%s</td>
"
]
(
specification
.
rawname
or
"
-
"
)
522
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>fontweight </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
fontweight
or
"
-
"
)
523
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>familyname </td><td style='width:20em'>%s</td>
"
]
(
specification
.
familyname
or
"
-
"
)
524
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>angle </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
angle
or
"
-
"
)
525
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>subfamily </td><td style='width:20em'>%s</td>
"
]
(
specification
.
subfamily
or
"
-
"
)
526
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>variant </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
variant
~
=
"
"
and
specification
.
variant
or
"
normal
"
)
527
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>format </td><td style='width:20em'>%s</td>
"
]
(
specification
.
format
or
"
-
"
)
528
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>style </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
style
~
=
"
"
and
specification
.
style
or
"
normal
"
)
529
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>pfmwidth </td><td style='width:20em'>%s</td>
"
]
(
specification
.
pfmwidth
~
=
"
"
and
specification
.
pfmwidth
or
"
-
"
)
530
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>weight </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
weight
~
=
"
"
and
specification
.
weight
or
"
normal
"
)
531
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td class='tc' style='width:10em'>pfmheight </td><td style='width:20em'>%s</td>
"
]
(
specification
.
pfmweight
~
=
"
"
and
specification
.
pfmweight
or
"
-
"
)
532
result
[
#
result
+
1
]
=
formatters
[
"
<td class='tc' style='width:10em'>width </td><td style='width:20em'>%s</td></tr>
"
]
(
specification
.
width
~
=
"
"
and
specification
.
width
or
"
normal
"
)
533
result
[
#
result
+
1
]
=
"
</table>
"
534
if
features
then
535
for
what
,
v
in
table
.
sortedhash
(
features
)
do
536
local
data
=
features
[
what
]
537
if
data
and
next
(
data
)
then
538
result
[
#
result
+
1
]
=
formatters
[
"
<h1>%s features</h1><br/>
"
]
(
what
)
539
result
[
#
result
+
1
]
=
"
<table>
"
540
result
[
#
result
+
1
]
=
"
<tr><th>feature</th><th>tag&nbsp;</th><th>script&nbsp;</th><th>languages&nbsp;</th></tr>
"
541
for
f
,
ff
in
table
.
sortedhash
(
data
)
do
542
local
done
=
false
543
for
s
,
ss
in
table
.
sortedhash
(
ff
)
do
544
if
s
=
=
"
*
"
then
s
=
"
all
"
end
545
if
ss
[
"
*
"
]
then
ss
[
"
*
"
]
=
nil
ss
.
all
=
true
end
546
if
done
then
547
f
=
"
"
548
else
549
done
=
true
550
end
551
local
title
=
fonts
.
handlers
.
otf
.
tables
.
features
[
f
]
or
"
"
552
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td width='50%%'>%s&nbsp;&nbsp;</td><td><tt>%s&nbsp;&nbsp;</tt></td><td><tt>%s&nbsp;&nbsp;</tt></td><td><tt>%s&nbsp;&nbsp;</tt></td></tr>
"
]
(
title
,
f
,
s
,
concat
(
table
.
sortedkeys
(
ss
)
,
"
"
)
)
553
end
554
end
555
result
[
#
result
+
1
]
=
"
</table>
"
556
end
557
end
558
else
559
result
[
#
result
+
1
]
=
"
<br/><br/>This font has no features.
"
560
end
561
return
concat
(
result
,
"
\n
"
)
562
end
563 564
local
info_template
=
formatters
[
[[
565<pre><tt> 566version : %s 567comment : %s 568author : %s 569copyright : %s 570 571maillist : ntg-context at ntg.nl 572webpage : www.pragma-ade.nl 573wiki : contextgarden.net 574</tt></pre> 575
]]
]
576 577
local
function
info_about
(
)
578
local
m
=
modules
[
'
mtx-server-ctx-fonttest
'
]
579
return
info_template
(
m
.
version
,
m
.
comment
,
m
.
author
,
m
.
copyright
)
580
end
581 582
local
save_template
=
formatters
[
[[
583 the current setup has been saved: 584 <br/> <br/> 585 <table> 586 <tr><td class='tc'>name&nbsp; </td><td>%s</td></tr> 587 <tr><td class='tc'>title&nbsp; </td><td>%s</td></tr> 588 <tr><td class='tc'>font&nbsp; </td><td>%s</td></tr> 589 <tr><td class='tc'>script&nbsp; </td><td>%s</td></tr> 590 <tr><td class='tc'>language&nbsp; </td><td>%s</td></tr> 591 <tr><td class='tc'>features&nbsp; </td><td>%s</td></tr> 592 <tr><td class='tc'>options&nbsp; </td><td>%s</td></tr> 593 <tr><td class='tc'>sampletext&nbsp;</td><td>%s</td></tr> 594 </table> 595
]]
]
596 597
local
function
loadbase
(
)
598
local
datafile
=
file
.
join
(
basepath
,
basename
)
599
local
storage
=
io
.
loaddata
(
datafile
)
or
"
"
600
if
storage
=
=
"
"
then
601
storage
=
{
}
602
else
603
report
(
"
loading '%s'
"
,
datafile
)
604
storage
=
loadstring
(
storage
)
605
storage
=
(
storage
and
storage
(
)
)
or
{
}
606
end
607
return
storage
608
end
609 610
local
function
loadstored
(
detail
,
currentfont
,
name
)
611
local
storage
=
loadbase
(
)
612
storage
=
storage
and
storage
[
name
]
613
if
storage
then
614
currentfont
=
storage
.
font
615
detail
.
script
=
storage
.
script
or
detail
.
script
616
detail
.
language
=
storage
.
language
or
detail
.
language
617
detail
.
title
=
storage
.
title
or
detail
.
title
618
detail
.
sampletext
=
storage
.
text
or
detail
.
sampletext
619
detail
.
name
=
name
or
"
no name
"
620
for
k
,
v
in
next
,
storage
.
features
do
621
detail
[
"
f-
"
.
.
k
]
=
v
622
end
623
for
k
,
v
in
next
,
storage
.
options
do
624
detail
[
"
o-
"
.
.
k
]
=
v
625
end
626
end
627
detail
.
loadname
=
nil
628
return
detail
,
currentfont
629
end
630 631
local
function
savebase
(
storage
,
name
)
632
local
datafile
=
file
.
join
(
basepath
,
basename
)
633
report
(
"
saving '%s' in '%s'
"
,
name
or
"
data
"
,
datafile
)
634
io
.
savedata
(
datafile
,
table
.
serialize
(
storage
,
true
)
)
635
end
636 637
local
function
deletestored
(
detail
,
currentfont
,
name
)
638
local
storage
=
loadbase
(
)
639
if
storage
and
name
and
storage
[
name
]
then
640
report
(
"
deleting '%s' from base
"
,
name
)
641
storage
[
name
]
=
nil
642
savebase
(
storage
)
643
end
644
detail
.
deletename
=
nil
645
return
detail
,
"
"
646
end
647 648
local
function
save_font
(
currentfont
,
detail
)
649
local
specification
=
get_specification
(
currentfont
)
650
local
name
,
title
,
script
,
language
,
features
,
options
,
text
=
currentfont
,
"
"
,
"
dflt
"
,
"
dflt
"
,
{
}
,
{
}
,
"
"
651
if
detail
then
652
local
htmldata
=
showfeatures
(
specification
.
filename
)
653
script
=
detail
.
script
or
script
654
language
=
detail
.
language
or
language
655
text
=
string
.
strip
(
detail
.
sampletext
or
text
)
656
name
=
string
.
strip
(
detail
.
name
or
name
)
657
title
=
string
.
strip
(
detail
.
title
or
title
)
658
for
k
,
v
in
next
,
htmldata
.
features
do
659
if
detail
[
"
f-
"
.
.
k
]
then
features
[
k
]
=
true
end
660
end
661
for
k
=
1
,
#
what_options
do
662
local
v
=
what_options
[
k
]
663
if
detail
[
"
o-
"
.
.
v
]
then
options
[
k
]
=
true
end
664
end
665
end
666
if
name
=
=
"
"
then
667
name
=
"
no name
"
668
end
669
local
storage
=
loadbase
(
)
670
storage
[
name
]
=
{
671
font
=
currentfont
,
title
=
title
,
script
=
script
,
language
=
language
,
features
=
features
,
options
=
options
,
text
=
text
,
672
}
673
savebase
(
storage
,
name
)
674
return
save_template
(
name
,
title
,
currentfont
,
script
,
language
,
concat
(
table
.
sortedkeys
(
features
)
,
"
"
)
,
concat
(
table
.
sortedkeys
(
options
)
,
"
"
)
,
text
)
675
end
676 677
local
function
load_font
(
currentfont
)
678
local
datafile
=
file
.
join
(
basepath
,
basename
)
679
local
storage
=
loadbase
(
datafile
)
680
local
result
=
{
}
681
result
[
#
result
+
1
]
=
"
<tr><th>del&nbsp;</th><th>name&nbsp;</th><th>font&nbsp;</th><th>fontname&nbsp;</th><th>script&nbsp;</th><th>language&nbsp;</th><th>features&nbsp;</th><th>title&nbsp;</th><th>sampletext&nbsp;</th></tr>
"
682
for
k
,
v
in
table
.
sortedhash
(
storage
)
do
683
local
fontname
,
fontfile
=
get_specification
(
v
.
font
)
684
result
[
#
result
+
1
]
=
formatters
[
"
<tr><td><a href='mtx-server-ctx-fonttest.lua?deletename=%s'>x</a>&nbsp;</td><td><a href='mtx-server-ctx-fonttest.lua?loadname=%s'>%s</a>&nbsp;</td><td>%s&nbsp;</td<td>%s&nbsp;</td><td>%s&nbsp;</td><td>%s&nbsp;</td><td>%s&nbsp;</td><td>%s&nbsp;</td><td>%s&nbsp;</td></tr>
"
]
(
685
k
,
k
,
k
,
v
.
font
,
fontname
,
v
.
script
,
v
.
language
,
concat
(
table
.
sortedkeys
(
v
.
features
)
,
"
"
)
,
v
.
title
or
"
no title
"
,
v
.
text
or
"
"
)
686
end
687
if
#
result
=
=
1
then
688
return
"
nothing saved yet
"
689
else
690
return
formatters
[
"
<table>%s</table>
"
]
(
concat
(
result
,
"
\n
"
)
)
691
end
692
end
693 694
local
function
reset_font
(
currentfont
)
695
return
edit_font
(
currentfont
)
696
end
697 698
local
extras_template
=
formatters
[
[[
699 <a href='mtx-server-ctx-fonttest.lua?extra=reload'>remake font database</a> (take some time)<br/><br/> 700
]]
]
701 702
local
function
do_extras
(
detail
,
currentfont
,
extra
)
703
return
extras_template
(
)
704
end
705 706
local
extras
=
{
}
707 708
local
function
do_extra
(
detail
,
currentfont
,
extra
)
709
local
e
=
extras
[
extra
]
710
if
e
then
e
(
detail
,
currentfont
,
extra
)
end
711
return
do_extras
(
detail
,
currentfont
,
extra
)
712
end
713 714
function
extras
.
reload
(
)
715
identifyfonts
(
)
716
return
do_extras
(
)
717
end
718 719
local
status_template
=
formatters
[
[[
720 <input type="hidden" name="currentfont" value="%s" /> 721
]]
]
722 723
local
variables
=
{
724
[
'
color-background-one
'
]
=
lmx
.
get
(
'
color-background-green
'
)
,
725
[
'
color-background-two
'
]
=
lmx
.
get
(
'
color-background-blue
'
)
,
726
[
'
title
'
]
=
'
ConTeXt Font Tester
'
,
727
[
'
formaction
'
]
=
"
mtx-server-ctx-fonttest.lua
"
,
728
}
729 730
-- todo: use lmx file
731 732
function
doit
(
configuration
,
filename
,
hashed
)
733 734
local
start
=
os
.
clock
(
)
735 736
local
detail
=
url
.
query
(
hashed
.
query
or
"
"
)
737 738
local
currentfont
=
detail
.
currentfont
739
local
action
=
detail
.
action
740
local
selection
=
detail
.
selection
741 742
if
action
=
=
"
luajittex
"
then
743
jitmode
=
true
744
elseif
action
=
=
"
luatex
"
then
745
jitmode
=
false
746
end
747 748
local
loadname
=
detail
.
loadname
749
local
deletename
=
detail
.
deletename
750
local
extra
=
detail
.
extra
751 752
if
loadname
and
loadname
~
=
"
"
then
753
detail
,
currentfont
=
loadstored
(
detail
,
currentfont
,
loadname
)
754
action
=
"
process
"
755
elseif
deletename
and
deletename
~
=
"
"
then
756
detail
,
currentfont
=
deletestored
(
detail
,
currentfont
,
deletename
)
757
action
=
"
load
"
758
elseif
selection
and
selection
~
=
"
"
then
759
currentfont
=
selection
760
elseif
extra
and
extra
~
=
"
"
then
761
do_extra
(
detail
,
currentfont
,
extra
)
762
action
=
"
extras
"
763
end
764 765
local
fontname
,
fontfile
=
get_specification
(
currentfont
)
766 767
if
fontfile
then
768
variables
.
title
=
formatters
[
'
ConTeXt Font Tester: %s (%s)
'
]
(
fontname
,
fontfile
)
769
else
770
variables
.
title
=
'
ConTeXt Font Tester
'
771
end
772 773
if
jitmode
then
774
variables
.
title
=
variables
.
title
.
.
"
(using LuaJit vm)
"
775
end
776 777
-- lua table and adapt
778 779
report
(
"
action: %s
"
,
action
or
"
no action
"
)
780 781
local
buttons
=
{
'
process
'
,
'
select
'
,
'
save
'
,
'
load
'
,
'
edit
'
,
'
reset
'
,
'
features
'
,
'
source
'
,
'
log
'
,
'
info
'
,
'
extras
'
,
jitmode
and
"
luatex
"
or
"
luajittex
"
}
782
local
menu
=
{
}
783 784
for
i
=
1
,
#
buttons
do
785
local
button
=
buttons
[
i
]
786
menu
[
#
menu
+
1
]
=
formatters
[
"
<button name='action' value='%s' type='submit'>%s</button>
"
]
(
button
,
button
)
787
end
788 789
variables
.
menu
=
concat
(
menu
,
"
&nbsp;
"
)
790
variables
.
status
=
status_template
(
currentfont
or
"
"
)
791
variables
.
maintext
=
"
"
792
variables
.
javascriptdata
=
"
"
793
variables
.
javascripts
=
"
"
794
variables
.
javascriptinit
=
"
"
795 796
local
result
797 798
if
action
=
=
"
select
"
then
799
variables
.
maintext
=
select_font
(
)
800
elseif
action
=
=
"
info
"
then
801
variables
.
maintext
=
info_about
(
)
802
elseif
action
=
=
"
extras
"
then
803
variables
.
maintext
=
do_extras
(
)
804
elseif
currentfont
and
currentfont
~
=
"
"
then
805
if
action
=
=
"
save
"
then
806
variables
.
maintext
=
save_font
(
currentfont
,
detail
)
807
elseif
action
=
=
"
load
"
then
808
variables
.
maintext
=
load_font
(
currentfont
,
detail
)
809
elseif
action
=
=
"
source
"
then
810
variables
.
maintext
=
show_source
(
currentfont
,
detail
)
811
elseif
action
=
=
"
log
"
then
812
variables
.
maintext
=
show_log
(
currentfont
,
detail
)
813
elseif
action
=
=
"
features
"
then
814
variables
.
maintext
=
show_font
(
currentfont
,
detail
)
815
else
816
local
e
,
s
817
if
action
=
=
"
process
"
then
818
e
,
s
=
process_font
(
currentfont
,
detail
)
819
elseif
action
=
=
"
reset
"
then
820
e
,
s
=
reset_font
(
currentfont
)
821
elseif
action
=
=
"
edit
"
then
822
e
,
s
=
edit_font
(
currentfont
,
detail
)
823
else
824
e
,
s
=
process_font
(
currentfont
,
detail
)
825
end
826
variables
.
maintext
=
e
827
variables
.
javascriptdata
=
s
828
variables
.
javascripts
=
javascripts
829
variables
.
javascriptinit
=
"
check_form()
"
830
end
831
else
832
variables
.
maintext
=
select_font
(
)
833
end
834 835
result
=
{
content
=
lmx
.
convert
(
'
context-fonttest.lmx
'
,
false
,
variables
)
}
836 837
report
(
"
time spent on page: %0.03f seconds
"
,
os
.
clock
(
)
-
start
)
838 839
return
result
840 841
end
842 843
return
doit
,
true
844 845
--~ make_lmx_page("test")
846