1if 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
10
11dofile(resolvers.findfile("trac-lmx.lua","tex"))
12dofile(resolvers.findfile("char-def.lua","tex"))
13
14dofile(resolvers.findfile("font-ini.lua","tex"))
15dofile(resolvers.findfile("font-log.lua","tex"))
16dofile(resolvers.findfile("font-con.lua","tex"))
17dofile(resolvers.findfile("font-cft.lua","tex"))
18dofile(resolvers.findfile("font-enc.lua","tex"))
19dofile(resolvers.findfile("font-agl.lua","tex"))
20dofile(resolvers.findfile("font-cid.lua","tex"))
21dofile(resolvers.findfile("font-map.lua","tex"))
22dofile(resolvers.findfile("font-otr.lua","tex"))
23dofile(resolvers.findfile("font-web.lua","tex"))
24dofile(resolvers.findfile("font-cff.lua","tex"))
25dofile(resolvers.findfile("font-ttf.lua","tex"))
26dofile(resolvers.findfile("font-dsp.lua","tex"))
27dofile(resolvers.findfile("font-hsh.lua","tex"))
28dofile(resolvers.findfile("font-oti.lua","tex"))
29dofile(resolvers.findfile("font-ott.lua","tex"))
30dofile(resolvers.findfile("font-otl.lua","tex"))
31
32
33dofile(resolvers.findfile("font-oup.lua","tex"))
34
35
36
37
38
39
40dofile(resolvers.findfile("font-onr.lua","tex"))
41
42dofile(resolvers.findfile("font-syn.lua","tex"))
43dofile(resolvers.findfile("font-mis.lua","tex"))
44
45local format, gsub, concat, match, find = string.format, string.gsub, table.concat, string.match, string.find
46
47local formatters = string.formatters
48
49local report = logs.reporter("ctx-fonttest")
50
51local sample_line = "This is a sample line!"
52local tempname = "mtx-server-ctx-fonttest-temp"
53local temppath = caches.setfirstwritablefile("temp","mtx-server-ctx-fonttest")
54local basename = "mtx-server-ctx-fonttest-data.lua"
55local basepath = temppath
56
57local remove_suffixes = { "tex", "pdf", "log" }
58local what_options = { "trace", "basemode" }
59
60for i=1,#remove_suffixes do
61 os.remove(file.join(temppath,file.addsuffix(tempname,remove_suffixes[i])))
62end
63
64local foolcache = 0
65
66local 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)
71end
72
73
74
75local process_templates = { }
76
77
78
79process_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
93process_templates.cache = formatters [ [[
94\starttext
95 \definedfont[name:%s]
96 \startTEXpage[offset=3pt]
97 cached: \detokenize{%s}
98 \stopTEXpage
99\stoptext
100]] ]
101
102process_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
120local 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
198local jitmode = false
199
200local run_context_normal = formatters["mtxrun --path=%q --script context --once --batchmode %q"]
201local run_context_jitted = formatters["mtxrun --path=%q --script context --once --batchmode --jit %q"]
202
203local 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
211end
212
213local function identifyfonts()
214 local command = "mtxrun --script font --reload"
215 report("command: %s",command)
216 os.execute(command)
217end
218
219local cache = { }
220
221local 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
247 else
248 fea[f] = true
249 for s, ss in next, ff do
250 if find(s,"%*") then
251
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
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
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
286 return {
287 scripts = scr,
288 languages = lan,
289 features = fea,
290 javascript = concat(stupid,"\n")
291 }
292 end
293 end
294end
295
296local template_h = formatters [ [[
297<tr>
298 <th>safe name </th>
299 <th>family name </th>
300 <th>style-variant-weight-width </th>
301 <th>font name </th>
302 <th>weight </th>
303 <th>filename</th>
304</tr>]] ]
305
306local template_d = formatters [ [[
307<tr>
308 <td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a> </td>
309 <td>%s </td>
310 <td>%s-%s-%s-%s </td>
311 <td>%s </td>
312 <td>%s </td>
313 <td>%s</td>
314</tr>]] ]
315
316local 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>"
345end
346
347local edit_template = formatters [ [[
348 <textarea name='sampletext' rows='5' cols='100'>%s</textarea>
349 <br/> <br/>name: <input type='text' name='name' size='20' value=%q/> title: <input type='text' name='title' size='40' value=%q/>
350 <br/> <br/>scripts: %s
351 <br/> <br/>languages: %s
352 <br/> <br/>features: %s
353 <br/> <br/>options: %s
354]] ]
355
356
357
358local result_template = formatters [ [[
359 <br/> <br/>
360 <embed src="%s#view=Fit&toolbar=0&navpanes=0&scrollbar=0" width="100%%"/>
361 <br/> <br/> results:
362 <a href='%s' target="source">tex file</a>
363 <a href='%s' target="result">pdf file</a>
364 (runtime: %s)
365 <br/> <br/>
366]] ]
367
368local main_template = formatters [ [[
369 <h1>Font: %s</h1><br/>
370 %s
371 %s
372]] ]
373
374scripts.webserver.registerpath(temppath)
375
376local function get_specification(name)
377 return fonts.names.resolvedspecification(name or "")
378end
379
380local 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'/> <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()' /> <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'/> <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()' /> <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'/> <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()' /> <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'/> %s"](v,v,v)
421 else
422 options[#options+1] = formatters["<input id='o-%s' type='checkbox' name='o-%s'/> %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
447end
448
449local function process_font(currentfont,detail)
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)
477end
478
479local tex_template = formatters [ [[
480<h1>Font: %s</h1><br/>
481<pre><tt>
482%s
483</tt></pre>
484]] ]
485
486local 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
494end
495
496local 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
505end
506
507
508
509local 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 </th><th>script </th><th>languages </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 local s = s == "*" and "all" or s
545 if ss ["*"] then
546 ss["*"] = nil
547 ss.all = true
548 end
549 local name
550 if done then
551 name = ""
552 else
553 done = true
554 name = f
555 end
556 local title = fonts.handlers.otf.tables.features[name] or ""
557 result[#result+1] = formatters["<tr><td width='50%%'>%s </td><td><tt>%s </tt></td><td><tt>%s </tt></td><td><tt>%s </tt></td></tr>"](title,name,s,concat(table.sortedkeys(ss)," "))
558 end
559 end
560 result[#result+1] = "</table>"
561 end
562 end
563 else
564 result[#result+1] = "<br/><br/>This font has no features."
565 end
566 return concat(result,"\n")
567end
568
569local info_template = formatters [ [[
570<pre><tt>
571version : %s
572comment : %s
573author : %s
574copyright : %s
575
576maillist : ntg-context at ntg.nl
577webpage : www.pragma-ade.nl
578wiki : contextgarden.net
579</tt></pre>
580]] ]
581
582local function info_about()
583 local m = modules ['mtx-server-ctx-fonttest']
584 return info_template(m.version,m.comment,m.author,m.copyright)
585end
586
587local save_template = formatters [ [[
588 the current setup has been saved:
589 <br/> <br/>
590 <table>
591 <tr><td class='tc'>name </td><td>%s</td></tr>
592 <tr><td class='tc'>title </td><td>%s</td></tr>
593 <tr><td class='tc'>font </td><td>%s</td></tr>
594 <tr><td class='tc'>script </td><td>%s</td></tr>
595 <tr><td class='tc'>language </td><td>%s</td></tr>
596 <tr><td class='tc'>features </td><td>%s</td></tr>
597 <tr><td class='tc'>options </td><td>%s</td></tr>
598 <tr><td class='tc'>sampletext </td><td>%s</td></tr>
599 </table>
600]] ]
601
602local function loadbase()
603 local datafile = file.join(basepath,basename)
604 local storage = io.loaddata(datafile) or ""
605 if storage == "" then
606 storage = { }
607 else
608 report("loading '%s'",datafile)
609 storage = loadstring(storage)
610 storage = (storage and storage()) or { }
611 end
612 return storage
613end
614
615local function loadstored(detail,currentfont,name)
616 local storage = loadbase()
617 storage = storage and storage[name]
618 if storage then
619 currentfont = storage.font
620 detail.script = storage.script or detail.script
621 detail.language = storage.language or detail.language
622 detail.title = storage.title or detail.title
623 detail.sampletext = storage.text or detail.sampletext
624 detail.name = name or "no name"
625 for k,v in next, storage.features do
626 detail["f-"..k] = v
627 end
628 for k,v in next, storage.options do
629 detail["o-"..k] = v
630 end
631 end
632 detail.loadname = nil
633 return detail, currentfont
634end
635
636local function savebase(storage,name)
637 local datafile = file.join(basepath,basename)
638 report("saving '%s' in '%s'",name or "data",datafile)
639 io.savedata(datafile,table.serialize(storage,true))
640end
641
642local function deletestored(detail,currentfont,name)
643 local storage = loadbase()
644 if storage and name and storage[name] then
645 report("deleting '%s' from base",name)
646 storage[name] = nil
647 savebase(storage)
648 end
649 detail.deletename = nil
650 return detail, ""
651end
652
653local function save_font(currentfont,detail)
654 local specification = get_specification(currentfont)
655 local name, title, script, language, features, options, text = currentfont, "", "dflt", "dflt", { }, { }, ""
656 if detail then
657 local htmldata = showfeatures(specification.filename)
658 script = detail.script or script
659 language = detail.language or language
660 text = string.strip(detail.sampletext or text)
661 name = string.strip(detail.name or name)
662 title = string.strip(detail.title or title)
663 for k,v in next, htmldata.features do
664 if detail["f-"..k] then features[k] = true end
665 end
666 for k=1,#what_options do
667 local v = what_options[k]
668 if detail["o-"..v] then options[k] = true end
669 end
670 end
671 if name == "" then
672 name = "no name"
673 end
674 local storage = loadbase()
675 storage[name] = {
676 font = currentfont, title = title, script = script, language = language, features = features, options = options, text = text,
677 }
678 savebase(storage,name)
679 return save_template(name,title,currentfont,script,language,concat(table.sortedkeys(features)," "),concat(table.sortedkeys(options)," "),text)
680end
681
682local function load_font(currentfont)
683 local datafile = file.join(basepath,basename)
684 local storage = loadbase(datafile)
685 local result = {}
686 result[#result+1] = "<tr><th>del </th><th>name </th><th>font </th><th>fontname </th><th>script </th><th>language </th><th>features </th><th>title </th><th>sampletext </th></tr>"
687 for k,v in table.sortedhash(storage) do
688 local fontname, fontfile = get_specification(v.font)
689 result[#result+1] = formatters["<tr><td><a href='mtx-server-ctx-fonttest.lua?deletename=%s'>x</a> </td><td><a href='mtx-server-ctx-fonttest.lua?loadname=%s'>%s</a> </td><td>%s </td<td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td></tr>"](
690 k,k,k,v.font,fontname,v.script,v.language,concat(table.sortedkeys(v.features)," "),v.title or "no title",v.text or "")
691 end
692 if #result == 1 then
693 return "nothing saved yet"
694 else
695 return formatters["<table>%s</table>"](concat(result,"\n"))
696 end
697end
698
699local function reset_font(currentfont)
700 return edit_font(currentfont)
701end
702
703local extras_template = formatters [ [[
704 <a href='mtx-server-ctx-fonttest.lua?extra=reload'>remake font database</a> (take some time)<br/><br/>
705]] ]
706
707local function do_extras(detail,currentfont,extra)
708 return extras_template()
709end
710
711local extras = { }
712
713local function do_extra(detail,currentfont,extra)
714 local e = extras[extra]
715 if e then e(detail,currentfont,extra) end
716 return do_extras(detail,currentfont,extra)
717end
718
719function extras.reload()
720 identifyfonts()
721 return do_extras()
722end
723
724local status_template = formatters [ [[
725 <input type="hidden" name="currentfont" value="%s" />
726]] ]
727
728local variables = {
729 ['color-background-one'] = lmx.get('color-background-green'),
730 ['color-background-two'] = lmx.get('color-background-blue'),
731 ['title'] = 'ConTeXt Font Tester',
732 ['formaction'] = "mtx-server-ctx-fonttest.lua",
733}
734
735
736
737function doit(configuration,filename,hashed)
738
739 local start = os.clock()
740
741 local detail = url.query(hashed.query or "")
742
743 local currentfont = detail.currentfont
744 local action = detail.action
745 local selection = detail.selection
746
747 if action == "luajittex" then
748 jitmode = true
749 elseif action == "luatex" then
750 jitmode = false
751 end
752
753 local loadname = detail.loadname
754 local deletename = detail.deletename
755 local extra = detail.extra
756
757 if loadname and loadname ~= "" then
758 detail, currentfont = loadstored(detail,currentfont,loadname)
759 action = "process"
760 elseif deletename and deletename ~= "" then
761 detail, currentfont = deletestored(detail,currentfont,deletename)
762 action = "load"
763 elseif selection and selection ~= "" then
764 currentfont = selection
765 elseif extra and extra ~= "" then
766 do_extra(detail,currentfont,extra)
767 action = "extras"
768 end
769
770 local fontname, fontfile = get_specification(currentfont)
771
772 if fontfile then
773 variables.title = formatters['ConTeXt Font Tester: %s (%s)'](fontname,fontfile)
774 else
775 variables.title = 'ConTeXt Font Tester'
776 end
777
778 if jitmode then
779 variables.title = variables.title .. " (using LuaJit vm)"
780 end
781
782
783
784 report("action: %s",action or "no action")
785
786 local buttons = { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras', jitmode and "luatex" or "luajittex" }
787 local menu = { }
788
789 for i=1,#buttons do
790 local button = buttons[i]
791 menu[#menu+1] = formatters["<button name='action' value='%s' type='submit'>%s</button>"](button,button)
792 end
793
794 variables.menu = concat(menu," ")
795 variables.status = status_template(currentfont or "")
796 variables.maintext = ""
797 variables.javascriptdata = ""
798 variables.javascripts = ""
799 variables.javascriptinit = ""
800
801 local result
802
803 if action == "select" then
804 variables.maintext = select_font()
805 elseif action == "info" then
806 variables.maintext = info_about()
807 elseif action == "extras" then
808 variables.maintext = do_extras()
809 elseif currentfont and currentfont ~= "" then
810 if action == "save" then
811 variables.maintext = save_font(currentfont,detail)
812 elseif action == "load" then
813 variables.maintext = load_font(currentfont,detail)
814 elseif action == "source" then
815 variables.maintext = show_source(currentfont,detail)
816 elseif action == "log" then
817 variables.maintext = show_log(currentfont,detail)
818 elseif action == "features" then
819 variables.maintext = show_font(currentfont,detail)
820 else
821 local e, s
822 if action == "process" then
823 e, s = process_font(currentfont,detail)
824 elseif action == "reset" then
825 e, s = reset_font(currentfont)
826 elseif action == "edit" then
827 e, s = edit_font(currentfont,detail)
828 else
829 e, s = process_font(currentfont,detail)
830 end
831 variables.maintext = e
832 variables.javascriptdata = s
833 variables.javascripts = javascripts
834 variables.javascriptinit = "check_form()"
835 end
836 else
837 variables.maintext = select_font()
838 end
839
840 result = { content = lmx.convert('context-fonttest.lmx',false,variables) }
841
842 report("time spent on page: %0.03f seconds",os.clock()-start)
843
844 return result
845
846end
847
848return doit, true
849
850
851 |