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 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 </td><td><tt>%s </tt></td><td><tt>%s </tt></td><td><tt>%s </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")
562end
563
564local 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
577local function info_about()
578 local m = modules ['mtx-server-ctx-fonttest']
579 return info_template(m.version,m.comment,m.author,m.copyright)
580end
581
582local save_template = formatters [ [[
583 the current setup has been saved:
584 <br/> <br/>
585 <table>
586 <tr><td class='tc'>name </td><td>%s</td></tr>
587 <tr><td class='tc'>title </td><td>%s</td></tr>
588 <tr><td class='tc'>font </td><td>%s</td></tr>
589 <tr><td class='tc'>script </td><td>%s</td></tr>
590 <tr><td class='tc'>language </td><td>%s</td></tr>
591 <tr><td class='tc'>features </td><td>%s</td></tr>
592 <tr><td class='tc'>options </td><td>%s</td></tr>
593 <tr><td class='tc'>sampletext </td><td>%s</td></tr>
594 </table>
595]] ]
596
597local 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
608end
609
610local 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
629end
630
631local 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))
635end
636
637local 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, ""
646end
647
648local 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)
675end
676
677local 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 </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>"
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> </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>"](
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
692end
693
694local function reset_font(currentfont)
695 return edit_font(currentfont)
696end
697
698local extras_template = formatters [ [[
699 <a href='mtx-server-ctx-fonttest.lua?extra=reload'>remake font database</a> (take some time)<br/><br/>
700]] ]
701
702local function do_extras(detail,currentfont,extra)
703 return extras_template()
704end
705
706local extras = { }
707
708local 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)
712end
713
714function extras.reload()
715 identifyfonts()
716 return do_extras()
717end
718
719local status_template = formatters [ [[
720 <input type="hidden" name="currentfont" value="%s" />
721]] ]
722
723local 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
731
732function 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
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," ")
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
841end
842
843return doit, true
844
845
846 |