summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/lua/mtx-base.lua268
-rw-r--r--scripts/context/lua/mtx-cache.lua274
-rw-r--r--scripts/context/lua/mtx-chars.lua866
-rw-r--r--scripts/context/lua/mtx-check.lua506
-rw-r--r--scripts/context/lua/mtx-colors.lua154
-rw-r--r--scripts/context/lua/mtx-context.lua2984
-rw-r--r--scripts/context/lua/mtx-convert.lua350
-rw-r--r--scripts/context/lua/mtx-fcd.lua772
-rw-r--r--scripts/context/lua/mtx-flac.lua476
-rw-r--r--scripts/context/lua/mtx-fonts.lua944
-rw-r--r--scripts/context/lua/mtx-grep.lua340
-rw-r--r--scripts/context/lua/mtx-metatex.lua160
-rw-r--r--scripts/context/lua/mtx-mk-help.lua946
-rw-r--r--scripts/context/lua/mtx-modules.lua404
-rw-r--r--scripts/context/lua/mtx-mtxworks.lua28
-rw-r--r--scripts/context/lua/mtx-package.lua168
-rw-r--r--scripts/context/lua/mtx-patterns.lua2
-rw-r--r--scripts/context/lua/mtx-pdf.lua598
-rw-r--r--scripts/context/lua/mtx-plain.lua258
-rw-r--r--scripts/context/lua/mtx-profile.lua374
-rw-r--r--scripts/context/lua/mtx-rsync.lua378
-rw-r--r--scripts/context/lua/mtx-scite.lua518
-rw-r--r--scripts/context/lua/mtx-server-ctx-fonttest.lua1498
-rw-r--r--scripts/context/lua/mtx-server-ctx-help.lua1410
-rw-r--r--scripts/context/lua/mtx-server-ctx-startup.lua78
-rw-r--r--scripts/context/lua/mtx-server.lua804
-rw-r--r--scripts/context/lua/mtx-texworks.lua242
-rw-r--r--scripts/context/lua/mtx-timing.lua436
-rw-r--r--scripts/context/lua/mtx-tools.lua398
-rw-r--r--scripts/context/lua/mtx-unzip.lua264
-rw-r--r--scripts/context/lua/mtx-update.lua1352
-rw-r--r--scripts/context/lua/mtx-watch.lua862
32 files changed, 9556 insertions, 9556 deletions
diff --git a/scripts/context/lua/mtx-base.lua b/scripts/context/lua/mtx-base.lua
index 66fd06624..bd6749717 100644
--- a/scripts/context/lua/mtx-base.lua
+++ b/scripts/context/lua/mtx-base.lua
@@ -1,134 +1,134 @@
-if not modules then modules = { } end modules ['mtx-base'] = {
- version = 1.001,
- comment = "formerly known as luatools",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-base</entry>
- <entry name="detail">ConTeXt TDS Management Tool (aka luatools)</entry>
- <entry name="version">1.35</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="generate"><short>generate file database</short></flag>
- <flag name="variables"><short>show configuration variables</short></flag>
- <flag name="configurations"><short>show configuration order</short></flag>
- <flag name="expand-braces"><short>expand complex variable</short></flag>
- <flag name="expand-path"><short>expand variable (resolve paths)</short></flag>
- <flag name="expand-var"><short>expand variable (resolve references)</short></flag>
- <flag name="show-path"><short>show path expansion of ...</short></flag>
- <flag name="var-value"><short>report value of variable</short></flag>
- <flag name="find-file"><short>report file location</short></flag>
- <flag name="find-path"><short>report path of file</short></flag>
- <flag name="make"><short>[or <ref name="ini"/>] make luatex format</short></flag>
- <flag name="run"><short>[or <ref name="fmt"/>] run luatex format</short></flag>
- <flag name="compile"><short>assemble and compile lua inifile</short></flag>
- <flag name="verbose"><short>give a bit more info</short></flag>
- <flag name="all"><short>show all found files</short></flag>
- <flag name="format" value="str"><short>filter cf format specification (default 'tex', use 'any' for any match)</short></flag>
- <flag name="pattern" value="str"><short>filter variables</short></flag>
- <flag name="trackers" value="list"><short>enable given trackers</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-base",
- banner = "ConTeXt TDS Management Tool (aka luatools) 1.35",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
--- private option --noluc for testing errors in the stub
-
-local instance = resolvers.instance
-
-local pattern = environment.arguments["pattern"] or nil
-local fileformat = environment.arguments["format"] or "" -- nil ?
-local allresults = environment.arguments["all"] or false
-local trace = environment.arguments["trace"]
-
-if type(pattern) == 'boolean' then
- report("invalid pattern specification")
- pattern = nil
-end
-
-if trace then
- resolvers.settrace(trace) -- move to mtxrun ?
-end
-
-if environment.arguments["find-file"] then
- resolvers.load()
- if pattern then
- resolvers.dowithfilesandreport(resolvers.findfiles, { pattern }, fileformat, allresults)
- else
- resolvers.dowithfilesandreport(resolvers.findfiles, environment.files, fileformat, allresults)
- end
-elseif environment.arguments["find-path"] then
- resolvers.load()
- local path = resolvers.findpath(environment.files[1], fileformat)
- print(path) -- quite basic, wil become function in logs
-elseif environment.arguments["run"] then
- resolvers.load("nofiles") -- ! no need for loading databases
- trackers.enable("resolvers.locating")
- environment.run_format(environment.files[1] or "",environment.files[2] or "",environment.files[3] or "")
-elseif environment.arguments["fmt"] then
- resolvers.load("nofiles") -- ! no need for loading databases
- trackers.enable("resolvers.locating")
- environment.run_format(environment.arguments["fmt"], environment.files[1] or "",environment.files[2] or "")
-elseif environment.arguments["expand-braces"] then
- resolvers.load("nofiles")
- resolvers.dowithfilesandreport(resolvers.expandbraces, environment.files)
-elseif environment.arguments["expand-path"] then
- resolvers.load("nofiles")
- resolvers.dowithfilesandreport(resolvers.expandpath, environment.files)
-elseif environment.arguments["expand-var"] or environment.arguments["expand-variable"] then
- resolvers.load("nofiles")
- resolvers.dowithfilesandreport(resolvers.expansion, environment.files)
-elseif environment.arguments["show-path"] or environment.arguments["path-value"] then
- resolvers.load("nofiles")
- resolvers.dowithfilesandreport(resolvers.showpath, environment.files)
-elseif environment.arguments["var-value"] or environment.arguments["show-value"] then
- resolvers.load("nofiles")
- resolvers.dowithfilesandreport(resolvers.variable, environment.files)
-elseif environment.arguments["format-path"] then
- resolvers.load()
- report(caches.getwritablepath("format"))
-elseif pattern then -- brrr
- resolvers.load()
- resolvers.dowithfilesandreport(resolvers.findfiles, { pattern }, fileformat, allresults)
-elseif environment.arguments["generate"] then
- instance.renewcache = true
- trackers.enable("resolvers.locating")
- resolvers.load()
-elseif environment.arguments["make"] or environment.arguments["ini"] or environment.arguments["compile"] then
- resolvers.load()
- trackers.enable("resolvers.locating")
- environment.make_format(environment.files[1] or "")
-elseif environment.arguments["variables"] or environment.arguments["show-variables"] or environment.arguments["expansions"] or environment.arguments["show-expansions"] then
- resolvers.load("nofiles")
- resolvers.listers.variables(pattern)
-elseif environment.arguments["configurations"] or environment.arguments["show-configurations"] then
- resolvers.load("nofiles")
- resolvers.listers.configurations()
-elseif environment.arguments["exporthelp"] then
- application.export(environment.arguments["exporthelp"],environment.files[1])
-elseif environment.arguments["help"] or (environment.files[1]=='help') or (#environment.files==0) then
- application.help()
-elseif environment.files[1] == 'texmfcnf.lua' then
- resolvers.load("nofiles")
- resolvers.listers.configurations()
-else
- resolvers.load()
- resolvers.dowithfilesandreport(resolvers.findfiles, environment.files, fileformat, allresults)
-end
+if not modules then modules = { } end modules ['mtx-base'] = {
+ version = 1.001,
+ comment = "formerly known as luatools",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-base</entry>
+ <entry name="detail">ConTeXt TDS Management Tool (aka luatools)</entry>
+ <entry name="version">1.35</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="generate"><short>generate file database</short></flag>
+ <flag name="variables"><short>show configuration variables</short></flag>
+ <flag name="configurations"><short>show configuration order</short></flag>
+ <flag name="expand-braces"><short>expand complex variable</short></flag>
+ <flag name="expand-path"><short>expand variable (resolve paths)</short></flag>
+ <flag name="expand-var"><short>expand variable (resolve references)</short></flag>
+ <flag name="show-path"><short>show path expansion of ...</short></flag>
+ <flag name="var-value"><short>report value of variable</short></flag>
+ <flag name="find-file"><short>report file location</short></flag>
+ <flag name="find-path"><short>report path of file</short></flag>
+ <flag name="make"><short>[or <ref name="ini"/>] make luatex format</short></flag>
+ <flag name="run"><short>[or <ref name="fmt"/>] run luatex format</short></flag>
+ <flag name="compile"><short>assemble and compile lua inifile</short></flag>
+ <flag name="verbose"><short>give a bit more info</short></flag>
+ <flag name="all"><short>show all found files</short></flag>
+ <flag name="format" value="str"><short>filter cf format specification (default 'tex', use 'any' for any match)</short></flag>
+ <flag name="pattern" value="str"><short>filter variables</short></flag>
+ <flag name="trackers" value="list"><short>enable given trackers</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-base",
+ banner = "ConTeXt TDS Management Tool (aka luatools) 1.35",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+-- private option --noluc for testing errors in the stub
+
+local instance = resolvers.instance
+
+local pattern = environment.arguments["pattern"] or nil
+local fileformat = environment.arguments["format"] or "" -- nil ?
+local allresults = environment.arguments["all"] or false
+local trace = environment.arguments["trace"]
+
+if type(pattern) == 'boolean' then
+ report("invalid pattern specification")
+ pattern = nil
+end
+
+if trace then
+ resolvers.settrace(trace) -- move to mtxrun ?
+end
+
+if environment.arguments["find-file"] then
+ resolvers.load()
+ if pattern then
+ resolvers.dowithfilesandreport(resolvers.findfiles, { pattern }, fileformat, allresults)
+ else
+ resolvers.dowithfilesandreport(resolvers.findfiles, environment.files, fileformat, allresults)
+ end
+elseif environment.arguments["find-path"] then
+ resolvers.load()
+ local path = resolvers.findpath(environment.files[1], fileformat)
+ print(path) -- quite basic, wil become function in logs
+elseif environment.arguments["run"] then
+ resolvers.load("nofiles") -- ! no need for loading databases
+ trackers.enable("resolvers.locating")
+ environment.run_format(environment.files[1] or "",environment.files[2] or "",environment.files[3] or "")
+elseif environment.arguments["fmt"] then
+ resolvers.load("nofiles") -- ! no need for loading databases
+ trackers.enable("resolvers.locating")
+ environment.run_format(environment.arguments["fmt"], environment.files[1] or "",environment.files[2] or "")
+elseif environment.arguments["expand-braces"] then
+ resolvers.load("nofiles")
+ resolvers.dowithfilesandreport(resolvers.expandbraces, environment.files)
+elseif environment.arguments["expand-path"] then
+ resolvers.load("nofiles")
+ resolvers.dowithfilesandreport(resolvers.expandpath, environment.files)
+elseif environment.arguments["expand-var"] or environment.arguments["expand-variable"] then
+ resolvers.load("nofiles")
+ resolvers.dowithfilesandreport(resolvers.expansion, environment.files)
+elseif environment.arguments["show-path"] or environment.arguments["path-value"] then
+ resolvers.load("nofiles")
+ resolvers.dowithfilesandreport(resolvers.showpath, environment.files)
+elseif environment.arguments["var-value"] or environment.arguments["show-value"] then
+ resolvers.load("nofiles")
+ resolvers.dowithfilesandreport(resolvers.variable, environment.files)
+elseif environment.arguments["format-path"] then
+ resolvers.load()
+ report(caches.getwritablepath("format"))
+elseif pattern then -- brrr
+ resolvers.load()
+ resolvers.dowithfilesandreport(resolvers.findfiles, { pattern }, fileformat, allresults)
+elseif environment.arguments["generate"] then
+ instance.renewcache = true
+ trackers.enable("resolvers.locating")
+ resolvers.load()
+elseif environment.arguments["make"] or environment.arguments["ini"] or environment.arguments["compile"] then
+ resolvers.load()
+ trackers.enable("resolvers.locating")
+ environment.make_format(environment.files[1] or "")
+elseif environment.arguments["variables"] or environment.arguments["show-variables"] or environment.arguments["expansions"] or environment.arguments["show-expansions"] then
+ resolvers.load("nofiles")
+ resolvers.listers.variables(pattern)
+elseif environment.arguments["configurations"] or environment.arguments["show-configurations"] then
+ resolvers.load("nofiles")
+ resolvers.listers.configurations()
+elseif environment.arguments["exporthelp"] then
+ application.export(environment.arguments["exporthelp"],environment.files[1])
+elseif environment.arguments["help"] or (environment.files[1]=='help') or (#environment.files==0) then
+ application.help()
+elseif environment.files[1] == 'texmfcnf.lua' then
+ resolvers.load("nofiles")
+ resolvers.listers.configurations()
+else
+ resolvers.load()
+ resolvers.dowithfilesandreport(resolvers.findfiles, environment.files, fileformat, allresults)
+end
diff --git a/scripts/context/lua/mtx-cache.lua b/scripts/context/lua/mtx-cache.lua
index 7ce5e21be..bff1cb496 100644
--- a/scripts/context/lua/mtx-cache.lua
+++ b/scripts/context/lua/mtx-cache.lua
@@ -1,137 +1,137 @@
-if not modules then modules = { } end modules ['mtx-cache'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-cache</entry>
- <entry name="detail">ConTeXt & MetaTeX Cache Management</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="purge"><short>remove not used files</short></flag>
- <flag name="erase"><short>completely remove cache</short></flag>
- <flag name="list"><short>show cache</short></flag>
- </subcategory>
- <subcategory>
- <flag name="all"><short>all (not yet implemented)</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-cache",
- banner = "ConTeXt & MetaTeX Cache Management 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.cache = scripts.cache or { }
-
-local function collect(path)
- local all = dir.glob(path .. "/**/*")
- local tmas, tmcs, rest = { }, { }, { }
- for i=1,#all do
- local name = all[i]
- local suffix = file.suffix(name)
- if suffix == "tma" then
- tmas[#tmas+1] = name
- elseif suffix == "tmc" then
- tmcs[#tmcs+1] = name
- else
- rest[#rest+1] = name
- end
- end
- return tmas, tmcs, rest, all
-end
-
-local function list(banner,path,tmas,tmcs,rest)
- report("%s: %s",banner,path)
- report()
- report("tma : %4i",#tmas)
- report("tmc : %4i",#tmcs)
- report("rest : %4i",#rest)
- report("total : %4i",#tmas+#tmcs+#rest)
- report()
-end
-
-local function purge(banner,path,list,all)
- report("%s: %s",banner,path)
- report()
- local n = 0
- for i=1,#list do
- local filename = list[i]
- if string.find(filename,"luatex%-cache") then -- safeguard
- if all then
- os.remove(filename)
- n = n + 1
- else
- local suffix = file.suffix(filename)
- if suffix == "tma" then
- local checkname = file.replacesuffix(filename,"tma","tmc")
- if lfs.isfile(checkname) then
- os.remove(filename)
- n = n + 1
- end
- end
- end
- end
- end
- report("removed tma files : %i",n)
- report()
- return n
-end
-
-function scripts.cache.purge()
- local writable = caches.getwritablepath()
- local tmas, tmcs, rest = collect(writable)
- list("writable path",writable,tmas,tmcs,rest)
- purge("writable path",writable,tmas)
- list("writable path",writable,tmas,tmcs,rest)
-end
-
-function scripts.cache.erase()
- local writable = caches.getwritablepath()
- local tmas, tmcs, rest, all = collect(writable)
- list("writable path",writable,tmas,tmcs,rest)
- purge("writable path",writable,all,true)
- list("writable path",writable,tmas,tmcs,rest)
-end
-
-function scripts.cache.list()
- local readables = caches.getreadablepaths()
- local writable = caches.getwritablepath()
- local tmas, tmcs, rest = collect(writable)
- list("writable path",writable,tmas,tmcs,rest)
- for i=1,#readables do
- local readable = readables[i]
- if readable ~= writable then
- local tmas, tmcs = collect(readable)
- list("readable path",readable,tmas,tmcs,rest)
- end
- end
-end
-
-if environment.argument("purge") then
- scripts.cache.purge()
-elseif environment.argument("erase") then
- scripts.cache.erase()
-elseif environment.argument("list") then
- scripts.cache.list()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-cache'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-cache</entry>
+ <entry name="detail">ConTeXt & MetaTeX Cache Management</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="purge"><short>remove not used files</short></flag>
+ <flag name="erase"><short>completely remove cache</short></flag>
+ <flag name="list"><short>show cache</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="all"><short>all (not yet implemented)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-cache",
+ banner = "ConTeXt & MetaTeX Cache Management 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.cache = scripts.cache or { }
+
+local function collect(path)
+ local all = dir.glob(path .. "/**/*")
+ local tmas, tmcs, rest = { }, { }, { }
+ for i=1,#all do
+ local name = all[i]
+ local suffix = file.suffix(name)
+ if suffix == "tma" then
+ tmas[#tmas+1] = name
+ elseif suffix == "tmc" then
+ tmcs[#tmcs+1] = name
+ else
+ rest[#rest+1] = name
+ end
+ end
+ return tmas, tmcs, rest, all
+end
+
+local function list(banner,path,tmas,tmcs,rest)
+ report("%s: %s",banner,path)
+ report()
+ report("tma : %4i",#tmas)
+ report("tmc : %4i",#tmcs)
+ report("rest : %4i",#rest)
+ report("total : %4i",#tmas+#tmcs+#rest)
+ report()
+end
+
+local function purge(banner,path,list,all)
+ report("%s: %s",banner,path)
+ report()
+ local n = 0
+ for i=1,#list do
+ local filename = list[i]
+ if string.find(filename,"luatex%-cache") then -- safeguard
+ if all then
+ os.remove(filename)
+ n = n + 1
+ else
+ local suffix = file.suffix(filename)
+ if suffix == "tma" then
+ local checkname = file.replacesuffix(filename,"tma","tmc")
+ if lfs.isfile(checkname) then
+ os.remove(filename)
+ n = n + 1
+ end
+ end
+ end
+ end
+ end
+ report("removed tma files : %i",n)
+ report()
+ return n
+end
+
+function scripts.cache.purge()
+ local writable = caches.getwritablepath()
+ local tmas, tmcs, rest = collect(writable)
+ list("writable path",writable,tmas,tmcs,rest)
+ purge("writable path",writable,tmas)
+ list("writable path",writable,tmas,tmcs,rest)
+end
+
+function scripts.cache.erase()
+ local writable = caches.getwritablepath()
+ local tmas, tmcs, rest, all = collect(writable)
+ list("writable path",writable,tmas,tmcs,rest)
+ purge("writable path",writable,all,true)
+ list("writable path",writable,tmas,tmcs,rest)
+end
+
+function scripts.cache.list()
+ local readables = caches.getreadablepaths()
+ local writable = caches.getwritablepath()
+ local tmas, tmcs, rest = collect(writable)
+ list("writable path",writable,tmas,tmcs,rest)
+ for i=1,#readables do
+ local readable = readables[i]
+ if readable ~= writable then
+ local tmas, tmcs = collect(readable)
+ list("readable path",readable,tmas,tmcs,rest)
+ end
+ end
+end
+
+if environment.argument("purge") then
+ scripts.cache.purge()
+elseif environment.argument("erase") then
+ scripts.cache.erase()
+elseif environment.argument("list") then
+ scripts.cache.list()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-chars.lua b/scripts/context/lua/mtx-chars.lua
index fa3b3d353..9f6852da2 100644
--- a/scripts/context/lua/mtx-chars.lua
+++ b/scripts/context/lua/mtx-chars.lua
@@ -1,433 +1,433 @@
-if not modules then modules = { } end modules ['mtx-chars'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- obsolete: --stix convert stix table to math table
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-chars</entry>
- <entry name="detail">MkII Character Table Generators</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="xtx"><short>generate xetx-*.tex (used by xetex)</short></flag>
- <flag name="pdf"><short>generate pdfr-def.tex (used by pdftex)</short></flag>
- <flag name="entities"><short>generate entities table</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-chars",
- banner = "MkII Character Table Generators 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-local format, gmatch, upper, lower = string.format, string.gmatch, string.upper, string.lower
-local tonumber = tonumber
-local concat = table.concat
-local utfchar = utf.char
-
-scripts = scripts or { }
-scripts.chars = scripts.chars or { }
-
---~ local banner = [[
---~ -- filename : char-mth.lua
---~ -- comment : companion to char-mth.tex (in ConTeXt)
---~ -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
---~ -- license : see context related readme files
---~ -- comment : generated from data file downloaded from STIX website
---~
---~ if not versions then versions = { } end versions['char-mth'] = 1.001
---~ if not characters then characters = { } end
---~ ]]
---~
---~ function scripts.chars.stixtomkiv(inname,outname)
---~ if inname == "" then
---~ report("aquiring math data, invalid datafilename")
---~ end
---~ local f = io.open(inname)
---~ if not f then
---~ report("aquiring math data, invalid datafile")
---~ else
---~ report("aquiring math data, processing %s",inname)
---~ if not outname or outname == "" then
---~ outname = "char-mth.lua"
---~ end
---~ local classes = {
---~ N = "normal",
---~ A = "alphabetic",
---~ D = "diacritic",
---~ P = "punctuation",
---~ B = "binary",
---~ R = "relation",
---~ L = "large",
---~ O = "opening",
---~ C = "closing",
---~ F = "fence"
---~ }
---~ local valid, done = false, { }
---~ local g = io.open(outname,'w')
---~ g:write(banner)
---~ g:write(format("\ncharacters.math = {\n"))
---~ for l in f:lines() do
---~ if not valid then
---~ valid = l:find("AMS/TeX name")
---~ end
---~ if valid then
---~ local unicode = l:sub(2,6)
---~ if unicode:sub(1,1) ~= " " and unicode ~= "" and not done[unicode] then
---~ local mathclass, adobename, texname = l:sub(57,57) or "", l:sub(13,36) or "", l:sub(84,109) or ""
---~ texname, adobename = texname:gsub("[\\ ]",""), adobename:gsub("[\\ ]","")
---~ local t = { }
---~ if mathclass ~= "" then t[#t+1] = format("mathclass='%s'", classes[mathclass] or "unknown") end
---~ if adobename ~= "" then t[#t+1] = format("adobename='%s'", adobename ) end
---~ if texname ~= "" then t[#t+1] = format("texname='%s'" , texname ) end
---~ if #t > 0 then
---~ g:write(format("\t[0x%s] = { %s },\n",unicode, concat(t,", ")))
---~ end
---~ done[unicode] = true
---~ end
---~ end
---~ end
---~ if not valid then
---~ g:write("\t-- The data file is corrupt, invalid or maybe the format has changed.\n")
---~ report("aquiring math data, problems with data table")
---~ else
---~ report("aquiring math data, table saved in %s",outname)
---~ end
---~ g:write("}\n")
---~ g:close()
---~ f:close()
---~ end
---~ end
-
-function scripts.chars.stixtomkiv(inname,outname)
- report("we no longer use this options but use our own tables instead")
-end
-
-local banner_pdf_1 = [[
-% filename : pdfr-def.tex
-% comment : generated by mtxrun --script chars --pdf
-% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-% copyright: PRAGMA ADE / ConTeXt Development Team
-% license : see context related readme files
-%
-]]
-
-local banner_pdf_2 = [[
-%
-\endinput
-]]
-
-function scripts.chars.makepdfr()
- local chartable = resolvers.findfile("char-def.lua") or ""
- if chartable ~= "" then
- dofile(chartable)
- if characters and characters.data then
- local f = io.open("pdfr-def.tex", 'w')
- if f then
- f:write(banner_pdf_1)
- local cd = characters.data
- local sd = table.sortedkeys(cd)
- for i=1,#sd do
- local char = cd[sd[i]]
- if char.adobename then
- f:write(format("\\pdfglyphtounicode{%s}{%04X}%%\n",char.adobename,char.unicodeslot))
- end
- end
- f:write(banner_pdf_2)
- f:close()
- end
- end
- end
-end
-
-local banner_utf_module = [[
-%% filename : %s
-%% comment : generated by mtxrun --script chars --xtx
-%% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-%% copyright: PRAGMA ADE / ConTeXt Development Team
-%% license : see context related readme files
-]]
-
-local banner_utf_mappings = [[
-
-% lc/uc/catcode mappings
-
-]]
-
-local banner_utf_patch = [[
-
-% patch needed for turkish
-
-\setXTXcharcodes "201C "201C "201C
-\setXTXcharcodes "201D "201D "201D
-
-% patch needed for french
-
-\setXTXcharcodes "2019 "2019 "2019
-
-]]
-
-local banner_utf_names = [[
-
-% named characters mapped onto utf (\\char is needed for accents)
-
-]]
-
-local banner_utf_classes = [[
-
-% some character classes for xetex; seems to be rather hard coded, these numbers
-% and also a mix of several classes; here we do linebreaks
-
-]]
-
-local banner_utf_finish = [[
-
-\endinput
-]]
-
-local xtxclasses = {
- id = 1,
- ex = 3,
- is = 3,
- cm = 256,
- op = 2,
- ns = 3,
- cl = 3,
-}
-
-function scripts.chars.makeencoutf()
- local chartable = resolvers.findfile("char-def.lua") or ""
- if chartable ~= "" then
- dofile(chartable)
- local function open(name,banner)
- local f = io.open(name,'w')
- if f then
- report("writing '%s'",name)
- f:write(format(banner_utf_module,name))
- f:write(banner)
- f:write()
- return f
- end
- end
- local function close(f)
- f:write(banner_utf_finish)
- f:close()
- end
- local data = characters and characters.data
- if data then
- local list = table.sortedkeys(characters.data)
- local f = open("xetx-utf.tex",banner_utf_mappings)
- if f then
- for i=1,#list do
- local code = list[i]
- if code <= 0xFFFF then
- local chr = data[code]
- local cc = chr.category
- if cc == 'll' or cc == 'lu' or cc == 'lt' then
- if not chr.lccode then chr.lccode = code end
- if not chr.uccode then chr.uccode = code end
- f:write(format('\\setXTXcharcodes "%05X "%05X "%05X %% %s\n',code,chr.lccode,chr.uccode,chr.description))
- end
- end
- end
- f:write("\n")
- for i=1,#list do
- local code = list[i]
- local chr = data[code]
- if chr and chr.range then
- local cc = chr.category
- if cc == 'lo' then
- f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharcodes\\recurselevel\\recurselevel\\recurselevel}\n',code,chr.range))
- end
- end
- end
- f:write(banner_utf_patch)
- close(f)
- end
- local f = open("xetx-chr.tex",banner_utf_names)
- if f then
- local length = 0
- for i=1,#list do
- local code = list[i]
- if code > 0x5B and code <= 0xFFFF then
- local chr = data[code]
- if chr and #(chr.contextname or "") > length then
- length = #chr.contextname
- end
- end
- end
- local template = "\\def\\%-".. length .. "s{\\char\"%05X } %% %s: %s\n"
- for i=1,#list do
- local code = list[i]
- if code > 0x5B and code <= 0xFFFF then
- local chr = data[code]
- if chr and chr.contextname then
- local ch = utfchar(code)
- f:write(format(template, chr.contextname, code, chr.description, ch))
- end
- end
- end
- close(f)
- end
- local f = open("xetx-cls.tex",banner_utf_classes)
- if f then
- for k, v in next, xtxclasses do
- f:write(format("\\defineXTXcharinjectionclass[lb:%s]\n",k))
- end
- f:write("\n")
- local i_first, i_last, i_clb = nil, nil, nil
- local function flush()
- if i_first then
- if i_first == i_last then
- f:write(format('\\dosetXTXcharacterclass{"%05X}{lb:%s}\n',i_first,i_clb))
- else
- f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharacterclass\\fastrecursecounter{lb:%s}}\n',i_first,i_last,i_clb))
- end
- end
- i_first, i_last, i_clb = nil, nil, nil
- end
- for i=1,#list do
- local code = list[i]
- local code_next = list[i+1]
- local chr = data[code]
- local chr_next = data[code_next]
- local clb = chr and chr.linebreak
- local lbc = xtxclasses[clb]
- if not lbc then
- flush()
- elseif clb == i_clb then
- if i_first then
- i_last = code
- else
- i_first, i_last, i_clb = code, code, clb
- end
- else
- flush()
- i_first, i_last, i_clb = code, code, clb
- end
- end
- flush()
- f:write("\n")
- for i=1,#list do
- local code = list[i]
- local chr = data[code]
- if chr and chr.range then
- local lbc = chr.linebreak
- if xtxclasses[lbc] then
- f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharacterclass\\fastrecursecounter{lb:%s}}\n',code,chr.range,lbc))
- end
- end
- end
- close(f)
- end
- end
- end
-end
-
-local entityfiles = {
- "http://www.w3.org/2003/entities/2007/w3centities-f.ent",
- "http://www.w3.org/2003/entities/2007/htmlmathml-f.ent",
-}
-
-function scripts.chars.xmlentities()
- local done = { }
- local entities = { "local entities = utilities.storage.allocate {" }
- for i=1,#entityfiles do
- local f = entityfiles[i]
- local s = url.hashed(f)
- local b = file.basename(s.path)
- local n = resolvers.findfile(b)
- local data = io.loaddata(n)
- for name, value in gmatch(data,'<!ENTITY +(%S+) +"(.-)" *>') do
- if not done[name] then
- done[name] = true
- local str, hex
- local low = lower(name)
- if name == "newline" then
- -- let's forget about that one
- elseif name == "lt" then
- str, hex = "<", format("%s %05X",hex,c)
- elseif name == "gt" then
- str, hex = ">", format("%s %05X",hex,c)
- elseif name == "amp" then
- str, hex = "&", format("%s %05X",hex,c)
- else
- for t, c in gmatch(value,"&#([x]*)([^;]+);") do
- if t == "x" then
- c = tonumber(c,16)
- else
- c = tonumber(c)
- end
- if str then
- str, hex = str .. utfchar(c), format("%s %05X",hex,c)
- else
- str, hex = utfchar(c), format("U+%05X",c)
- end
- end
- end
- if str and hex then
- entities[#entities+1] = format(' ["%s"] = %q, -- %s',name,str,hex)
- end
- end
- end
- end
- entities[#entities+1] = "}"
- io.savedata("xmlentities.tmp",concat(entities,"\n"))
-end
-
-if environment.argument("stix") then
- local inname = environment.files[1] or ""
- local outname = environment.files[2] or ""
- scripts.chars.stixtomkiv(inname,outname)
-elseif environment.argument("entities") then
- scripts.chars.xmlentities()
-elseif environment.argument("xtx") then
- scripts.chars.makeencoutf()
-elseif environment.argument("pdf") then
- scripts.chars.makepdfr()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
-
--- local http = require("socket.http")
--- local ltn12 = require("ltn12")
---
--- local t = { }
--- local status, message = http.request {
--- url = f,
--- sink = ltn12.sink.table(t)
--- }
---
--- local template = [[
--- <?xml version='1.0' ?>
---
--- <!DOCTYPE dummy [
---
--- %s
---
--- ]>
---
--- <dummy>This is just a placeholder.</dummy>
--- ]]
---
--- local e = string.format(template,io.loaddata(n))
--- local x = xml.convert(e, { utfize_entities = true } )
--- local entities = x.entities
+if not modules then modules = { } end modules ['mtx-chars'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- obsolete: --stix convert stix table to math table
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-chars</entry>
+ <entry name="detail">MkII Character Table Generators</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="xtx"><short>generate xetx-*.tex (used by xetex)</short></flag>
+ <flag name="pdf"><short>generate pdfr-def.tex (used by pdftex)</short></flag>
+ <flag name="entities"><short>generate entities table</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-chars",
+ banner = "MkII Character Table Generators 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+local format, gmatch, upper, lower = string.format, string.gmatch, string.upper, string.lower
+local tonumber = tonumber
+local concat = table.concat
+local utfchar = utf.char
+
+scripts = scripts or { }
+scripts.chars = scripts.chars or { }
+
+--~ local banner = [[
+--~ -- filename : char-mth.lua
+--~ -- comment : companion to char-mth.tex (in ConTeXt)
+--~ -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+--~ -- license : see context related readme files
+--~ -- comment : generated from data file downloaded from STIX website
+--~
+--~ if not versions then versions = { } end versions['char-mth'] = 1.001
+--~ if not characters then characters = { } end
+--~ ]]
+--~
+--~ function scripts.chars.stixtomkiv(inname,outname)
+--~ if inname == "" then
+--~ report("aquiring math data, invalid datafilename")
+--~ end
+--~ local f = io.open(inname)
+--~ if not f then
+--~ report("aquiring math data, invalid datafile")
+--~ else
+--~ report("aquiring math data, processing %s",inname)
+--~ if not outname or outname == "" then
+--~ outname = "char-mth.lua"
+--~ end
+--~ local classes = {
+--~ N = "normal",
+--~ A = "alphabetic",
+--~ D = "diacritic",
+--~ P = "punctuation",
+--~ B = "binary",
+--~ R = "relation",
+--~ L = "large",
+--~ O = "opening",
+--~ C = "closing",
+--~ F = "fence"
+--~ }
+--~ local valid, done = false, { }
+--~ local g = io.open(outname,'w')
+--~ g:write(banner)
+--~ g:write(format("\ncharacters.math = {\n"))
+--~ for l in f:lines() do
+--~ if not valid then
+--~ valid = l:find("AMS/TeX name")
+--~ end
+--~ if valid then
+--~ local unicode = l:sub(2,6)
+--~ if unicode:sub(1,1) ~= " " and unicode ~= "" and not done[unicode] then
+--~ local mathclass, adobename, texname = l:sub(57,57) or "", l:sub(13,36) or "", l:sub(84,109) or ""
+--~ texname, adobename = texname:gsub("[\\ ]",""), adobename:gsub("[\\ ]","")
+--~ local t = { }
+--~ if mathclass ~= "" then t[#t+1] = format("mathclass='%s'", classes[mathclass] or "unknown") end
+--~ if adobename ~= "" then t[#t+1] = format("adobename='%s'", adobename ) end
+--~ if texname ~= "" then t[#t+1] = format("texname='%s'" , texname ) end
+--~ if #t > 0 then
+--~ g:write(format("\t[0x%s] = { %s },\n",unicode, concat(t,", ")))
+--~ end
+--~ done[unicode] = true
+--~ end
+--~ end
+--~ end
+--~ if not valid then
+--~ g:write("\t-- The data file is corrupt, invalid or maybe the format has changed.\n")
+--~ report("aquiring math data, problems with data table")
+--~ else
+--~ report("aquiring math data, table saved in %s",outname)
+--~ end
+--~ g:write("}\n")
+--~ g:close()
+--~ f:close()
+--~ end
+--~ end
+
+function scripts.chars.stixtomkiv(inname,outname)
+ report("we no longer use this options but use our own tables instead")
+end
+
+local banner_pdf_1 = [[
+% filename : pdfr-def.tex
+% comment : generated by mtxrun --script chars --pdf
+% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+% copyright: PRAGMA ADE / ConTeXt Development Team
+% license : see context related readme files
+%
+]]
+
+local banner_pdf_2 = [[
+%
+\endinput
+]]
+
+function scripts.chars.makepdfr()
+ local chartable = resolvers.findfile("char-def.lua") or ""
+ if chartable ~= "" then
+ dofile(chartable)
+ if characters and characters.data then
+ local f = io.open("pdfr-def.tex", 'w')
+ if f then
+ f:write(banner_pdf_1)
+ local cd = characters.data
+ local sd = table.sortedkeys(cd)
+ for i=1,#sd do
+ local char = cd[sd[i]]
+ if char.adobename then
+ f:write(format("\\pdfglyphtounicode{%s}{%04X}%%\n",char.adobename,char.unicodeslot))
+ end
+ end
+ f:write(banner_pdf_2)
+ f:close()
+ end
+ end
+ end
+end
+
+local banner_utf_module = [[
+%% filename : %s
+%% comment : generated by mtxrun --script chars --xtx
+%% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+%% copyright: PRAGMA ADE / ConTeXt Development Team
+%% license : see context related readme files
+]]
+
+local banner_utf_mappings = [[
+
+% lc/uc/catcode mappings
+
+]]
+
+local banner_utf_patch = [[
+
+% patch needed for turkish
+
+\setXTXcharcodes "201C "201C "201C
+\setXTXcharcodes "201D "201D "201D
+
+% patch needed for french
+
+\setXTXcharcodes "2019 "2019 "2019
+
+]]
+
+local banner_utf_names = [[
+
+% named characters mapped onto utf (\\char is needed for accents)
+
+]]
+
+local banner_utf_classes = [[
+
+% some character classes for xetex; seems to be rather hard coded, these numbers
+% and also a mix of several classes; here we do linebreaks
+
+]]
+
+local banner_utf_finish = [[
+
+\endinput
+]]
+
+local xtxclasses = {
+ id = 1,
+ ex = 3,
+ is = 3,
+ cm = 256,
+ op = 2,
+ ns = 3,
+ cl = 3,
+}
+
+function scripts.chars.makeencoutf()
+ local chartable = resolvers.findfile("char-def.lua") or ""
+ if chartable ~= "" then
+ dofile(chartable)
+ local function open(name,banner)
+ local f = io.open(name,'w')
+ if f then
+ report("writing '%s'",name)
+ f:write(format(banner_utf_module,name))
+ f:write(banner)
+ f:write()
+ return f
+ end
+ end
+ local function close(f)
+ f:write(banner_utf_finish)
+ f:close()
+ end
+ local data = characters and characters.data
+ if data then
+ local list = table.sortedkeys(characters.data)
+ local f = open("xetx-utf.tex",banner_utf_mappings)
+ if f then
+ for i=1,#list do
+ local code = list[i]
+ if code <= 0xFFFF then
+ local chr = data[code]
+ local cc = chr.category
+ if cc == 'll' or cc == 'lu' or cc == 'lt' then
+ if not chr.lccode then chr.lccode = code end
+ if not chr.uccode then chr.uccode = code end
+ f:write(format('\\setXTXcharcodes "%05X "%05X "%05X %% %s\n',code,chr.lccode,chr.uccode,chr.description))
+ end
+ end
+ end
+ f:write("\n")
+ for i=1,#list do
+ local code = list[i]
+ local chr = data[code]
+ if chr and chr.range then
+ local cc = chr.category
+ if cc == 'lo' then
+ f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharcodes\\recurselevel\\recurselevel\\recurselevel}\n',code,chr.range))
+ end
+ end
+ end
+ f:write(banner_utf_patch)
+ close(f)
+ end
+ local f = open("xetx-chr.tex",banner_utf_names)
+ if f then
+ local length = 0
+ for i=1,#list do
+ local code = list[i]
+ if code > 0x5B and code <= 0xFFFF then
+ local chr = data[code]
+ if chr and #(chr.contextname or "") > length then
+ length = #chr.contextname
+ end
+ end
+ end
+ local template = "\\def\\%-".. length .. "s{\\char\"%05X } %% %s: %s\n"
+ for i=1,#list do
+ local code = list[i]
+ if code > 0x5B and code <= 0xFFFF then
+ local chr = data[code]
+ if chr and chr.contextname then
+ local ch = utfchar(code)
+ f:write(format(template, chr.contextname, code, chr.description, ch))
+ end
+ end
+ end
+ close(f)
+ end
+ local f = open("xetx-cls.tex",banner_utf_classes)
+ if f then
+ for k, v in next, xtxclasses do
+ f:write(format("\\defineXTXcharinjectionclass[lb:%s]\n",k))
+ end
+ f:write("\n")
+ local i_first, i_last, i_clb = nil, nil, nil
+ local function flush()
+ if i_first then
+ if i_first == i_last then
+ f:write(format('\\dosetXTXcharacterclass{"%05X}{lb:%s}\n',i_first,i_clb))
+ else
+ f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharacterclass\\fastrecursecounter{lb:%s}}\n',i_first,i_last,i_clb))
+ end
+ end
+ i_first, i_last, i_clb = nil, nil, nil
+ end
+ for i=1,#list do
+ local code = list[i]
+ local code_next = list[i+1]
+ local chr = data[code]
+ local chr_next = data[code_next]
+ local clb = chr and chr.linebreak
+ local lbc = xtxclasses[clb]
+ if not lbc then
+ flush()
+ elseif clb == i_clb then
+ if i_first then
+ i_last = code
+ else
+ i_first, i_last, i_clb = code, code, clb
+ end
+ else
+ flush()
+ i_first, i_last, i_clb = code, code, clb
+ end
+ end
+ flush()
+ f:write("\n")
+ for i=1,#list do
+ local code = list[i]
+ local chr = data[code]
+ if chr and chr.range then
+ local lbc = chr.linebreak
+ if xtxclasses[lbc] then
+ f:write(format('\\dofastrecurse{"%05X}{"%05X}{1}{\\dosetXTXcharacterclass\\fastrecursecounter{lb:%s}}\n',code,chr.range,lbc))
+ end
+ end
+ end
+ close(f)
+ end
+ end
+ end
+end
+
+local entityfiles = {
+ "http://www.w3.org/2003/entities/2007/w3centities-f.ent",
+ "http://www.w3.org/2003/entities/2007/htmlmathml-f.ent",
+}
+
+function scripts.chars.xmlentities()
+ local done = { }
+ local entities = { "local entities = utilities.storage.allocate {" }
+ for i=1,#entityfiles do
+ local f = entityfiles[i]
+ local s = url.hashed(f)
+ local b = file.basename(s.path)
+ local n = resolvers.findfile(b)
+ local data = io.loaddata(n)
+ for name, value in gmatch(data,'<!ENTITY +(%S+) +"(.-)" *>') do
+ if not done[name] then
+ done[name] = true
+ local str, hex
+ local low = lower(name)
+ if name == "newline" then
+ -- let's forget about that one
+ elseif name == "lt" then
+ str, hex = "<", format("%s %05X",hex,c)
+ elseif name == "gt" then
+ str, hex = ">", format("%s %05X",hex,c)
+ elseif name == "amp" then
+ str, hex = "&", format("%s %05X",hex,c)
+ else
+ for t, c in gmatch(value,"&#([x]*)([^;]+);") do
+ if t == "x" then
+ c = tonumber(c,16)
+ else
+ c = tonumber(c)
+ end
+ if str then
+ str, hex = str .. utfchar(c), format("%s %05X",hex,c)
+ else
+ str, hex = utfchar(c), format("U+%05X",c)
+ end
+ end
+ end
+ if str and hex then
+ entities[#entities+1] = format(' ["%s"] = %q, -- %s',name,str,hex)
+ end
+ end
+ end
+ end
+ entities[#entities+1] = "}"
+ io.savedata("xmlentities.tmp",concat(entities,"\n"))
+end
+
+if environment.argument("stix") then
+ local inname = environment.files[1] or ""
+ local outname = environment.files[2] or ""
+ scripts.chars.stixtomkiv(inname,outname)
+elseif environment.argument("entities") then
+ scripts.chars.xmlentities()
+elseif environment.argument("xtx") then
+ scripts.chars.makeencoutf()
+elseif environment.argument("pdf") then
+ scripts.chars.makepdfr()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
+
+-- local http = require("socket.http")
+-- local ltn12 = require("ltn12")
+--
+-- local t = { }
+-- local status, message = http.request {
+-- url = f,
+-- sink = ltn12.sink.table(t)
+-- }
+--
+-- local template = [[
+-- <?xml version='1.0' ?>
+--
+-- <!DOCTYPE dummy [
+--
+-- %s
+--
+-- ]>
+--
+-- <dummy>This is just a placeholder.</dummy>
+-- ]]
+--
+-- local e = string.format(template,io.loaddata(n))
+-- local x = xml.convert(e, { utfize_entities = true } )
+-- local entities = x.entities
diff --git a/scripts/context/lua/mtx-check.lua b/scripts/context/lua/mtx-check.lua
index bddb2e139..9f52509ec 100644
--- a/scripts/context/lua/mtx-check.lua
+++ b/scripts/context/lua/mtx-check.lua
@@ -1,253 +1,253 @@
-if not modules then modules = { } end modules ['mtx-check'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local P, R, S, V, C, CP, CC, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cp, lpeg.Cc, lpeg.match
-local gsub, sub, format = string.gsub, string.sub, string.format
-local insert, remove = table.insert, table.remove
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-check</entry>
- <entry name="detail">Basic ConTeXt Syntax Checking</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="convert"><short>check tex file for errors</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-check",
- banner = "Basic ConTeXt Syntax Checking 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.checker = scripts.checker or { }
-
-local validator = { }
-
-validator.n = 1
-validator.errors = { }
-validator.trace = false
-validator.direct = false
-
-validator.printer = print
-validator.tracer = print
-
-local message = function(position, kind, extra)
- local ve = validator.errors
- ve[#ve+1] = { kind, position, validator.n, extra }
- if validator.direct then
- position = position or "eof"
- if extra then
- validator.printer(format("%s error at position %s (line %s) (%s)",kind,position,validator.n,extra))
- else
- validator.printer(format("%s error at position %s (line %s)",kind,position,validator.n))
- end
- end
-end
-
-local progress = function(position, data, kind)
- if validator.trace then
- validator.tracer(format("%s at position %s: %s", kind, position, data or ""))
- end
-end
-
-local i_m, d_m = P("$"), P("$$")
-local l_s, r_s = P("["), P("]")
-local l_g, r_g = P("{"), P("}")
-
-local okay = lpeg.P("{[}") + lpeg.P("{]}")
-
-local esc = P("\\")
-local cr = P("\r")
-local lf = P("\n")
-local crlf = P("\r\n")
-local space = S(" \t\f\v")
-local newline = crlf + cr + lf
-
-local line = newline / function() validator.n = validator.n + 1 end
-
-local startluacode = P("\\startluacode")
-local stopluacode = P("\\stopluacode")
-
-local somecode = startluacode * (1-stopluacode)^1 * stopluacode
-
-local stack = { }
-
-local function push(p,s)
--- print("start",p,s)
- insert(stack,{ p, s, validator.n })
-end
-
-local function pop(p,s)
--- print("stop",p,s)
- local top = remove(stack)
- if not top then
- message(p,"missing start")
- elseif top[2] ~= s then
- message(p,"missing stop",format("see line %s",top[3]))
- else
- -- okay
- end
-end
-
-local cstoken = R("az","AZ","\127\255")
-
-local start = CP() * P("\\start") * C(cstoken^0) / push
-local stop = CP() * P("\\stop") * C(cstoken^0) / pop
-
-local contextgrammar = P { "tokens",
- ["tokens"] = (V("ignore") + V("start") + V("stop") + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + V("errors") + 1)^0,
- ["start"] = start,
- ["stop"] = stop,
- ["whatever"] = line + esc * 1 + C(P("%") * (1-line)^0),
- ["grouped"] = l_g * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_g - r_g))^0 * r_g,
- ["setup"] = l_s * (okay + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_s - r_s))^0 * r_s,
- ["display"] = d_m * (V("whatever") + V("grouped") + (1 - d_m))^0 * d_m,
- ["inline"] = i_m * (V("whatever") + V("grouped") + (1 - i_m))^0 * i_m,
- ["errors"] = V("gerror") + V("serror") + V("derror") + V("ierror"),
- ["gerror"] = CP() * (l_g + r_g) * CC("grouping error") / message,
- ["serror"] = CP() * (l_s + r_g) * CC("setup error") / message,
- ["derror"] = CP() * d_m * CC("display math error") / message,
- ["ierror"] = CP() * i_m * CC("inline math error") / message,
- ["ignore"] = somecode,
-}
-
--- metafun variant
-
-local function push(p,s)
- insert(stack,{ p, s, validator.n })
-end
-
-local function pop(p,s)
- local top = remove(stack)
- if not top then
- message(p,"missing <some>def")
- end
-end
-
-local function finish(p)
- local bot = stack[1]
- if bot then
- message(false,format("missing enddef for %s",bot[2]),format("see line %s",bot[3]))
- end
- stack = { }
-end
-
-local l_b, r_b = P("["), P("]")
-local l_g, r_g = P("{"), P("}")
-local l_p, r_p = P("("), P(")")
-
-local start = CP() * C( P("vardef") + P("primarydef") + P("secondarydef") + P("tertiarydef") + P("def") ) / push
-local stop = CP() * C( P("enddef") ) / pop
-
-local dstring = P('"') * (1-P('"'))^0 * P('"')
-local semicolon = P(";")
-
-local separator = line + space + semicolon
-
--- todo: start/stop also in ()
-
-local metafungrammar = P { "tokens",
- ["tokens"] = (V("start") + V("stop") + V("string") + V("whatever") + V("braces") + V("brackets") + V("parentheses") + V("errors") + 1)^0
- * (CP() / finish),
- ["start"] = separator * start * #separator,
- ["stop"] = separator * stop * #separator,
- ["string"] = dstring,
- ["whatever"] = line + C(P("%") * (1-line)^0),
- ["braces"] = l_g * (V("whatever") + V("string") + V("braces") + V("brackets") + V("parentheses") + (1 - l_g - r_g))^0 * r_g,
- ["brackets"] = l_b * (V("whatever") + V("string") + V("braces") + V("brackets") + V("parentheses") + (1 - l_b - r_b))^0 * r_b,
- ["parentheses"] = l_p * (V("whatever") + V("string") + V("braces") + V("brackets") + V("parentheses") + (1 - l_p - r_p))^0 * r_p,
- ["errors"] = V("gerror") + V("berror") + V("perror"),
- ["gerror"] = CP() * (l_g + r_g) * CC("braces error") / message,
- ["berror"] = CP() * (l_b + r_b) * CC("brackets error") / message,
- ["perror"] = CP() * (l_p + r_p) * CC("parentheses error") / message,
-}
-
-local grammars = {
- mp = metafungrammar,
- mpii = metafungrammar,
- mpiv = metafungrammar,
- tex = contextgrammar,
- mkii = contextgrammar,
- mkiv = contextgrammar,
-}
-
-function validator.check(str,filetype)
- validator.n = 1
- validator.errors = { }
- local grammar = grammars[filetype] or grammars.tex
- lpegmatch(grammar,str)
-end
-
---~ str = [[
---~ a{oeps {oe\{\}ps} }
---~ test { oeps \} \[\] oeps \setupxxx[oeps=bla]}
---~ test $$ \hbox{$ oeps \} \[\] oeps $} $$
---~ {$x\$xx$ $
---~ ]]
---~ str = string.rep(str,10)
-
-local remapper = {
- ["\n"] = " <lf> ",
- ["\r"] = " <cr> ",
- ["\t"] = " <tab> ",
-}
-
-function scripts.checker.check(filename)
- local str = io.loaddata(filename)
- if str then
- validator.check(str,file.suffix(filename))
- local errors = validator.errors
- if #errors > 0 then
- for k=1,#errors do
- local v = errors[k]
- local kind, position, line, extra = v[1], v[2], v[3], v[4]
- if not position then
- position = #str
- end
- local data = sub(str,position-30,position+30)
- data = gsub(data,".", remapper)
- data = gsub(data,"^ *","")
- if extra then
- print(format("% 5i %-10s %s (%s)", line, kind, data, extra))
- else
- print(format("% 5i %-10s %s", line, kind, data))
- end
- end
- else
- print("no error")
- end
- else
- print("no file")
- end
-end
-
-if environment.argument("check") then
- scripts.checker.check(environment.files[1])
-elseif environment.argument("help") then
- application.help()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-elseif environment.files[1] then
- scripts.checker.check(environment.files[1])
-else
- application.help()
-end
-
+if not modules then modules = { } end modules ['mtx-check'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local P, R, S, V, C, CP, CC, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cp, lpeg.Cc, lpeg.match
+local gsub, sub, format = string.gsub, string.sub, string.format
+local insert, remove = table.insert, table.remove
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-check</entry>
+ <entry name="detail">Basic ConTeXt Syntax Checking</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="convert"><short>check tex file for errors</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-check",
+ banner = "Basic ConTeXt Syntax Checking 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.checker = scripts.checker or { }
+
+local validator = { }
+
+validator.n = 1
+validator.errors = { }
+validator.trace = false
+validator.direct = false
+
+validator.printer = print
+validator.tracer = print
+
+local message = function(position, kind, extra)
+ local ve = validator.errors
+ ve[#ve+1] = { kind, position, validator.n, extra }
+ if validator.direct then
+ position = position or "eof"
+ if extra then
+ validator.printer(format("%s error at position %s (line %s) (%s)",kind,position,validator.n,extra))
+ else
+ validator.printer(format("%s error at position %s (line %s)",kind,position,validator.n))
+ end
+ end
+end
+
+local progress = function(position, data, kind)
+ if validator.trace then
+ validator.tracer(format("%s at position %s: %s", kind, position, data or ""))
+ end
+end
+
+local i_m, d_m = P("$"), P("$$")
+local l_s, r_s = P("["), P("]")
+local l_g, r_g = P("{"), P("}")
+
+local okay = lpeg.P("{[}") + lpeg.P("{]}")
+
+local esc = P("\\")
+local cr = P("\r")
+local lf = P("\n")
+local crlf = P("\r\n")
+local space = S(" \t\f\v")
+local newline = crlf + cr + lf
+
+local line = newline / function() validator.n = validator.n + 1 end
+
+local startluacode = P("\\startluacode")
+local stopluacode = P("\\stopluacode")
+
+local somecode = startluacode * (1-stopluacode)^1 * stopluacode
+
+local stack = { }
+
+local function push(p,s)
+-- print("start",p,s)
+ insert(stack,{ p, s, validator.n })
+end
+
+local function pop(p,s)
+-- print("stop",p,s)
+ local top = remove(stack)
+ if not top then
+ message(p,"missing start")
+ elseif top[2] ~= s then
+ message(p,"missing stop",format("see line %s",top[3]))
+ else
+ -- okay
+ end
+end
+
+local cstoken = R("az","AZ","\127\255")
+
+local start = CP() * P("\\start") * C(cstoken^0) / push
+local stop = CP() * P("\\stop") * C(cstoken^0) / pop
+
+local contextgrammar = P { "tokens",
+ ["tokens"] = (V("ignore") + V("start") + V("stop") + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + V("errors") + 1)^0,
+ ["start"] = start,
+ ["stop"] = stop,
+ ["whatever"] = line + esc * 1 + C(P("%") * (1-line)^0),
+ ["grouped"] = l_g * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_g - r_g))^0 * r_g,
+ ["setup"] = l_s * (okay + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_s - r_s))^0 * r_s,
+ ["display"] = d_m * (V("whatever") + V("grouped") + (1 - d_m))^0 * d_m,
+ ["inline"] = i_m * (V("whatever") + V("grouped") + (1 - i_m))^0 * i_m,
+ ["errors"] = V("gerror") + V("serror") + V("derror") + V("ierror"),
+ ["gerror"] = CP() * (l_g + r_g) * CC("grouping error") / message,
+ ["serror"] = CP() * (l_s + r_g) * CC("setup error") / message,
+ ["derror"] = CP() * d_m * CC("display math error") / message,
+ ["ierror"] = CP() * i_m * CC("inline math error") / message,
+ ["ignore"] = somecode,
+}
+
+-- metafun variant
+
+local function push(p,s)
+ insert(stack,{ p, s, validator.n })
+end
+
+local function pop(p,s)
+ local top = remove(stack)
+ if not top then
+ message(p,"missing <some>def")
+ end
+end
+
+local function finish(p)
+ local bot = stack[1]
+ if bot then
+ message(false,format("missing enddef for %s",bot[2]),format("see line %s",bot[3]))
+ end
+ stack = { }
+end
+
+local l_b, r_b = P("["), P("]")
+local l_g, r_g = P("{"), P("}")
+local l_p, r_p = P("("), P(")")
+
+local start = CP() * C( P("vardef") + P("primarydef") + P("secondarydef") + P("tertiarydef") + P("def") ) / push
+local stop = CP() * C( P("enddef") ) / pop
+
+local dstring = P('"') * (1-P('"'))^0 * P('"')
+local semicolon = P(";")
+
+local separator = line + space + semicolon
+
+-- todo: start/stop also in ()
+
+local metafungrammar = P { "tokens",
+ ["tokens"] = (V("start") + V("stop") + V("string") + V("whatever") + V("braces") + V("brackets") + V("parentheses") + V("errors") + 1)^0
+ * (CP() / finish),
+ ["start"] = separator * start * #separator,
+ ["stop"] = separator * stop * #separator,
+ ["string"] = dstring,
+ ["whatever"] = line + C(P("%") * (1-line)^0),
+ ["braces"] = l_g * (V("whatever") + V("string") + V("braces") + V("brackets") + V("parentheses") + (1 - l_g - r_g))^0 * r_g,
+ ["brackets"] = l_b * (V("whatever") + V("string") + V("braces") + V("brackets") + V("parentheses") + (1 - l_b - r_b))^0 * r_b,
+ ["parentheses"] = l_p * (V("whatever") + V("string") + V("braces") + V("brackets") + V("parentheses") + (1 - l_p - r_p))^0 * r_p,
+ ["errors"] = V("gerror") + V("berror") + V("perror"),
+ ["gerror"] = CP() * (l_g + r_g) * CC("braces error") / message,
+ ["berror"] = CP() * (l_b + r_b) * CC("brackets error") / message,
+ ["perror"] = CP() * (l_p + r_p) * CC("parentheses error") / message,
+}
+
+local grammars = {
+ mp = metafungrammar,
+ mpii = metafungrammar,
+ mpiv = metafungrammar,
+ tex = contextgrammar,
+ mkii = contextgrammar,
+ mkiv = contextgrammar,
+}
+
+function validator.check(str,filetype)
+ validator.n = 1
+ validator.errors = { }
+ local grammar = grammars[filetype] or grammars.tex
+ lpegmatch(grammar,str)
+end
+
+--~ str = [[
+--~ a{oeps {oe\{\}ps} }
+--~ test { oeps \} \[\] oeps \setupxxx[oeps=bla]}
+--~ test $$ \hbox{$ oeps \} \[\] oeps $} $$
+--~ {$x\$xx$ $
+--~ ]]
+--~ str = string.rep(str,10)
+
+local remapper = {
+ ["\n"] = " <lf> ",
+ ["\r"] = " <cr> ",
+ ["\t"] = " <tab> ",
+}
+
+function scripts.checker.check(filename)
+ local str = io.loaddata(filename)
+ if str then
+ validator.check(str,file.suffix(filename))
+ local errors = validator.errors
+ if #errors > 0 then
+ for k=1,#errors do
+ local v = errors[k]
+ local kind, position, line, extra = v[1], v[2], v[3], v[4]
+ if not position then
+ position = #str
+ end
+ local data = sub(str,position-30,position+30)
+ data = gsub(data,".", remapper)
+ data = gsub(data,"^ *","")
+ if extra then
+ print(format("% 5i %-10s %s (%s)", line, kind, data, extra))
+ else
+ print(format("% 5i %-10s %s", line, kind, data))
+ end
+ end
+ else
+ print("no error")
+ end
+ else
+ print("no file")
+ end
+end
+
+if environment.argument("check") then
+ scripts.checker.check(environment.files[1])
+elseif environment.argument("help") then
+ application.help()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+elseif environment.files[1] then
+ scripts.checker.check(environment.files[1])
+else
+ application.help()
+end
+
diff --git a/scripts/context/lua/mtx-colors.lua b/scripts/context/lua/mtx-colors.lua
index cd7dcce62..7dd1b4ac4 100644
--- a/scripts/context/lua/mtx-colors.lua
+++ b/scripts/context/lua/mtx-colors.lua
@@ -1,77 +1,77 @@
-if not modules then modules = { } end modules ['mtx-colors'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- todo: fc-cache -v en check dirs, or better is: fc-cat -v | grep Directory
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-colors</entry>
- <entry name="detail">ConTeXt Color Management</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="table"><short>show icc table</short></flag>
- </subcategory>
- </category>
- </flags>
- <examples>
- <category>
- <title>Example</title>
- <subcategory>
- <example><command>mtxrun --script color --table somename</command></example>
- </subcategory>
- </category>
- </examples>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-colors",
- banner = "ConTeXt Color Management 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-if not fontloader then fontloader = fontforge end
-
-dofile(resolvers.findfile("colo-icc.lua","tex"))
-
-scripts = scripts or { }
-scripts.colors = scripts.colors or { }
-
-function scripts.colors.table()
- local files = environment.files
- if #files > 0 then
- for i=1,#files do
- local profile, okay, message = colors.iccprofile(files[i])
- if not okay then
- report(message)
- else
- report(table.serialize(profile,"profile"))
- end
- end
- else
- report("no file(s) given" )
- end
-end
-
---~ local track = environment.argument("track")
---~ if track then trackers.enable(track) end
-
-if environment.argument("table") then
- scripts.colors.table()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-colors'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: fc-cache -v en check dirs, or better is: fc-cat -v | grep Directory
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-colors</entry>
+ <entry name="detail">ConTeXt Color Management</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="table"><short>show icc table</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Example</title>
+ <subcategory>
+ <example><command>mtxrun --script color --table somename</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-colors",
+ banner = "ConTeXt Color Management 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+if not fontloader then fontloader = fontforge end
+
+dofile(resolvers.findfile("colo-icc.lua","tex"))
+
+scripts = scripts or { }
+scripts.colors = scripts.colors or { }
+
+function scripts.colors.table()
+ local files = environment.files
+ if #files > 0 then
+ for i=1,#files do
+ local profile, okay, message = colors.iccprofile(files[i])
+ if not okay then
+ report(message)
+ else
+ report(table.serialize(profile,"profile"))
+ end
+ end
+ else
+ report("no file(s) given" )
+ end
+end
+
+--~ local track = environment.argument("track")
+--~ if track then trackers.enable(track) end
+
+if environment.argument("table") then
+ scripts.colors.table()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index 3c2311eef..87ed3475d 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -1,1492 +1,1492 @@
-if not modules then modules = { } end modules ['mtx-context'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- todo: more local functions
--- todo: pass jobticket/ctxdata table around
-
-local type, next, tostring, tonumber = type, next, tostring, tonumber
-local format, gmatch, match, gsub, find = string.format, string.gmatch, string.match, string.gsub, string.find
-local quote, validstring = string.quote, string.valid
-local concat = table.concat
-local settings_to_array = utilities.parsers.settings_to_array
-local appendtable = table.append
-local lpegpatterns, lpegmatch, Cs, P = lpeg.patterns, lpeg.match, lpeg.Cs, lpeg.P
-
-local getargument = environment.getargument or environment.argument
-local setargument = environment.setargument
-
-local application = logs.application {
- name = "mtx-context",
- banner = "ConTeXt Process Management 0.60",
- -- helpinfo = helpinfo, -- table with { category_a = text_1, category_b = text_2 } or helpstring or xml_blob
- helpinfo = "mtx-context.xml",
-}
-
--- local luatexflags = {
--- ["8bit"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["default-translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["etex"] = true, -- ignored, the etex extensions are always active
---
--- ["credits"] = true, -- display credits and exit
--- ["debug-format"] = true, -- enable format debugging
--- ["disable-write18"] = true, -- disable \write18{SHELL COMMAND}
--- ["draftmode"] = true, -- switch on draft mode (generates no output PDF)
--- ["enable-write18"] = true, -- enable \write18{SHELL COMMAND}
--- ["file-line-error"] = true, -- enable file:line:error style messages
--- ["file-line-error-style"] = true, -- aliases of --file-line-error
--- ["no-file-line-error"] = true, -- disable file:line:error style messages
--- ["no-file-line-error-style"] = true, -- aliases of --no-file-line-error
--- ["fmt"] = true, -- load the format file FORMAT
--- ["halt-on-error"] = true, -- stop processing at the first error
--- ["help"] = true, -- display help and exit
--- ["ini"] = true, -- be iniluatex, for dumping formats
--- ["interaction"] = true, -- set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)
--- ["jobname"] = true, -- set the job name to STRING
--- ["kpathsea-debug"] = true, -- set path searching debugging flags according to the bits of NUMBER
--- ["lua"] = true, -- load and execute a lua initialization script
--- ["mktex"] = true, -- enable mktexFMT generation (FMT=tex/tfm)
--- ["no-mktex"] = true, -- disable mktexFMT generation (FMT=tex/tfm)
--- ["nosocket"] = true, -- disable the lua socket library
--- ["output-comment"] = true, -- use STRING for DVI file comment instead of date (no effect for PDF)
--- ["output-directory"] = true, -- use existing DIR as the directory to write files in
--- ["output-format"] = true, -- use FORMAT for job output; FORMAT is 'dvi' or 'pdf'
--- ["parse-first-line"] = true, -- enable parsing of the first line of the input file
--- ["no-parse-first-line"] = true, -- disable parsing of the first line of the input file
--- ["progname"] = true, -- set the program name to STRING
--- ["recorder"] = true, -- enable filename recorder
--- ["safer"] = true, -- disable easily exploitable lua commands
--- ["shell-escape"] = true, -- enable \write18{SHELL COMMAND}
--- ["no-shell-escape"] = true, -- disable \write18{SHELL COMMAND}
--- ["shell-restricted"] = true, -- restrict \write18 to a list of commands given in texmf.cnf
--- ["synctex"] = true, -- enable synctex
--- ["version"] = true, -- display version and exit
--- ["luaonly"] = true, -- run a lua file, then exit
--- ["luaconly"] = true, -- byte-compile a lua file, then exit
--- ["jiton"] = false,
--- }
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.context = scripts.context or { }
-
--- for the moment here
-
-if getargument("jit") or getargument("jiton") then
- -- bonus shortcut, we assume than --jit also indicates the engine
- -- although --jit and --engine=luajittex are independent
- setargument("engine","luajittex")
-end
-
-local engine_new = getargument("engine") or directives.value("system.engine")
-local engine_old = environment.ownbin
-
-local function restart(engine_old,engine_new)
- local command = format("%s --luaonly %q %s --redirected",engine_new,environment.ownname,environment.reconstructcommandline())
- report(format("redirect %s -> %s: %s",engine_old,engine_new,command))
- local result = os.execute(command)
- os.exit(result)
-end
-
-if getargument("redirected") then
- setargument("engine",engine_old) -- later on we need this
-elseif engine_new == engine_old then
- setargument("engine",engine_new) -- later on we need this
-elseif environment.validengines[engine_new] and engine_new ~= environment.basicengines[engine_old] then
- restart(engine_old,engine_new)
-else
- setargument("engine",engine_new) -- later on we need this
-end
-
--- so far
-
--- constants
-
-local usedfiles = {
- nop = "cont-nop.mkiv",
- yes = "cont-yes.mkiv",
-}
-
-local usedsuffixes = {
- before = {
- "tuc"
- },
- after = {
- "pdf", "tuc", "log"
- },
- keep = {
- "log"
- },
-}
-
-local formatofinterface = {
- en = "cont-en",
- uk = "cont-uk",
- de = "cont-de",
- fr = "cont-fr",
- nl = "cont-nl",
- cs = "cont-cs",
- it = "cont-it",
- ro = "cont-ro",
- pe = "cont-pe",
-}
-
-local defaultformats = {
- "cont-en",
- "cont-nl",
-}
-
--- process information
-
-local ctxrunner = { } -- namespace will go
-
-local ctx_locations = { '..', '../..' }
-
-function ctxrunner.new()
- return {
- ctxname = "",
- jobname = "",
- flags = { },
- }
-end
-
-function ctxrunner.checkfile(ctxdata,ctxname,defaultname)
-
- if not ctxdata.jobname or ctxdata.jobname == "" then
- return
- end
-
- ctxdata.ctxname = ctxname or file.removesuffix(ctxdata.jobname) or ""
-
- if ctxdata.ctxname == "" then
- return
- end
-
- ctxdata.jobname = file.addsuffix(ctxdata.jobname,'tex')
- ctxdata.ctxname = file.addsuffix(ctxdata.ctxname,'ctx')
-
- report("jobname: %s",ctxdata.jobname)
- report("ctxname: %s",ctxdata.ctxname)
-
- -- mtxrun should resolve kpse: and file:
-
- local usedname = ctxdata.ctxname
- local found = lfs.isfile(usedname)
-
- -- no further test if qualified path
-
- if not found then
- for _, path in next, ctx_locations do
- local fullname = file.join(path,ctxdata.ctxname)
- if lfs.isfile(fullname) then
- usedname = fullname
- found = true
- break
- end
- end
- end
-
- if not found then
- usedname = resolvers.findfile(ctxdata.ctxname,"tex")
- found = usedname ~= ""
- end
-
- if not found and defaultname and defaultname ~= "" and lfs.isfile(defaultname) then
- usedname = defaultname
- found = true
- end
-
- if not found then
- return
- end
-
- local xmldata = xml.load(usedname)
-
- if not xmldata then
- return
- else
- -- test for valid, can be text file
- end
-
- local ctxpaths = table.append({'.', file.dirname(ctxdata.ctxname)}, ctx_locations)
-
- xml.include(xmldata,'ctx:include','name', ctxpaths)
-
- local flags = ctxdata.flags
-
- for e in xml.collected(xmldata,"/ctx:job/ctx:flags/ctx:flag") do
- local flag = xml.text(e) or ""
- local key, value = match(flag,"^(.-)=(.+)$")
- if key and value then
- flags[key] = value
- else
- flags[flag] = true
- end
- end
-
-end
-
-function ctxrunner.checkflags(ctxdata)
- if ctxdata then
- for k,v in next, ctxdata.flags do
- if getargument(k) == nil then
- setargument(k,v)
- end
- end
- end
-end
-
--- multipass control
-
-local multipass_suffixes = { ".tuc" }
-local multipass_nofruns = 8 -- or 7 to test oscillation
-
-local function multipass_hashfiles(jobname)
- local hash = { }
- for i=1,#multipass_suffixes do
- local suffix = multipass_suffixes[i]
- local full = jobname .. suffix
- hash[full] = md5.hex(io.loaddata(full) or "unknown")
- end
- return hash
-end
-
-local function multipass_changed(oldhash, newhash)
- for k,v in next, oldhash do
- if v ~= newhash[k] then
- return true
- end
- end
- return false
-end
-
-local function multipass_copyluafile(jobname)
- local tuaname, tucname = jobname..".tua", jobname..".tuc"
- if lfs.isfile(tuaname) then
- os.remove(tucname)
- os.rename(tuaname,tucname)
- end
-end
-
---
-
-local pattern = lpegpatterns.utfbom^-1 * (P("%% ") + P("% ")) * Cs((1-lpegpatterns.newline)^1)
-
-local function preamble_analyze(filename) -- only files on current path
- local t = { }
- local line = io.loadlines(file.addsuffix(filename,"tex"))
- if line then
- local preamble = lpegmatch(pattern,line)
- if preamble then
- for key, value in gmatch(preamble,"(%S+)%s*=%s*(%S+)") do
- t[key] = value
- end
- t.type = "tex"
- elseif find(line,"^<?xml ") then
- t.type = "xml"
- end
- if t.nofruns then
- multipass_nofruns = t.nofruns
- end
- if not t.engine then
- t.engine = environment.basicengines[engine_old] --'luatex'
- end
- if t.engine ~= engine_old then -- hack
- if environment.validengines[t.engine] and t.engine ~= environment.basicengines[engine_old] then
- restart(engine_old,t.engine)
- end
- end
- end
- return t
-end
-
--- automatically opening and closing pdf files
-
-local pdfview -- delayed
-
-local function pdf_open(name,method)
- pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
- pdfview.setmethod(method)
- report(pdfview.status())
- pdfview.open(file.replacesuffix(name,"pdf"))
-end
-
-local function pdf_close(name,method)
- pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
- pdfview.setmethod(method)
- pdfview.close(file.replacesuffix(name,"pdf"))
-end
-
--- result file handling
-
-local function result_push_purge(oldbase,newbase)
- for _, suffix in next, usedsuffixes.after do
- local oldname = file.addsuffix(oldbase,suffix)
- local newname = file.addsuffix(newbase,suffix)
- os.remove(newname)
- os.remove(oldname)
- end
-end
-
-local function result_push_keep(oldbase,newbase)
- for _, suffix in next, usedsuffixes.before do
- local oldname = file.addsuffix(oldbase,suffix)
- local newname = file.addsuffix(newbase,suffix)
- local tmpname = "keep-"..oldname
- os.remove(tmpname)
- os.rename(oldname,tmpname)
- os.remove(oldname)
- os.rename(newname,oldname)
- end
-end
-
-local function result_save_error(oldbase,newbase)
- for _, suffix in next, usedsuffixes.keep do
- local oldname = file.addsuffix(oldbase,suffix)
- local newname = file.addsuffix(newbase,suffix)
- os.remove(newname) -- to be sure
- os.rename(oldname,newname)
- end
-end
-
-local function result_save_purge(oldbase,newbase)
- for _, suffix in next, usedsuffixes.after do
- local oldname = file.addsuffix(oldbase,suffix)
- local newname = file.addsuffix(newbase,suffix)
- os.remove(newname) -- to be sure
- os.rename(oldname,newname)
- end
-end
-
-local function result_save_keep(oldbase,newbase)
- for _, suffix in next, usedsuffixes.after do
- local oldname = file.addsuffix(oldbase,suffix)
- local newname = file.addsuffix(newbase,suffix)
- local tmpname = "keep-"..oldname
- os.remove(newname)
- os.rename(oldname,newname)
- os.rename(tmpname,oldname)
- end
-end
-
--- executing luatex
-
-local function flags_to_string(flags,prefix) -- context flags get prepended by c:
- local t = { }
- for k, v in table.sortedhash(flags) do
- if prefix then
- k = format("c:%s",k)
- end
- if not v or v == "" or v == '""' then
- -- no need to flag false
- elseif v == true then
- t[#t+1] = format('--%s',k)
- elseif type(v) == "string" then
- t[#t+1] = format('--%s=%s',k,quote(v))
- else
- t[#t+1] = format('--%s=%s',k,tostring(v))
- end
- end
- return concat(t," ")
-end
-
-local function luatex_command(l_flags,c_flags,filename,engine)
- return format('%s %s %s "%s"',
- engine or "luatex",
- flags_to_string(l_flags),
- flags_to_string(c_flags,true),
- filename
- )
-end
-
-local plain_formats = {
- ["plain"] = "plain",
- ["luatex-plain"] = "luatex-plain",
-}
-
-local function plain_format(plainformat)
- return plainformat and plain_formats[plainformat]
-end
-
-local function run_plain(plainformat,filename)
- local plainformat = plain_formats[plainformat]
- if plainformat then
- local command = format("mtxrun --script --texformat=%s plain %s",plainformat,filename)
- report("running command: %s\n\n",command)
- -- todo: load and run
- local resultname = file.replacesuffix(filename,"pdf")
- local pdfview = getargument("autopdf") or getargument("closepdf")
- if pdfview then
- pdf_close(resultname,pdfview)
- os.execute(command)
- pdf_open(resultname,pdfview)
- else
- os.execute(command)
- end
- end
-end
-
-local function run_texexec(filename,a_purge,a_purgeall)
- if false then
- -- we need to write a top etc too and run mp etc so it's not worth the
- -- trouble, so it will take a while before the next is finished
- --
- -- context --extra=texutil --convert myfile
- else
- local texexec = resolvers.findfile("texexec.rb") or ""
- if texexec ~= "" then
- os.setenv("RUBYOPT","")
- local options = environment.reconstructcommandline(environment.arguments_after)
- options = gsub(options,"--purge","")
- options = gsub(options,"--purgeall","")
- local command = format("ruby %s %s",texexec,options)
- report("running command: %s\n\n",command)
- if a_purge then
- os.execute(command)
- scripts.context.purge_job(filename,false,true)
- elseif a_purgeall then
- os.execute(command)
- scripts.context.purge_job(filename,true,true)
- else
- os.execute(command) -- we can use os.exec but that doesn't give back timing
- end
- end
- end
-end
-
---
-
-function scripts.context.run(ctxdata,filename)
- --
- local a_nofile = getargument("nofile")
- local a_engine = getargument("engine")
- --
- local files = environment.files or { }
- --
- local filelist, mainfile
- --
- if filename then
- -- the given forced name is processed, the filelist is passed to context
- mainfile = filename
- filelist = { filename }
- -- files = files
- elseif a_nofile then
- -- the list of given files is processed using the dummy file
- mainfile = usedfiles.nop
- filelist = { usedfiles.nop }
- -- files = { }
- elseif #files > 0 then
- -- the list of given files is processed using the stub file
- mainfile = usedfiles.yes
- filelist = files
- files = { }
- else
- return
- end
- --
- local interface = validstring(getargument("interface")) or "en"
- local formatname = formatofinterface[interface] or "cont-en"
- local formatfile, scriptfile = resolvers.locateformat(formatname) -- regular engine !
- if not formatfile or not scriptfile then
- report("warning: no format found, forcing remake (commandline driven)")
- scripts.context.make(formatname)
- formatfile, scriptfile = resolvers.locateformat(formatname) -- variant
- end
- if formatfile and scriptfile then
- -- okay
- elseif formatname then
- report("error, no format found with name: %s, aborting",formatname)
- return
- else
- report("error, no format found (provide formatname or interface)")
- return
- end
- --
- local a_mkii = getargument("mkii") or getargument("pdftex") or getargument("xetex")
- local a_purge = getargument("purge")
- local a_purgeall = getargument("purgeall")
- local a_purgeresult = getargument("purgeresult")
- local a_global = getargument("global")
- local a_timing = getargument("timing")
- local a_profile = getargument("profile")
- local a_batchmode = getargument("batchmode")
- local a_nonstopmode = getargument("nonstopmode")
- local a_once = getargument("once")
- local a_synctex = getargument("synctex")
- local a_backend = getargument("backend")
- local a_arrange = getargument("arrange")
- local a_noarrange = getargument("noarrange")
- local a_jiton = getargument("jiton")
- local a_texformat = getargument("texformat")
- --
- a_batchmode = (a_batchmode and "batchmode") or (a_nonstopmode and "nonstopmode") or nil
- a_synctex = tonumber(a_synctex) or (toboolean(a_synctex,true) and 1) or (a_synctex == "zipped" and 1) or (a_synctex == "unzipped" and -1) or nil
- --
- for i=1,#filelist do
- --
- local filename = filelist[i]
- local basename = file.basename(filename) -- use splitter
- local pathname = file.dirname(filename)
- --
- if pathname == "" and not a_global and filename ~= usedfiles.nop then
- filename = "./" .. filename
- if not lfs.isfile(filename) then
- report("warning: no (local) file %a, proceeding",filename)
- end
- end
- --
- local jobname = file.removesuffix(basename)
- -- local jobname = file.removesuffix(filename)
- local ctxname = ctxdata and ctxdata.ctxname
- --
- local analysis = preamble_analyze(filename)
- --
- if a_mkii or analysis.engine == 'pdftex' or analysis.engine == 'xetex' then
- run_texexec(filename,a_purge,a_purgeall)
- elseif plain_format(a_texformat or analysis.texformat) then
- run_plain(a_texformat or analysis.texformat,filename)
- else
- if analysis.interface and analysis.interface ~= interface then
- formatname = formatofinterface[analysis.interface] or formatname
- formatfile, scriptfile = resolvers.locateformat(formatname)
- end
- --
- a_jiton = (a_jiton or toboolean(analysis.jiton,true)) and true or nil
- --
- if not formatfile or not scriptfile then
- report("warning: no format found, forcing remake (source driven)")
- scripts.context.make(formatname,a_engine)
- formatfile, scriptfile = resolvers.locateformat(formatname)
- end
- if formatfile and scriptfile then
- local suffix = validstring(getargument("suffix"))
- local resultname = validstring(getargument("result"))
- if suffix then
- resultname = file.removesuffix(jobname) .. suffix
- end
- local oldbase = ""
- local newbase = ""
- if resultname then
- oldbase = file.removesuffix(jobname)
- newbase = file.removesuffix(resultname)
- if oldbase ~= newbase then
- if a_purgeresult then
- result_push_purge(oldbase,newbase)
- else
- result_push_keep(oldbase,newbase)
- end
- else
- resultname = nil
- end
- end
- --
- local pdfview = getargument("autopdf") or getargument("closepdf")
- if pdfview then
- pdf_close(filename,pdfview)
- if resultname then
- pdf_close(resultname,pdfview)
- end
- end
- --
- -- we could do this when locating the format and exit from luatex when
- -- there is a version mismatch .. that way we can use stock luatex
- -- plus mtxrun to run luajittex instead .. this saves a restart but is
- -- also cleaner as then mtxrun only has to check for a special return
- -- code (signaling a make + rerun) .. maybe some day
- --
- local okay = statistics.checkfmtstatus(formatfile,a_engine)
- if okay ~= true then
- report("warning: %s, forcing remake",tostring(okay))
- scripts.context.make(formatname)
- end
- --
- local oldhash = multipass_hashfiles(jobname)
- local newhash = { }
- local maxnofruns = once and 1 or multipass_nofruns
- --
- local c_flags = {
- directives = validstring(environment.directives), -- gets passed via mtxrun
- trackers = validstring(environment.trackers), -- gets passed via mtxrun
- experiments = validstring(environment.experiments), -- gets passed via mtxrun
- --
- result = validstring(resultname),
- input = validstring(getargument("input") or filename), -- alternative input
- fulljobname = validstring(filename),
- files = concat(files,","),
- ctx = validstring(ctxname),
- }
- --
- for k, v in next, environment.arguments do
- -- the raw arguments
- if c_flags[k] == nil then
- c_flags[k] = v
- end
- end
- --
- --
- local l_flags = {
- ["interaction"] = a_batchmode,
- ["synctex"] = a_synctex,
- ["no-parse-first-line"] = true,
- -- ["no-mktex"] = true,
- -- ["file-line-error-style"] = true,
- ["fmt"] = formatfile,
- ["lua"] = scriptfile,
- ["jobname"] = jobname,
- ["jiton"] = a_jiton,
- }
- --
- if a_synctex then
- report("warning: synctex is enabled") -- can add upto 5% runtime
- end
- --
- if not a_timing then
- -- okay
- elseif c_flags.usemodule then
- c_flags.usemodule = format("timing,%s",c_flags.usemodule)
- else
- c_flags.usemodule = "timing"
- end
- --
- if not a_profile then
- -- okay
- elseif c_flags.directives then
- c_flags.directives = format("system.profile,%s",c_flags.directives)
- else
- c_flags.directives = "system.profile"
- end
- --
- -- kindofrun: 1:first run, 2:successive run, 3:once, 4:last of maxruns
- --
- for currentrun=1,maxnofruns do
- --
- c_flags.final = false
- c_flags.kindofrun = (a_once and 3) or (currentrun==1 and 1) or (currentrun==maxnofruns and 4) or 2
- c_flags.maxnofruns = maxnofruns
- c_flags.currentrun = currentrun
- c_flags.noarrange = a_noarrange or a_arrange or nil
- --
- local command = luatex_command(l_flags,c_flags,mainfile,a_engine)
- --
- report("run %s: %s",i,command)
- print("") -- cleaner, else continuation on same line
- local returncode, errorstring = os.spawn(command)
- if not returncode then
- report("fatal error: no return code, message: %s",errorstring or "?")
- if resultname then
- result_save_error(oldbase,newbase)
- end
- os.exit(1)
- break
- elseif returncode == 0 then
- multipass_copyluafile(jobname)
- newhash = multipass_hashfiles(jobname)
- if multipass_changed(oldhash,newhash) then
- oldhash = newhash
- else
- break
- end
- else
- report("fatal error: return code: %s",returncode or "?")
- if resultname then
- result_save_error(oldbase,newbase)
- end
- os.exit(1) -- (returncode)
- break
- end
- --
- end
- --
- if a_arrange then
- --
- c_flags.final = true
- c_flags.kindofrun = 3
- c_flags.currentrun = c_flags.currentrun + 1
- c_flags.noarrange = nil
- --
- local command = luatex_command(l_flags,c_flags,mainfile,a_engine)
- --
- report("arrange run: %s",command)
- local returncode, errorstring = os.spawn(command)
- if not returncode then
- report("fatal error: no return code, message: %s",errorstring or "?")
- os.exit(1)
- elseif returncode > 0 then
- report("fatal error: return code: %s",returncode or "?")
- os.exit(returncode)
- end
- --
- end
- --
- if a_purge then
- scripts.context.purge_job(jobname)
- elseif a_purgeall then
- scripts.context.purge_job(jobname,true)
- end
- --
- if resultname then
- if a_purgeresult then
- -- so, if there is no result then we don't get the old one, but
- -- related files (log etc) are still there for tracing purposes
- result_save_purge(oldbase,newbase)
- else
- result_save_keep(oldbase,newbase)
- end
- report("result renamed to: %s",newbase)
- end
- --
- if purge then
- scripts.context.purge_job(resultname)
- elseif purgeall then
- scripts.context.purge_job(resultname,true)
- end
- --
- local pdfview = getargument("autopdf")
- if pdfview then
- pdf_open(resultname or jobname,pdfview)
- end
- --
- if a_timing then
- report()
- report("you can process (timing) statistics with:",jobname)
- report()
- report("context --extra=timing '%s'",jobname)
- report("mtxrun --script timing --xhtml [--launch --remove] '%s'",jobname)
- report()
- end
- else
- if formatname then
- report("error, no format found with name: %s, skipping",formatname)
- else
- report("error, no format found (provide formatname or interface)")
- end
- break
- end
- end
- end
- --
-end
-
-function scripts.context.pipe() -- still used?
- -- context --pipe
- -- context --pipe --purge --dummyfile=whatever.tmp
- local interface = getargument("interface")
- interface = (type(interface) == "string" and interface) or "en"
- local formatname = formatofinterface[interface] or "cont-en"
- local formatfile, scriptfile = resolvers.locateformat(formatname)
- if not formatfile or not scriptfile then
- report("warning: no format found, forcing remake (commandline driven)")
- scripts.context.make(formatname)
- formatfile, scriptfile = resolvers.locateformat(formatname)
- end
- if formatfile and scriptfile then
- local okay = statistics.checkfmtstatus(formatfile)
- if okay ~= true then
- report("warning: %s, forcing remake",tostring(okay))
- scripts.context.make(formatname)
- end
- local l_flags = {
- interaction = "scrollmode",
- fmt = formatfile,
- lua = scriptfile,
- }
- local c_flags = {
- backend = "pdf",
- final = false,
- kindofrun = 3,
- currentrun = 1,
- }
- local filename = getargument("dummyfile") or ""
- if filename == "" then
- filename = "\\relax"
- report("entering scrollmode, end job with \\end")
- else
- filename = file.addsuffix(filename,"tmp")
- io.savedata(filename,"\\relax")
- report("entering scrollmode using '%s' with optionfile, end job with \\end",filename)
- end
- local command = luatex_command(l_flags,c_flags,filename)
- os.spawn(command)
- if getargument("purge") then
- scripts.context.purge_job(filename)
- elseif getargument("purgeall") then
- scripts.context.purge_job(filename,true)
- os.remove(filename)
- end
- else
- if formatname then
- report("error, no format found with name: %s, aborting",formatname)
- else
- report("error, no format found (provide formatname or interface)")
- end
- end
-end
-
-local function make_mkiv_format(name,engine)
- environment.make_format(name) -- jit is picked up later
-end
-
-local function make_mkii_format(name,engine)
- local command = format("mtxrun texexec.rb --make --%s %s",name,engine)
- report("running command: %s",command)
- os.spawn(command)
-end
-
-function scripts.context.generate()
- resolvers.instance.renewcache = true
- trackers.enable("resolvers.locating")
- resolvers.load()
-end
-
-function scripts.context.make(name)
- if not getargument("fast") then -- as in texexec
- scripts.context.generate()
- end
- local list = (name and { name }) or (environment.files[1] and environment.files) or defaultformats
- local engine = getargument("engine") or "luatex"
- if getargument("jit") or getargument("jiton") then
- engine = "luajittex"
- end
- for i=1,#list do
- local name = list[i]
- name = formatofinterface[name] or name or ""
- if name == "" then
- -- nothing
- elseif engine == "luatex" or engine == "luajittex" then
- make_mkiv_format(name,engine)
- elseif engine == "pdftex" or engine == "xetex" then
- make_mkii_format(name,engine)
- end
- end
-end
-
-function scripts.context.ctx()
- local ctxdata = ctxrunner.new()
- ctxdata.jobname = environment.files[1]
- ctxrunner.checkfile(ctxdata,getargument("ctx"))
- ctxrunner.checkflags(ctxdata)
- scripts.context.run(ctxdata)
-end
-
-function scripts.context.autoctx()
- local ctxdata = nil
- local files = environment.files
- local firstfile = #files > 0 and files[1]
- if firstfile then
- local suffix = file.suffix(firstfile)
- if suffix == "xml" then
- local chunk = io.loadchunk(firstfile) -- 1024
- if chunk then
- local ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>")
- if ctxname then
- ctxdata = ctxrunner.new()
- ctxdata.jobname = firstfile
- ctxrunner.checkfile(ctxdata,ctxname)
- ctxrunner.checkflags(ctxdata)
- end
- end
- elseif suffix == "tex" then
- -- maybe but we scan the preamble later too
- end
- end
- scripts.context.run(ctxdata)
-end
-
--- no longer ok as mlib-run misses something:
-
--- local template = [[
--- \starttext
--- \directMPgraphic{%s}{input "%s"}
--- \stoptext
--- ]]
---
--- local loaded = false
---
--- function scripts.context.metapost()
--- local filename = environment.files[1] or ""
--- if not loaded then
--- dofile(resolvers.findfile("mlib-run.lua"))
--- loaded = true
--- commands = commands or { }
--- commands.writestatus = report -- no longer needed
--- end
--- local formatname = getargument("format") or "metafun"
--- if formatname == "" or type(formatname) == "boolean" then
--- formatname = "metafun"
--- end
--- if getargument("pdf") then
--- local basename = file.removesuffix(filename)
--- local resultname = getargument("result") or basename
--- local jobname = "mtx-context-metapost"
--- local tempname = file.addsuffix(jobname,"tex")
--- io.savedata(tempname,format(template,"metafun",filename))
--- environment.files[1] = tempname
--- setargument("result",resultname)
--- setargument("once",true)
--- scripts.context.run()
--- scripts.context.purge_job(jobname,true)
--- scripts.context.purge_job(resultname,true)
--- elseif getargument("svg") then
--- metapost.directrun(formatname,filename,"svg")
--- else
--- metapost.directrun(formatname,filename,"mps")
--- end
--- end
-
--- --
-
-function scripts.context.version()
- local name = resolvers.findfile("context.mkiv")
- if name ~= "" then
- report("main context file: %s",name)
- local data = io.loaddata(name)
- if data then
- local version = match(data,"\\edef\\contextversion{(.-)}")
- if version then
- report("current version: %s",version)
- else
- report("context version: unknown, no timestamp found")
- end
- else
- report("context version: unknown, load error")
- end
- else
- report("main context file: unknown, 'context.mkiv' not found")
- end
-end
-
--- purging files
-
-local generic_files = {
- "texexec.tex", "texexec.tui", "texexec.tuo",
- "texexec.tuc", "texexec.tua",
- "texexec.ps", "texexec.pdf", "texexec.dvi",
- "cont-opt.tex", "cont-opt.bak"
-}
-
-local obsolete_results = {
- "dvi",
-}
-
-local temporary_runfiles = {
- "tui", "tua", "tup", "ted", "tes", "top",
- "log", "tmp", "run", "bck", "rlg",
- "mpt", "mpx", "mpd", "mpo", "mpb", "ctl",
- "synctex", "synctex.gz", "pgf",
- "prep",
-}
-
-local persistent_runfiles = {
- "tuo", "tub", "top", "tuc"
-}
-
-local special_runfiles = {
- "-mpgraph", "-mprun", "-temp-"
-}
-
-local function purge_file(dfile,cfile)
- if cfile and lfs.isfile(cfile) then
- if os.remove(dfile) then
- return file.basename(dfile)
- end
- elseif dfile then
- if os.remove(dfile) then
- return file.basename(dfile)
- end
- end
-end
-
-function scripts.context.purge_job(jobname,all,mkiitoo)
- if jobname and jobname ~= "" then
- jobname = file.basename(jobname)
- local filebase = file.removesuffix(jobname)
- if mkiitoo then
- scripts.context.purge(all,filebase,true) -- leading "./"
- else
- local deleted = { }
- for i=1,#obsolete_results do
- deleted[#deleted+1] = purge_file(filebase.."."..obsolete_results[i],filebase..".pdf")
- end
- for i=1,#temporary_runfiles do
- deleted[#deleted+1] = purge_file(filebase.."."..temporary_runfiles[i])
- end
- if all then
- for i=1,#persistent_runfiles do
- deleted[#deleted+1] = purge_file(filebase.."."..persistent_runfiles[i])
- end
- end
- if #deleted > 0 then
- report("purged files: %s", concat(deleted,", "))
- end
- end
- end
-end
-
-function scripts.context.purge(all,pattern,mkiitoo)
- local all = all or getargument("all")
- local pattern = getargument("pattern") or (pattern and (pattern.."*")) or "*.*"
- local files = dir.glob(pattern)
- local obsolete = table.tohash(obsolete_results)
- local temporary = table.tohash(temporary_runfiles)
- local persistent = table.tohash(persistent_runfiles)
- local generic = table.tohash(generic_files)
- local deleted = { }
- for i=1,#files do
- local name = files[i]
- local suffix = file.suffix(name)
- local basename = file.basename(name)
- if obsolete[suffix] or temporary[suffix] or persistent[suffix] or generic[basename] then
- deleted[#deleted+1] = purge_file(name)
- elseif mkiitoo then
- for i=1,#special_runfiles do
- if find(name,special_runfiles[i]) then
- deleted[#deleted+1] = purge_file(name)
- end
- end
- end
- end
- if #deleted > 0 then
- report("purged files: %s", concat(deleted,", "))
- end
-end
-
--- touching files (signals regeneration of formats)
-
-local function touch(path,name,versionpattern,kind,kindpattern)
- if path and path ~= "" then
- name = file.join(path,name)
-print(name)
- else
- name = resolvers.findfile(name)
- end
- local olddata = io.loaddata(name)
- if olddata then
- local oldkind, newkind = "", kind or ""
- local oldversion, newversion = "", os.date("%Y.%m.%d %H:%M")
- local newdata
- if versionpattern then
- newdata = gsub(olddata,versionpattern,function(pre,mid,post)
- oldversion = mid
- return pre .. newversion .. post
- end) or olddata
- end
- if kind and kindpattern then
- newdata = gsub(newdata,kindpattern,function(pre,mid,post)
- oldkind = mid
- return pre .. newkind .. post
- end) or newdata
- end
- if newdata ~= "" and (oldversion ~= newversion or oldkind ~= newkind or newdata ~= olddata) then
- local backup = file.replacesuffix(name,"tmp")
- os.remove(backup)
- os.rename(name,backup)
- io.savedata(name,newdata)
- return name, oldversion, newversion, oldkind, newkind
- end
- end
-end
-
-local p_contextkind = "(\\edef\\contextkind%s*{)(.-)(})"
-local p_contextversion = "(\\edef\\contextversion%s*{)(.-)(})"
-local p_newcontextversion = "(\\newcontextversion%s*{)(.-)(})"
-
-local function touchfiles(suffix,kind,path)
- local foundname, oldversion, newversion, oldkind, newkind = touch(path,file.addsuffix("context",suffix),p_contextversion,kind,p_contextkind)
- if foundname then
- report("old version : %s (%s)",oldversion,oldkind)
- report("new version : %s (%s)",newversion,newkind)
- report("touched file : %s",foundname)
- local foundname = touch(path,file.addsuffix("cont-new",suffix),p_newcontextversion)
- if foundname then
- report("touched file : %s", foundname)
- end
- else
- report("nothing touched")
- end
-end
-
-function scripts.context.touch()
- if getargument("expert") then
- local touch = getargument("touch")
- local kind = getargument("kind")
- local path = getargument("basepath")
- if touch == "mkii" or touch == "mkiv" or touch == "mkvi" then -- mkix mkxi
- touchfiles(touch,kind,path)
- else
- touchfiles("mkii",kind,path)
- touchfiles("mkiv",kind,path)
- touchfiles("mkvi",kind,path)
- end
- else
- report("touching needs --expert")
- end
-end
-
--- modules
-
-local labels = { "title", "comment", "status" }
-local cards = { "*.mkvi", "*.mkiv", "*.mkxi", "*.mkix", "*.tex" }
-
-function scripts.context.modules(pattern)
- local list = { }
- local found = resolvers.findfile("context.mkiv")
- if not pattern or pattern == "" then
- -- official files in the tree
- for i=1,#cards do
- resolvers.findwildcardfiles(cards[i],list)
- end
- -- my dev path
- for i=1,#cards do
- dir.glob(file.join(file.dirname(found),cards[i]),list)
- end
- else
- resolvers.findwildcardfiles(pattern,list)
- dir.glob(file.join(file.dirname(found,pattern)),list)
- end
- local done = { } -- todo : sort
- for i=1,#list do
- local v = list[i]
- local base = file.basename(v)
- if not done[base] then
- done[base] = true
- local suffix = file.suffix(base)
- if suffix == "tex" or suffix == "mkiv" or suffix == "mkvi" or suffix == "mkix" or suffix == "mkxi" then
- local prefix = match(base,"^([xmst])%-")
- if prefix then
- v = resolvers.findfile(base) -- so that files on my dev path are seen
- local data = io.loaddata(v) or ""
- data = match(data,"%% begin info(.-)%% end info")
- if data then
- local info = { }
- for label, text in gmatch(data,"%% +([^ ]+) *: *(.-)[\n\r]") do
- info[label] = text
- end
- report()
- report("%-7s : %s","module",base)
- report()
- for i=1,#labels do
- local l = labels[i]
- if info[l] then
- report("%-7s : %s",l,info[l])
- end
- end
- report()
- end
- end
- end
- end
- end
-end
-
--- extras
-
-function scripts.context.extras(pattern)
- -- only in base path, i.e. only official ones
- if type(pattern) ~= "string" then
- pattern = "*"
- end
- local found = resolvers.findfile("context.mkiv")
- if found ~= "" then
- pattern = file.join(dir.expandname(file.dirname(found)),format("mtx-context-%s.tex",pattern or "*"))
- local list = dir.glob(pattern)
- for i=1,#list do
- local v = list[i]
- local data = io.loaddata(v) or ""
- data = match(data,"%% begin help(.-)%% end help")
- if data then
- report()
- report("extra: %s (%s)",(gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1")),v)
- for s in gmatch(data,"%% *(.-)[\n\r]") do
- report(s)
- end
- report()
- end
- end
- end
-end
-
-function scripts.context.extra()
- local extra = getargument("extra")
- if type(extra) ~= "string" then
- scripts.context.extras()
- elseif getargument("help") then
- scripts.context.extras(extra)
- else
- local fullextra = extra
- if not find(fullextra,"mtx%-context%-") then
- fullextra = "mtx-context-" .. extra
- end
- local foundextra = resolvers.findfile(fullextra)
- if foundextra == "" then
- scripts.context.extras()
- return
- else
- report("processing extra: %s", foundextra)
- end
- setargument("purgeall",true)
- local result = getargument("result") or ""
- if result == "" then
- setargument("result","context-extra")
- end
- scripts.context.run(nil,foundextra)
- end
-end
-
--- todo: we need to do a dummy run
-
-function scripts.context.trackers()
- environment.files = { resolvers.findfile("m-trackers.mkiv") }
- multipass_nofruns = 1
- setargument("purgeall",true)
- scripts.context.run()
-end
-
-function scripts.context.directives()
- environment.files = { resolvers.findfile("m-directives.mkiv") }
- multipass_nofruns = 1
- setargument("purgeall",true)
- scripts.context.run()
-end
-
-function scripts.context.logcategories()
- environment.files = { resolvers.findfile("m-logcategories.mkiv") }
- multipass_nofruns = 1
- setargument("purgeall",true)
- scripts.context.run()
-end
-
--- updating (often one will use mtx-update instead)
-
-function scripts.context.timed(action)
- statistics.timed(action)
-end
-
-local zipname = "cont-tmf.zip"
-local mainzip = "http://www.pragma-ade.com/context/latest/" .. zipname
-local validtrees = { "texmf-local", "texmf-context" }
-local selfscripts = { "mtxrun.lua" } -- was: { "luatools.lua", "mtxrun.lua" }
-
-function zip.loaddata(zipfile,filename) -- should be in zip lib
- local f = zipfile:open(filename)
- if f then
- local data = f:read("*a")
- f:close()
- return data
- end
- return nil
-end
-
-function scripts.context.update()
- local force = getargument("force")
- local socket = require("socket")
- local http = require("socket.http")
- local basepath = resolvers.findfile("context.mkiv") or ""
- if basepath == "" then
- report("quiting, no 'context.mkiv' found")
- return
- end
- local basetree = basepath.match(basepath,"^(.-)tex/context/base/context.mkiv$") or ""
- if basetree == "" then
- report("quiting, no proper tds structure (%s)",basepath)
- return
- end
- local function is_okay(basetree)
- for _, tree in next, validtrees do
- local pattern = gsub(tree,"%-","%%-")
- if find(basetree,pattern) then
- return tree
- end
- end
- return false
- end
- local okay = is_okay(basetree)
- if not okay then
- report("quiting, tree '%s' is protected",okay)
- return
- else
- report("updating tree '%s'",okay)
- end
- if not lfs.chdir(basetree) then
- report("quiting, unable to change to '%s'",okay)
- return
- end
- report("fetching '%s'",mainzip)
- local latest = http.request(mainzip)
- if not latest then
- report("context tree '%s' can be updated, use --force",okay)
- return
- end
- io.savedata("cont-tmf.zip",latest)
- if false then
- -- variant 1
- os.execute("mtxrun --script unzip cont-tmf.zip")
- else
- -- variant 2
- local zipfile = zip.open(zipname)
- if not zipfile then
- report("quiting, unable to open '%s'",zipname)
- return
- end
- local newfile = zip.loaddata(zipfile,"tex/context/base/context.mkiv")
- if not newfile then
- report("quiting, unable to open '%s'","context.mkiv")
- return
- end
- local oldfile = io.loaddata(resolvers.findfile("context.mkiv")) or ""
- local function versiontonumber(what,str)
- local version = match(str,"\\edef\\contextversion{(.-)}") or ""
- local year, month, day, hour, minute = match(str,"\\edef\\contextversion{(%d+)%.(%d+)%.(%d+) *(%d+)%:(%d+)}")
- if year and minute then
- local time = os.time { year=year,month=month,day=day,hour=hour,minute=minute}
- report("%s version: %s (%s)",what,version,time)
- return time
- else
- report("%s version: %s (unknown)",what,version)
- return nil
- end
- end
- local oldversion = versiontonumber("old",oldfile)
- local newversion = versiontonumber("new",newfile)
- if not oldversion or not newversion then
- report("quiting, version cannot be determined")
- return
- elseif oldversion == newversion then
- report("quiting, your current version is up-to-date")
- return
- elseif oldversion > newversion then
- report("quiting, your current version is newer")
- return
- end
- for k in zipfile:files() do
- local filename = k.filename
- if find(filename,"/$") then
- lfs.mkdir(filename)
- else
- local data = zip.loaddata(zipfile,filename)
- if data then
- if force then
- io.savedata(filename,data)
- end
- report(filename)
- end
- end
- end
- for _, scriptname in next, selfscripts do
- local oldscript = resolvers.findfile(scriptname) or ""
- if oldscript ~= "" and is_okay(oldscript) then
- local newscript = "./scripts/context/lua/" .. scriptname
- local data = io.loaddata(newscript) or ""
- if data ~= "" then
- report("replacing script '%s' by '%s'",oldscript,newscript)
- if force then
- io.savedata(oldscript,data)
- end
- end
- else
- report("keeping script '%s'",oldscript)
- end
- end
- if force then
- scripts.context.make()
- end
- end
- if force then
- report("context tree '%s' has been updated",okay)
- else
- report("context tree '%s' can been updated (use --force)",okay)
- end
-end
-
--- getting it done
-
-if getargument("nostats") then
- setargument("nostatistics",true)
- setargument("nostat",nil)
-end
-
-if getargument("batch") then
- setargument("batchmode",true)
- setargument("batch",nil)
-end
-
-if getargument("nonstop") then
- setargument("nonstopmode",true)
- setargument("nonstop",nil)
-end
-
-do
-
- local silent = getargument("silent")
- if type(silent) == "string" then
- directives.enable(format("logs.blocked={%s}",silent))
- elseif silent then
- directives.enable("logs.blocked")
- end
-
-end
-
-if getargument("once") then
- multipass_nofruns = 1
-elseif getargument("runs") then
- multipass_nofruns = tonumber(getargument("runs")) or nil
-end
-
-if getargument("run") then
- scripts.context.timed(scripts.context.autoctx)
-elseif getargument("make") then
- scripts.context.timed(function() scripts.context.make() end)
-elseif getargument("generate") then
- scripts.context.timed(function() scripts.context.generate() end)
-elseif getargument("ctx") then
- scripts.context.timed(scripts.context.ctx)
--- elseif getargument("mp") or getargument("metapost") then
--- scripts.context.timed(scripts.context.metapost)
-elseif getargument("version") then
- application.identify()
- scripts.context.version()
-elseif getargument("touch") then
- scripts.context.touch()
-elseif getargument("update") then
- scripts.context.update()
-elseif getargument("expert") then
- application.help("expert", "special")
-elseif getargument("modules") then
- scripts.context.modules()
-elseif getargument("extras") then
- scripts.context.extras(environment.files[1] or getargument("extras"))
-elseif getargument("extra") then
- scripts.context.extra()
-elseif getargument("exporthelp") then
- -- application.export(getargument("exporthelp"),environment.files[1])
- application.export()
-elseif getargument("help") then
- if environment.files[1] == "extras" then
- scripts.context.extras()
- else
- application.help("basic")
- end
-elseif getargument("showtrackers") or getargument("trackers") == true then
- scripts.context.trackers()
-elseif getargument("showdirectives") or getargument("directives") == true then
- scripts.context.directives()
-elseif getargument("showlogcategories") then
- scripts.context.logcategories()
-elseif environment.files[1] or getargument("nofile") then
- scripts.context.timed(scripts.context.autoctx)
-elseif getargument("pipe") then
- scripts.context.timed(scripts.context.pipe)
-elseif getargument("purge") then
- -- only when no filename given, supports --pattern
- scripts.context.purge()
-elseif getargument("purgeall") then
- -- only when no filename given, supports --pattern
- scripts.context.purge(true,nil,true)
-else
- application.help("basic")
-end
+if not modules then modules = { } end modules ['mtx-context'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: more local functions
+-- todo: pass jobticket/ctxdata table around
+
+local type, next, tostring, tonumber = type, next, tostring, tonumber
+local format, gmatch, match, gsub, find = string.format, string.gmatch, string.match, string.gsub, string.find
+local quote, validstring = string.quote, string.valid
+local concat = table.concat
+local settings_to_array = utilities.parsers.settings_to_array
+local appendtable = table.append
+local lpegpatterns, lpegmatch, Cs, P = lpeg.patterns, lpeg.match, lpeg.Cs, lpeg.P
+
+local getargument = environment.getargument or environment.argument
+local setargument = environment.setargument
+
+local application = logs.application {
+ name = "mtx-context",
+ banner = "ConTeXt Process Management 0.60",
+ -- helpinfo = helpinfo, -- table with { category_a = text_1, category_b = text_2 } or helpstring or xml_blob
+ helpinfo = "mtx-context.xml",
+}
+
+-- local luatexflags = {
+-- ["8bit"] = true, -- ignored, input is assumed to be in UTF-8 encoding
+-- ["default-translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
+-- ["translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
+-- ["etex"] = true, -- ignored, the etex extensions are always active
+--
+-- ["credits"] = true, -- display credits and exit
+-- ["debug-format"] = true, -- enable format debugging
+-- ["disable-write18"] = true, -- disable \write18{SHELL COMMAND}
+-- ["draftmode"] = true, -- switch on draft mode (generates no output PDF)
+-- ["enable-write18"] = true, -- enable \write18{SHELL COMMAND}
+-- ["file-line-error"] = true, -- enable file:line:error style messages
+-- ["file-line-error-style"] = true, -- aliases of --file-line-error
+-- ["no-file-line-error"] = true, -- disable file:line:error style messages
+-- ["no-file-line-error-style"] = true, -- aliases of --no-file-line-error
+-- ["fmt"] = true, -- load the format file FORMAT
+-- ["halt-on-error"] = true, -- stop processing at the first error
+-- ["help"] = true, -- display help and exit
+-- ["ini"] = true, -- be iniluatex, for dumping formats
+-- ["interaction"] = true, -- set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)
+-- ["jobname"] = true, -- set the job name to STRING
+-- ["kpathsea-debug"] = true, -- set path searching debugging flags according to the bits of NUMBER
+-- ["lua"] = true, -- load and execute a lua initialization script
+-- ["mktex"] = true, -- enable mktexFMT generation (FMT=tex/tfm)
+-- ["no-mktex"] = true, -- disable mktexFMT generation (FMT=tex/tfm)
+-- ["nosocket"] = true, -- disable the lua socket library
+-- ["output-comment"] = true, -- use STRING for DVI file comment instead of date (no effect for PDF)
+-- ["output-directory"] = true, -- use existing DIR as the directory to write files in
+-- ["output-format"] = true, -- use FORMAT for job output; FORMAT is 'dvi' or 'pdf'
+-- ["parse-first-line"] = true, -- enable parsing of the first line of the input file
+-- ["no-parse-first-line"] = true, -- disable parsing of the first line of the input file
+-- ["progname"] = true, -- set the program name to STRING
+-- ["recorder"] = true, -- enable filename recorder
+-- ["safer"] = true, -- disable easily exploitable lua commands
+-- ["shell-escape"] = true, -- enable \write18{SHELL COMMAND}
+-- ["no-shell-escape"] = true, -- disable \write18{SHELL COMMAND}
+-- ["shell-restricted"] = true, -- restrict \write18 to a list of commands given in texmf.cnf
+-- ["synctex"] = true, -- enable synctex
+-- ["version"] = true, -- display version and exit
+-- ["luaonly"] = true, -- run a lua file, then exit
+-- ["luaconly"] = true, -- byte-compile a lua file, then exit
+-- ["jiton"] = false,
+-- }
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.context = scripts.context or { }
+
+-- for the moment here
+
+if getargument("jit") or getargument("jiton") then
+ -- bonus shortcut, we assume than --jit also indicates the engine
+ -- although --jit and --engine=luajittex are independent
+ setargument("engine","luajittex")
+end
+
+local engine_new = getargument("engine") or directives.value("system.engine")
+local engine_old = environment.ownbin
+
+local function restart(engine_old,engine_new)
+ local command = format("%s --luaonly %q %s --redirected",engine_new,environment.ownname,environment.reconstructcommandline())
+ report(format("redirect %s -> %s: %s",engine_old,engine_new,command))
+ local result = os.execute(command)
+ os.exit(result)
+end
+
+if getargument("redirected") then
+ setargument("engine",engine_old) -- later on we need this
+elseif engine_new == engine_old then
+ setargument("engine",engine_new) -- later on we need this
+elseif environment.validengines[engine_new] and engine_new ~= environment.basicengines[engine_old] then
+ restart(engine_old,engine_new)
+else
+ setargument("engine",engine_new) -- later on we need this
+end
+
+-- so far
+
+-- constants
+
+local usedfiles = {
+ nop = "cont-nop.mkiv",
+ yes = "cont-yes.mkiv",
+}
+
+local usedsuffixes = {
+ before = {
+ "tuc"
+ },
+ after = {
+ "pdf", "tuc", "log"
+ },
+ keep = {
+ "log"
+ },
+}
+
+local formatofinterface = {
+ en = "cont-en",
+ uk = "cont-uk",
+ de = "cont-de",
+ fr = "cont-fr",
+ nl = "cont-nl",
+ cs = "cont-cs",
+ it = "cont-it",
+ ro = "cont-ro",
+ pe = "cont-pe",
+}
+
+local defaultformats = {
+ "cont-en",
+ "cont-nl",
+}
+
+-- process information
+
+local ctxrunner = { } -- namespace will go
+
+local ctx_locations = { '..', '../..' }
+
+function ctxrunner.new()
+ return {
+ ctxname = "",
+ jobname = "",
+ flags = { },
+ }
+end
+
+function ctxrunner.checkfile(ctxdata,ctxname,defaultname)
+
+ if not ctxdata.jobname or ctxdata.jobname == "" then
+ return
+ end
+
+ ctxdata.ctxname = ctxname or file.removesuffix(ctxdata.jobname) or ""
+
+ if ctxdata.ctxname == "" then
+ return
+ end
+
+ ctxdata.jobname = file.addsuffix(ctxdata.jobname,'tex')
+ ctxdata.ctxname = file.addsuffix(ctxdata.ctxname,'ctx')
+
+ report("jobname: %s",ctxdata.jobname)
+ report("ctxname: %s",ctxdata.ctxname)
+
+ -- mtxrun should resolve kpse: and file:
+
+ local usedname = ctxdata.ctxname
+ local found = lfs.isfile(usedname)
+
+ -- no further test if qualified path
+
+ if not found then
+ for _, path in next, ctx_locations do
+ local fullname = file.join(path,ctxdata.ctxname)
+ if lfs.isfile(fullname) then
+ usedname = fullname
+ found = true
+ break
+ end
+ end
+ end
+
+ if not found then
+ usedname = resolvers.findfile(ctxdata.ctxname,"tex")
+ found = usedname ~= ""
+ end
+
+ if not found and defaultname and defaultname ~= "" and lfs.isfile(defaultname) then
+ usedname = defaultname
+ found = true
+ end
+
+ if not found then
+ return
+ end
+
+ local xmldata = xml.load(usedname)
+
+ if not xmldata then
+ return
+ else
+ -- test for valid, can be text file
+ end
+
+ local ctxpaths = table.append({'.', file.dirname(ctxdata.ctxname)}, ctx_locations)
+
+ xml.include(xmldata,'ctx:include','name', ctxpaths)
+
+ local flags = ctxdata.flags
+
+ for e in xml.collected(xmldata,"/ctx:job/ctx:flags/ctx:flag") do
+ local flag = xml.text(e) or ""
+ local key, value = match(flag,"^(.-)=(.+)$")
+ if key and value then
+ flags[key] = value
+ else
+ flags[flag] = true
+ end
+ end
+
+end
+
+function ctxrunner.checkflags(ctxdata)
+ if ctxdata then
+ for k,v in next, ctxdata.flags do
+ if getargument(k) == nil then
+ setargument(k,v)
+ end
+ end
+ end
+end
+
+-- multipass control
+
+local multipass_suffixes = { ".tuc" }
+local multipass_nofruns = 8 -- or 7 to test oscillation
+
+local function multipass_hashfiles(jobname)
+ local hash = { }
+ for i=1,#multipass_suffixes do
+ local suffix = multipass_suffixes[i]
+ local full = jobname .. suffix
+ hash[full] = md5.hex(io.loaddata(full) or "unknown")
+ end
+ return hash
+end
+
+local function multipass_changed(oldhash, newhash)
+ for k,v in next, oldhash do
+ if v ~= newhash[k] then
+ return true
+ end
+ end
+ return false
+end
+
+local function multipass_copyluafile(jobname)
+ local tuaname, tucname = jobname..".tua", jobname..".tuc"
+ if lfs.isfile(tuaname) then
+ os.remove(tucname)
+ os.rename(tuaname,tucname)
+ end
+end
+
+--
+
+local pattern = lpegpatterns.utfbom^-1 * (P("%% ") + P("% ")) * Cs((1-lpegpatterns.newline)^1)
+
+local function preamble_analyze(filename) -- only files on current path
+ local t = { }
+ local line = io.loadlines(file.addsuffix(filename,"tex"))
+ if line then
+ local preamble = lpegmatch(pattern,line)
+ if preamble then
+ for key, value in gmatch(preamble,"(%S+)%s*=%s*(%S+)") do
+ t[key] = value
+ end
+ t.type = "tex"
+ elseif find(line,"^<?xml ") then
+ t.type = "xml"
+ end
+ if t.nofruns then
+ multipass_nofruns = t.nofruns
+ end
+ if not t.engine then
+ t.engine = environment.basicengines[engine_old] --'luatex'
+ end
+ if t.engine ~= engine_old then -- hack
+ if environment.validengines[t.engine] and t.engine ~= environment.basicengines[engine_old] then
+ restart(engine_old,t.engine)
+ end
+ end
+ end
+ return t
+end
+
+-- automatically opening and closing pdf files
+
+local pdfview -- delayed
+
+local function pdf_open(name,method)
+ pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
+ pdfview.setmethod(method)
+ report(pdfview.status())
+ pdfview.open(file.replacesuffix(name,"pdf"))
+end
+
+local function pdf_close(name,method)
+ pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
+ pdfview.setmethod(method)
+ pdfview.close(file.replacesuffix(name,"pdf"))
+end
+
+-- result file handling
+
+local function result_push_purge(oldbase,newbase)
+ for _, suffix in next, usedsuffixes.after do
+ local oldname = file.addsuffix(oldbase,suffix)
+ local newname = file.addsuffix(newbase,suffix)
+ os.remove(newname)
+ os.remove(oldname)
+ end
+end
+
+local function result_push_keep(oldbase,newbase)
+ for _, suffix in next, usedsuffixes.before do
+ local oldname = file.addsuffix(oldbase,suffix)
+ local newname = file.addsuffix(newbase,suffix)
+ local tmpname = "keep-"..oldname
+ os.remove(tmpname)
+ os.rename(oldname,tmpname)
+ os.remove(oldname)
+ os.rename(newname,oldname)
+ end
+end
+
+local function result_save_error(oldbase,newbase)
+ for _, suffix in next, usedsuffixes.keep do
+ local oldname = file.addsuffix(oldbase,suffix)
+ local newname = file.addsuffix(newbase,suffix)
+ os.remove(newname) -- to be sure
+ os.rename(oldname,newname)
+ end
+end
+
+local function result_save_purge(oldbase,newbase)
+ for _, suffix in next, usedsuffixes.after do
+ local oldname = file.addsuffix(oldbase,suffix)
+ local newname = file.addsuffix(newbase,suffix)
+ os.remove(newname) -- to be sure
+ os.rename(oldname,newname)
+ end
+end
+
+local function result_save_keep(oldbase,newbase)
+ for _, suffix in next, usedsuffixes.after do
+ local oldname = file.addsuffix(oldbase,suffix)
+ local newname = file.addsuffix(newbase,suffix)
+ local tmpname = "keep-"..oldname
+ os.remove(newname)
+ os.rename(oldname,newname)
+ os.rename(tmpname,oldname)
+ end
+end
+
+-- executing luatex
+
+local function flags_to_string(flags,prefix) -- context flags get prepended by c:
+ local t = { }
+ for k, v in table.sortedhash(flags) do
+ if prefix then
+ k = format("c:%s",k)
+ end
+ if not v or v == "" or v == '""' then
+ -- no need to flag false
+ elseif v == true then
+ t[#t+1] = format('--%s',k)
+ elseif type(v) == "string" then
+ t[#t+1] = format('--%s=%s',k,quote(v))
+ else
+ t[#t+1] = format('--%s=%s',k,tostring(v))
+ end
+ end
+ return concat(t," ")
+end
+
+local function luatex_command(l_flags,c_flags,filename,engine)
+ return format('%s %s %s "%s"',
+ engine or "luatex",
+ flags_to_string(l_flags),
+ flags_to_string(c_flags,true),
+ filename
+ )
+end
+
+local plain_formats = {
+ ["plain"] = "plain",
+ ["luatex-plain"] = "luatex-plain",
+}
+
+local function plain_format(plainformat)
+ return plainformat and plain_formats[plainformat]
+end
+
+local function run_plain(plainformat,filename)
+ local plainformat = plain_formats[plainformat]
+ if plainformat then
+ local command = format("mtxrun --script --texformat=%s plain %s",plainformat,filename)
+ report("running command: %s\n\n",command)
+ -- todo: load and run
+ local resultname = file.replacesuffix(filename,"pdf")
+ local pdfview = getargument("autopdf") or getargument("closepdf")
+ if pdfview then
+ pdf_close(resultname,pdfview)
+ os.execute(command)
+ pdf_open(resultname,pdfview)
+ else
+ os.execute(command)
+ end
+ end
+end
+
+local function run_texexec(filename,a_purge,a_purgeall)
+ if false then
+ -- we need to write a top etc too and run mp etc so it's not worth the
+ -- trouble, so it will take a while before the next is finished
+ --
+ -- context --extra=texutil --convert myfile
+ else
+ local texexec = resolvers.findfile("texexec.rb") or ""
+ if texexec ~= "" then
+ os.setenv("RUBYOPT","")
+ local options = environment.reconstructcommandline(environment.arguments_after)
+ options = gsub(options,"--purge","")
+ options = gsub(options,"--purgeall","")
+ local command = format("ruby %s %s",texexec,options)
+ report("running command: %s\n\n",command)
+ if a_purge then
+ os.execute(command)
+ scripts.context.purge_job(filename,false,true)
+ elseif a_purgeall then
+ os.execute(command)
+ scripts.context.purge_job(filename,true,true)
+ else
+ os.execute(command) -- we can use os.exec but that doesn't give back timing
+ end
+ end
+ end
+end
+
+--
+
+function scripts.context.run(ctxdata,filename)
+ --
+ local a_nofile = getargument("nofile")
+ local a_engine = getargument("engine")
+ --
+ local files = environment.files or { }
+ --
+ local filelist, mainfile
+ --
+ if filename then
+ -- the given forced name is processed, the filelist is passed to context
+ mainfile = filename
+ filelist = { filename }
+ -- files = files
+ elseif a_nofile then
+ -- the list of given files is processed using the dummy file
+ mainfile = usedfiles.nop
+ filelist = { usedfiles.nop }
+ -- files = { }
+ elseif #files > 0 then
+ -- the list of given files is processed using the stub file
+ mainfile = usedfiles.yes
+ filelist = files
+ files = { }
+ else
+ return
+ end
+ --
+ local interface = validstring(getargument("interface")) or "en"
+ local formatname = formatofinterface[interface] or "cont-en"
+ local formatfile, scriptfile = resolvers.locateformat(formatname) -- regular engine !
+ if not formatfile or not scriptfile then
+ report("warning: no format found, forcing remake (commandline driven)")
+ scripts.context.make(formatname)
+ formatfile, scriptfile = resolvers.locateformat(formatname) -- variant
+ end
+ if formatfile and scriptfile then
+ -- okay
+ elseif formatname then
+ report("error, no format found with name: %s, aborting",formatname)
+ return
+ else
+ report("error, no format found (provide formatname or interface)")
+ return
+ end
+ --
+ local a_mkii = getargument("mkii") or getargument("pdftex") or getargument("xetex")
+ local a_purge = getargument("purge")
+ local a_purgeall = getargument("purgeall")
+ local a_purgeresult = getargument("purgeresult")
+ local a_global = getargument("global")
+ local a_timing = getargument("timing")
+ local a_profile = getargument("profile")
+ local a_batchmode = getargument("batchmode")
+ local a_nonstopmode = getargument("nonstopmode")
+ local a_once = getargument("once")
+ local a_synctex = getargument("synctex")
+ local a_backend = getargument("backend")
+ local a_arrange = getargument("arrange")
+ local a_noarrange = getargument("noarrange")
+ local a_jiton = getargument("jiton")
+ local a_texformat = getargument("texformat")
+ --
+ a_batchmode = (a_batchmode and "batchmode") or (a_nonstopmode and "nonstopmode") or nil
+ a_synctex = tonumber(a_synctex) or (toboolean(a_synctex,true) and 1) or (a_synctex == "zipped" and 1) or (a_synctex == "unzipped" and -1) or nil
+ --
+ for i=1,#filelist do
+ --
+ local filename = filelist[i]
+ local basename = file.basename(filename) -- use splitter
+ local pathname = file.dirname(filename)
+ --
+ if pathname == "" and not a_global and filename ~= usedfiles.nop then
+ filename = "./" .. filename
+ if not lfs.isfile(filename) then
+ report("warning: no (local) file %a, proceeding",filename)
+ end
+ end
+ --
+ local jobname = file.removesuffix(basename)
+ -- local jobname = file.removesuffix(filename)
+ local ctxname = ctxdata and ctxdata.ctxname
+ --
+ local analysis = preamble_analyze(filename)
+ --
+ if a_mkii or analysis.engine == 'pdftex' or analysis.engine == 'xetex' then
+ run_texexec(filename,a_purge,a_purgeall)
+ elseif plain_format(a_texformat or analysis.texformat) then
+ run_plain(a_texformat or analysis.texformat,filename)
+ else
+ if analysis.interface and analysis.interface ~= interface then
+ formatname = formatofinterface[analysis.interface] or formatname
+ formatfile, scriptfile = resolvers.locateformat(formatname)
+ end
+ --
+ a_jiton = (a_jiton or toboolean(analysis.jiton,true)) and true or nil
+ --
+ if not formatfile or not scriptfile then
+ report("warning: no format found, forcing remake (source driven)")
+ scripts.context.make(formatname,a_engine)
+ formatfile, scriptfile = resolvers.locateformat(formatname)
+ end
+ if formatfile and scriptfile then
+ local suffix = validstring(getargument("suffix"))
+ local resultname = validstring(getargument("result"))
+ if suffix then
+ resultname = file.removesuffix(jobname) .. suffix
+ end
+ local oldbase = ""
+ local newbase = ""
+ if resultname then
+ oldbase = file.removesuffix(jobname)
+ newbase = file.removesuffix(resultname)
+ if oldbase ~= newbase then
+ if a_purgeresult then
+ result_push_purge(oldbase,newbase)
+ else
+ result_push_keep(oldbase,newbase)
+ end
+ else
+ resultname = nil
+ end
+ end
+ --
+ local pdfview = getargument("autopdf") or getargument("closepdf")
+ if pdfview then
+ pdf_close(filename,pdfview)
+ if resultname then
+ pdf_close(resultname,pdfview)
+ end
+ end
+ --
+ -- we could do this when locating the format and exit from luatex when
+ -- there is a version mismatch .. that way we can use stock luatex
+ -- plus mtxrun to run luajittex instead .. this saves a restart but is
+ -- also cleaner as then mtxrun only has to check for a special return
+ -- code (signaling a make + rerun) .. maybe some day
+ --
+ local okay = statistics.checkfmtstatus(formatfile,a_engine)
+ if okay ~= true then
+ report("warning: %s, forcing remake",tostring(okay))
+ scripts.context.make(formatname)
+ end
+ --
+ local oldhash = multipass_hashfiles(jobname)
+ local newhash = { }
+ local maxnofruns = once and 1 or multipass_nofruns
+ --
+ local c_flags = {
+ directives = validstring(environment.directives), -- gets passed via mtxrun
+ trackers = validstring(environment.trackers), -- gets passed via mtxrun
+ experiments = validstring(environment.experiments), -- gets passed via mtxrun
+ --
+ result = validstring(resultname),
+ input = validstring(getargument("input") or filename), -- alternative input
+ fulljobname = validstring(filename),
+ files = concat(files,","),
+ ctx = validstring(ctxname),
+ }
+ --
+ for k, v in next, environment.arguments do
+ -- the raw arguments
+ if c_flags[k] == nil then
+ c_flags[k] = v
+ end
+ end
+ --
+ --
+ local l_flags = {
+ ["interaction"] = a_batchmode,
+ ["synctex"] = a_synctex,
+ ["no-parse-first-line"] = true,
+ -- ["no-mktex"] = true,
+ -- ["file-line-error-style"] = true,
+ ["fmt"] = formatfile,
+ ["lua"] = scriptfile,
+ ["jobname"] = jobname,
+ ["jiton"] = a_jiton,
+ }
+ --
+ if a_synctex then
+ report("warning: synctex is enabled") -- can add upto 5% runtime
+ end
+ --
+ if not a_timing then
+ -- okay
+ elseif c_flags.usemodule then
+ c_flags.usemodule = format("timing,%s",c_flags.usemodule)
+ else
+ c_flags.usemodule = "timing"
+ end
+ --
+ if not a_profile then
+ -- okay
+ elseif c_flags.directives then
+ c_flags.directives = format("system.profile,%s",c_flags.directives)
+ else
+ c_flags.directives = "system.profile"
+ end
+ --
+ -- kindofrun: 1:first run, 2:successive run, 3:once, 4:last of maxruns
+ --
+ for currentrun=1,maxnofruns do
+ --
+ c_flags.final = false
+ c_flags.kindofrun = (a_once and 3) or (currentrun==1 and 1) or (currentrun==maxnofruns and 4) or 2
+ c_flags.maxnofruns = maxnofruns
+ c_flags.currentrun = currentrun
+ c_flags.noarrange = a_noarrange or a_arrange or nil
+ --
+ local command = luatex_command(l_flags,c_flags,mainfile,a_engine)
+ --
+ report("run %s: %s",i,command)
+ print("") -- cleaner, else continuation on same line
+ local returncode, errorstring = os.spawn(command)
+ if not returncode then
+ report("fatal error: no return code, message: %s",errorstring or "?")
+ if resultname then
+ result_save_error(oldbase,newbase)
+ end
+ os.exit(1)
+ break
+ elseif returncode == 0 then
+ multipass_copyluafile(jobname)
+ newhash = multipass_hashfiles(jobname)
+ if multipass_changed(oldhash,newhash) then
+ oldhash = newhash
+ else
+ break
+ end
+ else
+ report("fatal error: return code: %s",returncode or "?")
+ if resultname then
+ result_save_error(oldbase,newbase)
+ end
+ os.exit(1) -- (returncode)
+ break
+ end
+ --
+ end
+ --
+ if a_arrange then
+ --
+ c_flags.final = true
+ c_flags.kindofrun = 3
+ c_flags.currentrun = c_flags.currentrun + 1
+ c_flags.noarrange = nil
+ --
+ local command = luatex_command(l_flags,c_flags,mainfile,a_engine)
+ --
+ report("arrange run: %s",command)
+ local returncode, errorstring = os.spawn(command)
+ if not returncode then
+ report("fatal error: no return code, message: %s",errorstring or "?")
+ os.exit(1)
+ elseif returncode > 0 then
+ report("fatal error: return code: %s",returncode or "?")
+ os.exit(returncode)
+ end
+ --
+ end
+ --
+ if a_purge then
+ scripts.context.purge_job(jobname)
+ elseif a_purgeall then
+ scripts.context.purge_job(jobname,true)
+ end
+ --
+ if resultname then
+ if a_purgeresult then
+ -- so, if there is no result then we don't get the old one, but
+ -- related files (log etc) are still there for tracing purposes
+ result_save_purge(oldbase,newbase)
+ else
+ result_save_keep(oldbase,newbase)
+ end
+ report("result renamed to: %s",newbase)
+ end
+ --
+ if purge then
+ scripts.context.purge_job(resultname)
+ elseif purgeall then
+ scripts.context.purge_job(resultname,true)
+ end
+ --
+ local pdfview = getargument("autopdf")
+ if pdfview then
+ pdf_open(resultname or jobname,pdfview)
+ end
+ --
+ if a_timing then
+ report()
+ report("you can process (timing) statistics with:",jobname)
+ report()
+ report("context --extra=timing '%s'",jobname)
+ report("mtxrun --script timing --xhtml [--launch --remove] '%s'",jobname)
+ report()
+ end
+ else
+ if formatname then
+ report("error, no format found with name: %s, skipping",formatname)
+ else
+ report("error, no format found (provide formatname or interface)")
+ end
+ break
+ end
+ end
+ end
+ --
+end
+
+function scripts.context.pipe() -- still used?
+ -- context --pipe
+ -- context --pipe --purge --dummyfile=whatever.tmp
+ local interface = getargument("interface")
+ interface = (type(interface) == "string" and interface) or "en"
+ local formatname = formatofinterface[interface] or "cont-en"
+ local formatfile, scriptfile = resolvers.locateformat(formatname)
+ if not formatfile or not scriptfile then
+ report("warning: no format found, forcing remake (commandline driven)")
+ scripts.context.make(formatname)
+ formatfile, scriptfile = resolvers.locateformat(formatname)
+ end
+ if formatfile and scriptfile then
+ local okay = statistics.checkfmtstatus(formatfile)
+ if okay ~= true then
+ report("warning: %s, forcing remake",tostring(okay))
+ scripts.context.make(formatname)
+ end
+ local l_flags = {
+ interaction = "scrollmode",
+ fmt = formatfile,
+ lua = scriptfile,
+ }
+ local c_flags = {
+ backend = "pdf",
+ final = false,
+ kindofrun = 3,
+ currentrun = 1,
+ }
+ local filename = getargument("dummyfile") or ""
+ if filename == "" then
+ filename = "\\relax"
+ report("entering scrollmode, end job with \\end")
+ else
+ filename = file.addsuffix(filename,"tmp")
+ io.savedata(filename,"\\relax")
+ report("entering scrollmode using '%s' with optionfile, end job with \\end",filename)
+ end
+ local command = luatex_command(l_flags,c_flags,filename)
+ os.spawn(command)
+ if getargument("purge") then
+ scripts.context.purge_job(filename)
+ elseif getargument("purgeall") then
+ scripts.context.purge_job(filename,true)
+ os.remove(filename)
+ end
+ else
+ if formatname then
+ report("error, no format found with name: %s, aborting",formatname)
+ else
+ report("error, no format found (provide formatname or interface)")
+ end
+ end
+end
+
+local function make_mkiv_format(name,engine)
+ environment.make_format(name) -- jit is picked up later
+end
+
+local function make_mkii_format(name,engine)
+ local command = format("mtxrun texexec.rb --make --%s %s",name,engine)
+ report("running command: %s",command)
+ os.spawn(command)
+end
+
+function scripts.context.generate()
+ resolvers.instance.renewcache = true
+ trackers.enable("resolvers.locating")
+ resolvers.load()
+end
+
+function scripts.context.make(name)
+ if not getargument("fast") then -- as in texexec
+ scripts.context.generate()
+ end
+ local list = (name and { name }) or (environment.files[1] and environment.files) or defaultformats
+ local engine = getargument("engine") or "luatex"
+ if getargument("jit") or getargument("jiton") then
+ engine = "luajittex"
+ end
+ for i=1,#list do
+ local name = list[i]
+ name = formatofinterface[name] or name or ""
+ if name == "" then
+ -- nothing
+ elseif engine == "luatex" or engine == "luajittex" then
+ make_mkiv_format(name,engine)
+ elseif engine == "pdftex" or engine == "xetex" then
+ make_mkii_format(name,engine)
+ end
+ end
+end
+
+function scripts.context.ctx()
+ local ctxdata = ctxrunner.new()
+ ctxdata.jobname = environment.files[1]
+ ctxrunner.checkfile(ctxdata,getargument("ctx"))
+ ctxrunner.checkflags(ctxdata)
+ scripts.context.run(ctxdata)
+end
+
+function scripts.context.autoctx()
+ local ctxdata = nil
+ local files = environment.files
+ local firstfile = #files > 0 and files[1]
+ if firstfile then
+ local suffix = file.suffix(firstfile)
+ if suffix == "xml" then
+ local chunk = io.loadchunk(firstfile) -- 1024
+ if chunk then
+ local ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>")
+ if ctxname then
+ ctxdata = ctxrunner.new()
+ ctxdata.jobname = firstfile
+ ctxrunner.checkfile(ctxdata,ctxname)
+ ctxrunner.checkflags(ctxdata)
+ end
+ end
+ elseif suffix == "tex" then
+ -- maybe but we scan the preamble later too
+ end
+ end
+ scripts.context.run(ctxdata)
+end
+
+-- no longer ok as mlib-run misses something:
+
+-- local template = [[
+-- \starttext
+-- \directMPgraphic{%s}{input "%s"}
+-- \stoptext
+-- ]]
+--
+-- local loaded = false
+--
+-- function scripts.context.metapost()
+-- local filename = environment.files[1] or ""
+-- if not loaded then
+-- dofile(resolvers.findfile("mlib-run.lua"))
+-- loaded = true
+-- commands = commands or { }
+-- commands.writestatus = report -- no longer needed
+-- end
+-- local formatname = getargument("format") or "metafun"
+-- if formatname == "" or type(formatname) == "boolean" then
+-- formatname = "metafun"
+-- end
+-- if getargument("pdf") then
+-- local basename = file.removesuffix(filename)
+-- local resultname = getargument("result") or basename
+-- local jobname = "mtx-context-metapost"
+-- local tempname = file.addsuffix(jobname,"tex")
+-- io.savedata(tempname,format(template,"metafun",filename))
+-- environment.files[1] = tempname
+-- setargument("result",resultname)
+-- setargument("once",true)
+-- scripts.context.run()
+-- scripts.context.purge_job(jobname,true)
+-- scripts.context.purge_job(resultname,true)
+-- elseif getargument("svg") then
+-- metapost.directrun(formatname,filename,"svg")
+-- else
+-- metapost.directrun(formatname,filename,"mps")
+-- end
+-- end
+
+-- --
+
+function scripts.context.version()
+ local name = resolvers.findfile("context.mkiv")
+ if name ~= "" then
+ report("main context file: %s",name)
+ local data = io.loaddata(name)
+ if data then
+ local version = match(data,"\\edef\\contextversion{(.-)}")
+ if version then
+ report("current version: %s",version)
+ else
+ report("context version: unknown, no timestamp found")
+ end
+ else
+ report("context version: unknown, load error")
+ end
+ else
+ report("main context file: unknown, 'context.mkiv' not found")
+ end
+end
+
+-- purging files
+
+local generic_files = {
+ "texexec.tex", "texexec.tui", "texexec.tuo",
+ "texexec.tuc", "texexec.tua",
+ "texexec.ps", "texexec.pdf", "texexec.dvi",
+ "cont-opt.tex", "cont-opt.bak"
+}
+
+local obsolete_results = {
+ "dvi",
+}
+
+local temporary_runfiles = {
+ "tui", "tua", "tup", "ted", "tes", "top",
+ "log", "tmp", "run", "bck", "rlg",
+ "mpt", "mpx", "mpd", "mpo", "mpb", "ctl",
+ "synctex", "synctex.gz", "pgf",
+ "prep",
+}
+
+local persistent_runfiles = {
+ "tuo", "tub", "top", "tuc"
+}
+
+local special_runfiles = {
+ "-mpgraph", "-mprun", "-temp-"
+}
+
+local function purge_file(dfile,cfile)
+ if cfile and lfs.isfile(cfile) then
+ if os.remove(dfile) then
+ return file.basename(dfile)
+ end
+ elseif dfile then
+ if os.remove(dfile) then
+ return file.basename(dfile)
+ end
+ end
+end
+
+function scripts.context.purge_job(jobname,all,mkiitoo)
+ if jobname and jobname ~= "" then
+ jobname = file.basename(jobname)
+ local filebase = file.removesuffix(jobname)
+ if mkiitoo then
+ scripts.context.purge(all,filebase,true) -- leading "./"
+ else
+ local deleted = { }
+ for i=1,#obsolete_results do
+ deleted[#deleted+1] = purge_file(filebase.."."..obsolete_results[i],filebase..".pdf")
+ end
+ for i=1,#temporary_runfiles do
+ deleted[#deleted+1] = purge_file(filebase.."."..temporary_runfiles[i])
+ end
+ if all then
+ for i=1,#persistent_runfiles do
+ deleted[#deleted+1] = purge_file(filebase.."."..persistent_runfiles[i])
+ end
+ end
+ if #deleted > 0 then
+ report("purged files: %s", concat(deleted,", "))
+ end
+ end
+ end
+end
+
+function scripts.context.purge(all,pattern,mkiitoo)
+ local all = all or getargument("all")
+ local pattern = getargument("pattern") or (pattern and (pattern.."*")) or "*.*"
+ local files = dir.glob(pattern)
+ local obsolete = table.tohash(obsolete_results)
+ local temporary = table.tohash(temporary_runfiles)
+ local persistent = table.tohash(persistent_runfiles)
+ local generic = table.tohash(generic_files)
+ local deleted = { }
+ for i=1,#files do
+ local name = files[i]
+ local suffix = file.suffix(name)
+ local basename = file.basename(name)
+ if obsolete[suffix] or temporary[suffix] or persistent[suffix] or generic[basename] then
+ deleted[#deleted+1] = purge_file(name)
+ elseif mkiitoo then
+ for i=1,#special_runfiles do
+ if find(name,special_runfiles[i]) then
+ deleted[#deleted+1] = purge_file(name)
+ end
+ end
+ end
+ end
+ if #deleted > 0 then
+ report("purged files: %s", concat(deleted,", "))
+ end
+end
+
+-- touching files (signals regeneration of formats)
+
+local function touch(path,name,versionpattern,kind,kindpattern)
+ if path and path ~= "" then
+ name = file.join(path,name)
+print(name)
+ else
+ name = resolvers.findfile(name)
+ end
+ local olddata = io.loaddata(name)
+ if olddata then
+ local oldkind, newkind = "", kind or ""
+ local oldversion, newversion = "", os.date("%Y.%m.%d %H:%M")
+ local newdata
+ if versionpattern then
+ newdata = gsub(olddata,versionpattern,function(pre,mid,post)
+ oldversion = mid
+ return pre .. newversion .. post
+ end) or olddata
+ end
+ if kind and kindpattern then
+ newdata = gsub(newdata,kindpattern,function(pre,mid,post)
+ oldkind = mid
+ return pre .. newkind .. post
+ end) or newdata
+ end
+ if newdata ~= "" and (oldversion ~= newversion or oldkind ~= newkind or newdata ~= olddata) then
+ local backup = file.replacesuffix(name,"tmp")
+ os.remove(backup)
+ os.rename(name,backup)
+ io.savedata(name,newdata)
+ return name, oldversion, newversion, oldkind, newkind
+ end
+ end
+end
+
+local p_contextkind = "(\\edef\\contextkind%s*{)(.-)(})"
+local p_contextversion = "(\\edef\\contextversion%s*{)(.-)(})"
+local p_newcontextversion = "(\\newcontextversion%s*{)(.-)(})"
+
+local function touchfiles(suffix,kind,path)
+ local foundname, oldversion, newversion, oldkind, newkind = touch(path,file.addsuffix("context",suffix),p_contextversion,kind,p_contextkind)
+ if foundname then
+ report("old version : %s (%s)",oldversion,oldkind)
+ report("new version : %s (%s)",newversion,newkind)
+ report("touched file : %s",foundname)
+ local foundname = touch(path,file.addsuffix("cont-new",suffix),p_newcontextversion)
+ if foundname then
+ report("touched file : %s", foundname)
+ end
+ else
+ report("nothing touched")
+ end
+end
+
+function scripts.context.touch()
+ if getargument("expert") then
+ local touch = getargument("touch")
+ local kind = getargument("kind")
+ local path = getargument("basepath")
+ if touch == "mkii" or touch == "mkiv" or touch == "mkvi" then -- mkix mkxi
+ touchfiles(touch,kind,path)
+ else
+ touchfiles("mkii",kind,path)
+ touchfiles("mkiv",kind,path)
+ touchfiles("mkvi",kind,path)
+ end
+ else
+ report("touching needs --expert")
+ end
+end
+
+-- modules
+
+local labels = { "title", "comment", "status" }
+local cards = { "*.mkvi", "*.mkiv", "*.mkxi", "*.mkix", "*.tex" }
+
+function scripts.context.modules(pattern)
+ local list = { }
+ local found = resolvers.findfile("context.mkiv")
+ if not pattern or pattern == "" then
+ -- official files in the tree
+ for i=1,#cards do
+ resolvers.findwildcardfiles(cards[i],list)
+ end
+ -- my dev path
+ for i=1,#cards do
+ dir.glob(file.join(file.dirname(found),cards[i]),list)
+ end
+ else
+ resolvers.findwildcardfiles(pattern,list)
+ dir.glob(file.join(file.dirname(found,pattern)),list)
+ end
+ local done = { } -- todo : sort
+ for i=1,#list do
+ local v = list[i]
+ local base = file.basename(v)
+ if not done[base] then
+ done[base] = true
+ local suffix = file.suffix(base)
+ if suffix == "tex" or suffix == "mkiv" or suffix == "mkvi" or suffix == "mkix" or suffix == "mkxi" then
+ local prefix = match(base,"^([xmst])%-")
+ if prefix then
+ v = resolvers.findfile(base) -- so that files on my dev path are seen
+ local data = io.loaddata(v) or ""
+ data = match(data,"%% begin info(.-)%% end info")
+ if data then
+ local info = { }
+ for label, text in gmatch(data,"%% +([^ ]+) *: *(.-)[\n\r]") do
+ info[label] = text
+ end
+ report()
+ report("%-7s : %s","module",base)
+ report()
+ for i=1,#labels do
+ local l = labels[i]
+ if info[l] then
+ report("%-7s : %s",l,info[l])
+ end
+ end
+ report()
+ end
+ end
+ end
+ end
+ end
+end
+
+-- extras
+
+function scripts.context.extras(pattern)
+ -- only in base path, i.e. only official ones
+ if type(pattern) ~= "string" then
+ pattern = "*"
+ end
+ local found = resolvers.findfile("context.mkiv")
+ if found ~= "" then
+ pattern = file.join(dir.expandname(file.dirname(found)),format("mtx-context-%s.tex",pattern or "*"))
+ local list = dir.glob(pattern)
+ for i=1,#list do
+ local v = list[i]
+ local data = io.loaddata(v) or ""
+ data = match(data,"%% begin help(.-)%% end help")
+ if data then
+ report()
+ report("extra: %s (%s)",(gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1")),v)
+ for s in gmatch(data,"%% *(.-)[\n\r]") do
+ report(s)
+ end
+ report()
+ end
+ end
+ end
+end
+
+function scripts.context.extra()
+ local extra = getargument("extra")
+ if type(extra) ~= "string" then
+ scripts.context.extras()
+ elseif getargument("help") then
+ scripts.context.extras(extra)
+ else
+ local fullextra = extra
+ if not find(fullextra,"mtx%-context%-") then
+ fullextra = "mtx-context-" .. extra
+ end
+ local foundextra = resolvers.findfile(fullextra)
+ if foundextra == "" then
+ scripts.context.extras()
+ return
+ else
+ report("processing extra: %s", foundextra)
+ end
+ setargument("purgeall",true)
+ local result = getargument("result") or ""
+ if result == "" then
+ setargument("result","context-extra")
+ end
+ scripts.context.run(nil,foundextra)
+ end
+end
+
+-- todo: we need to do a dummy run
+
+function scripts.context.trackers()
+ environment.files = { resolvers.findfile("m-trackers.mkiv") }
+ multipass_nofruns = 1
+ setargument("purgeall",true)
+ scripts.context.run()
+end
+
+function scripts.context.directives()
+ environment.files = { resolvers.findfile("m-directives.mkiv") }
+ multipass_nofruns = 1
+ setargument("purgeall",true)
+ scripts.context.run()
+end
+
+function scripts.context.logcategories()
+ environment.files = { resolvers.findfile("m-logcategories.mkiv") }
+ multipass_nofruns = 1
+ setargument("purgeall",true)
+ scripts.context.run()
+end
+
+-- updating (often one will use mtx-update instead)
+
+function scripts.context.timed(action)
+ statistics.timed(action)
+end
+
+local zipname = "cont-tmf.zip"
+local mainzip = "http://www.pragma-ade.com/context/latest/" .. zipname
+local validtrees = { "texmf-local", "texmf-context" }
+local selfscripts = { "mtxrun.lua" } -- was: { "luatools.lua", "mtxrun.lua" }
+
+function zip.loaddata(zipfile,filename) -- should be in zip lib
+ local f = zipfile:open(filename)
+ if f then
+ local data = f:read("*a")
+ f:close()
+ return data
+ end
+ return nil
+end
+
+function scripts.context.update()
+ local force = getargument("force")
+ local socket = require("socket")
+ local http = require("socket.http")
+ local basepath = resolvers.findfile("context.mkiv") or ""
+ if basepath == "" then
+ report("quiting, no 'context.mkiv' found")
+ return
+ end
+ local basetree = basepath.match(basepath,"^(.-)tex/context/base/context.mkiv$") or ""
+ if basetree == "" then
+ report("quiting, no proper tds structure (%s)",basepath)
+ return
+ end
+ local function is_okay(basetree)
+ for _, tree in next, validtrees do
+ local pattern = gsub(tree,"%-","%%-")
+ if find(basetree,pattern) then
+ return tree
+ end
+ end
+ return false
+ end
+ local okay = is_okay(basetree)
+ if not okay then
+ report("quiting, tree '%s' is protected",okay)
+ return
+ else
+ report("updating tree '%s'",okay)
+ end
+ if not lfs.chdir(basetree) then
+ report("quiting, unable to change to '%s'",okay)
+ return
+ end
+ report("fetching '%s'",mainzip)
+ local latest = http.request(mainzip)
+ if not latest then
+ report("context tree '%s' can be updated, use --force",okay)
+ return
+ end
+ io.savedata("cont-tmf.zip",latest)
+ if false then
+ -- variant 1
+ os.execute("mtxrun --script unzip cont-tmf.zip")
+ else
+ -- variant 2
+ local zipfile = zip.open(zipname)
+ if not zipfile then
+ report("quiting, unable to open '%s'",zipname)
+ return
+ end
+ local newfile = zip.loaddata(zipfile,"tex/context/base/context.mkiv")
+ if not newfile then
+ report("quiting, unable to open '%s'","context.mkiv")
+ return
+ end
+ local oldfile = io.loaddata(resolvers.findfile("context.mkiv")) or ""
+ local function versiontonumber(what,str)
+ local version = match(str,"\\edef\\contextversion{(.-)}") or ""
+ local year, month, day, hour, minute = match(str,"\\edef\\contextversion{(%d+)%.(%d+)%.(%d+) *(%d+)%:(%d+)}")
+ if year and minute then
+ local time = os.time { year=year,month=month,day=day,hour=hour,minute=minute}
+ report("%s version: %s (%s)",what,version,time)
+ return time
+ else
+ report("%s version: %s (unknown)",what,version)
+ return nil
+ end
+ end
+ local oldversion = versiontonumber("old",oldfile)
+ local newversion = versiontonumber("new",newfile)
+ if not oldversion or not newversion then
+ report("quiting, version cannot be determined")
+ return
+ elseif oldversion == newversion then
+ report("quiting, your current version is up-to-date")
+ return
+ elseif oldversion > newversion then
+ report("quiting, your current version is newer")
+ return
+ end
+ for k in zipfile:files() do
+ local filename = k.filename
+ if find(filename,"/$") then
+ lfs.mkdir(filename)
+ else
+ local data = zip.loaddata(zipfile,filename)
+ if data then
+ if force then
+ io.savedata(filename,data)
+ end
+ report(filename)
+ end
+ end
+ end
+ for _, scriptname in next, selfscripts do
+ local oldscript = resolvers.findfile(scriptname) or ""
+ if oldscript ~= "" and is_okay(oldscript) then
+ local newscript = "./scripts/context/lua/" .. scriptname
+ local data = io.loaddata(newscript) or ""
+ if data ~= "" then
+ report("replacing script '%s' by '%s'",oldscript,newscript)
+ if force then
+ io.savedata(oldscript,data)
+ end
+ end
+ else
+ report("keeping script '%s'",oldscript)
+ end
+ end
+ if force then
+ scripts.context.make()
+ end
+ end
+ if force then
+ report("context tree '%s' has been updated",okay)
+ else
+ report("context tree '%s' can been updated (use --force)",okay)
+ end
+end
+
+-- getting it done
+
+if getargument("nostats") then
+ setargument("nostatistics",true)
+ setargument("nostat",nil)
+end
+
+if getargument("batch") then
+ setargument("batchmode",true)
+ setargument("batch",nil)
+end
+
+if getargument("nonstop") then
+ setargument("nonstopmode",true)
+ setargument("nonstop",nil)
+end
+
+do
+
+ local silent = getargument("silent")
+ if type(silent) == "string" then
+ directives.enable(format("logs.blocked={%s}",silent))
+ elseif silent then
+ directives.enable("logs.blocked")
+ end
+
+end
+
+if getargument("once") then
+ multipass_nofruns = 1
+elseif getargument("runs") then
+ multipass_nofruns = tonumber(getargument("runs")) or nil
+end
+
+if getargument("run") then
+ scripts.context.timed(scripts.context.autoctx)
+elseif getargument("make") then
+ scripts.context.timed(function() scripts.context.make() end)
+elseif getargument("generate") then
+ scripts.context.timed(function() scripts.context.generate() end)
+elseif getargument("ctx") then
+ scripts.context.timed(scripts.context.ctx)
+-- elseif getargument("mp") or getargument("metapost") then
+-- scripts.context.timed(scripts.context.metapost)
+elseif getargument("version") then
+ application.identify()
+ scripts.context.version()
+elseif getargument("touch") then
+ scripts.context.touch()
+elseif getargument("update") then
+ scripts.context.update()
+elseif getargument("expert") then
+ application.help("expert", "special")
+elseif getargument("modules") then
+ scripts.context.modules()
+elseif getargument("extras") then
+ scripts.context.extras(environment.files[1] or getargument("extras"))
+elseif getargument("extra") then
+ scripts.context.extra()
+elseif getargument("exporthelp") then
+ -- application.export(getargument("exporthelp"),environment.files[1])
+ application.export()
+elseif getargument("help") then
+ if environment.files[1] == "extras" then
+ scripts.context.extras()
+ else
+ application.help("basic")
+ end
+elseif getargument("showtrackers") or getargument("trackers") == true then
+ scripts.context.trackers()
+elseif getargument("showdirectives") or getargument("directives") == true then
+ scripts.context.directives()
+elseif getargument("showlogcategories") then
+ scripts.context.logcategories()
+elseif environment.files[1] or getargument("nofile") then
+ scripts.context.timed(scripts.context.autoctx)
+elseif getargument("pipe") then
+ scripts.context.timed(scripts.context.pipe)
+elseif getargument("purge") then
+ -- only when no filename given, supports --pattern
+ scripts.context.purge()
+elseif getargument("purgeall") then
+ -- only when no filename given, supports --pattern
+ scripts.context.purge(true,nil,true)
+else
+ application.help("basic")
+end
diff --git a/scripts/context/lua/mtx-convert.lua b/scripts/context/lua/mtx-convert.lua
index e6de9356e..b76b3baaf 100644
--- a/scripts/context/lua/mtx-convert.lua
+++ b/scripts/context/lua/mtx-convert.lua
@@ -1,175 +1,175 @@
-if not modules then modules = { } end modules ['mtx-convert'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- todo: eps and svg
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-convert</entry>
- <entry name="detail">ConTeXT Graphic Conversion Helpers</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="convertall"><short>convert all graphics on path</short></flag>
- <flag name="inputpath" value="string"><short>original graphics path</short></flag>
- <flag name="outputpath" value="string"><short>converted graphics path</short></flag>
- <flag name="watch"><short>watch folders</short></flag>
- <flag name="force"><short>force conversion (even if older)</short></flag>
- <flag name="delay"><short>time between sweeps</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-convert",
- banner = "ConTeXT Graphic Conversion Helpers 0.10",
- helpinfo = helpinfo,
-}
-
-local format, find = string.format, string.find
-local concat = table.concat
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.convert = scripts.convert or { }
-local convert = scripts.convert
-convert.converters = convert.converters or { }
-local converters = convert.converters
-
-local gsprogram = os.type == "windows" and "gswin32c" or "gs"
-local gstemplate_eps = "%s -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dEPSCrop -dNOPAUSE -dSAFER -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit"
-local gstemplate_ps = "%s -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dNOPAUSE -dSAFER -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit"
-
-function converters.eps(oldname,newname)
- return format(gstemplate_eps,gsprogram,newname,oldname)
-end
-
-function converters.ps(oldname,newname)
- return format(gstemplate_ps,gsprogram,newname,oldname)
-end
-
-local improgram = "convert"
-local imtemplate = {
- low = "%s -quality 0 -compress zip %s pdf:%s",
- medium = "%s -quality 75 -compress zip %s pdf:%s",
- high = "%s -quality 100 -compress zip %s pdf:%s",
-}
-
-function converters.jpg(oldname,newname)
- local ea = environment.arguments
- local quality = (ea.high and 'high') or (ea.medium and 'medium') or (ea.low and 'low') or 'high'
- return format(imtemplate[quality],improgram,oldname,newname)
-end
-
-converters.gif = converters.jpg
-converters.tif = converters.jpg
-converters.tiff = converters.jpg
-converters.png = converters.jpg
-
-function converters.convertgraphic(kind,oldname,newname)
- if converters[kind] then -- extra test
- local tmpname = file.replacesuffix(newname,"tmp")
- local command = converters[kind](oldname,tmpname)
- report("command: %s",command)
- io.flush()
- os.spawn(command)
- os.remove(newname)
- os.rename(tmpname,newname)
- if lfs.attributes(newname,"size") == 0 then
- os.remove(newname)
- end
- end
-end
-
-function converters.convertpath(inputpath,outputpath)
- inputpath = inputpath or "."
- outputpath = outputpath or "."
- for name in lfs.dir(inputpath) do
- local suffix = file.suffix(name)
- if find(name,"%.$") then
- -- skip . and ..
- elseif converters[suffix] then
- local oldname = file.join(inputpath,name)
- local newname = file.join(outputpath,file.replacesuffix(name,"pdf"))
- local et = lfs.attributes(oldname,"modification")
- local pt = lfs.attributes(newname,"modification")
- if not pt or et > pt then
- dir.mkdirs(outputpath)
- converters.convertgraphic(suffix,oldname,newname)
- end
- elseif lfs.isdir(inputpath .. "/".. name) then
- converters.convertpath(inputpath .. "/".. name,outputpath .. "/".. name)
- end
- end
-end
-
-function converters.convertfile(oldname)
- local suffix = file.suffix(oldname)
- if converters[suffix] then
- local newname = file.replacesuffix(oldname,"pdf")
- if oldname == newname then
- -- todo: downsample, crop etc
- elseif environment.argument("force") then
- converters.convertgraphic(suffix,oldname,newname)
- else
- local et = lfs.attributes(oldname,"modification")
- local pt = lfs.attributes(newname,"modification")
- if not pt or et > pt then
- converters.convertgraphic(suffix,oldname,newname)
- end
- end
- end
-end
-
-if environment.ownscript then
- -- stand alone
-else
- report(application.banner)
- return convert
-end
-
-convert.delay = 5 * 60 -- 5 minutes
-
-function convert.convertall()
- local watch = environment.arguments.watch or false
- local delay = environment.arguments.delay or convert.delay
- local input = environment.arguments.inputpath or "."
- local output = environment.arguments.outputpath or "."
- while true do
- converters.convertpath(input, output)
- if watch then
- os.sleep(delay)
- else
- break
- end
- end
-end
-
-function convert.convertgiven()
- local files = environment.files
- for i=1,#files do
- converters.convertfile(files[i])
- end
-end
-
-if environment.arguments.convertall then
- convert.convertall()
-elseif environment.files[1] then
- convert.convertgiven()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-convert'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: eps and svg
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-convert</entry>
+ <entry name="detail">ConTeXT Graphic Conversion Helpers</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="convertall"><short>convert all graphics on path</short></flag>
+ <flag name="inputpath" value="string"><short>original graphics path</short></flag>
+ <flag name="outputpath" value="string"><short>converted graphics path</short></flag>
+ <flag name="watch"><short>watch folders</short></flag>
+ <flag name="force"><short>force conversion (even if older)</short></flag>
+ <flag name="delay"><short>time between sweeps</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-convert",
+ banner = "ConTeXT Graphic Conversion Helpers 0.10",
+ helpinfo = helpinfo,
+}
+
+local format, find = string.format, string.find
+local concat = table.concat
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.convert = scripts.convert or { }
+local convert = scripts.convert
+convert.converters = convert.converters or { }
+local converters = convert.converters
+
+local gsprogram = os.type == "windows" and "gswin32c" or "gs"
+local gstemplate_eps = "%s -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dEPSCrop -dNOPAUSE -dSAFER -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit"
+local gstemplate_ps = "%s -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dNOPAUSE -dSAFER -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit"
+
+function converters.eps(oldname,newname)
+ return format(gstemplate_eps,gsprogram,newname,oldname)
+end
+
+function converters.ps(oldname,newname)
+ return format(gstemplate_ps,gsprogram,newname,oldname)
+end
+
+local improgram = "convert"
+local imtemplate = {
+ low = "%s -quality 0 -compress zip %s pdf:%s",
+ medium = "%s -quality 75 -compress zip %s pdf:%s",
+ high = "%s -quality 100 -compress zip %s pdf:%s",
+}
+
+function converters.jpg(oldname,newname)
+ local ea = environment.arguments
+ local quality = (ea.high and 'high') or (ea.medium and 'medium') or (ea.low and 'low') or 'high'
+ return format(imtemplate[quality],improgram,oldname,newname)
+end
+
+converters.gif = converters.jpg
+converters.tif = converters.jpg
+converters.tiff = converters.jpg
+converters.png = converters.jpg
+
+function converters.convertgraphic(kind,oldname,newname)
+ if converters[kind] then -- extra test
+ local tmpname = file.replacesuffix(newname,"tmp")
+ local command = converters[kind](oldname,tmpname)
+ report("command: %s",command)
+ io.flush()
+ os.spawn(command)
+ os.remove(newname)
+ os.rename(tmpname,newname)
+ if lfs.attributes(newname,"size") == 0 then
+ os.remove(newname)
+ end
+ end
+end
+
+function converters.convertpath(inputpath,outputpath)
+ inputpath = inputpath or "."
+ outputpath = outputpath or "."
+ for name in lfs.dir(inputpath) do
+ local suffix = file.suffix(name)
+ if find(name,"%.$") then
+ -- skip . and ..
+ elseif converters[suffix] then
+ local oldname = file.join(inputpath,name)
+ local newname = file.join(outputpath,file.replacesuffix(name,"pdf"))
+ local et = lfs.attributes(oldname,"modification")
+ local pt = lfs.attributes(newname,"modification")
+ if not pt or et > pt then
+ dir.mkdirs(outputpath)
+ converters.convertgraphic(suffix,oldname,newname)
+ end
+ elseif lfs.isdir(inputpath .. "/".. name) then
+ converters.convertpath(inputpath .. "/".. name,outputpath .. "/".. name)
+ end
+ end
+end
+
+function converters.convertfile(oldname)
+ local suffix = file.suffix(oldname)
+ if converters[suffix] then
+ local newname = file.replacesuffix(oldname,"pdf")
+ if oldname == newname then
+ -- todo: downsample, crop etc
+ elseif environment.argument("force") then
+ converters.convertgraphic(suffix,oldname,newname)
+ else
+ local et = lfs.attributes(oldname,"modification")
+ local pt = lfs.attributes(newname,"modification")
+ if not pt or et > pt then
+ converters.convertgraphic(suffix,oldname,newname)
+ end
+ end
+ end
+end
+
+if environment.ownscript then
+ -- stand alone
+else
+ report(application.banner)
+ return convert
+end
+
+convert.delay = 5 * 60 -- 5 minutes
+
+function convert.convertall()
+ local watch = environment.arguments.watch or false
+ local delay = environment.arguments.delay or convert.delay
+ local input = environment.arguments.inputpath or "."
+ local output = environment.arguments.outputpath or "."
+ while true do
+ converters.convertpath(input, output)
+ if watch then
+ os.sleep(delay)
+ else
+ break
+ end
+ end
+end
+
+function convert.convertgiven()
+ local files = environment.files
+ for i=1,#files do
+ converters.convertfile(files[i])
+ end
+end
+
+if environment.arguments.convertall then
+ convert.convertall()
+elseif environment.files[1] then
+ convert.convertgiven()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-fcd.lua b/scripts/context/lua/mtx-fcd.lua
index 81e67ca2f..ba9299020 100644
--- a/scripts/context/lua/mtx-fcd.lua
+++ b/scripts/context/lua/mtx-fcd.lua
@@ -1,386 +1,386 @@
-if not modules then modules = { } end modules ['mtx-fcd'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
- comment = "based on the ruby version from 2005",
-}
-
--- This is a kind of variant of the good old ncd (norton change directory) program. This
--- script uses the same indirect cmd trick as Erwin Waterlander's wcd program.
---
--- The program is called via the stubs fcd.cmd or fcd.sh. On unix one should probably source
--- the file: ". fcd args" in order to make the chdir persistent.
---
--- You need to create a stub with:
---
--- mtxrun --script fcd --stub > fcd.cmd
--- mtxrun --script fcd --stub > fcd.sh
---
--- The stub starts this script and afterwards runs the created directory change script as
--- part if the same run, so that indeed we change.
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-fcd</entry>
- <entry name="detail">Fast Directory Change</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="clear"><short>clear the cache</short></flag>
- <flag name="clear"><short><ref name="history"/> [entry] clear the history</short></flag>
- <flag name="scan"><short>clear the cache and add given path(s)</short></flag>
- <flag name="add"><short>add given path(s)</short></flag>
- <flag name="find"><short>find given path (can be substring)</short></flag>
- <flag name="find"><short><ref name="nohistory"/> find given path (can be substring) but don't use history</short></flag>
- <flag name="stub"><short>print platform stub file</short></flag>
- <flag name="list"><short>show roots of cached dirs</short></flag>
- <flag name="list"><short><ref name="history"/> show history of chosen dirs</short></flag>
- <flag name="help"><short>show this help</short></flag>
- </subcategory>
- </category>
- </flags>
- <examples>
- <category>
- <title>Example</title>
- <subcategory>
- <example><command>fcd --scan t:\</command></example>
- <example><command>fcd --add f:\project</command></example>
- <example><command>fcd [--find] whatever</command></example>
- <example><command>fcd --list</command></example>
- </subcategory>
- </category>
- </examples>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-fcd",
- banner = "Fast Directory Change 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-local writeln = print -- texio.write_nl
-
-local find, char, byte, lower, gsub, format = string.find, string.char, string.byte, string.lower, string.gsub, string.format
-
-local mswinstub = [[@echo off
-
-rem this is: fcd.cmd
-
-@echo off
-
-if not exist "%HOME%" goto homepath
-
-:home
-
-mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
-
-if exist "%HOME%\mtx-fcd-goto.cmd" call "%HOME%\mtx-fcd-goto.cmd"
-
-goto end
-
-:homepath
-
-if not exist "%HOMEDRIVE%\%HOMEPATH%" goto end
-
-mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
-
-if exist "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd" call "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd"
-
-goto end
-
-:end
-]]
-
-local unixstub = [[#!/usr/bin/env sh
-
-# this is: fcd.sh
-
-# mv fcd.sh fcd
-# chmod fcd 755
-# . fcd [args]
-
-ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
-
-if test -f "$HOME/fcd_stage.sh" ; then
- . $HOME/fcd_stage.sh ;
-fi;
-
-]]
-
-local gotofile
-local datafile
-local stubfile
-local stubdata
-local stubdummy
-local stubchdir
-
-if os.platform == 'mswin' then
- gotofile = 'mtx-fcd-goto.cmd'
- datafile = 'mtx-fcd-data.lua'
- stubfile = 'fcd.cmd'
- stubdata = mswinstub
- stubdummy = 'rem no dir to change to'
- stubchdir = 'cd /d "%s"'
-else
- gotofile = 'mtx-fcd-goto.sh'
- datafile = 'mtx-fcd-data.lua'
- stubfile = 'fcd.sh'
- stubdata = unixstub
- stubdummy = '# no dir to change to'
- stubchdir = '# cd "%s"'
-end
-
-local homedir = os.env["HOME"] or "" -- no longer TMP etc
-
-if homedir == "" then
- homedir = format("%s/%s",os.env["HOMEDRIVE"] or "",os.env["HOMEPATH"] or "")
-end
-
-if homedir == "/" or not lfs.isdir(homedir) then
- os.exit()
-end
-
-local datafile = file.join(homedir,datafile)
-local gotofile = file.join(homedir,gotofile)
-local hash = nil
-local found = { }
-local pattern = ""
-local version = modules['mtx-fcd'].version
-
-io.savedata(gotofile,stubdummy)
-
-if not lfs.isfile(gotofile) then
- -- write error
- os.exit()
-end
-
-local function fcd_clear(onlyhistory,what)
- if onlyhistory and hash and hash.history then
- if what and what ~= "" then
- hash.history[what] = nil
- else
- hash.history = { }
- end
- else
- hash = {
- name = "fcd cache",
- comment = "generated by mtx-fcd.lua",
- created = os.date(),
- version = version,
- paths = { },
- history = { },
- }
- end
-end
-
-local function fcd_changeto(dir)
- if dir and dir ~= "" then
- io.savedata(gotofile,format(stubchdir,dir))
- end
-end
-
-local function fcd_load(forcecreate)
- if lfs.isfile(datafile) then
- hash = dofile(datafile)
- end
- if not hash or hash.version ~= version then
- if forcecache then
- fcd_clear()
- else
- writeln("empty dir cache")
- fcd_clear()
- os.exit()
- end
- end
-end
-
-local function fcd_save()
- if hash then
- io.savedata(datafile,table.serialize(hash,true))
- end
-end
-
-local function fcd_list(onlyhistory)
- if hash then
- writeln("")
- if onlyhistory then
- if next(hash.history) then
- for k, v in table.sortedhash(hash.history) do
- writeln(format("%s => %s",k,v))
- end
- else
- writeln("no history")
- end
- else
- local paths = hash.paths
- if #paths > 0 then
- for i=1,#paths do
- local path = paths[i]
- writeln(format("%4i %s",#path[2],path[1]))
- end
- else
- writeln("empty cache")
- end
- end
- end
-end
-
-local function fcd_find()
- found = { }
- pattern = environment.files[1] or ""
- if pattern ~= "" then
- pattern = string.escapedpattern(pattern)
- local paths = hash.paths
- for i=1,#paths do
- local paths = paths[i][2]
- for i=1,#paths do
- local path = paths[i]
- if find(path,pattern) then
- found[#found+1] = path
- end
- end
- end
- end
-end
-
-local function fcd_choose(new)
- if pattern == "" then
- writeln(format("staying in dir %q",(gsub(lfs.currentdir(),"\\","/"))))
- return
- end
- if #found == 0 then
- writeln(format("dir %q not found",pattern))
- return
- end
- local okay = #found == 1 and found[1] or (not new and hash.history[pattern])
- if okay then
- writeln(format("changing to %q",okay))
- fcd_changeto(okay)
- return
- end
- local offset = 0
- while true do
- if not found[offset] then
- offset = 0
- end
- io.write("\n")
- for i=1,26 do
- local v = found[i+offset]
- if v then
- writeln(format("%s %3i %s",char(i+96),offset+i,v))
- else
- break
- end
- end
- offset = offset + 26
- if found[offset+1] then
- io.write("\n[press enter for more or select letter]\n\n>> ")
- else
- io.write("\n[select letter]\n\n>> ")
- end
- local answer = lower(io.read() or "")
- if not answer or answer == 'quit' then
- break
- elseif #answer > 0 then
- local choice = tonumber(answer)
- if not choice then
- if answer >= "a" and answer <= "z" then
- choice = byte(answer) - 96 + offset - 26
- end
- end
- local newdir = found[choice]
- if newdir then
- hash.history[pattern] = newdir
- writeln(format("changing to %q",newdir))
- fcd_changeto(newdir)
- fcd_save()
- return
- end
- else
- -- try again
- end
- end
-end
-
-local function globdirs(path,dirs)
- local dirs = dirs or { }
- for name in lfs.dir(path) do
- if not find(name,"%.$") then
- local fullname = path .. "/" .. name
- if lfs.isdir(fullname) and not find(fullname,"/%.") then
- dirs[#dirs+1] = fullname
- globdirs(fullname,dirs)
- end
- end
- end
- return dirs
-end
-
-local function fcd_scan()
- if hash then
- local paths = hash.paths
- for i=1,#environment.files do
- local name = environment.files[i]
- local name = gsub(name,"\\","/")
- local name = gsub(name,"/$","")
- local list = globdirs(name)
- local done = false
- for i=1,#paths do
- if paths[i][1] == name then
- paths[i][2] = list
- done = true
- break
- end
- end
- if not done then
- paths[#paths+1] = { name, list }
- end
- end
- end
-end
-
-local argument = environment.argument
-
-if argument("clear") then
- if argument("history") then
- fcd_load()
- fcd_clear(true)
- else
- fcd_clear()
- end
- fcd_save()
-elseif argument("scan") then
- fcd_clear()
- fcd_scan()
- fcd_save()
-elseif argument("add") then
- fcd_load(true)
- fcd_scan()
- fcd_save()
-elseif argument("stub") then
- writeln(stubdata)
-elseif argument("list") then
- fcd_load()
- if argument("history") then
- fcd_list(true)
- else
- fcd_list()
- end
-elseif argument("help") then
- application.help()
-elseif argument("exporthelp") then
- application.export(argument("exporthelp"),environment.files[1])
-else -- also argument("find")
- fcd_load()
- fcd_find()
- fcd_choose(argument("nohistory"))
-end
-
+if not modules then modules = { } end modules ['mtx-fcd'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ comment = "based on the ruby version from 2005",
+}
+
+-- This is a kind of variant of the good old ncd (norton change directory) program. This
+-- script uses the same indirect cmd trick as Erwin Waterlander's wcd program.
+--
+-- The program is called via the stubs fcd.cmd or fcd.sh. On unix one should probably source
+-- the file: ". fcd args" in order to make the chdir persistent.
+--
+-- You need to create a stub with:
+--
+-- mtxrun --script fcd --stub > fcd.cmd
+-- mtxrun --script fcd --stub > fcd.sh
+--
+-- The stub starts this script and afterwards runs the created directory change script as
+-- part if the same run, so that indeed we change.
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-fcd</entry>
+ <entry name="detail">Fast Directory Change</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="clear"><short>clear the cache</short></flag>
+ <flag name="clear"><short><ref name="history"/> [entry] clear the history</short></flag>
+ <flag name="scan"><short>clear the cache and add given path(s)</short></flag>
+ <flag name="add"><short>add given path(s)</short></flag>
+ <flag name="find"><short>find given path (can be substring)</short></flag>
+ <flag name="find"><short><ref name="nohistory"/> find given path (can be substring) but don't use history</short></flag>
+ <flag name="stub"><short>print platform stub file</short></flag>
+ <flag name="list"><short>show roots of cached dirs</short></flag>
+ <flag name="list"><short><ref name="history"/> show history of chosen dirs</short></flag>
+ <flag name="help"><short>show this help</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Example</title>
+ <subcategory>
+ <example><command>fcd --scan t:\</command></example>
+ <example><command>fcd --add f:\project</command></example>
+ <example><command>fcd [--find] whatever</command></example>
+ <example><command>fcd --list</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-fcd",
+ banner = "Fast Directory Change 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+local writeln = print -- texio.write_nl
+
+local find, char, byte, lower, gsub, format = string.find, string.char, string.byte, string.lower, string.gsub, string.format
+
+local mswinstub = [[@echo off
+
+rem this is: fcd.cmd
+
+@echo off
+
+if not exist "%HOME%" goto homepath
+
+:home
+
+mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+if exist "%HOME%\mtx-fcd-goto.cmd" call "%HOME%\mtx-fcd-goto.cmd"
+
+goto end
+
+:homepath
+
+if not exist "%HOMEDRIVE%\%HOMEPATH%" goto end
+
+mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+if exist "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd" call "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd"
+
+goto end
+
+:end
+]]
+
+local unixstub = [[#!/usr/bin/env sh
+
+# this is: fcd.sh
+
+# mv fcd.sh fcd
+# chmod fcd 755
+# . fcd [args]
+
+ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+if test -f "$HOME/fcd_stage.sh" ; then
+ . $HOME/fcd_stage.sh ;
+fi;
+
+]]
+
+local gotofile
+local datafile
+local stubfile
+local stubdata
+local stubdummy
+local stubchdir
+
+if os.platform == 'mswin' then
+ gotofile = 'mtx-fcd-goto.cmd'
+ datafile = 'mtx-fcd-data.lua'
+ stubfile = 'fcd.cmd'
+ stubdata = mswinstub
+ stubdummy = 'rem no dir to change to'
+ stubchdir = 'cd /d "%s"'
+else
+ gotofile = 'mtx-fcd-goto.sh'
+ datafile = 'mtx-fcd-data.lua'
+ stubfile = 'fcd.sh'
+ stubdata = unixstub
+ stubdummy = '# no dir to change to'
+ stubchdir = '# cd "%s"'
+end
+
+local homedir = os.env["HOME"] or "" -- no longer TMP etc
+
+if homedir == "" then
+ homedir = format("%s/%s",os.env["HOMEDRIVE"] or "",os.env["HOMEPATH"] or "")
+end
+
+if homedir == "/" or not lfs.isdir(homedir) then
+ os.exit()
+end
+
+local datafile = file.join(homedir,datafile)
+local gotofile = file.join(homedir,gotofile)
+local hash = nil
+local found = { }
+local pattern = ""
+local version = modules['mtx-fcd'].version
+
+io.savedata(gotofile,stubdummy)
+
+if not lfs.isfile(gotofile) then
+ -- write error
+ os.exit()
+end
+
+local function fcd_clear(onlyhistory,what)
+ if onlyhistory and hash and hash.history then
+ if what and what ~= "" then
+ hash.history[what] = nil
+ else
+ hash.history = { }
+ end
+ else
+ hash = {
+ name = "fcd cache",
+ comment = "generated by mtx-fcd.lua",
+ created = os.date(),
+ version = version,
+ paths = { },
+ history = { },
+ }
+ end
+end
+
+local function fcd_changeto(dir)
+ if dir and dir ~= "" then
+ io.savedata(gotofile,format(stubchdir,dir))
+ end
+end
+
+local function fcd_load(forcecreate)
+ if lfs.isfile(datafile) then
+ hash = dofile(datafile)
+ end
+ if not hash or hash.version ~= version then
+ if forcecache then
+ fcd_clear()
+ else
+ writeln("empty dir cache")
+ fcd_clear()
+ os.exit()
+ end
+ end
+end
+
+local function fcd_save()
+ if hash then
+ io.savedata(datafile,table.serialize(hash,true))
+ end
+end
+
+local function fcd_list(onlyhistory)
+ if hash then
+ writeln("")
+ if onlyhistory then
+ if next(hash.history) then
+ for k, v in table.sortedhash(hash.history) do
+ writeln(format("%s => %s",k,v))
+ end
+ else
+ writeln("no history")
+ end
+ else
+ local paths = hash.paths
+ if #paths > 0 then
+ for i=1,#paths do
+ local path = paths[i]
+ writeln(format("%4i %s",#path[2],path[1]))
+ end
+ else
+ writeln("empty cache")
+ end
+ end
+ end
+end
+
+local function fcd_find()
+ found = { }
+ pattern = environment.files[1] or ""
+ if pattern ~= "" then
+ pattern = string.escapedpattern(pattern)
+ local paths = hash.paths
+ for i=1,#paths do
+ local paths = paths[i][2]
+ for i=1,#paths do
+ local path = paths[i]
+ if find(path,pattern) then
+ found[#found+1] = path
+ end
+ end
+ end
+ end
+end
+
+local function fcd_choose(new)
+ if pattern == "" then
+ writeln(format("staying in dir %q",(gsub(lfs.currentdir(),"\\","/"))))
+ return
+ end
+ if #found == 0 then
+ writeln(format("dir %q not found",pattern))
+ return
+ end
+ local okay = #found == 1 and found[1] or (not new and hash.history[pattern])
+ if okay then
+ writeln(format("changing to %q",okay))
+ fcd_changeto(okay)
+ return
+ end
+ local offset = 0
+ while true do
+ if not found[offset] then
+ offset = 0
+ end
+ io.write("\n")
+ for i=1,26 do
+ local v = found[i+offset]
+ if v then
+ writeln(format("%s %3i %s",char(i+96),offset+i,v))
+ else
+ break
+ end
+ end
+ offset = offset + 26
+ if found[offset+1] then
+ io.write("\n[press enter for more or select letter]\n\n>> ")
+ else
+ io.write("\n[select letter]\n\n>> ")
+ end
+ local answer = lower(io.read() or "")
+ if not answer or answer == 'quit' then
+ break
+ elseif #answer > 0 then
+ local choice = tonumber(answer)
+ if not choice then
+ if answer >= "a" and answer <= "z" then
+ choice = byte(answer) - 96 + offset - 26
+ end
+ end
+ local newdir = found[choice]
+ if newdir then
+ hash.history[pattern] = newdir
+ writeln(format("changing to %q",newdir))
+ fcd_changeto(newdir)
+ fcd_save()
+ return
+ end
+ else
+ -- try again
+ end
+ end
+end
+
+local function globdirs(path,dirs)
+ local dirs = dirs or { }
+ for name in lfs.dir(path) do
+ if not find(name,"%.$") then
+ local fullname = path .. "/" .. name
+ if lfs.isdir(fullname) and not find(fullname,"/%.") then
+ dirs[#dirs+1] = fullname
+ globdirs(fullname,dirs)
+ end
+ end
+ end
+ return dirs
+end
+
+local function fcd_scan()
+ if hash then
+ local paths = hash.paths
+ for i=1,#environment.files do
+ local name = environment.files[i]
+ local name = gsub(name,"\\","/")
+ local name = gsub(name,"/$","")
+ local list = globdirs(name)
+ local done = false
+ for i=1,#paths do
+ if paths[i][1] == name then
+ paths[i][2] = list
+ done = true
+ break
+ end
+ end
+ if not done then
+ paths[#paths+1] = { name, list }
+ end
+ end
+ end
+end
+
+local argument = environment.argument
+
+if argument("clear") then
+ if argument("history") then
+ fcd_load()
+ fcd_clear(true)
+ else
+ fcd_clear()
+ end
+ fcd_save()
+elseif argument("scan") then
+ fcd_clear()
+ fcd_scan()
+ fcd_save()
+elseif argument("add") then
+ fcd_load(true)
+ fcd_scan()
+ fcd_save()
+elseif argument("stub") then
+ writeln(stubdata)
+elseif argument("list") then
+ fcd_load()
+ if argument("history") then
+ fcd_list(true)
+ else
+ fcd_list()
+ end
+elseif argument("help") then
+ application.help()
+elseif argument("exporthelp") then
+ application.export(argument("exporthelp"),environment.files[1])
+else -- also argument("find")
+ fcd_load()
+ fcd_find()
+ fcd_choose(argument("nohistory"))
+end
+
diff --git a/scripts/context/lua/mtx-flac.lua b/scripts/context/lua/mtx-flac.lua
index 2e988b412..2155b24be 100644
--- a/scripts/context/lua/mtx-flac.lua
+++ b/scripts/context/lua/mtx-flac.lua
@@ -1,238 +1,238 @@
-if not modules then modules = { } end modules ['mtx-flac'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local sub, match, byte, lower = string.sub, string.match, string.byte, string.lower
-local readstring, readnumber = io.readstring, io.readnumber
-local concat, sortedpairs = table.concat, table.sortedpairs
-local tonumber = tonumber
-local tobitstring = number.tobitstring
-local lpegmatch = lpeg.match
-local p_escaped = lpeg.patterns.xml.escaped
-
--- rather silly: pack info in bits while a flac file is large anyway
-
-flac = flac or { }
-
-flac.report = string.format
-
-local splitter = lpeg.splitat("=")
-local readers = { }
-
-readers[0] = function(f,size,target) -- not yet ok .. todo: use bit32 lib
- local info = { }
- target.info = info
- info.minimum_block_size = readnumber(f,-2)
- info.maximum_block_size = readnumber(f,-2)
- info.minimum_frame_size = readnumber(f,-3)
- info.maximum_frame_size = readnumber(f,-3)
- local buffer = { }
- for i=1,8 do
- buffer[i] = tobitstring(readnumber(f,1))
- end
- local bytes = concat(buffer)
- info.sample_rate_in_hz = tonumber(sub(bytes, 1,20),2) -- 20
- info.number_of_channels = tonumber(sub(bytes,21,23),2) -- 3
- info.bits_per_sample = tonumber(sub(bytes,24,28),2) -- 5
- info.samples_in_stream = tonumber(sub(bytes,29,64),2) -- 36
- info.md5_signature = readstring(f,16) -- 128
-end
-
-readers[4] = function(f,size,target,banner)
- local tags = { }
- target.tags = tags
- target.vendor = readstring(f,readnumber(f,-4))
- for i=1,readnumber(f,-4) do
- local key, value = lpeg.match(splitter,readstring(f,readnumber(f,-4)))
- tags[lower(key)] = value
- end
-end
-
-readers.default = function(f,size,target)
- f:seek("cur",size)
-end
-
-function flac.getmetadata(filename)
- local f = io.open(filename, "rb")
- if f then
- local banner = readstring(f,4)
- if banner == "fLaC" then
- local data = {
- banner = banner,
- filename = filename,
- filesize = lfs.attributes(filename,"size"),
- }
- while true do
- local flag = readnumber(f,1)
- local size = readnumber(f,3)
- local last = flag > 127
- if last then
- flag = flag - 128
- end
- local reader = readers[flag] or readers.default
- reader(f,size,data,banner)
- if last then
- f:close()
- return data
- end
- end
- else
- flac.report("no flac file: %s (%s)",filename,banner)
- end
- f:close()
- else
- flac.report("no file: %s",filename)
- end
-end
-
-function flac.savecollection(pattern,filename)
- pattern = (pattern ~= "" and pattern) or "**/*.flac"
- filename = (filename ~= "" and filename) or "music-collection.xml"
- flac.report("identifying files using pattern %q" ,pattern)
- local files = dir.glob(pattern)
- flac.report("%s files found, analyzing files",#files)
- local music = { }
- for i=1,#files do
- local data = flac.getmetadata(files[i])
- if data then
- local tags = data.tags
- local info = data.info
- local artist = tags.artist
- local album = tags.album
- local albums = music[artist]
- if not albums then
- albums = { }
- music[artist] = albums
- end
- local albumx = albums[album]
- if not albumx then
- albumx = {
- year = tags.date,
- tracks = { },
- }
- albums[album] = albumx
- end
- albumx.tracks[tonumber(tags.tracknumber) or 0] = {
- title = tags.title,
- length = math.round((info.samples_in_stream/info.sample_rate_in_hz)),
- }
- end
- end
- -- inspect(music)
- local nofartists, nofalbums, noftracks, noferrors = 0, 0, 0, 0
- local f = io.open(filename,"wb")
- if f then
- flac.report("saving data in file %q",filename)
- f:write("<?xml version='1.0' standalone='yes'?>\n\n")
- f:write("<collection>\n")
- for artist, albums in sortedpairs(music) do
- nofartists = nofartists + 1
- f:write("\t<artist>\n")
- f:write("\t\t<name>",lpegmatch(p_escaped,artist),"</name>\n")
- f:write("\t\t<albums>\n")
- for album, data in sortedpairs(albums) do
- nofalbums = nofalbums + 1
- f:write("\t\t\t<album year='",data.year or 0,"'>\n")
- f:write("\t\t\t\t<name>",lpegmatch(p_escaped,album),"</name>\n")
- f:write("\t\t\t\t<tracks>\n")
- local tracks = data.tracks
- for i=1,#tracks do
- local track = tracks[i]
- if track then
- noftracks = noftracks + 1
- f:write("\t\t\t\t\t<track length='",track.length,"'>",lpegmatch(p_escaped,track.title),"</track>\n")
- else
- noferrors = noferrors + 1
- flac.report("error in album: %q of %q, no track %s",album,artist,i)
- f:write("\t\t\t\t\t<error track='",i,"'/>\n")
- end
- end
- f:write("\t\t\t\t</tracks>\n")
- f:write("\t\t\t</album>\n")
- end
- f:write("\t\t</albums>\n")
- f:write("\t</artist>\n")
- end
- f:write("</collection>\n")
- f:close()
- flac.report("%s tracks of %s albums of %s artists saved in %q (%s errors)",noftracks,nofalbums,nofartists,filename,noferrors)
- else
- flac.report("unable to save data in file %q",filename)
- end
-end
-
---
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-flac</entry>
- <entry name="detail">ConTeXt Flac Helpers</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="collect"><short>collect albums in xml file</short></flag>
- </subcategory>
- </category>
- </flags>
- <examples>
- <category>
- <title>Example</title>
- <subcategory>
- <example><command>mtxrun --script flac --collect somename.flac</command></example>
- <example><command>mtxrun --script flac --collect --pattern="m:/music/**")</command></example>
- </subcategory>
- </category>
- </examples>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-flac",
- banner = "ConTeXt Flac Helpers 0.10",
- helpinfo = helpinfo,
-}
-
-flac.report = application.report
-
--- script code
-
-scripts = scripts or { }
-scripts.flac = scripts.flac or { }
-
-function scripts.flac.collect()
- local files = environment.files
- local pattern = environment.arguments.pattern
- if #files > 0 then
- for i=1,#files do
- local filename = files[1]
- if file.suffix(filename) == "flac" then
- flac.savecollection(filename,file.replacesuffix(filename,"xml"))
- elseif lfs.isdir(filename) then
- local pattern = filename .. "/**.flac"
- flac.savecollection(pattern,file.addsuffix(file.basename(filename),"xml"))
- else
- flac.savecollection(file.replacesuffix(filename,"flac"),file.replacesuffix(filename,"xml"))
- end
- end
- elseif pattern then
- flac.savecollection(file.addsuffix(pattern,"flac"),"music-collection.xml")
- else
- flac.report("no file(s) or pattern given" )
- end
-end
-
-if environment.argument("collect") then
- scripts.flac.collect()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-flac'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local sub, match, byte, lower = string.sub, string.match, string.byte, string.lower
+local readstring, readnumber = io.readstring, io.readnumber
+local concat, sortedpairs = table.concat, table.sortedpairs
+local tonumber = tonumber
+local tobitstring = number.tobitstring
+local lpegmatch = lpeg.match
+local p_escaped = lpeg.patterns.xml.escaped
+
+-- rather silly: pack info in bits while a flac file is large anyway
+
+flac = flac or { }
+
+flac.report = string.format
+
+local splitter = lpeg.splitat("=")
+local readers = { }
+
+readers[0] = function(f,size,target) -- not yet ok .. todo: use bit32 lib
+ local info = { }
+ target.info = info
+ info.minimum_block_size = readnumber(f,-2)
+ info.maximum_block_size = readnumber(f,-2)
+ info.minimum_frame_size = readnumber(f,-3)
+ info.maximum_frame_size = readnumber(f,-3)
+ local buffer = { }
+ for i=1,8 do
+ buffer[i] = tobitstring(readnumber(f,1))
+ end
+ local bytes = concat(buffer)
+ info.sample_rate_in_hz = tonumber(sub(bytes, 1,20),2) -- 20
+ info.number_of_channels = tonumber(sub(bytes,21,23),2) -- 3
+ info.bits_per_sample = tonumber(sub(bytes,24,28),2) -- 5
+ info.samples_in_stream = tonumber(sub(bytes,29,64),2) -- 36
+ info.md5_signature = readstring(f,16) -- 128
+end
+
+readers[4] = function(f,size,target,banner)
+ local tags = { }
+ target.tags = tags
+ target.vendor = readstring(f,readnumber(f,-4))
+ for i=1,readnumber(f,-4) do
+ local key, value = lpeg.match(splitter,readstring(f,readnumber(f,-4)))
+ tags[lower(key)] = value
+ end
+end
+
+readers.default = function(f,size,target)
+ f:seek("cur",size)
+end
+
+function flac.getmetadata(filename)
+ local f = io.open(filename, "rb")
+ if f then
+ local banner = readstring(f,4)
+ if banner == "fLaC" then
+ local data = {
+ banner = banner,
+ filename = filename,
+ filesize = lfs.attributes(filename,"size"),
+ }
+ while true do
+ local flag = readnumber(f,1)
+ local size = readnumber(f,3)
+ local last = flag > 127
+ if last then
+ flag = flag - 128
+ end
+ local reader = readers[flag] or readers.default
+ reader(f,size,data,banner)
+ if last then
+ f:close()
+ return data
+ end
+ end
+ else
+ flac.report("no flac file: %s (%s)",filename,banner)
+ end
+ f:close()
+ else
+ flac.report("no file: %s",filename)
+ end
+end
+
+function flac.savecollection(pattern,filename)
+ pattern = (pattern ~= "" and pattern) or "**/*.flac"
+ filename = (filename ~= "" and filename) or "music-collection.xml"
+ flac.report("identifying files using pattern %q" ,pattern)
+ local files = dir.glob(pattern)
+ flac.report("%s files found, analyzing files",#files)
+ local music = { }
+ for i=1,#files do
+ local data = flac.getmetadata(files[i])
+ if data then
+ local tags = data.tags
+ local info = data.info
+ local artist = tags.artist
+ local album = tags.album
+ local albums = music[artist]
+ if not albums then
+ albums = { }
+ music[artist] = albums
+ end
+ local albumx = albums[album]
+ if not albumx then
+ albumx = {
+ year = tags.date,
+ tracks = { },
+ }
+ albums[album] = albumx
+ end
+ albumx.tracks[tonumber(tags.tracknumber) or 0] = {
+ title = tags.title,
+ length = math.round((info.samples_in_stream/info.sample_rate_in_hz)),
+ }
+ end
+ end
+ -- inspect(music)
+ local nofartists, nofalbums, noftracks, noferrors = 0, 0, 0, 0
+ local f = io.open(filename,"wb")
+ if f then
+ flac.report("saving data in file %q",filename)
+ f:write("<?xml version='1.0' standalone='yes'?>\n\n")
+ f:write("<collection>\n")
+ for artist, albums in sortedpairs(music) do
+ nofartists = nofartists + 1
+ f:write("\t<artist>\n")
+ f:write("\t\t<name>",lpegmatch(p_escaped,artist),"</name>\n")
+ f:write("\t\t<albums>\n")
+ for album, data in sortedpairs(albums) do
+ nofalbums = nofalbums + 1
+ f:write("\t\t\t<album year='",data.year or 0,"'>\n")
+ f:write("\t\t\t\t<name>",lpegmatch(p_escaped,album),"</name>\n")
+ f:write("\t\t\t\t<tracks>\n")
+ local tracks = data.tracks
+ for i=1,#tracks do
+ local track = tracks[i]
+ if track then
+ noftracks = noftracks + 1
+ f:write("\t\t\t\t\t<track length='",track.length,"'>",lpegmatch(p_escaped,track.title),"</track>\n")
+ else
+ noferrors = noferrors + 1
+ flac.report("error in album: %q of %q, no track %s",album,artist,i)
+ f:write("\t\t\t\t\t<error track='",i,"'/>\n")
+ end
+ end
+ f:write("\t\t\t\t</tracks>\n")
+ f:write("\t\t\t</album>\n")
+ end
+ f:write("\t\t</albums>\n")
+ f:write("\t</artist>\n")
+ end
+ f:write("</collection>\n")
+ f:close()
+ flac.report("%s tracks of %s albums of %s artists saved in %q (%s errors)",noftracks,nofalbums,nofartists,filename,noferrors)
+ else
+ flac.report("unable to save data in file %q",filename)
+ end
+end
+
+--
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-flac</entry>
+ <entry name="detail">ConTeXt Flac Helpers</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="collect"><short>collect albums in xml file</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Example</title>
+ <subcategory>
+ <example><command>mtxrun --script flac --collect somename.flac</command></example>
+ <example><command>mtxrun --script flac --collect --pattern="m:/music/**")</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-flac",
+ banner = "ConTeXt Flac Helpers 0.10",
+ helpinfo = helpinfo,
+}
+
+flac.report = application.report
+
+-- script code
+
+scripts = scripts or { }
+scripts.flac = scripts.flac or { }
+
+function scripts.flac.collect()
+ local files = environment.files
+ local pattern = environment.arguments.pattern
+ if #files > 0 then
+ for i=1,#files do
+ local filename = files[1]
+ if file.suffix(filename) == "flac" then
+ flac.savecollection(filename,file.replacesuffix(filename,"xml"))
+ elseif lfs.isdir(filename) then
+ local pattern = filename .. "/**.flac"
+ flac.savecollection(pattern,file.addsuffix(file.basename(filename),"xml"))
+ else
+ flac.savecollection(file.replacesuffix(filename,"flac"),file.replacesuffix(filename,"xml"))
+ end
+ end
+ elseif pattern then
+ flac.savecollection(file.addsuffix(pattern,"flac"),"music-collection.xml")
+ else
+ flac.report("no file(s) or pattern given" )
+ end
+end
+
+if environment.argument("collect") then
+ scripts.flac.collect()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 2c28f63d9..b171dd611 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -1,472 +1,472 @@
-if not modules then modules = { } end modules ['mtx-fonts'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local getargument = environment.getargument
-local setargument = environment.setargument
-local givenfiles = environment.files
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-fonts</entry>
- <entry name="detail">ConTeXt Font Database Management</entry>
- <entry name="version">0.21</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="save"><short>save open type font in raw table</short></flag>
- <flag name="unpack"><short>save a tma file in a more readable format</short></flag>
- </subcategory>
- <subcategory>
- <flag name="reload"><short>generate new font database (use <ref name="force"/> when in doubt)</short></flag>
- <flag name="reload"><short><ref name="simple"/>:generate luatex-fonts-names.lua (not for context!)</short></flag>
- </subcategory>
- <subcategory>
- <flag name="list"><short><ref name="name"/>: list installed fonts, filter by name [<ref name="pattern"/>]</short></flag>
- <flag name="list"><short><ref name="spec"/>: list installed fonts, filter by spec [<ref name="filter"/>]</short></flag>
- <flag name="list"><short><ref name="file"/>: list installed fonts, filter by file [<ref name="pattern"/>]</short></flag>
- </subcategory>
- <subcategory>
- <flag name="pattern" value="str"><short>filter files using pattern</short></flag>
- <flag name="filter" value="list"><short>key-value pairs</short></flag>
- <flag name="all"><short>show all found instances (combined with other flags)</short></flag>
- <flag name="info"><short>give more details</short></flag>
- <flag name="track" value="list"><short>enable trackers</short></flag>
- <flag name="statistics"><short>some info about the database</short></flag>
- </subcategory>
- </category>
- </flags>
- <examples>
- <category>
- <title>Examples</title>
- <subcategory>
- <example><command>mtxrun --script font --list somename (== --pattern=*somename*)</command></example>
- </subcategory>
- <subcategory>
- <example><command>mtxrun --script font --list --name somename</command></example>
- <example><command>mtxrun --script font --list --name --pattern=*somename*</command></example>
- </subcategory>
- <subcategory>
- <example><command>mtxrun --script font --list --spec somename</command></example>
- <example><command>mtxrun --script font --list --spec somename-bold-italic</command></example>
- <example><command>mtxrun --script font --list --spec --pattern=*somename*</command></example>
- <example><command>mtxrun --script font --list --spec --filter="fontname=somename"</command></example>
- <example><command>mtxrun --script font --list --spec --filter="familyname=somename,weight=bold,style=italic,width=condensed"</command></example>
- <example><command>mtxrun --script font --list --spec --filter="familyname=crap*,weight=bold,style=italic"</command></example>
- </subcategory>
- <subcategory>
- <example><command>mtxrun --script font --list --all</command></example>
- <example><command>mtxrun --script font --list --file somename</command></example>
- <example><command>mtxrun --script font --list --file --all somename</command></example>
- <example><command>mtxrun --script font --list --file --pattern=*somename*</command></example>
- </subcategory>
- </category>
- </examples>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-fonts",
- banner = "ConTeXt Font Database Management 0.21",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
--- todo: fc-cache -v en check dirs, or better is: fc-cat -v | grep Directory
-
-if not fontloader then fontloader = fontforge end
-
-dofile(resolvers.findfile("font-otp.lua","tex")) -- we need to unpack the font for analysis
-dofile(resolvers.findfile("font-trt.lua","tex"))
-dofile(resolvers.findfile("font-syn.lua","tex"))
-dofile(resolvers.findfile("font-mis.lua","tex"))
-
-scripts = scripts or { }
-scripts.fonts = scripts.fonts or { }
-
-function fonts.names.statistics()
- fonts.names.load()
-
- local data = fonts.names.data
- local statistics = data.statistics
-
- local function counted(t)
- local n = { }
- for k, v in next, t do
- n[k] = table.count(v)
- end
- return table.sequenced(n)
- end
-
- report("cache uuid : %s", data.cache_uuid)
- report("cache version : %s", data.cache_version)
- report("number of trees : %s", #data.datastate)
- report()
- report("number of fonts : %s", statistics.fonts or 0)
- report("used files : %s", statistics.readfiles or 0)
- report("skipped files : %s", statistics.skippedfiles or 0)
- report("duplicate files : %s", statistics.duplicatefiles or 0)
- report("specifications : %s", #data.specifications)
- report("families : %s", table.count(data.families))
- report()
- report("mappings : %s", counted(data.mappings))
- report("fallbacks : %s", counted(data.fallbacks))
- report()
- report("used styles : %s", table.sequenced(statistics.used_styles))
- report("used variants : %s", table.sequenced(statistics.used_variants))
- report("used weights : %s", table.sequenced(statistics.used_weights))
- report("used widths : %s", table.sequenced(statistics.used_widths))
- report()
- report("found styles : %s", table.sequenced(statistics.styles))
- report("found variants : %s", table.sequenced(statistics.variants))
- report("found weights : %s", table.sequenced(statistics.weights))
- report("found widths : %s", table.sequenced(statistics.widths))
-
-end
-
-function fonts.names.simple()
- local simpleversion = 1.001
- local simplelist = { "ttf", "otf", "ttc", "dfont" }
- local name = "luatex-fonts-names.lua"
- local path = file.collapsepath(caches.getwritablepath("..","..","generic","fonts","data"))
- fonts.names.filters.list = simplelist
- fonts.names.version = simpleversion -- this number is the same as in font-dum.lua
- report("generating font database for 'luatex-fonts' version %s",fonts.names.version)
- fonts.names.identify(true)
- local data = fonts.names.data
- if data then
- local simplemappings = { }
- local simplified = {
- mappings = simplemappings,
- version = simpleversion,
- cache_version = simpleversion,
- }
- local specifications = data.specifications
- for i=1,#simplelist do
- local format = simplelist[i]
- for tag, index in next, data.mappings[format] do
- local s = specifications[index]
- simplemappings[tag] = { s.rawname, s.filename, s.subfont }
- end
- end
- if environment.arguments.nocache then
- report("not using cache path %a",path)
- else
- dir.mkdirs(path)
- if lfs.isdir(path) then
- report("saving names on cache path %a",path)
- name = file.join(path,name)
- else
- report("invalid cache path %a",path)
- end
- end
- report("saving names in %a",name)
- io.savedata(name,table.serialize(simplified,true))
- local data = io.loaddata(resolvers.findfile("luatex-fonts-syn.lua","tex")) or ""
- local dummy = string.match(data,"fonts%.names%.version%s*=%s*([%d%.]+)")
- if tonumber(dummy) ~= simpleversion then
- report("warning: version number %s in 'font-dum' does not match database version number %s",dummy or "?",simpleversion)
- end
- elseif lfs.isfile(name) then
- os.remove(name)
- end
-end
-
-function scripts.fonts.reload()
- if getargument("simple") then
- fonts.names.simple()
- else
- fonts.names.load(true,getargument("force"))
- end
-end
-
-local function subfont(sf)
- if sf then
- return string.format("index: % 2s", sf)
- else
- return ""
- end
-end
-
-local function fontweight(fw)
- if fw then
- return string.format("conflict: %s", fw)
- else
- return ""
- end
-end
-
-local function showfeatures(tag,specification)
- report()
- report("mapping : %s",tag)
- report("fontname: %s",specification.fontname)
- report("fullname: %s",specification.fullname)
- report("filename: %s",specification.filename)
- report("family : %s",specification.familyname or "<nofamily>")
- report("weight : %s",specification.weight or "<noweight>")
- report("style : %s",specification.style or "<nostyle>")
- report("width : %s",specification.width or "<nowidth>")
- report("variant : %s",specification.variant or "<novariant>")
- report("subfont : %s",subfont(specification.subfont))
- report("fweight : %s",fontweight(specification.fontweight))
- -- maybe more
- local features = fonts.helpers.getfeatures(specification.filename,specification.format)
- if features then
- for what, v in table.sortedhash(features) do
- local data = features[what]
- if data and next(data) then
- report()
- report("%s features:",what)
- report()
- report("feature script languages")
- report()
- for f,ff in table.sortedhash(data) do
- local done = false
- for s, ss in table.sortedhash(ff) do
- if s == "*" then s = "all" end
- if ss ["*"] then ss["*"] = nil ss.all = true end
- if done then
- f = ""
- else
- done = true
- end
- report("% -8s % -8s % -8s",f,s,table.concat(table.sortedkeys(ss), " ")) -- todo: padd 4
- end
- end
- end
- end
- else
- report("no features")
- end
- report()
-end
-
-local function reloadbase(reload)
- if reload then
- report("fontnames, reloading font database")
- names.load(true,getargument("force"))
- report("fontnames, done\n\n")
- end
-end
-
-local function list_specifications(t,info)
- if t then
- local s = table.sortedkeys(t)
- if info then
- for k=1,#s do
- local v = s[k]
- showfeatures(v,t[v])
- end
- else
- for k=1,#s do
- local v = s[k]
- local entry = t[v]
- s[k] = {
- entry.familyname or "<nofamily>",
- entry.weight or "<noweight>",
- entry.style or "<nostyle>",
- entry.width or "<nowidth>",
- entry.variant or "<novariant>",
- entry.fontname,
- entry.filename,
- subfont(entry.subfont),
- fontweight(entry.fontweight),
- }
- end
- utilities.formatters.formatcolumns(s)
- for k=1,#s do
- texio.write_nl(s[k])
- end
- end
- end
-end
-
-local function list_matches(t,info)
- if t then
- local s, w = table.sortedkeys(t), { 0, 0, 0 }
- if info then
- for k=1,#s do
- local v = s[k]
- showfeatures(v,t[v])
- end
- else
- for k=1,#s do
- local v = s[k]
- local entry = t[v]
- s[k] = {
- v,
- entry.fontname,
- entry.filename,
- subfont(entry.subfont)
- }
- end
- utilities.formatters.formatcolumns(s)
- for k=1,#s do
- texio.write_nl(s[k])
- end
- end
- end
-end
-
-function scripts.fonts.list()
-
- local all = getargument("all")
- local info = getargument("info")
- local reload = getargument("reload")
- local pattern = getargument("pattern")
- local filter = getargument("filter")
- local given = givenfiles[1]
-
- reloadbase(reload)
-
- if getargument("name") then
- if pattern then
- --~ mtxrun --script font --list --name --pattern=*somename*
- list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info)
- elseif filter then
- report("not supported: --list --name --filter",name)
- elseif given then
- --~ mtxrun --script font --list --name somename
- list_matches(fonts.names.list(given,reload,all),info)
- else
- report("not supported: --list --name <no specification>",name)
- end
- elseif getargument("spec") then
- if pattern then
- --~ mtxrun --script font --list --spec --pattern=*somename*
- report("not supported: --list --spec --pattern",name)
- elseif filter then
- --~ mtxrun --script font --list --spec --filter="fontname=somename"
- list_specifications(fonts.names.getlookups(filter),info)
- elseif given then
- --~ mtxrun --script font --list --spec somename
- list_specifications(fonts.names.collectspec(given,reload,all),info)
- else
- report("not supported: --list --spec <no specification>",name)
- end
- elseif getargument("file") then
- if pattern then
- --~ mtxrun --script font --list --file --pattern=*somename*
- list_specifications(fonts.names.collectfiles(string.topattern(pattern,true),reload,all),info)
- elseif filter then
- report("not supported: --list --spec",name)
- elseif given then
- --~ mtxrun --script font --list --file somename
- list_specifications(fonts.names.collectfiles(given,reload,all),info)
- else
- report("not supported: --list --file <no specification>",name)
- end
- elseif pattern then
- --~ mtxrun --script font --list --pattern=*somename*
- list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info)
- elseif given then
- --~ mtxrun --script font --list somename
- list_matches(fonts.names.list(given,reload,all),info)
- elseif all then
- pattern = "*"
- list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info)
- else
- report("not supported: --list <no specification>",name)
- end
-
-end
-
-function scripts.fonts.justload()
- local fullname = environment.files[1]
- if fullname then
- local result = fontloader.open(fullname)
- if type(result) == "table" then
- report("loading %s: %s","succeeded",fullname)
- end
- end
- report("loading %s: %s","failed",fullname)
-end
-
-function scripts.fonts.unpack()
- local name = file.removesuffix(file.basename(givenfiles[1] or ""))
- if name and name ~= "" then
- local cache = containers.define("fonts", "otf", 2.742, true)
- local cleanname = containers.cleanname(name)
- local data = containers.read(cache,cleanname)
- if data then
- local savename = file.addsuffix(cleanname .. "-unpacked","tma")
- report("fontsave, saving data in %s",savename)
- fonts.handlers.otf.enhancers.unpack(data)
- io.savedata(savename,table.serialize(data,true))
- else
- report("unknown file %a",name)
- end
- end
-end
-
-function scripts.fonts.save()
- local name = givenfiles[1] or ""
- local sub = givenfiles[2] or ""
- local function save(savename,fontblob)
- if fontblob then
- savename = file.addsuffix(string.lower(savename),"lua")
- report("fontsave, saving data in %s",savename)
- table.tofile(savename,fontloader.to_table(fontblob),"return")
- fontloader.close(fontblob)
- end
- end
- if name and name ~= "" then
- local filename = resolvers.findfile(name) -- maybe also search for opentype
- if filename and filename ~= "" then
- local suffix = string.lower(file.suffix(filename))
- if suffix == 'ttf' or suffix == 'otf' or suffix == 'ttc' or suffix == "dfont" then
- local fontinfo = fontloader.info(filename)
- if fontinfo then
- report("font: %s located as %s",name,filename)
- if fontinfo[1] then
- for k=1,#fontinfo do
- local v = fontinfo[k]
- save(v.fontname,fontloader.open(filename,v.fullname))
- end
- else
- save(fontinfo.fullname,fontloader.open(filename))
- end
- else
- report("font: %s cannot be read",filename)
- end
- else
- report("font: %s not saved",filename)
- end
- else
- report("font: %s not found",name)
- end
- else
- report("font: no name given")
- end
-end
-
-if getargument("names") then
- setargument("reload",true)
- setargument("simple",true)
-end
-
-if getargument("list") then
- scripts.fonts.list()
-elseif getargument("reload") then
- scripts.fonts.reload()
-elseif getargument("save") then
- scripts.fonts.save()
-elseif getargument("justload") then
- scripts.fonts.justload()
-elseif getargument("unpack") then
- scripts.fonts.unpack()
-elseif getargument("statistics") then
- fonts.names.statistics()
-elseif getargument("exporthelp") then
- application.export(getargument("exporthelp"),givenfiles[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-fonts'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local getargument = environment.getargument
+local setargument = environment.setargument
+local givenfiles = environment.files
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-fonts</entry>
+ <entry name="detail">ConTeXt Font Database Management</entry>
+ <entry name="version">0.21</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="save"><short>save open type font in raw table</short></flag>
+ <flag name="unpack"><short>save a tma file in a more readable format</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="reload"><short>generate new font database (use <ref name="force"/> when in doubt)</short></flag>
+ <flag name="reload"><short><ref name="simple"/>:generate luatex-fonts-names.lua (not for context!)</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="list"><short><ref name="name"/>: list installed fonts, filter by name [<ref name="pattern"/>]</short></flag>
+ <flag name="list"><short><ref name="spec"/>: list installed fonts, filter by spec [<ref name="filter"/>]</short></flag>
+ <flag name="list"><short><ref name="file"/>: list installed fonts, filter by file [<ref name="pattern"/>]</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="pattern" value="str"><short>filter files using pattern</short></flag>
+ <flag name="filter" value="list"><short>key-value pairs</short></flag>
+ <flag name="all"><short>show all found instances (combined with other flags)</short></flag>
+ <flag name="info"><short>give more details</short></flag>
+ <flag name="track" value="list"><short>enable trackers</short></flag>
+ <flag name="statistics"><short>some info about the database</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Examples</title>
+ <subcategory>
+ <example><command>mtxrun --script font --list somename (== --pattern=*somename*)</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script font --list --name somename</command></example>
+ <example><command>mtxrun --script font --list --name --pattern=*somename*</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script font --list --spec somename</command></example>
+ <example><command>mtxrun --script font --list --spec somename-bold-italic</command></example>
+ <example><command>mtxrun --script font --list --spec --pattern=*somename*</command></example>
+ <example><command>mtxrun --script font --list --spec --filter="fontname=somename"</command></example>
+ <example><command>mtxrun --script font --list --spec --filter="familyname=somename,weight=bold,style=italic,width=condensed"</command></example>
+ <example><command>mtxrun --script font --list --spec --filter="familyname=crap*,weight=bold,style=italic"</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script font --list --all</command></example>
+ <example><command>mtxrun --script font --list --file somename</command></example>
+ <example><command>mtxrun --script font --list --file --all somename</command></example>
+ <example><command>mtxrun --script font --list --file --pattern=*somename*</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-fonts",
+ banner = "ConTeXt Font Database Management 0.21",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+-- todo: fc-cache -v en check dirs, or better is: fc-cat -v | grep Directory
+
+if not fontloader then fontloader = fontforge end
+
+dofile(resolvers.findfile("font-otp.lua","tex")) -- we need to unpack the font for analysis
+dofile(resolvers.findfile("font-trt.lua","tex"))
+dofile(resolvers.findfile("font-syn.lua","tex"))
+dofile(resolvers.findfile("font-mis.lua","tex"))
+
+scripts = scripts or { }
+scripts.fonts = scripts.fonts or { }
+
+function fonts.names.statistics()
+ fonts.names.load()
+
+ local data = fonts.names.data
+ local statistics = data.statistics
+
+ local function counted(t)
+ local n = { }
+ for k, v in next, t do
+ n[k] = table.count(v)
+ end
+ return table.sequenced(n)
+ end
+
+ report("cache uuid : %s", data.cache_uuid)
+ report("cache version : %s", data.cache_version)
+ report("number of trees : %s", #data.datastate)
+ report()
+ report("number of fonts : %s", statistics.fonts or 0)
+ report("used files : %s", statistics.readfiles or 0)
+ report("skipped files : %s", statistics.skippedfiles or 0)
+ report("duplicate files : %s", statistics.duplicatefiles or 0)
+ report("specifications : %s", #data.specifications)
+ report("families : %s", table.count(data.families))
+ report()
+ report("mappings : %s", counted(data.mappings))
+ report("fallbacks : %s", counted(data.fallbacks))
+ report()
+ report("used styles : %s", table.sequenced(statistics.used_styles))
+ report("used variants : %s", table.sequenced(statistics.used_variants))
+ report("used weights : %s", table.sequenced(statistics.used_weights))
+ report("used widths : %s", table.sequenced(statistics.used_widths))
+ report()
+ report("found styles : %s", table.sequenced(statistics.styles))
+ report("found variants : %s", table.sequenced(statistics.variants))
+ report("found weights : %s", table.sequenced(statistics.weights))
+ report("found widths : %s", table.sequenced(statistics.widths))
+
+end
+
+function fonts.names.simple()
+ local simpleversion = 1.001
+ local simplelist = { "ttf", "otf", "ttc", "dfont" }
+ local name = "luatex-fonts-names.lua"
+ local path = file.collapsepath(caches.getwritablepath("..","..","generic","fonts","data"))
+ fonts.names.filters.list = simplelist
+ fonts.names.version = simpleversion -- this number is the same as in font-dum.lua
+ report("generating font database for 'luatex-fonts' version %s",fonts.names.version)
+ fonts.names.identify(true)
+ local data = fonts.names.data
+ if data then
+ local simplemappings = { }
+ local simplified = {
+ mappings = simplemappings,
+ version = simpleversion,
+ cache_version = simpleversion,
+ }
+ local specifications = data.specifications
+ for i=1,#simplelist do
+ local format = simplelist[i]
+ for tag, index in next, data.mappings[format] do
+ local s = specifications[index]
+ simplemappings[tag] = { s.rawname, s.filename, s.subfont }
+ end
+ end
+ if environment.arguments.nocache then
+ report("not using cache path %a",path)
+ else
+ dir.mkdirs(path)
+ if lfs.isdir(path) then
+ report("saving names on cache path %a",path)
+ name = file.join(path,name)
+ else
+ report("invalid cache path %a",path)
+ end
+ end
+ report("saving names in %a",name)
+ io.savedata(name,table.serialize(simplified,true))
+ local data = io.loaddata(resolvers.findfile("luatex-fonts-syn.lua","tex")) or ""
+ local dummy = string.match(data,"fonts%.names%.version%s*=%s*([%d%.]+)")
+ if tonumber(dummy) ~= simpleversion then
+ report("warning: version number %s in 'font-dum' does not match database version number %s",dummy or "?",simpleversion)
+ end
+ elseif lfs.isfile(name) then
+ os.remove(name)
+ end
+end
+
+function scripts.fonts.reload()
+ if getargument("simple") then
+ fonts.names.simple()
+ else
+ fonts.names.load(true,getargument("force"))
+ end
+end
+
+local function subfont(sf)
+ if sf then
+ return string.format("index: % 2s", sf)
+ else
+ return ""
+ end
+end
+
+local function fontweight(fw)
+ if fw then
+ return string.format("conflict: %s", fw)
+ else
+ return ""
+ end
+end
+
+local function showfeatures(tag,specification)
+ report()
+ report("mapping : %s",tag)
+ report("fontname: %s",specification.fontname)
+ report("fullname: %s",specification.fullname)
+ report("filename: %s",specification.filename)
+ report("family : %s",specification.familyname or "<nofamily>")
+ report("weight : %s",specification.weight or "<noweight>")
+ report("style : %s",specification.style or "<nostyle>")
+ report("width : %s",specification.width or "<nowidth>")
+ report("variant : %s",specification.variant or "<novariant>")
+ report("subfont : %s",subfont(specification.subfont))
+ report("fweight : %s",fontweight(specification.fontweight))
+ -- maybe more
+ local features = fonts.helpers.getfeatures(specification.filename,specification.format)
+ if features then
+ for what, v in table.sortedhash(features) do
+ local data = features[what]
+ if data and next(data) then
+ report()
+ report("%s features:",what)
+ report()
+ report("feature script languages")
+ report()
+ for f,ff in table.sortedhash(data) do
+ local done = false
+ for s, ss in table.sortedhash(ff) do
+ if s == "*" then s = "all" end
+ if ss ["*"] then ss["*"] = nil ss.all = true end
+ if done then
+ f = ""
+ else
+ done = true
+ end
+ report("% -8s % -8s % -8s",f,s,table.concat(table.sortedkeys(ss), " ")) -- todo: padd 4
+ end
+ end
+ end
+ end
+ else
+ report("no features")
+ end
+ report()
+end
+
+local function reloadbase(reload)
+ if reload then
+ report("fontnames, reloading font database")
+ names.load(true,getargument("force"))
+ report("fontnames, done\n\n")
+ end
+end
+
+local function list_specifications(t,info)
+ if t then
+ local s = table.sortedkeys(t)
+ if info then
+ for k=1,#s do
+ local v = s[k]
+ showfeatures(v,t[v])
+ end
+ else
+ for k=1,#s do
+ local v = s[k]
+ local entry = t[v]
+ s[k] = {
+ entry.familyname or "<nofamily>",
+ entry.weight or "<noweight>",
+ entry.style or "<nostyle>",
+ entry.width or "<nowidth>",
+ entry.variant or "<novariant>",
+ entry.fontname,
+ entry.filename,
+ subfont(entry.subfont),
+ fontweight(entry.fontweight),
+ }
+ end
+ utilities.formatters.formatcolumns(s)
+ for k=1,#s do
+ texio.write_nl(s[k])
+ end
+ end
+ end
+end
+
+local function list_matches(t,info)
+ if t then
+ local s, w = table.sortedkeys(t), { 0, 0, 0 }
+ if info then
+ for k=1,#s do
+ local v = s[k]
+ showfeatures(v,t[v])
+ end
+ else
+ for k=1,#s do
+ local v = s[k]
+ local entry = t[v]
+ s[k] = {
+ v,
+ entry.fontname,
+ entry.filename,
+ subfont(entry.subfont)
+ }
+ end
+ utilities.formatters.formatcolumns(s)
+ for k=1,#s do
+ texio.write_nl(s[k])
+ end
+ end
+ end
+end
+
+function scripts.fonts.list()
+
+ local all = getargument("all")
+ local info = getargument("info")
+ local reload = getargument("reload")
+ local pattern = getargument("pattern")
+ local filter = getargument("filter")
+ local given = givenfiles[1]
+
+ reloadbase(reload)
+
+ if getargument("name") then
+ if pattern then
+ --~ mtxrun --script font --list --name --pattern=*somename*
+ list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info)
+ elseif filter then
+ report("not supported: --list --name --filter",name)
+ elseif given then
+ --~ mtxrun --script font --list --name somename
+ list_matches(fonts.names.list(given,reload,all),info)
+ else
+ report("not supported: --list --name <no specification>",name)
+ end
+ elseif getargument("spec") then
+ if pattern then
+ --~ mtxrun --script font --list --spec --pattern=*somename*
+ report("not supported: --list --spec --pattern",name)
+ elseif filter then
+ --~ mtxrun --script font --list --spec --filter="fontname=somename"
+ list_specifications(fonts.names.getlookups(filter),info)
+ elseif given then
+ --~ mtxrun --script font --list --spec somename
+ list_specifications(fonts.names.collectspec(given,reload,all),info)
+ else
+ report("not supported: --list --spec <no specification>",name)
+ end
+ elseif getargument("file") then
+ if pattern then
+ --~ mtxrun --script font --list --file --pattern=*somename*
+ list_specifications(fonts.names.collectfiles(string.topattern(pattern,true),reload,all),info)
+ elseif filter then
+ report("not supported: --list --spec",name)
+ elseif given then
+ --~ mtxrun --script font --list --file somename
+ list_specifications(fonts.names.collectfiles(given,reload,all),info)
+ else
+ report("not supported: --list --file <no specification>",name)
+ end
+ elseif pattern then
+ --~ mtxrun --script font --list --pattern=*somename*
+ list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info)
+ elseif given then
+ --~ mtxrun --script font --list somename
+ list_matches(fonts.names.list(given,reload,all),info)
+ elseif all then
+ pattern = "*"
+ list_matches(fonts.names.list(string.topattern(pattern,true),reload,all),info)
+ else
+ report("not supported: --list <no specification>",name)
+ end
+
+end
+
+function scripts.fonts.justload()
+ local fullname = environment.files[1]
+ if fullname then
+ local result = fontloader.open(fullname)
+ if type(result) == "table" then
+ report("loading %s: %s","succeeded",fullname)
+ end
+ end
+ report("loading %s: %s","failed",fullname)
+end
+
+function scripts.fonts.unpack()
+ local name = file.removesuffix(file.basename(givenfiles[1] or ""))
+ if name and name ~= "" then
+ local cache = containers.define("fonts", "otf", 2.742, true)
+ local cleanname = containers.cleanname(name)
+ local data = containers.read(cache,cleanname)
+ if data then
+ local savename = file.addsuffix(cleanname .. "-unpacked","tma")
+ report("fontsave, saving data in %s",savename)
+ fonts.handlers.otf.enhancers.unpack(data)
+ io.savedata(savename,table.serialize(data,true))
+ else
+ report("unknown file %a",name)
+ end
+ end
+end
+
+function scripts.fonts.save()
+ local name = givenfiles[1] or ""
+ local sub = givenfiles[2] or ""
+ local function save(savename,fontblob)
+ if fontblob then
+ savename = file.addsuffix(string.lower(savename),"lua")
+ report("fontsave, saving data in %s",savename)
+ table.tofile(savename,fontloader.to_table(fontblob),"return")
+ fontloader.close(fontblob)
+ end
+ end
+ if name and name ~= "" then
+ local filename = resolvers.findfile(name) -- maybe also search for opentype
+ if filename and filename ~= "" then
+ local suffix = string.lower(file.suffix(filename))
+ if suffix == 'ttf' or suffix == 'otf' or suffix == 'ttc' or suffix == "dfont" then
+ local fontinfo = fontloader.info(filename)
+ if fontinfo then
+ report("font: %s located as %s",name,filename)
+ if fontinfo[1] then
+ for k=1,#fontinfo do
+ local v = fontinfo[k]
+ save(v.fontname,fontloader.open(filename,v.fullname))
+ end
+ else
+ save(fontinfo.fullname,fontloader.open(filename))
+ end
+ else
+ report("font: %s cannot be read",filename)
+ end
+ else
+ report("font: %s not saved",filename)
+ end
+ else
+ report("font: %s not found",name)
+ end
+ else
+ report("font: no name given")
+ end
+end
+
+if getargument("names") then
+ setargument("reload",true)
+ setargument("simple",true)
+end
+
+if getargument("list") then
+ scripts.fonts.list()
+elseif getargument("reload") then
+ scripts.fonts.reload()
+elseif getargument("save") then
+ scripts.fonts.save()
+elseif getargument("justload") then
+ scripts.fonts.justload()
+elseif getargument("unpack") then
+ scripts.fonts.unpack()
+elseif getargument("statistics") then
+ fonts.names.statistics()
+elseif getargument("exporthelp") then
+ application.export(getargument("exporthelp"),givenfiles[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-grep.lua b/scripts/context/lua/mtx-grep.lua
index cd4856040..dbcce67f6 100644
--- a/scripts/context/lua/mtx-grep.lua
+++ b/scripts/context/lua/mtx-grep.lua
@@ -1,170 +1,170 @@
-if not modules then modules = { } end modules ['mtx-babel'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-grep</entry>
- <entry name="detail">Simple Grepper</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="pattern"><short>search for pattern (optional)</short></flag>
- <flag name="count"><short>count matches only</short></flag>
- <flag name="nocomment"><short>skip lines that start with %% or #</short></flag>
- <flag name="xml"><short>pattern is lpath expression</short></flag>
- </subcategory>
- </category>
- </flags>
- <comments>
- <comment>patterns are lua patterns and need to be escaped accordingly</comment>
- </comments>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-grep",
- banner = "Simple Grepper 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.grep = scripts.grep or { }
-
-local find, format = string.find, string.format
-
-local cr = lpeg.P("\r")
-local lf = lpeg.P("\n")
-local crlf = cr * lf
-local newline = crlf + cr + lf
-local content = lpeg.C((1-newline)^0) * newline + lpeg.C(lpeg.P(1)^1)
-
-local write_nl = texio.write_nl
-
- -- local pattern = "LIJST[@TYPE='BULLET']/LIJSTITEM[contains(text(),'Kern')]"
-
-function scripts.grep.find(pattern, files, offset)
- if pattern and pattern ~= "" then
- statistics.starttiming(scripts.grep)
- local nofmatches, noffiles, nofmatchedfiles = 0, 0, 0
- local n, m, name, check = 0, 0, "", nil
- local count, nocomment = environment.argument("count"), environment.argument("nocomment")
- if environment.argument("xml") then
- for i=offset or 1, #files do
- local globbed = dir.glob(files[i])
- for i=1,#globbed do
- local nam = globbed[i]
- name = nam
- local data = xml.load(name)
- if data and not data.error then
- n, m, noffiles = 0, 0, noffiles + 1
- if count then
- for c in xml.collected(data,pattern) do
- m = m + 1
- end
- if m > 0 then
- nofmatches = nofmatches + m
- nofmatchedfiles = nofmatchedfiles + 1
- write_nl(format("%5i %s",m,name))
- io.flush()
- end
- else
- for c in xml.collected(data,pattern) do
- m = m + 1
- write_nl(format("%s: %s",name,xml.tostring(c)))
- end
- end
- end
- end
- end
- else
- if nocomment then
- if count then
- check = function(line)
- n = n + 1
- if find(line,"^[%%#]") then
- -- skip
- elseif find(line,pattern) then
- m = m + 1
- end
- end
- else
- check = function(line)
- n = n + 1
- if find(line,"^[%%#]") then
- -- skip
- elseif find(line,pattern) then
- m = m + 1
- write_nl(format("%s %6i: %s",name,n,line))
- io.flush()
- end
- end
- end
- else
- if count then
- check = function(line)
- n = n + 1
- if find(line,pattern) then
- m = m + 1
- end
- end
- else
- check = function(line)
- n = n + 1
- if find(line,pattern) then
- m = m + 1
- write_nl(format("%s %6i: %s",name,n,line))
- io.flush()
- end
- end
- end
- end
- local capture = (content/check)^0
- for i=offset or 1, #files do
- local globbed = dir.glob(files[i])
- for i=1,#globbed do
- local nam = globbed[i]
- name = nam
- local data = io.loaddata(name)
- if data then
- n, m, noffiles = 0, 0, noffiles + 1
- capture:match(data)
- if count and m > 0 then
- nofmatches = nofmatches + m
- nofmatchedfiles = nofmatchedfiles + 1
- write_nl(format("%5i %s",m,name))
- io.flush()
- end
- end
- end
- end
- end
- statistics.stoptiming(scripts.grep)
- if count and nofmatches > 0 then
- write_nl(format("\nfiles: %s, matches: %s, matched files: %s, runtime: %0.3f seconds",noffiles,nofmatches,nofmatchedfiles,statistics.elapsedtime(scripts.grep)))
- end
- end
-end
-
-local pattern = environment.argument("pattern")
-local files = environment.files and #environment.files > 0 and environment.files
-
-if environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),files[1])
-elseif pattern and files then
- scripts.grep.find(pattern, files)
-elseif files then
- scripts.grep.find(files[1], files, 2)
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-babel'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-grep</entry>
+ <entry name="detail">Simple Grepper</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="pattern"><short>search for pattern (optional)</short></flag>
+ <flag name="count"><short>count matches only</short></flag>
+ <flag name="nocomment"><short>skip lines that start with %% or #</short></flag>
+ <flag name="xml"><short>pattern is lpath expression</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <comments>
+ <comment>patterns are lua patterns and need to be escaped accordingly</comment>
+ </comments>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-grep",
+ banner = "Simple Grepper 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.grep = scripts.grep or { }
+
+local find, format = string.find, string.format
+
+local cr = lpeg.P("\r")
+local lf = lpeg.P("\n")
+local crlf = cr * lf
+local newline = crlf + cr + lf
+local content = lpeg.C((1-newline)^0) * newline + lpeg.C(lpeg.P(1)^1)
+
+local write_nl = texio.write_nl
+
+ -- local pattern = "LIJST[@TYPE='BULLET']/LIJSTITEM[contains(text(),'Kern')]"
+
+function scripts.grep.find(pattern, files, offset)
+ if pattern and pattern ~= "" then
+ statistics.starttiming(scripts.grep)
+ local nofmatches, noffiles, nofmatchedfiles = 0, 0, 0
+ local n, m, name, check = 0, 0, "", nil
+ local count, nocomment = environment.argument("count"), environment.argument("nocomment")
+ if environment.argument("xml") then
+ for i=offset or 1, #files do
+ local globbed = dir.glob(files[i])
+ for i=1,#globbed do
+ local nam = globbed[i]
+ name = nam
+ local data = xml.load(name)
+ if data and not data.error then
+ n, m, noffiles = 0, 0, noffiles + 1
+ if count then
+ for c in xml.collected(data,pattern) do
+ m = m + 1
+ end
+ if m > 0 then
+ nofmatches = nofmatches + m
+ nofmatchedfiles = nofmatchedfiles + 1
+ write_nl(format("%5i %s",m,name))
+ io.flush()
+ end
+ else
+ for c in xml.collected(data,pattern) do
+ m = m + 1
+ write_nl(format("%s: %s",name,xml.tostring(c)))
+ end
+ end
+ end
+ end
+ end
+ else
+ if nocomment then
+ if count then
+ check = function(line)
+ n = n + 1
+ if find(line,"^[%%#]") then
+ -- skip
+ elseif find(line,pattern) then
+ m = m + 1
+ end
+ end
+ else
+ check = function(line)
+ n = n + 1
+ if find(line,"^[%%#]") then
+ -- skip
+ elseif find(line,pattern) then
+ m = m + 1
+ write_nl(format("%s %6i: %s",name,n,line))
+ io.flush()
+ end
+ end
+ end
+ else
+ if count then
+ check = function(line)
+ n = n + 1
+ if find(line,pattern) then
+ m = m + 1
+ end
+ end
+ else
+ check = function(line)
+ n = n + 1
+ if find(line,pattern) then
+ m = m + 1
+ write_nl(format("%s %6i: %s",name,n,line))
+ io.flush()
+ end
+ end
+ end
+ end
+ local capture = (content/check)^0
+ for i=offset or 1, #files do
+ local globbed = dir.glob(files[i])
+ for i=1,#globbed do
+ local nam = globbed[i]
+ name = nam
+ local data = io.loaddata(name)
+ if data then
+ n, m, noffiles = 0, 0, noffiles + 1
+ capture:match(data)
+ if count and m > 0 then
+ nofmatches = nofmatches + m
+ nofmatchedfiles = nofmatchedfiles + 1
+ write_nl(format("%5i %s",m,name))
+ io.flush()
+ end
+ end
+ end
+ end
+ end
+ statistics.stoptiming(scripts.grep)
+ if count and nofmatches > 0 then
+ write_nl(format("\nfiles: %s, matches: %s, matched files: %s, runtime: %0.3f seconds",noffiles,nofmatches,nofmatchedfiles,statistics.elapsedtime(scripts.grep)))
+ end
+ end
+end
+
+local pattern = environment.argument("pattern")
+local files = environment.files and #environment.files > 0 and environment.files
+
+if environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),files[1])
+elseif pattern and files then
+ scripts.grep.find(pattern, files)
+elseif files then
+ scripts.grep.find(files[1], files, 2)
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-metatex.lua b/scripts/context/lua/mtx-metatex.lua
index ff13d00e3..455ecbd52 100644
--- a/scripts/context/lua/mtx-metatex.lua
+++ b/scripts/context/lua/mtx-metatex.lua
@@ -1,80 +1,80 @@
-if not modules then modules = { } end modules ['mtx-metatex'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- future versions will deal with specific variants of metatex
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-metatex</entry>
- <entry name="detail">MetaTeX Process Management</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="run"><short>process (one or more) files (default action)</short></flag>
- <flag name="make"><short>create metatex format(s)</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-metatex",
- banner = "MetaTeX Process Management 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.metatex = scripts.metatex or { }
-
--- metatex
-
-function scripts.metatex.make()
- environment.make_format("metatex")
-end
-
-function scripts.metatex.run(ctxdata,filename)
- local filename = environment.files[1] or ""
- if filename ~= "" then
- local formatfile, scriptfile = resolvers.locateformat("metatex")
- if formatfile and scriptfile then
- local command = string.format("luatex --fmt=%s --lua=%s %s",
- string.quote(formatfile), string.quote(scriptfile), string.quote(filename))
- report("running command: %s",command)
- os.spawn(command)
- elseif formatname then
- report("error, no format found with name: %s",formatname)
- else
- report("error, no format found (provide formatname or interface)")
- end
- end
-end
-
-function scripts.metatex.timed(action)
- statistics.timed(action)
-end
-
-if environment.argument("run") then
- scripts.metatex.timed(scripts.metatex.run)
-elseif environment.argument("make") then
- scripts.metatex.timed(scripts.metatex.make)
-elseif environment.argument("help") then
- logs.help(messages.help,false)
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-elseif environment.files[1] then
- scripts.metatex.timed(scripts.metatex.run)
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-metatex'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- future versions will deal with specific variants of metatex
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-metatex</entry>
+ <entry name="detail">MetaTeX Process Management</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="run"><short>process (one or more) files (default action)</short></flag>
+ <flag name="make"><short>create metatex format(s)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-metatex",
+ banner = "MetaTeX Process Management 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.metatex = scripts.metatex or { }
+
+-- metatex
+
+function scripts.metatex.make()
+ environment.make_format("metatex")
+end
+
+function scripts.metatex.run(ctxdata,filename)
+ local filename = environment.files[1] or ""
+ if filename ~= "" then
+ local formatfile, scriptfile = resolvers.locateformat("metatex")
+ if formatfile and scriptfile then
+ local command = string.format("luatex --fmt=%s --lua=%s %s",
+ string.quote(formatfile), string.quote(scriptfile), string.quote(filename))
+ report("running command: %s",command)
+ os.spawn(command)
+ elseif formatname then
+ report("error, no format found with name: %s",formatname)
+ else
+ report("error, no format found (provide formatname or interface)")
+ end
+ end
+end
+
+function scripts.metatex.timed(action)
+ statistics.timed(action)
+end
+
+if environment.argument("run") then
+ scripts.metatex.timed(scripts.metatex.run)
+elseif environment.argument("make") then
+ scripts.metatex.timed(scripts.metatex.make)
+elseif environment.argument("help") then
+ logs.help(messages.help,false)
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+elseif environment.files[1] then
+ scripts.metatex.timed(scripts.metatex.run)
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-mk-help.lua b/scripts/context/lua/mtx-mk-help.lua
index 68ad16f93..794bbca37 100644
--- a/scripts/context/lua/mtx-mk-help.lua
+++ b/scripts/context/lua/mtx-mk-help.lua
@@ -1,473 +1,473 @@
-if not modules then modules = { } end modules ['mtx-mk-help'] = {
- version = 1.001,
- comment = "a script for making help files",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[
-
-mtxrun --exporthelp=all %targetpath%\mkiv\mtxrun.tmp
-context --exporthelp=all %targetpath%\mkiv\context.tmp
-mtxrun --script context --exporthelp=all %targetpath%\mkiv\mtx-context.tmp
-
-mtxrun --script babel --exporthelp=all %targetpath%\mkiv\mtx-babel.tmp
-mtxrun --script base --exporthelp=all %targetpath%\mkiv\mtx-base.tmp
-mtxrun --script cache --exporthelp=all %targetpath%\mkiv\mtx-cache.tmp
-mtxrun --script chars --exporthelp=all %targetpath%\mkiv\mtx-chars.tmp
-mtxrun --script check --exporthelp=all %targetpath%\mkiv\mtx-check.tmp
-mtxrun --script colors --exporthelp=all %targetpath%\mkiv\mtx-colors.tmp
-mtxrun --script convert --exporthelp=all %targetpath%\mkiv\mtx-convert.tmp
-mtxrun --script epub --exporthelp=all %targetpath%\mkiv\mtx-epub.tmp
-mtxrun --script fcd --exporthelp=all %targetpath%\mkiv\mtx-fcd.tmp
-mtxrun --script flac --exporthelp=all %targetpath%\mkiv\mtx-flac.tmp
-mtxrun --script fonts --exporthelp=all %targetpath%\mkiv\mtx-fonts.tmp
-mtxrun --script grep --exporthelp=all %targetpath%\mkiv\mtx-grep.tmp
-mtxrun --script interface --exporthelp=all %targetpath%\mkiv\mtx-interface.tmp
-mtxrun --script metapost --exporthelp=all %targetpath%\mkiv\mtx-metapost.tmp
-mtxrun --script metatex --exporthelp=all %targetpath%\mkiv\mtx-metatex.tmp
-mtxrun --script modules --exporthelp=all %targetpath%\mkiv\mtx-modules.tmp
-mtxrun --script mtxworks --exporthelp=all %targetpath%\mkiv\mtx-mtxworks.tmp
-mtxrun --script package --exporthelp=all %targetpath%\mkiv\mtx-package.tmp
-mtxrun --script patterns --exporthelp=all %targetpath%\mkiv\mtx-patterns.tmp
-mtxrun --script pdf --exporthelp=all %targetpath%\mkiv\mtx-pdf.tmp
-mtxrun --script profile --exporthelp=all %targetpath%\mkiv\mtx-profile.tmp
-mtxrun --script rsync --exporthelp=all %targetpath%\mkiv\mtx-rsync.tmp
-mtxrun --script scite --exporthelp=all %targetpath%\mkiv\mtx-scite.tmp
-mtxrun --script server --exporthelp=all %targetpath%\mkiv\mtx-server.tmp
-mtxrun --script texworks --exporthelp=all %targetpath%\mkiv\mtx-texworks.tmp
-mtxrun --script timing --exporthelp=all %targetpath%\mkiv\mtx-timing.tmp
-mtxrun --script tools --exporthelp=all %targetpath%\mkiv\mtx-tools.tmp
-mtxrun --script unzip --exporthelp=all %targetpath%\mkiv\mtx-unzip.tmp
-mtxrun --script update --exporthelp=all %targetpath%\mkiv\mtx-update.tmp
-mtxrun --script watch --exporthelp=all %targetpath%\mkiv\mtx-watch.tmp
-
-mtxrun --script mk-help luatools --exporthelp=all %targetpath%\mkiv\luatools.tmp
-
-mtxrun --script mk-help texmfstart --exporthelp=all %targetpath%\mkii\texmfstart.tmp
-mtxrun --script mk-help texexec --exporthelp=all %targetpath%\mkii\texexec.tmp
-mtxrun --script mk-help texutil --exporthelp=all %targetpath%\mkii\texutil.tmp
-mtxrun --script mk-help ctxtools --exporthelp=all %targetpath%\mkii\ctxtools.tmp
-mtxrun --script mk-help textools --exporthelp=all %targetpath%\mkii\textools.tmp
-mtxrun --script mk-help pdftools --exporthelp=all %targetpath%\mkii\pdftools.tmp
-mtxrun --script mk-help tmftools --exporthelp=all %targetpath%\mkii\tmftools.tmp
-mtxrun --script mk-help xmltools --exporthelp=all %targetpath%\mkii\xmltools.tmp
-mtxrun --script mk-help pstopdf --exporthelp=all %targetpath%\mkii\pstopdf.tmp
-mtxrun --script mk-help rlxtools --exporthelp=all %targetpath%\mkii\rlxtools.tmp
-mtxrun --script mk-help imgtopdf --exporthelp=all %targetpath%\mkii\imgtopdf.tmp
-
-]]--
-
-local helpinfo = os.resultof("mtxrun --exporthelp") or ""
-local helpinfo = string.match(helpinfo,[[^.-(<application>.-</application>)]]) or [[<application></application>]]
-
-local texmfstart = logs.application {
- name = "texmfstart",
- banner = "texmfstart 7.0.0",
- helpinfo = [[<?xml version="1.0"?>]] .. helpinfo,
-}
-
--- let's also put luatools here:
-
-local helpinfo = os.resultof("luatools --exporthelp") or ""
-local helpinfo = string.match(helpinfo,[[^.-(<application>.-</application>)]]) or [[<application></application>]]
-local helpinfo = string.gsub(helpinfo,"mtx%-base","luatools")
-
-local luatools = logs.application {
- name = "luatools",
- banner = "luatools 1.35",
- helpinfo = [[<?xml version="1.0"?>]] .. helpinfo,
-}
-
---
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">texexec</entry>
- <entry name="detail">TeXExec</entry>
- <entry name="version">6.2.1</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="make"><short>make formats</short></flag>
- <flag name="check"><short>check versions</short></flag>
- <flag name="process"><short>process file</short></flag>
- <flag name="mptex"><short>process mp file</short></flag>
- <flag name="mpxtex"><short>process mpx file</short></flag>
- <flag name="mpgraphic"><short>process mp file to stand-alone graphics</short></flag>
- <flag name="mpstatic"><short>process mp/ctx file to stand-alone graphics</short></flag>
- <flag name="listing"><short>list of file content</short></flag>
- <flag name="figures"><short>generate overview of figures</short></flag>
- <flag name="modules"><short>generate module documentation</short></flag>
- <flag name="pdfarrange"><short>impose pages (booklets)</short></flag>
- <flag name="pdfselect"><short>select pages from file(s)</short></flag>
- <flag name="pdfcopy"><short>copy pages from file(s)</short></flag>
- <flag name="pdftrim"><short>trim pages from file(s)</short></flag>
- <flag name="pdfcombine"><short>combine multiple pages</short></flag>
- <flag name="pdfsplit"><short>split file in pages</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local texexec = logs.application {
- name = "texexec",
- banner = "TeXExec 6.2.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">texutil</entry>
- <entry name="detail">TeXUtil</entry>
- <entry name="version">9.1.0</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="references"><short>convert tui file into tuo file</short></flag>
- <flag name="figures"><short>generate figure dimensions file</short></flag>
- <flag name="logfile"><short>filter essential log messages</short></flag>
- <flag name="purgefiles"><short>remove most temporary files</short></flag>
- <flag name="purgeallfiles"><short>remove all temporary files</short></flag>
- <flag name="documentation"><short>generate documentation file from source</short></flag>
- <flag name="analyzefile"><short>analyze pdf file</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>]]
-
-local texutil = logs.application {
- name = "texutil",
- banner = "TeXUtil 9.1.0",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">ctxtools</entry>
- <entry name="detail">CtxTools</entry>
- <entry name="version">1.3.5</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="touchcontextfile"><short>update context version</short></flag>
- <flag name="contextversion"><short>report context version</short></flag>
- <flag name="jeditinterface"><short>generate jedit syntax files [<ref name="pipe]"/></short></flag>
- <flag name="bbeditinterface"><short>generate bbedit syntax files [<ref name="pipe]"/></short></flag>
- <flag name="sciteinterface"><short>generate scite syntax files [<ref name="pipe]"/></short></flag>
- <flag name="rawinterface"><short>generate raw syntax files [<ref name="pipe]"/></short></flag>
- <flag name="translateinterface"><short>generate interface files (xml) [nl de ..]</short></flag>
- <flag name="purgefiles"><short>remove temporary files [<ref name="all"/> <ref name="recurse]"/> [basename]</short></flag>
- <flag name="documentation generate documentation [--type" value="]"><short>[filename]</short></flag>
- <flag name="filterpages'"><short>) # no help, hidden temporary feature</short></flag>
- <flag name="dpxmapfiles"><short>convert pdftex mapfiles to dvipdfmx [<ref name="force]"/> [texmfroot]</short></flag>
- <flag name="listentities"><short>create doctype entity definition from enco-uc.tex</short></flag>
- <flag name="brandfiles"><short>add context copyright notice [<ref name="force]"/></short></flag>
- <flag name="platformize"><short>replace line-endings [<ref name="recurse"/> <ref name="force]"/> [pattern]</short></flag>
- <flag name="dependencies analyze depedencies within context [--save --compact --filter" value="[macros|filenames] ]"><short>[filename]</short></flag>
- <flag name="updatecontext"><short>download latest version and remake formats [<ref name="proxy]"/></short></flag>
- <flag name="disarmutfbom"><short>remove utf bom [<ref name="force]"/></short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local ctxtools = logs.application {
- name = "ctxtools",
- banner = "CtxTools 1.3.5",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">textools</entry>
- <entry name="detail">TeXTools</entry>
- <entry name="version">1.3.1</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="removemapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="restoremapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="hidemapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="videmapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="findfile"><short>filename [<ref name="recurse]"/></short></flag>
- <flag name="unzipfiles"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="fixafmfiles"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="mactodos"><short>[pattern] [<ref name="recurse]"/></short></flag>
- <flag name="fixtexmftrees"><short>[texmfroot] [<ref name="force]"/></short></flag>
- <flag name="replacefile"><short>filename [<ref name="force]"/></short></flag>
- <flag name="updatetree"><short>fromroot toroot [<ref name="force"/> <ref name="nocheck"/> <ref name="merge"/> <ref name="delete]"/></short></flag>
- <flag name="downcasefilenames"><short>[<ref name="recurse]"/> [<ref name="force]"/></short></flag>
- <flag name="stripformfeeds"><short>[<ref name="recurse]"/> [<ref name="force]"/></short></flag>
- <flag name="showfont"><short>filename</short></flag>
- <flag name="encmake"><short>afmfile encodingname</short></flag>
- <flag name="tpmmake"><short>tpm file (run in texmf root)</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local textools = logs.application {
- name = "textools",
- banner = "TeXTools 1.3.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">pdftools</entry>
- <entry name="detail">PDFTools</entry>
- <entry name="version">1.2.1</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="spotimage filename --colorspec" value=""><short><ref name="colorname="/> [<ref name="retain"/> <ref name="invert"/> <ref name="subpath=]"/></short></flag>
- <flag name="colorimage filename --colorspec" value=""><short>[<ref name="retain"/> <ref name="invert"/> <ref name="colorname="/> ]</short></flag>
- <flag name="convertimage"><short>filename [<ref name="retain"/> <ref name="subpath]"/></short></flag>
- <flag name="downsampleimage"><short>filename [<ref name="retain"/> <ref name="subpath"/> <ref name="lowres"/> <ref name="normal]"/></short></flag>
- <flag name="info"><short>filename</short></flag>
- <flag name="countpages"><short>[<ref name="pattern"/> <ref name="threshold]"/></short></flag>
- <flag name="checkembedded"><short>[<ref name="pattern]"/></short></flag>
- <flag name="analyzefile"><short>filename</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local pdftools = logs.application {
- name = "pdftools",
- banner = "PDFTools 1.2.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">tmftools</entry>
- <entry name="detail">TMFTools</entry>
- <entry name="version">1.1.0</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="analyze"><short>[<ref name="strict"/> <ref name="sort"/> <ref name="rootpath"/> <ref name="treepath"/> <ref name="delete"/> <ref name="force"/>] [pattern]</short></flag>
- </subcategory>
- <subcategory>
- <flag name="serve"><short>act as kpse server</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local tmftools = logs.application {
- name = "tmftools",
- banner = "TMFTools 1.2.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">xmltools</entry>
- <entry name="detail">XMLTools</entry>
- <entry name="version">1.2.2</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="dir"><short>generate directory listing</short></flag>
- <flag name="mmlpages"><short>generate graphic from mathml</short></flag>
- <flag name="analyze"><short>report entities and elements [<ref name="utf"/> <ref name="process"/>]</short></flag>
- <flag name="cleanup"><short>cleanup xml file [<ref name="force"/>]</short></flag>
- <flag name="enhance"><short>enhance xml file (partial)</short></flag>
- <flag name="filter"><short>filter elements from xml file [<ref name="element"/>]</short></flag>
- <flag name="dir"><short>generate ddirectory listing</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local xmltools = logs.application {
- name = "xmltools",
- banner = "XMLTools 1.2.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">pstopdf</entry>
- <entry name="detail">PStoPDF</entry>
- <entry name="version">2.0.1</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="request"><short>handles exa request file</short></flag>
- <flag name="watch"><short>watch folders for conversions (untested)</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local pstopdf = logs.application {
- name = "pstopdf",
- banner = "PStoPDF 2.0.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">rlxtools</entry>
- <entry name="detail">RlxTools</entry>
- <entry name="version">1.0.1</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="manipulate"><short>[<ref name="test]"/> manipulatorfile resourselog</short></flag>
- <flag name="identify"><short>[<ref name="collect]"/> filename</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local rlxtools = logs.application {
- name = "rlxtools",
- banner = "RlxTools 1.0.1",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">imgtopdf</entry>
- <entry name="detail">ImgToPdf</entry>
- <entry name="version">1.1.2</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="convert"><short>convert image into pdf</short></flag>
- <flag name="compression"><short>level of compression in percent</short></flag>
- <flag name="depth"><short>image depth in bits</short></flag>
- <flag name="colorspace"><short> colorspace (rgb,cmyk,gray)</short></flag>
- <flag name="quality"><short>quality in percent</short></flag>
- <flag name="inputpath"><short>path where files are looked for</short></flag>
- <flag name="outputpath"><short>path where files end up</short></flag>
- <flag name="auto"><short>determine settings automatically</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local imgtopdf = logs.application {
- name = "imgtopdf",
- banner = "ImgToPdf 1.1.2",
- helpinfo = helpinfo,
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mptopdf</entry>
- <entry name="detail">convert MetaPost to PDF</entry>
- <entry name="version">1.4.1</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="metafun"><short>use the metafun format to process the file (default is mpost)</short></flag>
- <flag name="texexec"><short>use texexec (context) to process text snippets</short></flag>
- <flag name="latex"><short>use latex to process text snippets</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local mptopdf = logs.application {
- name = "mptopdf",
- banner = "MPtoPDF 1.4.1",
- helpinfo = helpinfo,
-}
-
--- texmfstart.rb is normally replaced by mtxrun
--- runtools.rb is run from within context
--- concheck.rb is run from within editors
--- texsync.rb is no longer in the zip
--- mpstools.rb is no longer in the zip
--- rscortool.rb is only run indirectly
--- rsfiltool.rb is only run indirectly
--- rslibtool.rb is only run indirectly
-
-local application = logs.application {
- name = "mk-help",
- banner = "Mk Help generator 1.00",
-}
-
-local filename = environment.files[1]
-
-if not filename then
- application.report("no mk script given")
- return
-end
-
-local mkapplication
-
-if filename == "texmfstart" then mkapplication = texmfstart
-elseif filename == "luatools" then mkapplication = luatools
-elseif filename == "texexec" then mkapplication = texexec
-elseif filename == "texutil" then mkapplication = texutil
-elseif filename == "ctxtools" then mkapplication = ctxtools
-elseif filename == "textools" then mkapplication = textools
-elseif filename == "pdftools" then mkapplication = pdftools
-elseif filename == "tmftools" then mkapplication = tmftools
-elseif filename == "xmltools" then mkapplication = xmltools
-elseif filename == "pstopdf" then mkapplication = pstopdf
-elseif filename == "rlxtools" then mkapplication = rlxtools
-elseif filename == "imgtopdf" then mkapplication = imgtopdf
-elseif filename == "mptopdf" then mkapplication = mptopdf end
-
-if not mkapplication then
- application.report("no valid mk script given")
- return
-end
-
-if environment.argument("exporthelp") then
- mkapplication.export(environment.argument("exporthelp"),environment.files[2])
-else
- mkapplication.help()
-end
+if not modules then modules = { } end modules ['mtx-mk-help'] = {
+ version = 1.001,
+ comment = "a script for making help files",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[
+
+mtxrun --exporthelp=all %targetpath%\mkiv\mtxrun.tmp
+context --exporthelp=all %targetpath%\mkiv\context.tmp
+mtxrun --script context --exporthelp=all %targetpath%\mkiv\mtx-context.tmp
+
+mtxrun --script babel --exporthelp=all %targetpath%\mkiv\mtx-babel.tmp
+mtxrun --script base --exporthelp=all %targetpath%\mkiv\mtx-base.tmp
+mtxrun --script cache --exporthelp=all %targetpath%\mkiv\mtx-cache.tmp
+mtxrun --script chars --exporthelp=all %targetpath%\mkiv\mtx-chars.tmp
+mtxrun --script check --exporthelp=all %targetpath%\mkiv\mtx-check.tmp
+mtxrun --script colors --exporthelp=all %targetpath%\mkiv\mtx-colors.tmp
+mtxrun --script convert --exporthelp=all %targetpath%\mkiv\mtx-convert.tmp
+mtxrun --script epub --exporthelp=all %targetpath%\mkiv\mtx-epub.tmp
+mtxrun --script fcd --exporthelp=all %targetpath%\mkiv\mtx-fcd.tmp
+mtxrun --script flac --exporthelp=all %targetpath%\mkiv\mtx-flac.tmp
+mtxrun --script fonts --exporthelp=all %targetpath%\mkiv\mtx-fonts.tmp
+mtxrun --script grep --exporthelp=all %targetpath%\mkiv\mtx-grep.tmp
+mtxrun --script interface --exporthelp=all %targetpath%\mkiv\mtx-interface.tmp
+mtxrun --script metapost --exporthelp=all %targetpath%\mkiv\mtx-metapost.tmp
+mtxrun --script metatex --exporthelp=all %targetpath%\mkiv\mtx-metatex.tmp
+mtxrun --script modules --exporthelp=all %targetpath%\mkiv\mtx-modules.tmp
+mtxrun --script mtxworks --exporthelp=all %targetpath%\mkiv\mtx-mtxworks.tmp
+mtxrun --script package --exporthelp=all %targetpath%\mkiv\mtx-package.tmp
+mtxrun --script patterns --exporthelp=all %targetpath%\mkiv\mtx-patterns.tmp
+mtxrun --script pdf --exporthelp=all %targetpath%\mkiv\mtx-pdf.tmp
+mtxrun --script profile --exporthelp=all %targetpath%\mkiv\mtx-profile.tmp
+mtxrun --script rsync --exporthelp=all %targetpath%\mkiv\mtx-rsync.tmp
+mtxrun --script scite --exporthelp=all %targetpath%\mkiv\mtx-scite.tmp
+mtxrun --script server --exporthelp=all %targetpath%\mkiv\mtx-server.tmp
+mtxrun --script texworks --exporthelp=all %targetpath%\mkiv\mtx-texworks.tmp
+mtxrun --script timing --exporthelp=all %targetpath%\mkiv\mtx-timing.tmp
+mtxrun --script tools --exporthelp=all %targetpath%\mkiv\mtx-tools.tmp
+mtxrun --script unzip --exporthelp=all %targetpath%\mkiv\mtx-unzip.tmp
+mtxrun --script update --exporthelp=all %targetpath%\mkiv\mtx-update.tmp
+mtxrun --script watch --exporthelp=all %targetpath%\mkiv\mtx-watch.tmp
+
+mtxrun --script mk-help luatools --exporthelp=all %targetpath%\mkiv\luatools.tmp
+
+mtxrun --script mk-help texmfstart --exporthelp=all %targetpath%\mkii\texmfstart.tmp
+mtxrun --script mk-help texexec --exporthelp=all %targetpath%\mkii\texexec.tmp
+mtxrun --script mk-help texutil --exporthelp=all %targetpath%\mkii\texutil.tmp
+mtxrun --script mk-help ctxtools --exporthelp=all %targetpath%\mkii\ctxtools.tmp
+mtxrun --script mk-help textools --exporthelp=all %targetpath%\mkii\textools.tmp
+mtxrun --script mk-help pdftools --exporthelp=all %targetpath%\mkii\pdftools.tmp
+mtxrun --script mk-help tmftools --exporthelp=all %targetpath%\mkii\tmftools.tmp
+mtxrun --script mk-help xmltools --exporthelp=all %targetpath%\mkii\xmltools.tmp
+mtxrun --script mk-help pstopdf --exporthelp=all %targetpath%\mkii\pstopdf.tmp
+mtxrun --script mk-help rlxtools --exporthelp=all %targetpath%\mkii\rlxtools.tmp
+mtxrun --script mk-help imgtopdf --exporthelp=all %targetpath%\mkii\imgtopdf.tmp
+
+]]--
+
+local helpinfo = os.resultof("mtxrun --exporthelp") or ""
+local helpinfo = string.match(helpinfo,[[^.-(<application>.-</application>)]]) or [[<application></application>]]
+
+local texmfstart = logs.application {
+ name = "texmfstart",
+ banner = "texmfstart 7.0.0",
+ helpinfo = [[<?xml version="1.0"?>]] .. helpinfo,
+}
+
+-- let's also put luatools here:
+
+local helpinfo = os.resultof("luatools --exporthelp") or ""
+local helpinfo = string.match(helpinfo,[[^.-(<application>.-</application>)]]) or [[<application></application>]]
+local helpinfo = string.gsub(helpinfo,"mtx%-base","luatools")
+
+local luatools = logs.application {
+ name = "luatools",
+ banner = "luatools 1.35",
+ helpinfo = [[<?xml version="1.0"?>]] .. helpinfo,
+}
+
+--
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">texexec</entry>
+ <entry name="detail">TeXExec</entry>
+ <entry name="version">6.2.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="make"><short>make formats</short></flag>
+ <flag name="check"><short>check versions</short></flag>
+ <flag name="process"><short>process file</short></flag>
+ <flag name="mptex"><short>process mp file</short></flag>
+ <flag name="mpxtex"><short>process mpx file</short></flag>
+ <flag name="mpgraphic"><short>process mp file to stand-alone graphics</short></flag>
+ <flag name="mpstatic"><short>process mp/ctx file to stand-alone graphics</short></flag>
+ <flag name="listing"><short>list of file content</short></flag>
+ <flag name="figures"><short>generate overview of figures</short></flag>
+ <flag name="modules"><short>generate module documentation</short></flag>
+ <flag name="pdfarrange"><short>impose pages (booklets)</short></flag>
+ <flag name="pdfselect"><short>select pages from file(s)</short></flag>
+ <flag name="pdfcopy"><short>copy pages from file(s)</short></flag>
+ <flag name="pdftrim"><short>trim pages from file(s)</short></flag>
+ <flag name="pdfcombine"><short>combine multiple pages</short></flag>
+ <flag name="pdfsplit"><short>split file in pages</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local texexec = logs.application {
+ name = "texexec",
+ banner = "TeXExec 6.2.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">texutil</entry>
+ <entry name="detail">TeXUtil</entry>
+ <entry name="version">9.1.0</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="references"><short>convert tui file into tuo file</short></flag>
+ <flag name="figures"><short>generate figure dimensions file</short></flag>
+ <flag name="logfile"><short>filter essential log messages</short></flag>
+ <flag name="purgefiles"><short>remove most temporary files</short></flag>
+ <flag name="purgeallfiles"><short>remove all temporary files</short></flag>
+ <flag name="documentation"><short>generate documentation file from source</short></flag>
+ <flag name="analyzefile"><short>analyze pdf file</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>]]
+
+local texutil = logs.application {
+ name = "texutil",
+ banner = "TeXUtil 9.1.0",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">ctxtools</entry>
+ <entry name="detail">CtxTools</entry>
+ <entry name="version">1.3.5</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="touchcontextfile"><short>update context version</short></flag>
+ <flag name="contextversion"><short>report context version</short></flag>
+ <flag name="jeditinterface"><short>generate jedit syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="bbeditinterface"><short>generate bbedit syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="sciteinterface"><short>generate scite syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="rawinterface"><short>generate raw syntax files [<ref name="pipe]"/></short></flag>
+ <flag name="translateinterface"><short>generate interface files (xml) [nl de ..]</short></flag>
+ <flag name="purgefiles"><short>remove temporary files [<ref name="all"/> <ref name="recurse]"/> [basename]</short></flag>
+ <flag name="documentation generate documentation [--type" value="]"><short>[filename]</short></flag>
+ <flag name="filterpages'"><short>) # no help, hidden temporary feature</short></flag>
+ <flag name="dpxmapfiles"><short>convert pdftex mapfiles to dvipdfmx [<ref name="force]"/> [texmfroot]</short></flag>
+ <flag name="listentities"><short>create doctype entity definition from enco-uc.tex</short></flag>
+ <flag name="brandfiles"><short>add context copyright notice [<ref name="force]"/></short></flag>
+ <flag name="platformize"><short>replace line-endings [<ref name="recurse"/> <ref name="force]"/> [pattern]</short></flag>
+ <flag name="dependencies analyze depedencies within context [--save --compact --filter" value="[macros|filenames] ]"><short>[filename]</short></flag>
+ <flag name="updatecontext"><short>download latest version and remake formats [<ref name="proxy]"/></short></flag>
+ <flag name="disarmutfbom"><short>remove utf bom [<ref name="force]"/></short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local ctxtools = logs.application {
+ name = "ctxtools",
+ banner = "CtxTools 1.3.5",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">textools</entry>
+ <entry name="detail">TeXTools</entry>
+ <entry name="version">1.3.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="removemapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="restoremapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="hidemapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="videmapnames"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="findfile"><short>filename [<ref name="recurse]"/></short></flag>
+ <flag name="unzipfiles"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="fixafmfiles"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="mactodos"><short>[pattern] [<ref name="recurse]"/></short></flag>
+ <flag name="fixtexmftrees"><short>[texmfroot] [<ref name="force]"/></short></flag>
+ <flag name="replacefile"><short>filename [<ref name="force]"/></short></flag>
+ <flag name="updatetree"><short>fromroot toroot [<ref name="force"/> <ref name="nocheck"/> <ref name="merge"/> <ref name="delete]"/></short></flag>
+ <flag name="downcasefilenames"><short>[<ref name="recurse]"/> [<ref name="force]"/></short></flag>
+ <flag name="stripformfeeds"><short>[<ref name="recurse]"/> [<ref name="force]"/></short></flag>
+ <flag name="showfont"><short>filename</short></flag>
+ <flag name="encmake"><short>afmfile encodingname</short></flag>
+ <flag name="tpmmake"><short>tpm file (run in texmf root)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local textools = logs.application {
+ name = "textools",
+ banner = "TeXTools 1.3.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">pdftools</entry>
+ <entry name="detail">PDFTools</entry>
+ <entry name="version">1.2.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="spotimage filename --colorspec" value=""><short><ref name="colorname="/> [<ref name="retain"/> <ref name="invert"/> <ref name="subpath=]"/></short></flag>
+ <flag name="colorimage filename --colorspec" value=""><short>[<ref name="retain"/> <ref name="invert"/> <ref name="colorname="/> ]</short></flag>
+ <flag name="convertimage"><short>filename [<ref name="retain"/> <ref name="subpath]"/></short></flag>
+ <flag name="downsampleimage"><short>filename [<ref name="retain"/> <ref name="subpath"/> <ref name="lowres"/> <ref name="normal]"/></short></flag>
+ <flag name="info"><short>filename</short></flag>
+ <flag name="countpages"><short>[<ref name="pattern"/> <ref name="threshold]"/></short></flag>
+ <flag name="checkembedded"><short>[<ref name="pattern]"/></short></flag>
+ <flag name="analyzefile"><short>filename</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local pdftools = logs.application {
+ name = "pdftools",
+ banner = "PDFTools 1.2.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">tmftools</entry>
+ <entry name="detail">TMFTools</entry>
+ <entry name="version">1.1.0</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="analyze"><short>[<ref name="strict"/> <ref name="sort"/> <ref name="rootpath"/> <ref name="treepath"/> <ref name="delete"/> <ref name="force"/>] [pattern]</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="serve"><short>act as kpse server</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local tmftools = logs.application {
+ name = "tmftools",
+ banner = "TMFTools 1.2.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">xmltools</entry>
+ <entry name="detail">XMLTools</entry>
+ <entry name="version">1.2.2</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="dir"><short>generate directory listing</short></flag>
+ <flag name="mmlpages"><short>generate graphic from mathml</short></flag>
+ <flag name="analyze"><short>report entities and elements [<ref name="utf"/> <ref name="process"/>]</short></flag>
+ <flag name="cleanup"><short>cleanup xml file [<ref name="force"/>]</short></flag>
+ <flag name="enhance"><short>enhance xml file (partial)</short></flag>
+ <flag name="filter"><short>filter elements from xml file [<ref name="element"/>]</short></flag>
+ <flag name="dir"><short>generate ddirectory listing</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local xmltools = logs.application {
+ name = "xmltools",
+ banner = "XMLTools 1.2.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">pstopdf</entry>
+ <entry name="detail">PStoPDF</entry>
+ <entry name="version">2.0.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="request"><short>handles exa request file</short></flag>
+ <flag name="watch"><short>watch folders for conversions (untested)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local pstopdf = logs.application {
+ name = "pstopdf",
+ banner = "PStoPDF 2.0.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">rlxtools</entry>
+ <entry name="detail">RlxTools</entry>
+ <entry name="version">1.0.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="manipulate"><short>[<ref name="test]"/> manipulatorfile resourselog</short></flag>
+ <flag name="identify"><short>[<ref name="collect]"/> filename</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local rlxtools = logs.application {
+ name = "rlxtools",
+ banner = "RlxTools 1.0.1",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">imgtopdf</entry>
+ <entry name="detail">ImgToPdf</entry>
+ <entry name="version">1.1.2</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="convert"><short>convert image into pdf</short></flag>
+ <flag name="compression"><short>level of compression in percent</short></flag>
+ <flag name="depth"><short>image depth in bits</short></flag>
+ <flag name="colorspace"><short> colorspace (rgb,cmyk,gray)</short></flag>
+ <flag name="quality"><short>quality in percent</short></flag>
+ <flag name="inputpath"><short>path where files are looked for</short></flag>
+ <flag name="outputpath"><short>path where files end up</short></flag>
+ <flag name="auto"><short>determine settings automatically</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local imgtopdf = logs.application {
+ name = "imgtopdf",
+ banner = "ImgToPdf 1.1.2",
+ helpinfo = helpinfo,
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mptopdf</entry>
+ <entry name="detail">convert MetaPost to PDF</entry>
+ <entry name="version">1.4.1</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="metafun"><short>use the metafun format to process the file (default is mpost)</short></flag>
+ <flag name="texexec"><short>use texexec (context) to process text snippets</short></flag>
+ <flag name="latex"><short>use latex to process text snippets</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local mptopdf = logs.application {
+ name = "mptopdf",
+ banner = "MPtoPDF 1.4.1",
+ helpinfo = helpinfo,
+}
+
+-- texmfstart.rb is normally replaced by mtxrun
+-- runtools.rb is run from within context
+-- concheck.rb is run from within editors
+-- texsync.rb is no longer in the zip
+-- mpstools.rb is no longer in the zip
+-- rscortool.rb is only run indirectly
+-- rsfiltool.rb is only run indirectly
+-- rslibtool.rb is only run indirectly
+
+local application = logs.application {
+ name = "mk-help",
+ banner = "Mk Help generator 1.00",
+}
+
+local filename = environment.files[1]
+
+if not filename then
+ application.report("no mk script given")
+ return
+end
+
+local mkapplication
+
+if filename == "texmfstart" then mkapplication = texmfstart
+elseif filename == "luatools" then mkapplication = luatools
+elseif filename == "texexec" then mkapplication = texexec
+elseif filename == "texutil" then mkapplication = texutil
+elseif filename == "ctxtools" then mkapplication = ctxtools
+elseif filename == "textools" then mkapplication = textools
+elseif filename == "pdftools" then mkapplication = pdftools
+elseif filename == "tmftools" then mkapplication = tmftools
+elseif filename == "xmltools" then mkapplication = xmltools
+elseif filename == "pstopdf" then mkapplication = pstopdf
+elseif filename == "rlxtools" then mkapplication = rlxtools
+elseif filename == "imgtopdf" then mkapplication = imgtopdf
+elseif filename == "mptopdf" then mkapplication = mptopdf end
+
+if not mkapplication then
+ application.report("no valid mk script given")
+ return
+end
+
+if environment.argument("exporthelp") then
+ mkapplication.export(environment.argument("exporthelp"),environment.files[2])
+else
+ mkapplication.help()
+end
diff --git a/scripts/context/lua/mtx-modules.lua b/scripts/context/lua/mtx-modules.lua
index 766be6b49..f4003c1db 100644
--- a/scripts/context/lua/mtx-modules.lua
+++ b/scripts/context/lua/mtx-modules.lua
@@ -1,202 +1,202 @@
-if not modules then modules = { } end modules ['mtx-modules'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-scripts = scripts or { }
-scripts.modules = scripts.modules or { }
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-modules</entry>
- <entry name="detail">ConTeXt Module Documentation Generators</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="convert"><short>convert source files (tex, mkii, mkiv, mp) to 'ted' files</short></flag>
- <flag name="process"><short>process source files (tex, mkii, mkiv, mp) to 'pdf' files</short></flag>
- <flag name="prep"><short>use original name with suffix 'prep' appended</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-modules",
- banner = "ConTeXt Module Documentation Generators 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
--- Documentation can be woven into a source file. This script can generates
--- a file with the documentation and source fragments properly tagged. The
--- documentation is included as comment:
---
--- %D ...... some kind of documentation
--- %M ...... macros needed for documenation
--- %S B begin skipping
--- %S E end skipping
---
--- The generated file is structured as:
---
--- \starttypen
--- \startmodule[type=suffix]
--- \startdocumentation
--- \stopdocumentation
--- \startdefinition
--- \stopdefinition
--- \stopmodule
--- \stoptypen
---
--- Macro definitions specific to the documentation are not surrounded by
--- start-stop commands. The suffix specificaction can be overruled at runtime,
--- but defaults to the file extension. This specification can be used for language
--- depended verbatim typesetting.
---
--- In the mkiv variant we filter the \module settings so that we don't have
--- to mess with global document settings.
-
-local find, format, sub, is_empty, strip, gsub = string.find, string.format, string.sub, string.is_empty, string.strip, string.gsub
-
-local function source_to_ted(inpname,outname,filetype)
- local data = io.loaddata(inpname)
- if not data or data == "" then
- report("invalid module name '%s'",inpname)
- return
- end
- report("converting '%s' to '%s'",inpname,outname)
- local skiplevel, indocument, indefinition = 0, false, false
- local started = false
- local settings = format("type=%s",filetype or file.suffix(inpname))
- local preamble, n = lpeg.match(lpeg.Cs((1-lpeg.patterns.newline^2)^1) * lpeg.Cp(),data)
- if preamble then
- preamble = string.match(preamble,"\\module.-%[(.-)%]")
- if preamble then
- preamble = gsub(preamble,"%%D *","")
- preamble = gsub(preamble,"%%(.-)[\n\r]","")
- preamble = gsub(preamble,"[\n\r]","")
- preamble = strip(preamble)
- settings = format("%s,%s",settings,preamble)
- data = string.sub(data,n,#data)
- end
- end
- local lines = string.splitlines(data)
- local result = { }
- result[#result+1] = format("\\startmoduledocumentation[%s]",settings)
- for i=1,#lines do
- local line = lines[i]
- if find(line,"^%%D ") or find(line,"^%%D$") then
- if skiplevel == 0 then
- local someline = #line < 3 and "" or sub(line,4,#line)
- if indocument then
- result[#result+1] = someline
- else
- if indefinition then
- result[#result+1] = "\\stopdefinition"
- indefinition = false
- end
- if not indocument then
- result[#result+1] = "\\startdocumentation"
- end
- result[#result+1] = someline
- indocument = true
- end
- end
- elseif find(line,"^%%M ") or find(line,"^%%M$") then
- if skiplevel == 0 then
- local someline = (#line < 3 and "") or sub(line,4,#line)
- result[#result+1] = someline
- end
- elseif find(line,"^%%S B") then
- skiplevel = skiplevel + 1
- elseif find(line,"^%%S E") then
- skiplevel = skiplevel - 1
- elseif find(line,"^%%") then
- -- nothing
- elseif skiplevel == 0 then
- inlocaldocument = indocument
- inlocaldocument = false
- local someline = line
- if indocument then
- result[#result+1] = "\\stopdocumentation"
- indocument = false
- end
- if indefinition then
- if is_empty(someline) then
- result[#result+1] = "\\stopdefinition"
- indefinition = false
- else
- result[#result+1] = someline
- end
- elseif not is_empty(someline) then
- result[#result+1] = "\n"
- result[#result+1] = "\\startdefinition"
- indefinition = true
- if inlocaldocument then
- -- nothing
- else
- result[#result+1] = someline
- end
- end
- end
- end
- if indocument then
- result[#result+1] = "\\stopdocumentation"
- end
- if indefinition then
- result[#result+1] = "\\stopdefinition"
- end
- result[#result+1] = "\\stopmoduledocumentation"
- io.savedata(outname,table.concat(result,"\n"))
- return true
-end
-
-local suffixes = table.tohash { 'tex','mkii','mkiv', 'mkvi', 'mp' }
-
-function scripts.modules.process(runtex)
- local processed = { }
- local prep = environment.argument("prep")
- local files = environment.files
- for i=1,#files do
- local shortname = files[i]
- local suffix = file.suffix(shortname)
- if suffixes[suffix] then
- local longname
- if prep then
- longname = shortname .. ".prep"
- else
- longname = file.removesuffix(shortname) .. "-" .. suffix .. ".ted"
- end
- local done = source_to_ted(shortname,longname)
- if done and runtex then
- os.execute(format("mtxrun --script context --usemodule=mod-01 --purge %s",longname))
- processed[#processed+1] = longname
- end
- end
- end
- for i=1,#processed do
- local name = processed[i]
- report("modules","processed: %s",name)
- end
-end
-
--- context --ctx=m-modules.ctx xxx.mkiv
-
-if environment.argument("process") then
- scripts.modules.process(true)
-elseif environment.argument("convert") then
- scripts.modules.process(false)
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-modules'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+scripts = scripts or { }
+scripts.modules = scripts.modules or { }
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-modules</entry>
+ <entry name="detail">ConTeXt Module Documentation Generators</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="convert"><short>convert source files (tex, mkii, mkiv, mp) to 'ted' files</short></flag>
+ <flag name="process"><short>process source files (tex, mkii, mkiv, mp) to 'pdf' files</short></flag>
+ <flag name="prep"><short>use original name with suffix 'prep' appended</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-modules",
+ banner = "ConTeXt Module Documentation Generators 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+-- Documentation can be woven into a source file. This script can generates
+-- a file with the documentation and source fragments properly tagged. The
+-- documentation is included as comment:
+--
+-- %D ...... some kind of documentation
+-- %M ...... macros needed for documenation
+-- %S B begin skipping
+-- %S E end skipping
+--
+-- The generated file is structured as:
+--
+-- \starttypen
+-- \startmodule[type=suffix]
+-- \startdocumentation
+-- \stopdocumentation
+-- \startdefinition
+-- \stopdefinition
+-- \stopmodule
+-- \stoptypen
+--
+-- Macro definitions specific to the documentation are not surrounded by
+-- start-stop commands. The suffix specificaction can be overruled at runtime,
+-- but defaults to the file extension. This specification can be used for language
+-- depended verbatim typesetting.
+--
+-- In the mkiv variant we filter the \module settings so that we don't have
+-- to mess with global document settings.
+
+local find, format, sub, is_empty, strip, gsub = string.find, string.format, string.sub, string.is_empty, string.strip, string.gsub
+
+local function source_to_ted(inpname,outname,filetype)
+ local data = io.loaddata(inpname)
+ if not data or data == "" then
+ report("invalid module name '%s'",inpname)
+ return
+ end
+ report("converting '%s' to '%s'",inpname,outname)
+ local skiplevel, indocument, indefinition = 0, false, false
+ local started = false
+ local settings = format("type=%s",filetype or file.suffix(inpname))
+ local preamble, n = lpeg.match(lpeg.Cs((1-lpeg.patterns.newline^2)^1) * lpeg.Cp(),data)
+ if preamble then
+ preamble = string.match(preamble,"\\module.-%[(.-)%]")
+ if preamble then
+ preamble = gsub(preamble,"%%D *","")
+ preamble = gsub(preamble,"%%(.-)[\n\r]","")
+ preamble = gsub(preamble,"[\n\r]","")
+ preamble = strip(preamble)
+ settings = format("%s,%s",settings,preamble)
+ data = string.sub(data,n,#data)
+ end
+ end
+ local lines = string.splitlines(data)
+ local result = { }
+ result[#result+1] = format("\\startmoduledocumentation[%s]",settings)
+ for i=1,#lines do
+ local line = lines[i]
+ if find(line,"^%%D ") or find(line,"^%%D$") then
+ if skiplevel == 0 then
+ local someline = #line < 3 and "" or sub(line,4,#line)
+ if indocument then
+ result[#result+1] = someline
+ else
+ if indefinition then
+ result[#result+1] = "\\stopdefinition"
+ indefinition = false
+ end
+ if not indocument then
+ result[#result+1] = "\\startdocumentation"
+ end
+ result[#result+1] = someline
+ indocument = true
+ end
+ end
+ elseif find(line,"^%%M ") or find(line,"^%%M$") then
+ if skiplevel == 0 then
+ local someline = (#line < 3 and "") or sub(line,4,#line)
+ result[#result+1] = someline
+ end
+ elseif find(line,"^%%S B") then
+ skiplevel = skiplevel + 1
+ elseif find(line,"^%%S E") then
+ skiplevel = skiplevel - 1
+ elseif find(line,"^%%") then
+ -- nothing
+ elseif skiplevel == 0 then
+ inlocaldocument = indocument
+ inlocaldocument = false
+ local someline = line
+ if indocument then
+ result[#result+1] = "\\stopdocumentation"
+ indocument = false
+ end
+ if indefinition then
+ if is_empty(someline) then
+ result[#result+1] = "\\stopdefinition"
+ indefinition = false
+ else
+ result[#result+1] = someline
+ end
+ elseif not is_empty(someline) then
+ result[#result+1] = "\n"
+ result[#result+1] = "\\startdefinition"
+ indefinition = true
+ if inlocaldocument then
+ -- nothing
+ else
+ result[#result+1] = someline
+ end
+ end
+ end
+ end
+ if indocument then
+ result[#result+1] = "\\stopdocumentation"
+ end
+ if indefinition then
+ result[#result+1] = "\\stopdefinition"
+ end
+ result[#result+1] = "\\stopmoduledocumentation"
+ io.savedata(outname,table.concat(result,"\n"))
+ return true
+end
+
+local suffixes = table.tohash { 'tex','mkii','mkiv', 'mkvi', 'mp' }
+
+function scripts.modules.process(runtex)
+ local processed = { }
+ local prep = environment.argument("prep")
+ local files = environment.files
+ for i=1,#files do
+ local shortname = files[i]
+ local suffix = file.suffix(shortname)
+ if suffixes[suffix] then
+ local longname
+ if prep then
+ longname = shortname .. ".prep"
+ else
+ longname = file.removesuffix(shortname) .. "-" .. suffix .. ".ted"
+ end
+ local done = source_to_ted(shortname,longname)
+ if done and runtex then
+ os.execute(format("mtxrun --script context --usemodule=mod-01 --purge %s",longname))
+ processed[#processed+1] = longname
+ end
+ end
+ end
+ for i=1,#processed do
+ local name = processed[i]
+ report("modules","processed: %s",name)
+ end
+end
+
+-- context --ctx=m-modules.ctx xxx.mkiv
+
+if environment.argument("process") then
+ scripts.modules.process(true)
+elseif environment.argument("convert") then
+ scripts.modules.process(false)
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-mtxworks.lua b/scripts/context/lua/mtx-mtxworks.lua
index e6517dd95..1239ae4c5 100644
--- a/scripts/context/lua/mtx-mtxworks.lua
+++ b/scripts/context/lua/mtx-mtxworks.lua
@@ -1,14 +1,14 @@
-if not modules then modules = { } end modules ['mtx-mtxworks'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- this is a shortcut to "mtxrun --script texworks --start"
-
-environment.setargument("start",true)
-
-require "mtx-texworks"
-
+if not modules then modules = { } end modules ['mtx-mtxworks'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this is a shortcut to "mtxrun --script texworks --start"
+
+environment.setargument("start",true)
+
+require "mtx-texworks"
+
diff --git a/scripts/context/lua/mtx-package.lua b/scripts/context/lua/mtx-package.lua
index a5792ec4f..8c9e6b9fc 100644
--- a/scripts/context/lua/mtx-package.lua
+++ b/scripts/context/lua/mtx-package.lua
@@ -1,84 +1,84 @@
-if not modules then modules = { } end modules ['mtx-package'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local format, gsub, gmatch = string.format, string.gsub, string.gmatch
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-package</entry>
- <entry name="detail">Distribution Related Goodies</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="merge"><short>merge 'loadmodule' into merge file</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-package",
- banner = "Distribution Related Goodies 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-messages = messages or { }
-scripts.package = scripts.package or { }
-
-function scripts.package.merge_luatex_files(name)
- local oldname = resolvers.findfile(name) or ""
- oldname = file.replacesuffix(oldname,"lua")
- if oldname == "" then
- report("missing %q",name)
- else
- local newname = file.removesuffix(oldname) .. "-merged.lua"
- local data = io.loaddata(oldname) or ""
- if data == "" then
- report("missing %q",newname)
- else
- report("loading %q",oldname)
- local collected = { }
- collected[#collected+1] = format("-- merged file : %s\n",newname)
- collected[#collected+1] = format("-- parent file : %s\n",oldname)
- collected[#collected+1] = format("-- merge date : %s\n",os.date())
- -- loadmodule can have extra arguments
- for lib in gmatch(data,"loadmodule *%([\'\"](.-)[\'\"]") do
- if file.basename(lib) ~= file.basename(newname) then
- local fullname = resolvers.findfile(lib) or ""
- if fullname == "" then
- report("missing %q",lib)
- else
- report("fetching %q",fullname)
- local data = io.loaddata(fullname)
- collected[#collected+1] = "\ndo -- begin closure to overcome local limits and interference\n\n"
- collected[#collected+1] = utilities.merger.compact(data)
- collected[#collected+1] = "\nend -- closure\n"
- end
- end
- end
- report("saving %q",newname)
- io.savedata(newname,table.concat(collected))
- end
- end
-end
-
-if environment.argument("merge") then
- scripts.package.merge_luatex_files(environment.files[1] or "")
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-package'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, gsub, gmatch = string.format, string.gsub, string.gmatch
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-package</entry>
+ <entry name="detail">Distribution Related Goodies</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="merge"><short>merge 'loadmodule' into merge file</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-package",
+ banner = "Distribution Related Goodies 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+messages = messages or { }
+scripts.package = scripts.package or { }
+
+function scripts.package.merge_luatex_files(name)
+ local oldname = resolvers.findfile(name) or ""
+ oldname = file.replacesuffix(oldname,"lua")
+ if oldname == "" then
+ report("missing %q",name)
+ else
+ local newname = file.removesuffix(oldname) .. "-merged.lua"
+ local data = io.loaddata(oldname) or ""
+ if data == "" then
+ report("missing %q",newname)
+ else
+ report("loading %q",oldname)
+ local collected = { }
+ collected[#collected+1] = format("-- merged file : %s\n",newname)
+ collected[#collected+1] = format("-- parent file : %s\n",oldname)
+ collected[#collected+1] = format("-- merge date : %s\n",os.date())
+ -- loadmodule can have extra arguments
+ for lib in gmatch(data,"loadmodule *%([\'\"](.-)[\'\"]") do
+ if file.basename(lib) ~= file.basename(newname) then
+ local fullname = resolvers.findfile(lib) or ""
+ if fullname == "" then
+ report("missing %q",lib)
+ else
+ report("fetching %q",fullname)
+ local data = io.loaddata(fullname)
+ collected[#collected+1] = "\ndo -- begin closure to overcome local limits and interference\n\n"
+ collected[#collected+1] = utilities.merger.compact(data)
+ collected[#collected+1] = "\nend -- closure\n"
+ end
+ end
+ end
+ report("saving %q",newname)
+ io.savedata(newname,table.concat(collected))
+ end
+ end
+end
+
+if environment.argument("merge") then
+ scripts.package.merge_luatex_files(environment.files[1] or "")
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-patterns.lua b/scripts/context/lua/mtx-patterns.lua
index 1abe90385..dca81568e 100644
--- a/scripts/context/lua/mtx-patterns.lua
+++ b/scripts/context/lua/mtx-patterns.lua
@@ -639,7 +639,7 @@ end
-- mtxrun --script pattern --check hyph-*.tex
-- mtxrun --script pattern --check --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns
-- mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex --destination=e:/tmp/patterns
--- mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/txt --destination=e:/tmp/patterns --compress
+-- mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/txt --destination=e:/tmp/patterns
-- copy /Y *.hyp e:\tex-context\tex\texmf-context\tex\context\patterns
-- copy /Y *.pat e:\tex-context\tex\texmf-context\tex\context\patterns
diff --git a/scripts/context/lua/mtx-pdf.lua b/scripts/context/lua/mtx-pdf.lua
index 2ff22e07f..551aa5b37 100644
--- a/scripts/context/lua/mtx-pdf.lua
+++ b/scripts/context/lua/mtx-pdf.lua
@@ -1,299 +1,299 @@
-if not modules then modules = { } end modules ['mtx-pdf'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local tonumber = tonumber
-local format, gmatch = string.format, string.gmatch
-local utfchar = utf.char
-local concat = table.concat
-local setmetatableindex, sortedhash, sortedkeys = table.setmetatableindex, table.sortedhash, table.sortedkeys
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-pdf</entry>
- <entry name="detail">ConTeXt PDF Helpers</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="info"><short>show some info about the given file</short></flag>
- <flag name="metadata"><short>show metadata xml blob</short></flag>
- <flag name="fonts"><short>show used fonts (<ref name="detail)"/></short></flag>
- <flag name="linearize"><short>linearize given file</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-pdf",
- banner = "ConTeXt PDF Helpers 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-dofile(resolvers.findfile("lpdf-epd.lua","tex"))
-
-scripts = scripts or { }
-scripts.pdf = scripts.pdf or { }
-
-local function loadpdffile(filename)
- if not filename or filename == "" then
- report("no filename given")
- elseif not lfs.isfile(filename) then
- report("unknown file '%s'",filename)
- else
- local pdffile = lpdf.epdf.load(filename)
- if pdffile then
- return pdffile
- else
- report("no valid pdf file '%s'",filename)
- end
- end
-end
-
-function scripts.pdf.info(filename)
- local pdffile = loadpdffile(filename)
- if pdffile then
- local catalog = pdffile.Catalog
- local info = pdffile.Info
- local pages = pdffile.pages
- local nofpages = pages.n -- no # yet. will be in 5.2
-
- report("filename > %s",filename)
- report("pdf version > %s",catalog.Version)
- report("number of pages > %s",nofpages)
- report("title > %s",info.Title)
- report("creator > %s",info.Creator)
- report("producer > %s",info.Producer)
- report("creation date > %s",info.CreationDate)
- report("modification date > %s",info.ModDate)
-
- local width, height, start
- for i=1, nofpages do
- local page = pages[i]
- local bbox = page.CropBox or page.MediaBox
- local w, h = bbox[4]-bbox[2],bbox[3]-bbox[1]
- if w ~= width or h ~= height then
- if start then
- report("cropbox > pages: %s-%s, width: %s, height: %s",start,i-1,width,height)
- end
- width, height, start = w, h, i
- end
- end
- report("cropbox > pages: %s-%s, width: %s, height: %s",start,nofpages,width,height)
- end
-end
-
-function scripts.pdf.metadata(filename)
- local pdffile = loadpdffile(filename)
- if pdffile then
- local catalog = pdffile.Catalog
- local metadata = catalog.Metadata
- if metadata then
- report("metadata > \n\n%s\n",metadata())
- else
- report("no metadata")
- end
- end
-end
-
-local function getfonts(pdffile)
- local usedfonts = { }
- for i=1,pdffile.pages.n do
- local page = pdffile.pages[i]
- local fontlist = page.Resources.Font
- for k, v in next, lpdf.epdf.expand(fontlist) do
- usedfonts[k] = lpdf.epdf.expand(v)
- end
- end
- return usedfonts
-end
-
-local function getunicodes(font)
- local cid = font.ToUnicode
- if cid then
- cid = cid()
- local counts = { }
- -- for s in gmatch(cid,"begincodespacerange%s*(.-)%s*endcodespacerange") do
- -- for a, b in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
- -- print(a,b)
- -- end
- -- end
- setmetatableindex(counts, function(t,k) t[k] = 0 return 0 end)
- for s in gmatch(cid,"beginbfrange%s*(.-)%s*endbfrange") do
- for first, last, offset in gmatch(s,"<([^>]+)>%s+<([^>]+)>%s+<([^>]+)>") do
- first = tonumber(first,16)
- last = tonumber(last,16)
- offset = tonumber(offset,16)
- offset = offset - first
- for i=first,last do
- local c = i + offset
- counts[c] = counts[c] + 1
- end
- end
- end
- for s in gmatch(cid,"beginbfchar%s*(.-)%s*endbfchar") do
- for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
- for n in gmatch(new,"....") do
- local c = tonumber(n,16)
- counts[c] = counts[c] + 1
- end
- end
- end
- return counts
- end
-end
-
-function scripts.pdf.fonts(filename)
- local pdffile = loadpdffile(filename)
- if pdffile then
- local usedfonts = getfonts(pdffile)
- local found = { }
- for k, v in table.sortedhash(usedfonts) do
- local counts = getunicodes(v)
- local codes = { }
- local chars = { }
- local freqs = { }
- if counts then
- codes = sortedkeys(counts)
- for i=1,#codes do
- local k = codes[i]
- local c = utfchar(k)
- chars[i] = c
- freqs[i] = format("U+%05X %s %s",k,counts[k] > 1 and "+" or " ", c)
- end
- for i=1,#codes do
- codes[i] = format("U+%05X",codes[i])
- end
- end
- found[k] = {
- basefont = v.BaseFont or "no basefont",
- encoding = v.Encoding or "no encoding",
- subtype = v.Subtype or "no subtype",
- unicode = v.ToUnicode and "unicode" or "no unicode",
- chars = chars,
- codes = codes,
- freqs = freqs,
- }
- end
-
- if environment.argument("detail") then
- for k, v in sortedhash(found) do
- report("id : %s",k)
- report("basefont : %s",v.basefont)
- report("encoding : %s",v.encoding)
- report("subtype : %s",v.subtype)
- report("unicode : %s",v.unicode)
- report("characters : %s", concat(v.chars," "))
- report("codepoints : %s", concat(v.codes," "))
- report("")
- end
- else
- local results = { { "id", "basefont", "encoding", "subtype", "unicode", "characters" } }
- for k, v in sortedhash(found) do
- results[#results+1] = { k, v.basefont, v.encoding, v.subtype, v.unicode, concat(v.chars," ") }
- end
- utilities.formatters.formatcolumns(results)
- report(results[1])
- report("")
- for i=2,#results do
- report(results[i])
- end
- report("")
- end
- end
-end
-
--- this is a quick hack ... proof of concept .. will change (derived from luigi's example) ...
--- i will make a ctx wrapper
-
-local qpdf
-
-function scripts.pdf.linearize(filename)
- qpdf = qpdf or swiglib("qpdf.core")
- local oldfile = filename or environment.files[1]
- if not oldfile then
- return
- end
- file.addsuffix(oldfile,"pdf")
- if not lfs.isfile(oldfile) then
- return
- end
- local newfile = environment.files[2]
- if not newfile or file.removesuffix(oldfile) == file.removesuffix(newfile)then
- newfile = file.addsuffix(file.removesuffix(oldfile) .. "-linearized","pdf")
- end
- local password = environment.arguments.password
- local instance = qpdf.qpdf_init()
- if bit32.band(qpdf.qpdf_read(instance,oldfile,password),qpdf.QPDF_ERRORS) ~= 0 then
- report("unable to open input file")
- elseif bit32.band(qpdf.qpdf_init_write(instance,newfile),qpdf.QPDF_ERRORS) ~= 0 then
- report("unable to open output file")
- else
- report("linearizing %a into %a",oldfile,newfile)
- qpdf.qpdf_set_static_ID(instance,qpdf.QPDF_TRUE)
- qpdf.qpdf_set_linearization(instance,qpdf.QPDF_TRUE)
- qpdf.qpdf_write(instance)
- end
- while qpdf.qpdf_more_warnings(instance) ~= 0 do
- report("warning: %s",qpdf.qpdf_get_error_full_text(instance,qpdf.qpdf_next_warning(qpdf)))
- end
- if qpdf.qpdf_has_error(instance) ~= 0 then
- report("error: %s",qpdf.qpdf_get_error_full_text(instance,qpdf.qpdf_get_error(qpdf)))
- end
- qpdf.qpdf_cleanup_p(instance)
-end
-
--- scripts.pdf.info("e:/tmp/oeps.pdf")
--- scripts.pdf.metadata("e:/tmp/oeps.pdf")
--- scripts.pdf.fonts("e:/tmp/oeps.pdf")
--- scripts.pdf.linearize("e:/tmp/oeps.pdf")
-
-local filename = environment.files[1] or ""
-
-if filename == "" then
- application.help()
-elseif environment.argument("info") then
- scripts.pdf.info(filename)
-elseif environment.argument("metadata") then
- scripts.pdf.metadata(filename)
-elseif environment.argument("fonts") then
- scripts.pdf.fonts(filename)
-elseif environment.argument("linearize") then
- scripts.pdf.linearize(filename)
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),filename)
-else
- application.help()
-end
-
--- a variant on an experiment by hartmut
-
---~ function downloadlinks(filename)
---~ local document = lpdf.epdf.load(filename)
---~ if document then
---~ local pages = document.pages
---~ for p = 1,#pages do
---~ local annotations = pages[p].Annots
---~ if annotations then
---~ for a=1,#annotations do
---~ local annotation = annotations[a]
---~ local uri = annotation.Subtype == "Link" and annotation.A and annotation.A.URI
---~ if uri and string.find(uri,"^http") then
---~ os.execute("wget " .. uri)
---~ end
---~ end
---~ end
---~ end
---~ end
---~ end
+if not modules then modules = { } end modules ['mtx-pdf'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local tonumber = tonumber
+local format, gmatch = string.format, string.gmatch
+local utfchar = utf.char
+local concat = table.concat
+local setmetatableindex, sortedhash, sortedkeys = table.setmetatableindex, table.sortedhash, table.sortedkeys
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-pdf</entry>
+ <entry name="detail">ConTeXt PDF Helpers</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="info"><short>show some info about the given file</short></flag>
+ <flag name="metadata"><short>show metadata xml blob</short></flag>
+ <flag name="fonts"><short>show used fonts (<ref name="detail)"/></short></flag>
+ <flag name="linearize"><short>linearize given file</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-pdf",
+ banner = "ConTeXt PDF Helpers 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+dofile(resolvers.findfile("lpdf-epd.lua","tex"))
+
+scripts = scripts or { }
+scripts.pdf = scripts.pdf or { }
+
+local function loadpdffile(filename)
+ if not filename or filename == "" then
+ report("no filename given")
+ elseif not lfs.isfile(filename) then
+ report("unknown file '%s'",filename)
+ else
+ local pdffile = lpdf.epdf.load(filename)
+ if pdffile then
+ return pdffile
+ else
+ report("no valid pdf file '%s'",filename)
+ end
+ end
+end
+
+function scripts.pdf.info(filename)
+ local pdffile = loadpdffile(filename)
+ if pdffile then
+ local catalog = pdffile.Catalog
+ local info = pdffile.Info
+ local pages = pdffile.pages
+ local nofpages = pages.n -- no # yet. will be in 5.2
+
+ report("filename > %s",filename)
+ report("pdf version > %s",catalog.Version)
+ report("number of pages > %s",nofpages)
+ report("title > %s",info.Title)
+ report("creator > %s",info.Creator)
+ report("producer > %s",info.Producer)
+ report("creation date > %s",info.CreationDate)
+ report("modification date > %s",info.ModDate)
+
+ local width, height, start
+ for i=1, nofpages do
+ local page = pages[i]
+ local bbox = page.CropBox or page.MediaBox
+ local w, h = bbox[4]-bbox[2],bbox[3]-bbox[1]
+ if w ~= width or h ~= height then
+ if start then
+ report("cropbox > pages: %s-%s, width: %s, height: %s",start,i-1,width,height)
+ end
+ width, height, start = w, h, i
+ end
+ end
+ report("cropbox > pages: %s-%s, width: %s, height: %s",start,nofpages,width,height)
+ end
+end
+
+function scripts.pdf.metadata(filename)
+ local pdffile = loadpdffile(filename)
+ if pdffile then
+ local catalog = pdffile.Catalog
+ local metadata = catalog.Metadata
+ if metadata then
+ report("metadata > \n\n%s\n",metadata())
+ else
+ report("no metadata")
+ end
+ end
+end
+
+local function getfonts(pdffile)
+ local usedfonts = { }
+ for i=1,pdffile.pages.n do
+ local page = pdffile.pages[i]
+ local fontlist = page.Resources.Font
+ for k, v in next, lpdf.epdf.expand(fontlist) do
+ usedfonts[k] = lpdf.epdf.expand(v)
+ end
+ end
+ return usedfonts
+end
+
+local function getunicodes(font)
+ local cid = font.ToUnicode
+ if cid then
+ cid = cid()
+ local counts = { }
+ -- for s in gmatch(cid,"begincodespacerange%s*(.-)%s*endcodespacerange") do
+ -- for a, b in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
+ -- print(a,b)
+ -- end
+ -- end
+ setmetatableindex(counts, function(t,k) t[k] = 0 return 0 end)
+ for s in gmatch(cid,"beginbfrange%s*(.-)%s*endbfrange") do
+ for first, last, offset in gmatch(s,"<([^>]+)>%s+<([^>]+)>%s+<([^>]+)>") do
+ first = tonumber(first,16)
+ last = tonumber(last,16)
+ offset = tonumber(offset,16)
+ offset = offset - first
+ for i=first,last do
+ local c = i + offset
+ counts[c] = counts[c] + 1
+ end
+ end
+ end
+ for s in gmatch(cid,"beginbfchar%s*(.-)%s*endbfchar") do
+ for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
+ for n in gmatch(new,"....") do
+ local c = tonumber(n,16)
+ counts[c] = counts[c] + 1
+ end
+ end
+ end
+ return counts
+ end
+end
+
+function scripts.pdf.fonts(filename)
+ local pdffile = loadpdffile(filename)
+ if pdffile then
+ local usedfonts = getfonts(pdffile)
+ local found = { }
+ for k, v in table.sortedhash(usedfonts) do
+ local counts = getunicodes(v)
+ local codes = { }
+ local chars = { }
+ local freqs = { }
+ if counts then
+ codes = sortedkeys(counts)
+ for i=1,#codes do
+ local k = codes[i]
+ local c = utfchar(k)
+ chars[i] = c
+ freqs[i] = format("U+%05X %s %s",k,counts[k] > 1 and "+" or " ", c)
+ end
+ for i=1,#codes do
+ codes[i] = format("U+%05X",codes[i])
+ end
+ end
+ found[k] = {
+ basefont = v.BaseFont or "no basefont",
+ encoding = v.Encoding or "no encoding",
+ subtype = v.Subtype or "no subtype",
+ unicode = v.ToUnicode and "unicode" or "no unicode",
+ chars = chars,
+ codes = codes,
+ freqs = freqs,
+ }
+ end
+
+ if environment.argument("detail") then
+ for k, v in sortedhash(found) do
+ report("id : %s",k)
+ report("basefont : %s",v.basefont)
+ report("encoding : %s",v.encoding)
+ report("subtype : %s",v.subtype)
+ report("unicode : %s",v.unicode)
+ report("characters : %s", concat(v.chars," "))
+ report("codepoints : %s", concat(v.codes," "))
+ report("")
+ end
+ else
+ local results = { { "id", "basefont", "encoding", "subtype", "unicode", "characters" } }
+ for k, v in sortedhash(found) do
+ results[#results+1] = { k, v.basefont, v.encoding, v.subtype, v.unicode, concat(v.chars," ") }
+ end
+ utilities.formatters.formatcolumns(results)
+ report(results[1])
+ report("")
+ for i=2,#results do
+ report(results[i])
+ end
+ report("")
+ end
+ end
+end
+
+-- this is a quick hack ... proof of concept .. will change (derived from luigi's example) ...
+-- i will make a ctx wrapper
+
+local qpdf
+
+function scripts.pdf.linearize(filename)
+ qpdf = qpdf or swiglib("qpdf.core")
+ local oldfile = filename or environment.files[1]
+ if not oldfile then
+ return
+ end
+ file.addsuffix(oldfile,"pdf")
+ if not lfs.isfile(oldfile) then
+ return
+ end
+ local newfile = environment.files[2]
+ if not newfile or file.removesuffix(oldfile) == file.removesuffix(newfile)then
+ newfile = file.addsuffix(file.removesuffix(oldfile) .. "-linearized","pdf")
+ end
+ local password = environment.arguments.password
+ local instance = qpdf.qpdf_init()
+ if bit32.band(qpdf.qpdf_read(instance,oldfile,password),qpdf.QPDF_ERRORS) ~= 0 then
+ report("unable to open input file")
+ elseif bit32.band(qpdf.qpdf_init_write(instance,newfile),qpdf.QPDF_ERRORS) ~= 0 then
+ report("unable to open output file")
+ else
+ report("linearizing %a into %a",oldfile,newfile)
+ qpdf.qpdf_set_static_ID(instance,qpdf.QPDF_TRUE)
+ qpdf.qpdf_set_linearization(instance,qpdf.QPDF_TRUE)
+ qpdf.qpdf_write(instance)
+ end
+ while qpdf.qpdf_more_warnings(instance) ~= 0 do
+ report("warning: %s",qpdf.qpdf_get_error_full_text(instance,qpdf.qpdf_next_warning(qpdf)))
+ end
+ if qpdf.qpdf_has_error(instance) ~= 0 then
+ report("error: %s",qpdf.qpdf_get_error_full_text(instance,qpdf.qpdf_get_error(qpdf)))
+ end
+ qpdf.qpdf_cleanup_p(instance)
+end
+
+-- scripts.pdf.info("e:/tmp/oeps.pdf")
+-- scripts.pdf.metadata("e:/tmp/oeps.pdf")
+-- scripts.pdf.fonts("e:/tmp/oeps.pdf")
+-- scripts.pdf.linearize("e:/tmp/oeps.pdf")
+
+local filename = environment.files[1] or ""
+
+if filename == "" then
+ application.help()
+elseif environment.argument("info") then
+ scripts.pdf.info(filename)
+elseif environment.argument("metadata") then
+ scripts.pdf.metadata(filename)
+elseif environment.argument("fonts") then
+ scripts.pdf.fonts(filename)
+elseif environment.argument("linearize") then
+ scripts.pdf.linearize(filename)
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),filename)
+else
+ application.help()
+end
+
+-- a variant on an experiment by hartmut
+
+--~ function downloadlinks(filename)
+--~ local document = lpdf.epdf.load(filename)
+--~ if document then
+--~ local pages = document.pages
+--~ for p = 1,#pages do
+--~ local annotations = pages[p].Annots
+--~ if annotations then
+--~ for a=1,#annotations do
+--~ local annotation = annotations[a]
+--~ local uri = annotation.Subtype == "Link" and annotation.A and annotation.A.URI
+--~ if uri and string.find(uri,"^http") then
+--~ os.execute("wget " .. uri)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
diff --git a/scripts/context/lua/mtx-plain.lua b/scripts/context/lua/mtx-plain.lua
index 975c91ee7..f43dcdeaf 100644
--- a/scripts/context/lua/mtx-plain.lua
+++ b/scripts/context/lua/mtx-plain.lua
@@ -1,129 +1,129 @@
-if not modules then modules = { } end modules ['mtx-plain'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- future version will use the texmf-cache/generic/formats/<engine> path
--- instead because then we can use some more of the generic context
--- initializers ... in that case we will also use the regular database
--- instead of kpse here, just like with the font database code (as that
--- one also works with kpse runtime)
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-plain</entry>
- <entry name="detail">Plain TeX Runner</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="make"><short>create format file</short></flag>
- <flag name="run"><short>process file</short></flag>
- <flag name="format" value="string"><short>format name (default: luatex-plain)</short></flag>
- <flag name="engine" value="string"><short>engine to use (default: luatex)</short></flag>
- <flag name="jit"><short>use luajittex</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-plain",
- banner = "Plain TeX Runner 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.plain = scripts.plain or { }
-
-local function execute(...)
- local command = string.format(...)
- report("running command %a\n",command)
- os.execute(command)
-end
-
-local function resultof(...)
- local command = string.format(...)
- report("running command %a",command)
- return string.strip(os.resultof(command) or "")
-end
-
-function scripts.plain.make(texengine,texformat)
- report("generating kpse file database")
- execute("mktexlsr") -- better play safe and use this one
- local fmtpathspec = resultof("kpsewhich --var-value=TEXFORMATS --engine=%s",texengine)
- if fmtpathspec ~= "" then
- report("using path specification %a",fmtpathspec)
- fmtpathspec = resultof('kpsewhich -expand-braces="%s"',fmtpathspec)
- end
- if fmtpathspec ~= "" then
- report("using path expansion %a",fmtpathspec)
- else
- report("no valid path reported, trying alternative")
- fmtpathspec = resultof("kpsewhich --show-path=fmt --engine=%s",texengine)
- if fmtpathspec ~= "" then
- report("using path expansion %a",fmtpathspec)
- else
- report("no valid path reported, falling back to current path")
- fmtpathspec = "."
- end
- end
- fmtpathspec = string.splitlines(fmtpathspec)[1] or fmtpathspec
- fmtpathspec = file.splitpath(fmtpathspec)
- local fmtpath = nil
- for i=1,#fmtpathspec do
- local path = fmtpathspec[i]
- if path ~= "." then
- dir.makedirs(path)
- if lfs.isdir(path) and file.is_writable(path) then
- fmtpath = path
- break
- end
- end
- end
- if not fmtpath or fmtpath == "" then
- fmtpath = "."
- else
- lfs.chdir(fmtpath)
- end
- execute('%s --ini %s \\dump',texengine,file.addsuffix(texformat,"tex"))
- report("generating kpse file database")
- execute("mktexlsr")
- report("format %a saved on path %a",texformat,fmtpath)
-end
-
-function scripts.plain.run(texengine,texformat,filename)
- execute('%s --fmt=%s "%s"',texengine,file.removesuffix(texformat),filename)
-end
-
-local texformat = environment.arguments.texformat or environment.arguments.format
-local texengine = environment.arguments.texengine or environment.arguments.engine
-
-if type(texengine) ~= "string" or texengine == "" then
- texengine = environment.arguments.jit and "luajittex" or"luatex"
-end
-
-if type(texformat) ~= "string" or texformat == "" then
- texformat = "luatex-plain"
-end
-
-local filename = environment.files[1]
-
-if environment.arguments.exporthelp then
- application.export(environment.arguments.exporthelp,filename)
-elseif environment.arguments.make then
- scripts.plain.make(texengine,texformat)
-elseif filename then
- scripts.plain.run(texengine,texformat,filename)
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-plain'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- future version will use the texmf-cache/generic/formats/<engine> path
+-- instead because then we can use some more of the generic context
+-- initializers ... in that case we will also use the regular database
+-- instead of kpse here, just like with the font database code (as that
+-- one also works with kpse runtime)
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-plain</entry>
+ <entry name="detail">Plain TeX Runner</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="make"><short>create format file</short></flag>
+ <flag name="run"><short>process file</short></flag>
+ <flag name="format" value="string"><short>format name (default: luatex-plain)</short></flag>
+ <flag name="engine" value="string"><short>engine to use (default: luatex)</short></flag>
+ <flag name="jit"><short>use luajittex</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-plain",
+ banner = "Plain TeX Runner 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.plain = scripts.plain or { }
+
+local function execute(...)
+ local command = string.format(...)
+ report("running command %a\n",command)
+ os.execute(command)
+end
+
+local function resultof(...)
+ local command = string.format(...)
+ report("running command %a",command)
+ return string.strip(os.resultof(command) or "")
+end
+
+function scripts.plain.make(texengine,texformat)
+ report("generating kpse file database")
+ execute("mktexlsr") -- better play safe and use this one
+ local fmtpathspec = resultof("kpsewhich --var-value=TEXFORMATS --engine=%s",texengine)
+ if fmtpathspec ~= "" then
+ report("using path specification %a",fmtpathspec)
+ fmtpathspec = resultof('kpsewhich -expand-braces="%s"',fmtpathspec)
+ end
+ if fmtpathspec ~= "" then
+ report("using path expansion %a",fmtpathspec)
+ else
+ report("no valid path reported, trying alternative")
+ fmtpathspec = resultof("kpsewhich --show-path=fmt --engine=%s",texengine)
+ if fmtpathspec ~= "" then
+ report("using path expansion %a",fmtpathspec)
+ else
+ report("no valid path reported, falling back to current path")
+ fmtpathspec = "."
+ end
+ end
+ fmtpathspec = string.splitlines(fmtpathspec)[1] or fmtpathspec
+ fmtpathspec = file.splitpath(fmtpathspec)
+ local fmtpath = nil
+ for i=1,#fmtpathspec do
+ local path = fmtpathspec[i]
+ if path ~= "." then
+ dir.makedirs(path)
+ if lfs.isdir(path) and file.is_writable(path) then
+ fmtpath = path
+ break
+ end
+ end
+ end
+ if not fmtpath or fmtpath == "" then
+ fmtpath = "."
+ else
+ lfs.chdir(fmtpath)
+ end
+ execute('%s --ini %s \\dump',texengine,file.addsuffix(texformat,"tex"))
+ report("generating kpse file database")
+ execute("mktexlsr")
+ report("format %a saved on path %a",texformat,fmtpath)
+end
+
+function scripts.plain.run(texengine,texformat,filename)
+ execute('%s --fmt=%s "%s"',texengine,file.removesuffix(texformat),filename)
+end
+
+local texformat = environment.arguments.texformat or environment.arguments.format
+local texengine = environment.arguments.texengine or environment.arguments.engine
+
+if type(texengine) ~= "string" or texengine == "" then
+ texengine = environment.arguments.jit and "luajittex" or"luatex"
+end
+
+if type(texformat) ~= "string" or texformat == "" then
+ texformat = "luatex-plain"
+end
+
+local filename = environment.files[1]
+
+if environment.arguments.exporthelp then
+ application.export(environment.arguments.exporthelp,filename)
+elseif environment.arguments.make then
+ scripts.plain.make(texengine,texformat)
+elseif filename then
+ scripts.plain.run(texengine,texformat,filename)
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-profile.lua b/scripts/context/lua/mtx-profile.lua
index 15ff595d2..3550474f3 100644
--- a/scripts/context/lua/mtx-profile.lua
+++ b/scripts/context/lua/mtx-profile.lua
@@ -1,187 +1,187 @@
-if not modules then modules = { } end modules ['mtx-profile'] = {
- version = 1.000,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- todo: also line number
--- todo: sort runtime as option
-
-local match, format, find = string.match, string.format, string.find
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-profile</entry>
- <entry name="detail">ConTeXt MkIV LuaTeX Profiler</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="analyze"><short>analyze lua calls</short></flag>
- <flag name="trace"><short>analyze tex calls</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-cache",
- banner = "ConTeXt MkIV LuaTeX Profiler 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.profiler = scripts.profiler or { }
-
-local timethreshold = 0
-local callthreshold = 2500
-local countthreshold = 2500
-
-local functiontemplate = "%12s %03.4f %9i %s"
-local calltemplate = "%9i %s"
-local totaltemplate = "%i internal calls, %i function calls taking %3.4f seconds"
-local thresholdtemplate = "thresholds: %i internal calls, %i function calls, %i seconds"
-
-function scripts.profiler.analyze(filename)
- local f = io.open(filename)
- if f then
- local times, counts, calls = { }, { }, { }
- local totalruntime, totalcount, totalcalls = 0, 0, 0
- for line in f:lines() do
- local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)")
- if not filename then
- -- next
- elseif filename == "=[C]" then
- if not functionname:find("^%(") then
- calls[functionname] = (calls[functionname] or 0) + 1
- end
- else
- local filename = filename:match("^@(.*)$")
- if filename then
- local fi = times[filename]
- if not fi then fi = { } times[filename] = fi end
- fi[functionname] = (fi[functionname] or 0) + tonumber(localtime)
- counts[functionname] = (counts[functionname] or 0) + 1
- end
- end
- end
- f:close()
- print("")
- local loaded = { }
- local sorted = table.sortedkeys(times)
- for i=1,#sorted do
- local filename = sorted[i]
- local functions = times[filename]
- local sorted = table.sortedkeys(functions)
- for i=1,#sorted do
- local functionname = sorted[i]
- local totaltime = functions[functionname]
- local count = counts[functionname]
- totalcount = totalcount + count
- if totaltime > timethreshold or count > countthreshold then
- totalruntime = totalruntime + totaltime
- local functionfile, somenumber = functionname:match("^@(.+):(.-)$")
- if functionfile then
- local number = tonumber(somenumber)
- if number then
- if not loaded[functionfile] then
- loaded[functionfile] = string.splitlines(io.loaddata(functionfile) or "")
- end
- functionname = loaded[functionfile][number] or functionname
- functionname = functionname:gsub("^%s*","")
- functionname = functionname:gsub("%s*%-%-.*$","")
- functionname = number .. ": " .. functionname
- end
- end
- filename = file.basename(filename)
- print(functiontemplate:format(filename,totaltime,count,functionname))
- end
- end
- end
- print("")
- local sorted = table.sortedkeys(calls)
- for i=1,#sorted do
- local call = sorted[i]
- local n = calls[call]
- totalcalls = totalcalls + n
- if n > callthreshold then
- print(calltemplate:format(n,call))
- end
- end
- print("")
- print(totaltemplate:format(totalcalls,totalcount,totalruntime))
- print("")
- print(thresholdtemplate:format(callthreshold,countthreshold,timethreshold))
- end
-end
-
-function scripts.profiler.x_analyze(filename)
- local f = io.open(filename)
- local calls = { }
- local lines = 0
- if f then
- while true do
- local line = f:read()
- if line then
- lines = lines + 1
- local c = match(line,"\\([a-zA-Z%!%?@]+) *%->")
- if c then
- local cc = calls[c]
- if not cc then
- calls[c] = 1
- else
- calls[c] = cc + 1
- end
- end
- else
- break
- end
- end
- f:close()
- local noc = 0
-local criterium = 100
- for name, n in next, calls do
- if n > criterium then
- if find(name,"^@@[a-z][a-z]") then
- -- parameter
- elseif find(name,"^[cvserft]%!") then
- -- variables and constants
- elseif find(name,"^%?%?[a-z][a-z]$") then
- -- prefix
- elseif find(name,"^%!%!") then
- -- reserved
- elseif find(name,"^@.+@$") then
- -- weird
- else
- noc = noc + n
- print(format("%6i: %s",n,name))
- end
- end
- end
- print("")
- print(format("number of lines: %s",lines))
- print(format("number of calls: %s",noc))
- print(format("criterium calls: %s",criterium))
- end
-end
-
---~ scripts.profiler.analyze("t:/manuals/mk/mk-fonts-profile.lua")
---~ scripts.profiler.analyze("t:/manuals/mk/mk-introduction-profile.lua")
-
-if environment.argument("analyze") then
- scripts.profiler.analyze(environment.files[1] or "luatex-profile.log")
-elseif environment.argument("trace") then
- scripts.profiler.analyze(environment.files[1] or "temp.log")
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-profile'] = {
+ version = 1.000,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: also line number
+-- todo: sort runtime as option
+
+local match, format, find = string.match, string.format, string.find
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-profile</entry>
+ <entry name="detail">ConTeXt MkIV LuaTeX Profiler</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="analyze"><short>analyze lua calls</short></flag>
+ <flag name="trace"><short>analyze tex calls</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-cache",
+ banner = "ConTeXt MkIV LuaTeX Profiler 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.profiler = scripts.profiler or { }
+
+local timethreshold = 0
+local callthreshold = 2500
+local countthreshold = 2500
+
+local functiontemplate = "%12s %03.4f %9i %s"
+local calltemplate = "%9i %s"
+local totaltemplate = "%i internal calls, %i function calls taking %3.4f seconds"
+local thresholdtemplate = "thresholds: %i internal calls, %i function calls, %i seconds"
+
+function scripts.profiler.analyze(filename)
+ local f = io.open(filename)
+ if f then
+ local times, counts, calls = { }, { }, { }
+ local totalruntime, totalcount, totalcalls = 0, 0, 0
+ for line in f:lines() do
+ local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)")
+ if not filename then
+ -- next
+ elseif filename == "=[C]" then
+ if not functionname:find("^%(") then
+ calls[functionname] = (calls[functionname] or 0) + 1
+ end
+ else
+ local filename = filename:match("^@(.*)$")
+ if filename then
+ local fi = times[filename]
+ if not fi then fi = { } times[filename] = fi end
+ fi[functionname] = (fi[functionname] or 0) + tonumber(localtime)
+ counts[functionname] = (counts[functionname] or 0) + 1
+ end
+ end
+ end
+ f:close()
+ print("")
+ local loaded = { }
+ local sorted = table.sortedkeys(times)
+ for i=1,#sorted do
+ local filename = sorted[i]
+ local functions = times[filename]
+ local sorted = table.sortedkeys(functions)
+ for i=1,#sorted do
+ local functionname = sorted[i]
+ local totaltime = functions[functionname]
+ local count = counts[functionname]
+ totalcount = totalcount + count
+ if totaltime > timethreshold or count > countthreshold then
+ totalruntime = totalruntime + totaltime
+ local functionfile, somenumber = functionname:match("^@(.+):(.-)$")
+ if functionfile then
+ local number = tonumber(somenumber)
+ if number then
+ if not loaded[functionfile] then
+ loaded[functionfile] = string.splitlines(io.loaddata(functionfile) or "")
+ end
+ functionname = loaded[functionfile][number] or functionname
+ functionname = functionname:gsub("^%s*","")
+ functionname = functionname:gsub("%s*%-%-.*$","")
+ functionname = number .. ": " .. functionname
+ end
+ end
+ filename = file.basename(filename)
+ print(functiontemplate:format(filename,totaltime,count,functionname))
+ end
+ end
+ end
+ print("")
+ local sorted = table.sortedkeys(calls)
+ for i=1,#sorted do
+ local call = sorted[i]
+ local n = calls[call]
+ totalcalls = totalcalls + n
+ if n > callthreshold then
+ print(calltemplate:format(n,call))
+ end
+ end
+ print("")
+ print(totaltemplate:format(totalcalls,totalcount,totalruntime))
+ print("")
+ print(thresholdtemplate:format(callthreshold,countthreshold,timethreshold))
+ end
+end
+
+function scripts.profiler.x_analyze(filename)
+ local f = io.open(filename)
+ local calls = { }
+ local lines = 0
+ if f then
+ while true do
+ local line = f:read()
+ if line then
+ lines = lines + 1
+ local c = match(line,"\\([a-zA-Z%!%?@]+) *%->")
+ if c then
+ local cc = calls[c]
+ if not cc then
+ calls[c] = 1
+ else
+ calls[c] = cc + 1
+ end
+ end
+ else
+ break
+ end
+ end
+ f:close()
+ local noc = 0
+local criterium = 100
+ for name, n in next, calls do
+ if n > criterium then
+ if find(name,"^@@[a-z][a-z]") then
+ -- parameter
+ elseif find(name,"^[cvserft]%!") then
+ -- variables and constants
+ elseif find(name,"^%?%?[a-z][a-z]$") then
+ -- prefix
+ elseif find(name,"^%!%!") then
+ -- reserved
+ elseif find(name,"^@.+@$") then
+ -- weird
+ else
+ noc = noc + n
+ print(format("%6i: %s",n,name))
+ end
+ end
+ end
+ print("")
+ print(format("number of lines: %s",lines))
+ print(format("number of calls: %s",noc))
+ print(format("criterium calls: %s",criterium))
+ end
+end
+
+--~ scripts.profiler.analyze("t:/manuals/mk/mk-fonts-profile.lua")
+--~ scripts.profiler.analyze("t:/manuals/mk/mk-introduction-profile.lua")
+
+if environment.argument("analyze") then
+ scripts.profiler.analyze(environment.files[1] or "luatex-profile.log")
+elseif environment.argument("trace") then
+ scripts.profiler.analyze(environment.files[1] or "temp.log")
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-rsync.lua b/scripts/context/lua/mtx-rsync.lua
index 1095f2d05..65f795ee5 100644
--- a/scripts/context/lua/mtx-rsync.lua
+++ b/scripts/context/lua/mtx-rsync.lua
@@ -1,189 +1,189 @@
-if not modules then modules = { } end modules ['mtx-rsync'] = {
- version = 1.000,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- This is an experimental script that will be extended over time and
--- is used by myself. An example or a copy spec:
---
---
--- local devdir = "m:/develop/services"
--- local orgdir = "m:/pod/m4all"
---
--- return {
--- {
--- origin = { devdir, "framework/scripts/d-dispatchers.lua"},
--- target = { orgdir, "framework/scripts" },
--- },
--- {
--- origin = { devdir, "framework/scripts/common/*"},
--- target = { orgdir, "framework/scripts/common" },
--- },
--- {
--- origin = { devdir, "framework/scripts/d-buildtool.lua" },
--- target = { orgdir, "framework/scripts" }
--- },
--- {
--- origin = { devdir, "framework/scripts/buildtool/*"},
--- target = { orgdir, "framework/scripts/buildtool" },
--- },
--- {
--- origin = { devdir, "framework/m4all*" },
--- target = { orgdir, "framework" },
--- },
--- {
--- origin = { devdir, "framework/configurations/*m4all*"},
--- target = { orgdir, "framework/configurations" },
--- },
--- {
--- recurse = true,
--- origin = { devdir, "context/tex/texmf-project/tex/context/user/m4all/*" },
--- target = { orgdir, "context/tex/texmf-project/tex/context/user/m4all" },
--- },
--- }
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-rsync</entry>
- <entry name="detail">Rsync Helpers</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="job"><short>use given file as specification</short></flag>
- <flag name="dryrun"><short>show what would happen</short></flag>
- <flag name="force"><short>force run</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-rsync",
- banner = "Rsync Helpers 0.10",
- helpinfo = helpinfo,
-}
-
-local format, gsub = string.format, string.gsub
-local concat = table.concat
-
-local report_message = logs.new("rsync message")
-local report_dryrun = logs.new("rsync dryrun")
-local report_normal = logs.new("rsync normal")
-local report_command = logs.new("rsync command")
-
-local cleanup
-
-if os.platform == "mswin" then
- os.setenv("CYGWIN","nontsec")
- cleanup = function(name)
- return (gsub(name,"([a-zA-Z]):/", "/cygdrive/%1/"))
- end
-else
- cleanup = function(name)
- return name
- end
-end
-
-function rsynccommand(dryrun,recurse,origin,target)
- local command = "rsync -ptlva "
- if dryrun then
- command = command .. "-n "
- end
- if recurse then
- command = command .. "-r "
- end
- return format('%s %s %s',command,origin,target)
-end
-
-scripts = scripts or { }
-scripts.rsync = scripts.rsync or { }
-local rsync = scripts.rsync
-
-rsync.mode = "command"
-
-function rsync.run(origin,target,message,recurse)
- if type(origin) == "table" then
- origin = concat(origin,"/")
- end
- if type(target) == "table" then
- target = concat(target,"/")
- end
- origin = cleanup(origin)
- target = cleanup(target)
- local path = gsub(target,"^/cygdrive/(.)","%1:")
- if not lfs.isdir(path) then
- report_message("creating target dir %s",path)
- dir.makedirs(path) -- as rsync only creates them when --recursive
- end
- if message then
- report_message(message)
- end
- if rsync.mode == "dryrun" then
- local command = rsynccommand(true,recurse,origin,target)
- report_dryrun(command.."\n")
- os.execute(command)
- elseif rsync.mode == "force" then
- local command = rsynccommand(false,recurse,origin,target)
- report_normal(command.."\n")
- os.execute(command)
- else
- local command = rsynccommand(true,recurse,origin,target)
- report_command(command)
- end
-end
-
-function rsync.job(list)
- if type(list) == "string" and lfs.isfile(list) then
- list = dofile(list)
- end
- if type(list) ~= "table" then
- report_message("invalid job specification")
- return
- end
- for i=1,#list do
- local li = list[i]
- local origin = li.origin
- local target = li.target
- local message = li.message
- local recurse = li.recurse
- if origin and #origin > 0 and target and #target > 0 then -- string or table
- rsync.run(origin,target,message,recurse)
- else
- report_message("invalid job specification at index %s",i)
- end
- end
-end
-
-if environment.ownscript then
- -- stand alone
-else
- report(application.banner)
- return rsync
-end
-
-local arguments = environment.arguments
-local files = environment.files
-
-if arguments.dryrun then
- rsync.mode = "dryrun"
-elseif arguments.force then
- rsync.mode = "force"
-end
-
-if arguments.exporthelp then
- application.export(arguments.exporthelp,environment.files[1])
-elseif arguments.job then
- rsync.job(files[1])
-elseif files[1] and files[2] then
- rsync.run(files[1],files[2])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-rsync'] = {
+ version = 1.000,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is an experimental script that will be extended over time and
+-- is used by myself. An example or a copy spec:
+--
+--
+-- local devdir = "m:/develop/services"
+-- local orgdir = "m:/pod/m4all"
+--
+-- return {
+-- {
+-- origin = { devdir, "framework/scripts/d-dispatchers.lua"},
+-- target = { orgdir, "framework/scripts" },
+-- },
+-- {
+-- origin = { devdir, "framework/scripts/common/*"},
+-- target = { orgdir, "framework/scripts/common" },
+-- },
+-- {
+-- origin = { devdir, "framework/scripts/d-buildtool.lua" },
+-- target = { orgdir, "framework/scripts" }
+-- },
+-- {
+-- origin = { devdir, "framework/scripts/buildtool/*"},
+-- target = { orgdir, "framework/scripts/buildtool" },
+-- },
+-- {
+-- origin = { devdir, "framework/m4all*" },
+-- target = { orgdir, "framework" },
+-- },
+-- {
+-- origin = { devdir, "framework/configurations/*m4all*"},
+-- target = { orgdir, "framework/configurations" },
+-- },
+-- {
+-- recurse = true,
+-- origin = { devdir, "context/tex/texmf-project/tex/context/user/m4all/*" },
+-- target = { orgdir, "context/tex/texmf-project/tex/context/user/m4all" },
+-- },
+-- }
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-rsync</entry>
+ <entry name="detail">Rsync Helpers</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="job"><short>use given file as specification</short></flag>
+ <flag name="dryrun"><short>show what would happen</short></flag>
+ <flag name="force"><short>force run</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-rsync",
+ banner = "Rsync Helpers 0.10",
+ helpinfo = helpinfo,
+}
+
+local format, gsub = string.format, string.gsub
+local concat = table.concat
+
+local report_message = logs.new("rsync message")
+local report_dryrun = logs.new("rsync dryrun")
+local report_normal = logs.new("rsync normal")
+local report_command = logs.new("rsync command")
+
+local cleanup
+
+if os.platform == "mswin" then
+ os.setenv("CYGWIN","nontsec")
+ cleanup = function(name)
+ return (gsub(name,"([a-zA-Z]):/", "/cygdrive/%1/"))
+ end
+else
+ cleanup = function(name)
+ return name
+ end
+end
+
+function rsynccommand(dryrun,recurse,origin,target)
+ local command = "rsync -ptlva "
+ if dryrun then
+ command = command .. "-n "
+ end
+ if recurse then
+ command = command .. "-r "
+ end
+ return format('%s %s %s',command,origin,target)
+end
+
+scripts = scripts or { }
+scripts.rsync = scripts.rsync or { }
+local rsync = scripts.rsync
+
+rsync.mode = "command"
+
+function rsync.run(origin,target,message,recurse)
+ if type(origin) == "table" then
+ origin = concat(origin,"/")
+ end
+ if type(target) == "table" then
+ target = concat(target,"/")
+ end
+ origin = cleanup(origin)
+ target = cleanup(target)
+ local path = gsub(target,"^/cygdrive/(.)","%1:")
+ if not lfs.isdir(path) then
+ report_message("creating target dir %s",path)
+ dir.makedirs(path) -- as rsync only creates them when --recursive
+ end
+ if message then
+ report_message(message)
+ end
+ if rsync.mode == "dryrun" then
+ local command = rsynccommand(true,recurse,origin,target)
+ report_dryrun(command.."\n")
+ os.execute(command)
+ elseif rsync.mode == "force" then
+ local command = rsynccommand(false,recurse,origin,target)
+ report_normal(command.."\n")
+ os.execute(command)
+ else
+ local command = rsynccommand(true,recurse,origin,target)
+ report_command(command)
+ end
+end
+
+function rsync.job(list)
+ if type(list) == "string" and lfs.isfile(list) then
+ list = dofile(list)
+ end
+ if type(list) ~= "table" then
+ report_message("invalid job specification")
+ return
+ end
+ for i=1,#list do
+ local li = list[i]
+ local origin = li.origin
+ local target = li.target
+ local message = li.message
+ local recurse = li.recurse
+ if origin and #origin > 0 and target and #target > 0 then -- string or table
+ rsync.run(origin,target,message,recurse)
+ else
+ report_message("invalid job specification at index %s",i)
+ end
+ end
+end
+
+if environment.ownscript then
+ -- stand alone
+else
+ report(application.banner)
+ return rsync
+end
+
+local arguments = environment.arguments
+local files = environment.files
+
+if arguments.dryrun then
+ rsync.mode = "dryrun"
+elseif arguments.force then
+ rsync.mode = "force"
+end
+
+if arguments.exporthelp then
+ application.export(arguments.exporthelp,environment.files[1])
+elseif arguments.job then
+ rsync.job(files[1])
+elseif files[1] and files[2] then
+ rsync.run(files[1],files[2])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-scite.lua b/scripts/context/lua/mtx-scite.lua
index 47aa3d009..972edbfe6 100644
--- a/scripts/context/lua/mtx-scite.lua
+++ b/scripts/context/lua/mtx-scite.lua
@@ -1,259 +1,259 @@
-if not modules then modules = { } end modules ['mtx-scite'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local P, R, S, C, Ct, Cf, Cc, Cg = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cf, lpeg.Cc, lpeg.Cg
-local lpegmatch = lpeg.match
-local format, lower, gmatch = string.format, string.lower, string.gmatch
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-scite</entry>
- <entry name="detail">Scite Helper Script</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="words"><short>convert spell-*.txt into spell-*.lua</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-scite",
- banner = "Scite Helper Script 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.scite = scripts.scite or { }
-
--- todo: append to global properties else order of loading problem
--- linux problem ... files are under root protection so we need --install
---
--- local scitesignals = { "scite-context.rme", "context.properties" }
--- local screenfont = "lmtypewriter10-regular.ttf"
-
--- function scripts.scite.start(indeed)
--- local usedsignal, datapath, fullname, workname, userpath, fontpath
--- if os.type == "windows" then
--- workname = "scite.exe"
--- userpath = os.getenv("USERPROFILE") or ""
--- fontpath = os.getenv("SYSTEMROOT")
--- fontpath = (fontpath and file.join(fontpath,"fonts")) or ""
--- else
--- workname = "scite"
--- userpath = os.getenv("HOME") or ""
--- fontpath = ""
--- end
--- local binpaths = file.split_path(os.getenv("PATH")) or file.split_path(os.getenv("path"))
--- for i=1,#scitesignals do
--- local scitesignal = scitesignals[i]
--- local scitepath = resolvers.findfile(scitesignal,"other text files") or ""
--- if scitepath ~= "" then
--- scitepath = file.dirname(scitepath) -- data
--- if scitepath == "" then
--- scitepath = resolvers.cleanpath(lfs.currentdir())
--- else
--- usedsignal, datapath = scitesignal, scitepath
--- break
--- end
--- end
--- end
--- if not datapath or datapath == "" then
--- report("invalid datapath, maybe you need to regenerate the file database")
--- return false
--- end
--- if not binpaths or #binpaths == 0 then
--- report("invalid binpath")
--- return false
--- end
--- for i=1,#binpaths do
--- local p = file.join(binpaths[i],workname)
--- if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub
--- fullname = p
--- break
--- end
--- end
--- if not fullname then
--- report("unable to locate %s",workname)
--- return false
--- end
--- local properties = dir.glob(file.join(datapath,"*.properties"))
--- local luafiles = dir.glob(file.join(datapath,"*.lua"))
--- local extrafont = resolvers.findfile(screenfont,"truetype font") or ""
--- local pragmafound = dir.glob(file.join(datapath,"pragma.properties"))
--- if userpath == "" then
--- report("unable to figure out userpath")
--- return false
--- end
--- local verbose = environment.argument("verbose")
--- local tobecopied, logdata = { }, { }
--- local function check_state(fullname,newpath)
--- local basename = file.basename(fullname)
--- local destination = file.join(newpath,basename)
--- local pa, da = lfs.attributes(fullname), lfs.attributes(destination)
--- if not da then
--- logdata[#logdata+1] = { "new : %s", basename }
--- tobecopied[#tobecopied+1] = { fullname, destination }
--- elseif pa.modification > da.modification then
--- logdata[#logdata+1] = { "outdated : %s", basename }
--- tobecopied[#tobecopied+1] = { fullname, destination }
--- else
--- logdata[#logdata+1] = { "up to date : %s", basename }
--- end
--- end
--- for i=1,#properties do
--- check_state(properties[i],userpath)
--- end
--- for i=1,#luafiles do
--- check_state(luafiles[i],userpath)
--- end
--- if fontpath ~= "" then
--- check_state(extrafont,fontpath)
--- end
--- local userpropfile = "SciTEUser.properties"
--- if os.name ~= "windows" then
--- userpropfile = "." .. userpropfile
--- end
--- local fullpropfile = file.join(userpath,userpropfile)
--- local userpropdata = io.loaddata(fullpropfile) or ""
--- local propfiledone = false
--- if pragmafound then
--- if userpropdata == "" then
--- logdata[#logdata+1] = { "error : no user properties found on '%s'", fullpropfile }
--- elseif string.find(userpropdata,"import *pragma") then
--- logdata[#logdata+1] = { "up to date : 'import pragma' in '%s'", userpropfile }
--- else
--- logdata[#logdata+1] = { "yet unset : 'import pragma' in '%s'", userpropfile }
--- userproperties = userpropdata .. "\n\nimport pragma\n\n"
--- propfiledone = true
--- end
--- else
--- if string.find(userpropdata,"import *context") then
--- logdata[#logdata+1] = { "up to date : 'import context' in '%s'", userpropfile }
--- else
--- logdata[#logdata+1] = { "yet unset : 'import context' in '%s'", userpropfile }
--- userproperties = userpropdata .. "\n\nimport context\n\n"
--- propfiledone = true
--- end
--- end
--- if not indeed or verbose then
--- report("used signal: %s", usedsignal)
--- report("data path : %s", datapath)
--- report("full name : %s", fullname)
--- report("user path : %s", userpath)
--- report("extra font : %s", extrafont)
--- end
--- if #logdata > 0 then
--- report("")
--- for k=1,#logdata do
--- local v = logdata[k]
--- report(v[1],v[2])
--- end
--- end
--- if indeed then
--- if #tobecopied > 0 then
--- report("warning : copying updated files")
--- for i=1,#tobecopied do
--- local what = tobecopied[i]
--- report("copying : '%s' => '%s'",what[1],what[2])
--- file.copy(what[1],what[2])
--- end
--- end
--- if propfiledone then
--- report("saving : '%s'",userpropfile)
--- io.savedata(fullpropfile,userpropdata)
--- end
--- os.launch(fullname)
--- end
--- end
-
--- local splitter = (Cf(Ct("") * (Cg(C(R("az","AZ","\127\255")^1) * Cc(true)) + P(1))^1,rawset) )^0
---
--- local function splitwords(words)
--- return lpegmatch(splitter,words) -- or just split and tohash
--- end
-
-local function splitwords(words)
- local w = { }
- for s in string.gmatch(words,"[a-zA-Z\127-255]+") do
- if #s > 2 then -- will become option
- w[lower(s)] = s
- end
- end
- return w
-end
-
--- maybe: lowerkey = UpperWhatever
-
-function scripts.scite.words()
- for i=1,#environment.files do
- local tag = environment.files[i]
- local tag = string.match(tag,"spell%-(..)%.") or tag
- local txtname = format("spell-%s.txt",tag)
- local luaname = format("spell-%s.lua",tag)
- local lucname = format("spell-%s.luc",tag)
- if lfs.isfile(txtname) then
- report("loading %s",txtname)
- local olddata = io.loaddata(txtname) or ""
- local words = splitwords(olddata)
- local min, max, n = 100, 1, 0
- for k, v in next, words do
- local l = #k
- if l < min then
- min = l
- end
- if l > max then
- max = l
- end
- n = n + 1
- end
- if min > max then
- min = max
- end
- local newdata = {
- words = words,
- source = oldname,
- min = min,
- max = max,
- n = n,
- }
- report("saving %q, %s words, %s shortest, %s longest",luaname,n,min,max)
- io.savedata(luaname,table.serialize(newdata,true))
- report("compiling %q",lucname)
- os.execute(format("luac -s -o %s %s",lucname,luaname))
- else
- report("no data file %s",txtname)
- end
- end
- report("you need to move the lua files to lexers/data")
-end
-
--- if environment.argument("start") then
--- scripts.scite.start(true)
--- elseif environment.argument("test") then
--- scripts.scite.start()
--- else
--- application.help()
--- end
-
-if environment.argument("words") then
- scripts.scite.words()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
-
+if not modules then modules = { } end modules ['mtx-scite'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local P, R, S, C, Ct, Cf, Cc, Cg = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cf, lpeg.Cc, lpeg.Cg
+local lpegmatch = lpeg.match
+local format, lower, gmatch = string.format, string.lower, string.gmatch
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-scite</entry>
+ <entry name="detail">Scite Helper Script</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="words"><short>convert spell-*.txt into spell-*.lua</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-scite",
+ banner = "Scite Helper Script 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.scite = scripts.scite or { }
+
+-- todo: append to global properties else order of loading problem
+-- linux problem ... files are under root protection so we need --install
+--
+-- local scitesignals = { "scite-context.rme", "context.properties" }
+-- local screenfont = "lmtypewriter10-regular.ttf"
+
+-- function scripts.scite.start(indeed)
+-- local usedsignal, datapath, fullname, workname, userpath, fontpath
+-- if os.type == "windows" then
+-- workname = "scite.exe"
+-- userpath = os.getenv("USERPROFILE") or ""
+-- fontpath = os.getenv("SYSTEMROOT")
+-- fontpath = (fontpath and file.join(fontpath,"fonts")) or ""
+-- else
+-- workname = "scite"
+-- userpath = os.getenv("HOME") or ""
+-- fontpath = ""
+-- end
+-- local binpaths = file.split_path(os.getenv("PATH")) or file.split_path(os.getenv("path"))
+-- for i=1,#scitesignals do
+-- local scitesignal = scitesignals[i]
+-- local scitepath = resolvers.findfile(scitesignal,"other text files") or ""
+-- if scitepath ~= "" then
+-- scitepath = file.dirname(scitepath) -- data
+-- if scitepath == "" then
+-- scitepath = resolvers.cleanpath(lfs.currentdir())
+-- else
+-- usedsignal, datapath = scitesignal, scitepath
+-- break
+-- end
+-- end
+-- end
+-- if not datapath or datapath == "" then
+-- report("invalid datapath, maybe you need to regenerate the file database")
+-- return false
+-- end
+-- if not binpaths or #binpaths == 0 then
+-- report("invalid binpath")
+-- return false
+-- end
+-- for i=1,#binpaths do
+-- local p = file.join(binpaths[i],workname)
+-- if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub
+-- fullname = p
+-- break
+-- end
+-- end
+-- if not fullname then
+-- report("unable to locate %s",workname)
+-- return false
+-- end
+-- local properties = dir.glob(file.join(datapath,"*.properties"))
+-- local luafiles = dir.glob(file.join(datapath,"*.lua"))
+-- local extrafont = resolvers.findfile(screenfont,"truetype font") or ""
+-- local pragmafound = dir.glob(file.join(datapath,"pragma.properties"))
+-- if userpath == "" then
+-- report("unable to figure out userpath")
+-- return false
+-- end
+-- local verbose = environment.argument("verbose")
+-- local tobecopied, logdata = { }, { }
+-- local function check_state(fullname,newpath)
+-- local basename = file.basename(fullname)
+-- local destination = file.join(newpath,basename)
+-- local pa, da = lfs.attributes(fullname), lfs.attributes(destination)
+-- if not da then
+-- logdata[#logdata+1] = { "new : %s", basename }
+-- tobecopied[#tobecopied+1] = { fullname, destination }
+-- elseif pa.modification > da.modification then
+-- logdata[#logdata+1] = { "outdated : %s", basename }
+-- tobecopied[#tobecopied+1] = { fullname, destination }
+-- else
+-- logdata[#logdata+1] = { "up to date : %s", basename }
+-- end
+-- end
+-- for i=1,#properties do
+-- check_state(properties[i],userpath)
+-- end
+-- for i=1,#luafiles do
+-- check_state(luafiles[i],userpath)
+-- end
+-- if fontpath ~= "" then
+-- check_state(extrafont,fontpath)
+-- end
+-- local userpropfile = "SciTEUser.properties"
+-- if os.name ~= "windows" then
+-- userpropfile = "." .. userpropfile
+-- end
+-- local fullpropfile = file.join(userpath,userpropfile)
+-- local userpropdata = io.loaddata(fullpropfile) or ""
+-- local propfiledone = false
+-- if pragmafound then
+-- if userpropdata == "" then
+-- logdata[#logdata+1] = { "error : no user properties found on '%s'", fullpropfile }
+-- elseif string.find(userpropdata,"import *pragma") then
+-- logdata[#logdata+1] = { "up to date : 'import pragma' in '%s'", userpropfile }
+-- else
+-- logdata[#logdata+1] = { "yet unset : 'import pragma' in '%s'", userpropfile }
+-- userproperties = userpropdata .. "\n\nimport pragma\n\n"
+-- propfiledone = true
+-- end
+-- else
+-- if string.find(userpropdata,"import *context") then
+-- logdata[#logdata+1] = { "up to date : 'import context' in '%s'", userpropfile }
+-- else
+-- logdata[#logdata+1] = { "yet unset : 'import context' in '%s'", userpropfile }
+-- userproperties = userpropdata .. "\n\nimport context\n\n"
+-- propfiledone = true
+-- end
+-- end
+-- if not indeed or verbose then
+-- report("used signal: %s", usedsignal)
+-- report("data path : %s", datapath)
+-- report("full name : %s", fullname)
+-- report("user path : %s", userpath)
+-- report("extra font : %s", extrafont)
+-- end
+-- if #logdata > 0 then
+-- report("")
+-- for k=1,#logdata do
+-- local v = logdata[k]
+-- report(v[1],v[2])
+-- end
+-- end
+-- if indeed then
+-- if #tobecopied > 0 then
+-- report("warning : copying updated files")
+-- for i=1,#tobecopied do
+-- local what = tobecopied[i]
+-- report("copying : '%s' => '%s'",what[1],what[2])
+-- file.copy(what[1],what[2])
+-- end
+-- end
+-- if propfiledone then
+-- report("saving : '%s'",userpropfile)
+-- io.savedata(fullpropfile,userpropdata)
+-- end
+-- os.launch(fullname)
+-- end
+-- end
+
+-- local splitter = (Cf(Ct("") * (Cg(C(R("az","AZ","\127\255")^1) * Cc(true)) + P(1))^1,rawset) )^0
+--
+-- local function splitwords(words)
+-- return lpegmatch(splitter,words) -- or just split and tohash
+-- end
+
+local function splitwords(words)
+ local w = { }
+ for s in string.gmatch(words,"[a-zA-Z\127-255]+") do
+ if #s > 2 then -- will become option
+ w[lower(s)] = s
+ end
+ end
+ return w
+end
+
+-- maybe: lowerkey = UpperWhatever
+
+function scripts.scite.words()
+ for i=1,#environment.files do
+ local tag = environment.files[i]
+ local tag = string.match(tag,"spell%-(..)%.") or tag
+ local txtname = format("spell-%s.txt",tag)
+ local luaname = format("spell-%s.lua",tag)
+ local lucname = format("spell-%s.luc",tag)
+ if lfs.isfile(txtname) then
+ report("loading %s",txtname)
+ local olddata = io.loaddata(txtname) or ""
+ local words = splitwords(olddata)
+ local min, max, n = 100, 1, 0
+ for k, v in next, words do
+ local l = #k
+ if l < min then
+ min = l
+ end
+ if l > max then
+ max = l
+ end
+ n = n + 1
+ end
+ if min > max then
+ min = max
+ end
+ local newdata = {
+ words = words,
+ source = oldname,
+ min = min,
+ max = max,
+ n = n,
+ }
+ report("saving %q, %s words, %s shortest, %s longest",luaname,n,min,max)
+ io.savedata(luaname,table.serialize(newdata,true))
+ report("compiling %q",lucname)
+ os.execute(format("luac -s -o %s %s",lucname,luaname))
+ else
+ report("no data file %s",txtname)
+ end
+ end
+ report("you need to move the lua files to lexers/data")
+end
+
+-- if environment.argument("start") then
+-- scripts.scite.start(true)
+-- elseif environment.argument("test") then
+-- scripts.scite.start()
+-- else
+-- application.help()
+-- end
+
+if environment.argument("words") then
+ scripts.scite.words()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
+
diff --git a/scripts/context/lua/mtx-server-ctx-fonttest.lua b/scripts/context/lua/mtx-server-ctx-fonttest.lua
index cbfc91559..a8d7edf41 100644
--- a/scripts/context/lua/mtx-server-ctx-fonttest.lua
+++ b/scripts/context/lua/mtx-server-ctx-fonttest.lua
@@ -1,749 +1,749 @@
-if not modules then modules = { } end modules ['mtx-server-ctx-fonttest'] = {
- version = 1.001,
- comment = "Font Feature Tester",
- author = "Hans Hagen",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- probably too much but who cares
-
-dofile(resolvers.findfile("trac-lmx.lua","tex"))
-dofile(resolvers.findfile("font-ini.lua","tex"))
-dofile(resolvers.findfile("font-con.lua","tex"))
-dofile(resolvers.findfile("font-oti.lua","tex"))
-dofile(resolvers.findfile("font-otf.lua","tex"))
-dofile(resolvers.findfile("font-otp.lua","tex"))
-dofile(resolvers.findfile("font-ott.lua","tex"))
-dofile(resolvers.findfile("font-syn.lua","tex"))
-dofile(resolvers.findfile("font-mis.lua","tex"))
-
-local format, gsub, concat, match, find = string.format, string.gsub, table.concat, string.match, string.find
-
-local report = logs.reporter("ctx-fonttest")
-
-local sample_line = "This is a sample line!"
-local tempname = "mtx-server-ctx-fonttest-temp"
-local temppath = caches.setfirstwritablefile("temp","mtx-server-ctx-fonttest")
-local basename = "mtx-server-ctx-fonttest-data.lua"
-local basepath = temppath
-
-local remove_suffixes = { "tex", "pdf", "log" }
-local what_options = { "trace", "basemode" }
-
-for i=1,#remove_suffixes do
- os.remove(file.join(temppath,file.addsuffix(tempname,remove_suffixes[i])))
-end
-
-local process_templates = { }
-
-process_templates.default = [[
-\starttext
- \setupdirections[bidi=global]
- \definefontfeature[sample][analyze=yes,%s]
- \definedfont[name:%s*sample]
- \startTEXpage[offset=3pt]
- \detokenize{%s}
- \stopTEXpage
-\stoptext
-]]
-
-process_templates.cache = [[
-\starttext
- \definedfont[name:%s]
- \startTEXpage[offset=3pt]
- cached: \detokenize{%s}
- \stopTEXpage
-\stoptext
-]]
-
-process_templates.trace = [[
-\usemodule[fnt-20]
-
-\definefontfeature[sample][%s]
-
-\setupcolors[state=start]
-
-\setupdirections[bidi=global]
-
-\setvariables
- [otftracker]
- [title=Test Run,
- font=name:%s,
- direction=0,
- features=sample,
- sample={‍\detokenize{%s}}]
-]]
-
-local javascripts = [[
-function selected_radio(name) {
- var form = document.forms["main-form"] ;
- var script = form.elements[name] ;
- if (script) {
- var n = script.length ;
- if (n) {
- for (var i=0; i<n; i++) {
- if (script[i].checked) {
- return script[i].value ;
- }
- }
- }
- }
- return "" ;
-}
-
-function reset_valid() {
- var fields = document.getElementsByTagName("span") ;
- for (var i=0; i<fields.length; i++) {
- var e = fields[i]
- if (e) {
- if (e.className == "valid") {
- e.className = "" ;
- }
- }
- }
-}
-
-function set_valid() {
- var script = selected_radio("script") ;
- var language = selected_radio("language") ;
- if (script && language) {
- var s = feature_hash[script] ;
- if (s) {
- for (l in s) {
- var e = document.getElementById("t-l-" + l) ;
- if (e) {
- e.className = "valid" ;
- }
- }
- var l = s[language] ;
- if (l) {
- for (i in l) {
- var e = document.getElementById("t-f-" + i) ;
- if (e) {
- e.className = "valid" ;
- }
- }
- }
- var e = document.getElementById("t-s-" + script) ;
- if (e) {
- e.className = "valid" ;
- }
- }
- }
-}
-
-function check_form() {
- reset_valid() ;
- set_valid() ;
-}
-
-function check_script() {
- reset_valid() ;
- set_valid() ;
-}
-
-function check_language() {
- reset_valid() ;
- set_valid() ;
-}
-
-function check_feature() {
- // not needed
-}
-]]
-
-local cache = { }
-
-local function showfeatures(f)
- if f then
- report("processing font '%s'",f)
- local features = cache[f]
- if features == nil then
- features = fonts.helpers.getfeatures(resolvers.findfile(f))
- if not features then
- report("building cache for '%s'",f)
- io.savedata(file.join(temppath,file.addsuffix(tempname,"tex")),format(process_templates.cache,f,f))
- os.execute(format("mtxrun --path=%s --script context --once --batchmode %s",temppath,tempname))
- features = fonts.helpers.getfeatures(f)
- end
- cache[f] = features or false
- report("caching info of '%s'",f)
- else
- report("using cached info of '%s'",f)
- end
- if features then
- local scr, lan, fea, rev = { }, { }, { }, { }
- local function show(what)
- local data = features[what]
- if data and next(data) then
- for f,ff in next, data do
- if find(f,"<") then
- -- ignore aat for the moment
- else
- fea[f] = true
- for s, ss in next, ff do
- if find(s,"%*") then
- -- ignore *
- else
- scr[s] = true
- local rs = rev[s] if not rs then rs = {} rev[s] = rs end
- for k, l in next, ss do
- if find(k,"%*") then
- -- ignore *
- else
- lan[k] = true
- local rsk = rs[k] if not rsk then rsk = { } rs[k] = rsk end
- rsk[f] = true
- end
- end
- end
- end
- end
- end
- end
- end
- for what, v in table.sortedhash(features) do
- show(what)
- end
- local stupid = { }
- stupid[#stupid+1] = "var feature_hash = new Array ;"
- for s, sr in next, rev do
- stupid[#stupid+1] = format("feature_hash['%s'] = new Array ;",s)
- for l, lr in next, sr do
- stupid[#stupid+1] = format("feature_hash['%s']['%s'] = new Array ;",s,l)
- for f, fr in next, lr do
- stupid[#stupid+1] = format("feature_hash['%s']['%s']['%s'] = true ;",s,l,f)
- end
- end
- end
- -- gpos feature script languages
- return {
- scripts = scr,
- languages = lan,
- features = fea,
- javascript = concat(stupid,"\n")
- }
- end
- end
-end
-
-local template_h = [[
-<tr>
- <th>safe name&nbsp;&nbsp;&nbsp;&nbsp;</th>
- <th>family name&nbsp;&nbsp;&nbsp;&nbsp;</th>
- <th>style-variant-weight-width&nbsp;&nbsp;&nbsp;&nbsp;</th>
- <th>font name&nbsp;&nbsp;&nbsp;&nbsp;</th>
- <th>weight&nbsp;&nbsp;&nbsp;&nbsp;</th>
- <th>filename</th>
-</tr>]]
-
-local template_d = [[
-<tr>
- <td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a>&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td>%s-%s-%s-%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td>%s</td>
-</tr>]]
-
-local function select_font()
- local t = fonts.names.list(".*",false,true)
- if t then
- local listoffonts = { }
- listoffonts[#listoffonts+1] = "<table>"
- listoffonts[#listoffonts+1] = template_h
- for k, v in table.sortedhash(t) do
- local kind = v.format
- if kind == "otf" or kind == "ttf" or kind == "ttc" then
- local fontname = v.fontname
- listoffonts[#listoffonts+1] = format(template_d, fontname, fontname,
- v.familyname or "",
- t.variant or "normal",
- t.weight or "normal",
- t.width or "normal",
- t.style or "normal",
- v.rawname or fontname,
- v.fontweight or "",
- v.filename or ""
- )
- end
- end
- listoffonts[#listoffonts+1] = "</table>"
- return concat(listoffonts,"\n")
- end
- return "<b>no fonts</b>"
-end
-
-local edit_template = [[
- <textarea name='sampletext' rows='5' cols='100'>%s</textarea>
- <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/>
- <br/> <br/>scripts:&nbsp;%s
- <br/> <br/>languages:&nbsp;%s
- <br/> <br/>features:&nbsp;%s
- <br/> <br/>options:&nbsp;%s
-]]
-
--- <embed src="%s#toolbar=0&amp;navpanes=0&amp;scrollbar=0" width="100%%"/>
-
-local result_template = [[
- <br/> <br/>
- <embed src="%s#view=Fit&amp;toolbar=0&amp;navpanes=0&amp;scrollbar=0" width="100%%"/>
- <br/> <br/> results:
- <a href='%s' target="source">tex file</a>
- <a href='%s' target="result">pdf file</a>
- <br/> <br/>
-]]
-
-scripts.webserver.registerpath(temppath)
-
-local function get_specification(name)
- return fonts.names.resolvedspecification(name or "")
-end
-
-local function edit_font(currentfont,detail,tempname)
- report("entering edit mode for '%s'",currentfont)
- local specification = get_specification(currentfont)
- if specification then
- local htmldata = showfeatures(specification.filename)
- if htmldata then
- local features, languages, scripts, options = { }, { }, { }, { }
- local sorted = table.sortedkeys(htmldata.scripts)
- for k=1,#sorted do
- local v = sorted[k]
- local s = fonts.handlers.otf.tables.scripts[v] or v
- if detail and v == detail.script then
- scripts[#scripts+1] = format("<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)
- else
- scripts[#scripts+1] = format("<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)
- end
- end
- local sorted = table.sortedkeys(htmldata.languages)
- for k=1,#sorted do
- local v = sorted[k]
- local l = fonts.handlers.otf.tables.languages[v] or v
- if detail and v == detail.language then
- languages[#languages+1] = format("<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)
- else
- languages[#languages+1] = format("<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)
- end
- end
- local sorted = table.sortedkeys(htmldata.features)
- for k=1,#sorted do
- local v = sorted[k]
- local f = fonts.handlers.otf.tables.features[v] or v
- if detail and detail["f-"..v] then
- features[#features+1] = format("<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)
- else
- features[#features+1] = format("<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)
- end
- end
- for k=1,#what_options do
- local v = what_options[k]
- if detail and detail["o-"..v] then
- options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/>&nbsp;%s",v,v,v)
- else
- options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s'/>&nbsp;%s",v,v,v)
- end
- end
- local e = format(edit_template,
- (detail and detail.sampletext) or sample_line,(detail and detail.name) or "no name",(detail and detail.title) or "",
- concat(scripts," "),concat(languages," "),concat(features," "),concat(options," "))
- if tempname then
- local pdffile, texfile = file.addsuffix(tempname,"pdf"), file.addsuffix(tempname,"tex")
- local r = format(result_template,pdffile,texfile,pdffile)
- return e .. r, htmldata.javascript or ""
- else
- return e, htmldata.javascript or ""
- end
- else
- return "error, nothing set up yet"
- end
- else
- return "error, no info about font"
- end
-end
-
-local function process_font(currentfont,detail) -- maybe just fontname
- local features = {
- "mode=node",
- format("language=%s",detail.language or "dflt"),
- format("script=%s",detail.script or "dflt"),
- }
- for k,v in next, detail do
- local f = match(k,"^f%-(.*)$")
- if f then
- features[#features+1] = format("%s=yes",f)
- end
- end
- local variant = process_templates.default
- if detail["o-trace"] then
- variant = process_templates.trace
- end
- local sample = string.strip(detail.sampletext or "")
- if sample == "" then sample = sample_line end
- report("sample text: %s",sample)
- dir.mkdirs(temppath)
- local fullname = file.join(temppath,file.addsuffix(tempname,"tex"))
- local data = format(variant,concat(features,","),currentfont,sample)
- local command = format("mtxrun --path=%q --script context --once --batchmode %q",temppath,tempname)
- report("filename: %s",fullname)
- report("command: %s",command)
- io.savedata(fullname,data)
- os.execute(command)
- return edit_font(currentfont,detail,tempname)
-end
-
-local tex_template = [[
-<pre><tt>
-%s
-</tt></pre>
-]]
-
-local function show_source(currentfont,detail)
- if tempname and tempname ~= "" then
- local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,"tex"))) or "no source yet"
- return format(tex_template,data)
- else
- return "no source file"
- end
-end
-
-local function show_log(currentfont,detail)
- if tempname and tempname ~= "" then
- local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,'log'))) or "no log file yet"
- data = gsub(data,"[%s%%]*begin of optionfile.-end of optionfile[%s%%]*","\n")
- return format(tex_template,data)
- else
- return "no log file"
- end
-end
-
-local function show_font(currentfont,detail)
- local specification = get_specification(currentfont)
- local features = fonts.helpers.getfeatures(specification.filename)
- local result = { }
- result[#result+1] = format("<h1>names</h1>",what)
- result[#result+1] = "<table>"
- result[#result+1] = format("<tr><td class='tc'>fontname: </td><td>%s</td></tr>",currentfont)
- result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fontname or "-")
- result[#result+1] = format("<tr><td class='tc'>filename: </td><td>%s</td></tr>",specification.fontfile or "-")
- result[#result+1] = format("<tr><td class='tc'>familyname: </td><td>%s</td></tr>",specification.familyname or "-")
- result[#result+1] = format("<tr><td class='tc'>fontweight: </td><td>%s</td></tr>",specification.fontweight or "-")
- result[#result+1] = format("<tr><td class='tc'>format: </td><td>%s</td></tr>",specification.format or "-")
- result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fullname or "-")
- result[#result+1] = format("<tr><td class='tc'>subfamily: </td><td>%s</td></tr>",specification.subfamily or "-")
- result[#result+1] = format("<tr><td class='tc'>rawname: </td><td>%s</td></tr>",specification.rawname or "-")
- result[#result+1] = format("<tr><td class='tc'>designsize: </td><td>%s</td></tr>",specification.designsize or "-")
- result[#result+1] = format("<tr><td class='tc'>minimumsize:</td><td>%s</td></tr>",specification.minsize or "-")
- result[#result+1] = format("<tr><td class='tc'>maximumsize:</td><td>%s</td></tr>",specification.maxsize or "-")
- result[#result+1] = format("<tr><td class='tc'>style: </td><td>%s</td></tr>",specification.style ~= "" and specification.style or "normal")
- result[#result+1] = format("<tr><td class='tc'>variant: </td><td>%s</td></tr>",specification.variant ~= "" and specification.variant or "normal")
- result[#result+1] = format("<tr><td class='tc'>weight: </td><td>%s</td></tr>",specification.weight ~= "" and specification.weight or "normal")
- result[#result+1] = format("<tr><td class='tc'>width: </td><td>%s</td></tr>",specification.width ~= "" and specification.width or "normal")
- result[#result+1] = "</table>"
- if features then
- for what, v in table.sortedhash(features) do
- local data = features[what]
- if data and next(data) then
- result[#result+1] = format("<h1>%s features</h1>",what)
- result[#result+1] = "<table>"
- result[#result+1] = "<tr><th>feature</th><th>tag&nbsp;</th><th>script&nbsp;</th><th>languages&nbsp;</th></tr>"
- for f,ff in table.sortedhash(data) do
- local done = false
- for s, ss in table.sortedhash(ff) do
- if s == "*" then s = "all" end
- if ss ["*"] then ss["*"] = nil ss.all = true end
- if done then
- f = ""
- else
- done = true
- end
- local title = fonts.handlers.otf.tables.features[f] or ""
- result[#result+1] = format("<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)," "))
- end
- end
- result[#result+1] = "</table>"
- end
- end
- else
- result[#result+1] = "<br/><br/>This font has no features."
- end
- return concat(result,"\n")
-end
-
-
-local info_template = [[
-<pre><tt>
-version : %s
-comment : %s
-author : %s
-copyright : %s
-
-maillist : ntg-context at ntg.nl
-webpage : www.pragma-ade.nl
-wiki : contextgarden.net
-</tt></pre>
-]]
-
-local function info_about()
- local m = modules ['mtx-server-ctx-fonttest']
- return format(info_template,m.version,m.comment,m.author,m.copyright)
-end
-
-local save_template = [[
- the current setup has been saved:
- <br/> <br/>
- <table>
- <tr><td class='tc'>name&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>title&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>font&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>script&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>language&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>features&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>options&nbsp; </td><td>%s</td></tr>
- <tr><td class='tc'>sampletext&nbsp;</td><td>%s</td></tr>
- </table>
-]]
-
-local function loadbase()
- local datafile = file.join(basepath,basename)
- local storage = io.loaddata(datafile) or ""
- if storage == "" then
- storage = { }
- else
- report("loading '%s'",datafile)
- storage = loadstring(storage)
- storage = (storage and storage()) or { }
- end
- return storage
-end
-
-local function loadstored(detail,currentfont,name)
- local storage = loadbase()
- storage = storage and storage[name]
- if storage then
- currentfont = storage.font
- detail.script = storage.script or detail.script
- detail.language = storage.language or detail.language
- detail.title = storage.title or detail.title
- detail.sampletext = storage.text or detail.sampletext
- detail.name = name or "no name"
- for k,v in next, storage.features do
- detail["f-"..k] = v
- end
- for k,v in next, storage.options do
- detail["o-"..k] = v
- end
- end
- detail.loadname = nil
- return detail, currentfont
-end
-
-local function savebase(storage,name)
- local datafile = file.join(basepath,basename)
- report("saving '%s' in '%s'",name or "data",datafile)
- io.savedata(datafile,table.serialize(storage,true))
-end
-
-local function deletestored(detail,currentfont,name)
- local storage = loadbase()
- if storage and name and storage[name] then
- report("deleting '%s' from base",name)
- storage[name] = nil
- savebase(storage)
- end
- detail.deletename = nil
- return detail, ""
-end
-
-local function save_font(currentfont,detail)
- local specification = get_specification(currentfont)
- local name, title, script, language, features, options, text = currentfont, "", "dflt", "dflt", { }, { }, ""
- if detail then
- local htmldata = showfeatures(specification.filename)
- script = detail.script or script
- language = detail.language or language
- text = string.strip(detail.sampletext or text)
- name = string.strip(detail.name or name)
- title = string.strip(detail.title or title)
- for k,v in next, htmldata.features do
- if detail["f-"..k] then features[k] = true end
- end
- for k=1,#what_options do
- local v = what_options[k]
- if detail["o-"..v] then options[k] = true end
- end
- end
- if name == "" then
- name = "no name"
- end
- local storage = loadbase()
- storage[name] = {
- font = currentfont, title = title, script = script, language = language, features = features, options = options, text = text,
- }
- savebase(storage,name)
- return format(save_template,name,title,currentfont,script,language,concat(table.sortedkeys(features)," "),concat(table.sortedkeys(options)," "),text)
-end
-
-local function load_font(currentfont)
- local datafile = file.join(basepath,basename)
- local storage = loadbase(datafile)
- local result = {}
- result[#result+1] = format("<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>")
- for k,v in table.sortedhash(storage) do
- local fontname, fontfile = get_specification(v.font)
- result[#result+1] = format("<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>",
- k,k,k,v.font,fontname,v.script,v.language,concat(table.sortedkeys(v.features)," "),v.title or "no title",v.text or "")
- end
- if #result == 1 then
- return "nothing saved yet"
- else
- return format("<table>%s</table>",concat(result,"\n"))
- end
-end
-
-local function reset_font(currentfont)
- return edit_font(currentfont)
-end
-
-local extras_template = [[
- <a href='mtx-server-ctx-fonttest.lua?extra=reload'>remake font database</a> (take some time)<br/><br/>
-]]
-
-local function do_extras(detail,currentfont,extra)
- return extras_template
-end
-
-local extras = { }
-
-local function do_extra(detail,currentfont,extra)
- local e = extras[extra]
- if e then e(detail,currentfont,extra) end
- return do_extras(detail,currentfont,extra)
-end
-
-function extras.reload()
- local command = "mtxrun --script font --reload"
- report("run command: %s",command)
- os.execute(command)
- return do_extras()
-end
-
-
-local status_template = [[
- <input type="hidden" name="currentfont" value="%s" />
-]]
-
-local variables = {
- ['color-background-one'] = lmx.get('color-background-green'),
- ['color-background-two'] = lmx.get('color-background-blue'),
- ['title'] = 'ConTeXt Font Tester',
- ['formaction'] = "mtx-server-ctx-fonttest.lua",
-}
-
-function doit(configuration,filename,hashed)
-
- local start = os.clock()
-
- local detail = url.query(hashed.query or "")
-
- local currentfont = detail.currentfont
- local action = detail.action
- local selection = detail.selection
-
- local loadname = detail.loadname
- local deletename = detail.deletename
- local extra = detail.extra
-
- if loadname and loadname ~= "" then
- detail, currentfont = loadstored(detail,currentfont,loadname)
- action = "process"
- elseif deletename and deletename ~= "" then
- detail, currentfont = deletestored(detail,currentfont,deletename)
- action = "load"
- elseif selection and selection ~= "" then
- currentfont = selection
- elseif extra and extra ~= "" then
- do_extra(detail,currentfont,extra)
- action = "extras"
- end
-
- local fontname, fontfile = get_specification(currentfont)
-
- if fontfile then
- variables.title = format('ConTeXt Font Tester: %s (%s)',fontname,fontfile)
- else
- variables.title = 'ConTeXt Font Tester'
- end
-
- -- lua table and adapt
-
- local buttons = { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras'}
- local menu = { }
-
- for i=1,#buttons do
- local button = buttons[i]
- menu[#menu+1] = format("<button name='action' value='%s' type='submit'>%s</button>",button,button)
- end
-
- variables.menu = concat(menu,"&nbsp;")
- variables.status = format(status_template,currentfont or "")
- variables.maintext = ""
- variables.javascriptdata = ""
- variables.javascripts = ""
- variables.javascriptinit = ""
-
- report("action: %s",action or "no action")
-
- local result
-
- if action == "select" then
- variables.maintext = select_font()
- elseif action == "info" then
- variables.maintext = info_about()
- elseif action == "extras" then
- variables.maintext = do_extras()
- elseif currentfont and currentfont ~= "" then
- if action == "save" then
- variables.maintext = save_font(currentfont,detail)
- elseif action == "load" then
- variables.maintext = load_font(currentfont,detail)
- elseif action == "source" then
- variables.maintext = show_source(currentfont,detail)
- elseif action == "log" then
- variables.maintext = show_log(currentfont,detail)
- elseif action == "features" then
- variables.maintext = show_font(currentfont,detail)
- else
- local e, s
- if action == "process" then
- e, s = process_font(currentfont,detail)
- elseif action == "reset" then
- e, s = reset_font(currentfont)
- elseif action == "edit" then
- e, s = edit_font(currentfont,detail)
- else
- e, s = process_font(currentfont,detail)
- end
- variables.maintext = e
- variables.javascriptdata = s
- variables.javascripts = javascripts
- variables.javascriptinit = "check_form()"
- end
- else
- variables.maintext = select_font()
- end
-
- result = { content = lmx.convert('context-fonttest.lmx',false,variables) }
-
- report("time spent on page: %0.03f seconds",os.clock()-start)
-
- return result
-
-end
-
-return doit, true
-
---~ make_lmx_page("test")
+if not modules then modules = { } end modules ['mtx-server-ctx-fonttest'] = {
+ version = 1.001,
+ comment = "Font Feature Tester",
+ author = "Hans Hagen",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- probably too much but who cares
+
+dofile(resolvers.findfile("trac-lmx.lua","tex"))
+dofile(resolvers.findfile("font-ini.lua","tex"))
+dofile(resolvers.findfile("font-con.lua","tex"))
+dofile(resolvers.findfile("font-oti.lua","tex"))
+dofile(resolvers.findfile("font-otf.lua","tex"))
+dofile(resolvers.findfile("font-otp.lua","tex"))
+dofile(resolvers.findfile("font-ott.lua","tex"))
+dofile(resolvers.findfile("font-syn.lua","tex"))
+dofile(resolvers.findfile("font-mis.lua","tex"))
+
+local format, gsub, concat, match, find = string.format, string.gsub, table.concat, string.match, string.find
+
+local report = logs.reporter("ctx-fonttest")
+
+local sample_line = "This is a sample line!"
+local tempname = "mtx-server-ctx-fonttest-temp"
+local temppath = caches.setfirstwritablefile("temp","mtx-server-ctx-fonttest")
+local basename = "mtx-server-ctx-fonttest-data.lua"
+local basepath = temppath
+
+local remove_suffixes = { "tex", "pdf", "log" }
+local what_options = { "trace", "basemode" }
+
+for i=1,#remove_suffixes do
+ os.remove(file.join(temppath,file.addsuffix(tempname,remove_suffixes[i])))
+end
+
+local process_templates = { }
+
+process_templates.default = [[
+\starttext
+ \setupdirections[bidi=global]
+ \definefontfeature[sample][analyze=yes,%s]
+ \definedfont[name:%s*sample]
+ \startTEXpage[offset=3pt]
+ \detokenize{%s}
+ \stopTEXpage
+\stoptext
+]]
+
+process_templates.cache = [[
+\starttext
+ \definedfont[name:%s]
+ \startTEXpage[offset=3pt]
+ cached: \detokenize{%s}
+ \stopTEXpage
+\stoptext
+]]
+
+process_templates.trace = [[
+\usemodule[fnt-20]
+
+\definefontfeature[sample][%s]
+
+\setupcolors[state=start]
+
+\setupdirections[bidi=global]
+
+\setvariables
+ [otftracker]
+ [title=Test Run,
+ font=name:%s,
+ direction=0,
+ features=sample,
+ sample={‍\detokenize{%s}}]
+]]
+
+local javascripts = [[
+function selected_radio(name) {
+ var form = document.forms["main-form"] ;
+ var script = form.elements[name] ;
+ if (script) {
+ var n = script.length ;
+ if (n) {
+ for (var i=0; i<n; i++) {
+ if (script[i].checked) {
+ return script[i].value ;
+ }
+ }
+ }
+ }
+ return "" ;
+}
+
+function reset_valid() {
+ var fields = document.getElementsByTagName("span") ;
+ for (var i=0; i<fields.length; i++) {
+ var e = fields[i]
+ if (e) {
+ if (e.className == "valid") {
+ e.className = "" ;
+ }
+ }
+ }
+}
+
+function set_valid() {
+ var script = selected_radio("script") ;
+ var language = selected_radio("language") ;
+ if (script && language) {
+ var s = feature_hash[script] ;
+ if (s) {
+ for (l in s) {
+ var e = document.getElementById("t-l-" + l) ;
+ if (e) {
+ e.className = "valid" ;
+ }
+ }
+ var l = s[language] ;
+ if (l) {
+ for (i in l) {
+ var e = document.getElementById("t-f-" + i) ;
+ if (e) {
+ e.className = "valid" ;
+ }
+ }
+ }
+ var e = document.getElementById("t-s-" + script) ;
+ if (e) {
+ e.className = "valid" ;
+ }
+ }
+ }
+}
+
+function check_form() {
+ reset_valid() ;
+ set_valid() ;
+}
+
+function check_script() {
+ reset_valid() ;
+ set_valid() ;
+}
+
+function check_language() {
+ reset_valid() ;
+ set_valid() ;
+}
+
+function check_feature() {
+ // not needed
+}
+]]
+
+local cache = { }
+
+local function showfeatures(f)
+ if f then
+ report("processing font '%s'",f)
+ local features = cache[f]
+ if features == nil then
+ features = fonts.helpers.getfeatures(resolvers.findfile(f))
+ if not features then
+ report("building cache for '%s'",f)
+ io.savedata(file.join(temppath,file.addsuffix(tempname,"tex")),format(process_templates.cache,f,f))
+ os.execute(format("mtxrun --path=%s --script context --once --batchmode %s",temppath,tempname))
+ features = fonts.helpers.getfeatures(f)
+ end
+ cache[f] = features or false
+ report("caching info of '%s'",f)
+ else
+ report("using cached info of '%s'",f)
+ end
+ if features then
+ local scr, lan, fea, rev = { }, { }, { }, { }
+ local function show(what)
+ local data = features[what]
+ if data and next(data) then
+ for f,ff in next, data do
+ if find(f,"<") then
+ -- ignore aat for the moment
+ else
+ fea[f] = true
+ for s, ss in next, ff do
+ if find(s,"%*") then
+ -- ignore *
+ else
+ scr[s] = true
+ local rs = rev[s] if not rs then rs = {} rev[s] = rs end
+ for k, l in next, ss do
+ if find(k,"%*") then
+ -- ignore *
+ else
+ lan[k] = true
+ local rsk = rs[k] if not rsk then rsk = { } rs[k] = rsk end
+ rsk[f] = true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ for what, v in table.sortedhash(features) do
+ show(what)
+ end
+ local stupid = { }
+ stupid[#stupid+1] = "var feature_hash = new Array ;"
+ for s, sr in next, rev do
+ stupid[#stupid+1] = format("feature_hash['%s'] = new Array ;",s)
+ for l, lr in next, sr do
+ stupid[#stupid+1] = format("feature_hash['%s']['%s'] = new Array ;",s,l)
+ for f, fr in next, lr do
+ stupid[#stupid+1] = format("feature_hash['%s']['%s']['%s'] = true ;",s,l,f)
+ end
+ end
+ end
+ -- gpos feature script languages
+ return {
+ scripts = scr,
+ languages = lan,
+ features = fea,
+ javascript = concat(stupid,"\n")
+ }
+ end
+ end
+end
+
+local template_h = [[
+<tr>
+ <th>safe name&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <th>family name&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <th>style-variant-weight-width&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <th>font name&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <th>weight&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <th>filename</th>
+</tr>]]
+
+local template_d = [[
+<tr>
+ <td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a>&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td>%s-%s-%s-%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td>%s&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td>%s</td>
+</tr>]]
+
+local function select_font()
+ local t = fonts.names.list(".*",false,true)
+ if t then
+ local listoffonts = { }
+ listoffonts[#listoffonts+1] = "<table>"
+ listoffonts[#listoffonts+1] = template_h
+ for k, v in table.sortedhash(t) do
+ local kind = v.format
+ if kind == "otf" or kind == "ttf" or kind == "ttc" then
+ local fontname = v.fontname
+ listoffonts[#listoffonts+1] = format(template_d, fontname, fontname,
+ v.familyname or "",
+ t.variant or "normal",
+ t.weight or "normal",
+ t.width or "normal",
+ t.style or "normal",
+ v.rawname or fontname,
+ v.fontweight or "",
+ v.filename or ""
+ )
+ end
+ end
+ listoffonts[#listoffonts+1] = "</table>"
+ return concat(listoffonts,"\n")
+ end
+ return "<b>no fonts</b>"
+end
+
+local edit_template = [[
+ <textarea name='sampletext' rows='5' cols='100'>%s</textarea>
+ <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/>
+ <br/> <br/>scripts:&nbsp;%s
+ <br/> <br/>languages:&nbsp;%s
+ <br/> <br/>features:&nbsp;%s
+ <br/> <br/>options:&nbsp;%s
+]]
+
+-- <embed src="%s#toolbar=0&amp;navpanes=0&amp;scrollbar=0" width="100%%"/>
+
+local result_template = [[
+ <br/> <br/>
+ <embed src="%s#view=Fit&amp;toolbar=0&amp;navpanes=0&amp;scrollbar=0" width="100%%"/>
+ <br/> <br/> results:
+ <a href='%s' target="source">tex file</a>
+ <a href='%s' target="result">pdf file</a>
+ <br/> <br/>
+]]
+
+scripts.webserver.registerpath(temppath)
+
+local function get_specification(name)
+ return fonts.names.resolvedspecification(name or "")
+end
+
+local function edit_font(currentfont,detail,tempname)
+ report("entering edit mode for '%s'",currentfont)
+ local specification = get_specification(currentfont)
+ if specification then
+ local htmldata = showfeatures(specification.filename)
+ if htmldata then
+ local features, languages, scripts, options = { }, { }, { }, { }
+ local sorted = table.sortedkeys(htmldata.scripts)
+ for k=1,#sorted do
+ local v = sorted[k]
+ local s = fonts.handlers.otf.tables.scripts[v] or v
+ if detail and v == detail.script then
+ scripts[#scripts+1] = format("<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)
+ else
+ scripts[#scripts+1] = format("<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)
+ end
+ end
+ local sorted = table.sortedkeys(htmldata.languages)
+ for k=1,#sorted do
+ local v = sorted[k]
+ local l = fonts.handlers.otf.tables.languages[v] or v
+ if detail and v == detail.language then
+ languages[#languages+1] = format("<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)
+ else
+ languages[#languages+1] = format("<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)
+ end
+ end
+ local sorted = table.sortedkeys(htmldata.features)
+ for k=1,#sorted do
+ local v = sorted[k]
+ local f = fonts.handlers.otf.tables.features[v] or v
+ if detail and detail["f-"..v] then
+ features[#features+1] = format("<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)
+ else
+ features[#features+1] = format("<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)
+ end
+ end
+ for k=1,#what_options do
+ local v = what_options[k]
+ if detail and detail["o-"..v] then
+ options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/>&nbsp;%s",v,v,v)
+ else
+ options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s'/>&nbsp;%s",v,v,v)
+ end
+ end
+ local e = format(edit_template,
+ (detail and detail.sampletext) or sample_line,(detail and detail.name) or "no name",(detail and detail.title) or "",
+ concat(scripts," "),concat(languages," "),concat(features," "),concat(options," "))
+ if tempname then
+ local pdffile, texfile = file.addsuffix(tempname,"pdf"), file.addsuffix(tempname,"tex")
+ local r = format(result_template,pdffile,texfile,pdffile)
+ return e .. r, htmldata.javascript or ""
+ else
+ return e, htmldata.javascript or ""
+ end
+ else
+ return "error, nothing set up yet"
+ end
+ else
+ return "error, no info about font"
+ end
+end
+
+local function process_font(currentfont,detail) -- maybe just fontname
+ local features = {
+ "mode=node",
+ format("language=%s",detail.language or "dflt"),
+ format("script=%s",detail.script or "dflt"),
+ }
+ for k,v in next, detail do
+ local f = match(k,"^f%-(.*)$")
+ if f then
+ features[#features+1] = format("%s=yes",f)
+ end
+ end
+ local variant = process_templates.default
+ if detail["o-trace"] then
+ variant = process_templates.trace
+ end
+ local sample = string.strip(detail.sampletext or "")
+ if sample == "" then sample = sample_line end
+ report("sample text: %s",sample)
+ dir.mkdirs(temppath)
+ local fullname = file.join(temppath,file.addsuffix(tempname,"tex"))
+ local data = format(variant,concat(features,","),currentfont,sample)
+ local command = format("mtxrun --path=%q --script context --once --batchmode %q",temppath,tempname)
+ report("filename: %s",fullname)
+ report("command: %s",command)
+ io.savedata(fullname,data)
+ os.execute(command)
+ return edit_font(currentfont,detail,tempname)
+end
+
+local tex_template = [[
+<pre><tt>
+%s
+</tt></pre>
+]]
+
+local function show_source(currentfont,detail)
+ if tempname and tempname ~= "" then
+ local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,"tex"))) or "no source yet"
+ return format(tex_template,data)
+ else
+ return "no source file"
+ end
+end
+
+local function show_log(currentfont,detail)
+ if tempname and tempname ~= "" then
+ local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,'log'))) or "no log file yet"
+ data = gsub(data,"[%s%%]*begin of optionfile.-end of optionfile[%s%%]*","\n")
+ return format(tex_template,data)
+ else
+ return "no log file"
+ end
+end
+
+local function show_font(currentfont,detail)
+ local specification = get_specification(currentfont)
+ local features = fonts.helpers.getfeatures(specification.filename)
+ local result = { }
+ result[#result+1] = format("<h1>names</h1>",what)
+ result[#result+1] = "<table>"
+ result[#result+1] = format("<tr><td class='tc'>fontname: </td><td>%s</td></tr>",currentfont)
+ result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fontname or "-")
+ result[#result+1] = format("<tr><td class='tc'>filename: </td><td>%s</td></tr>",specification.fontfile or "-")
+ result[#result+1] = format("<tr><td class='tc'>familyname: </td><td>%s</td></tr>",specification.familyname or "-")
+ result[#result+1] = format("<tr><td class='tc'>fontweight: </td><td>%s</td></tr>",specification.fontweight or "-")
+ result[#result+1] = format("<tr><td class='tc'>format: </td><td>%s</td></tr>",specification.format or "-")
+ result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fullname or "-")
+ result[#result+1] = format("<tr><td class='tc'>subfamily: </td><td>%s</td></tr>",specification.subfamily or "-")
+ result[#result+1] = format("<tr><td class='tc'>rawname: </td><td>%s</td></tr>",specification.rawname or "-")
+ result[#result+1] = format("<tr><td class='tc'>designsize: </td><td>%s</td></tr>",specification.designsize or "-")
+ result[#result+1] = format("<tr><td class='tc'>minimumsize:</td><td>%s</td></tr>",specification.minsize or "-")
+ result[#result+1] = format("<tr><td class='tc'>maximumsize:</td><td>%s</td></tr>",specification.maxsize or "-")
+ result[#result+1] = format("<tr><td class='tc'>style: </td><td>%s</td></tr>",specification.style ~= "" and specification.style or "normal")
+ result[#result+1] = format("<tr><td class='tc'>variant: </td><td>%s</td></tr>",specification.variant ~= "" and specification.variant or "normal")
+ result[#result+1] = format("<tr><td class='tc'>weight: </td><td>%s</td></tr>",specification.weight ~= "" and specification.weight or "normal")
+ result[#result+1] = format("<tr><td class='tc'>width: </td><td>%s</td></tr>",specification.width ~= "" and specification.width or "normal")
+ result[#result+1] = "</table>"
+ if features then
+ for what, v in table.sortedhash(features) do
+ local data = features[what]
+ if data and next(data) then
+ result[#result+1] = format("<h1>%s features</h1>",what)
+ result[#result+1] = "<table>"
+ result[#result+1] = "<tr><th>feature</th><th>tag&nbsp;</th><th>script&nbsp;</th><th>languages&nbsp;</th></tr>"
+ for f,ff in table.sortedhash(data) do
+ local done = false
+ for s, ss in table.sortedhash(ff) do
+ if s == "*" then s = "all" end
+ if ss ["*"] then ss["*"] = nil ss.all = true end
+ if done then
+ f = ""
+ else
+ done = true
+ end
+ local title = fonts.handlers.otf.tables.features[f] or ""
+ result[#result+1] = format("<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)," "))
+ end
+ end
+ result[#result+1] = "</table>"
+ end
+ end
+ else
+ result[#result+1] = "<br/><br/>This font has no features."
+ end
+ return concat(result,"\n")
+end
+
+
+local info_template = [[
+<pre><tt>
+version : %s
+comment : %s
+author : %s
+copyright : %s
+
+maillist : ntg-context at ntg.nl
+webpage : www.pragma-ade.nl
+wiki : contextgarden.net
+</tt></pre>
+]]
+
+local function info_about()
+ local m = modules ['mtx-server-ctx-fonttest']
+ return format(info_template,m.version,m.comment,m.author,m.copyright)
+end
+
+local save_template = [[
+ the current setup has been saved:
+ <br/> <br/>
+ <table>
+ <tr><td class='tc'>name&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>title&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>font&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>script&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>language&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>features&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>options&nbsp; </td><td>%s</td></tr>
+ <tr><td class='tc'>sampletext&nbsp;</td><td>%s</td></tr>
+ </table>
+]]
+
+local function loadbase()
+ local datafile = file.join(basepath,basename)
+ local storage = io.loaddata(datafile) or ""
+ if storage == "" then
+ storage = { }
+ else
+ report("loading '%s'",datafile)
+ storage = loadstring(storage)
+ storage = (storage and storage()) or { }
+ end
+ return storage
+end
+
+local function loadstored(detail,currentfont,name)
+ local storage = loadbase()
+ storage = storage and storage[name]
+ if storage then
+ currentfont = storage.font
+ detail.script = storage.script or detail.script
+ detail.language = storage.language or detail.language
+ detail.title = storage.title or detail.title
+ detail.sampletext = storage.text or detail.sampletext
+ detail.name = name or "no name"
+ for k,v in next, storage.features do
+ detail["f-"..k] = v
+ end
+ for k,v in next, storage.options do
+ detail["o-"..k] = v
+ end
+ end
+ detail.loadname = nil
+ return detail, currentfont
+end
+
+local function savebase(storage,name)
+ local datafile = file.join(basepath,basename)
+ report("saving '%s' in '%s'",name or "data",datafile)
+ io.savedata(datafile,table.serialize(storage,true))
+end
+
+local function deletestored(detail,currentfont,name)
+ local storage = loadbase()
+ if storage and name and storage[name] then
+ report("deleting '%s' from base",name)
+ storage[name] = nil
+ savebase(storage)
+ end
+ detail.deletename = nil
+ return detail, ""
+end
+
+local function save_font(currentfont,detail)
+ local specification = get_specification(currentfont)
+ local name, title, script, language, features, options, text = currentfont, "", "dflt", "dflt", { }, { }, ""
+ if detail then
+ local htmldata = showfeatures(specification.filename)
+ script = detail.script or script
+ language = detail.language or language
+ text = string.strip(detail.sampletext or text)
+ name = string.strip(detail.name or name)
+ title = string.strip(detail.title or title)
+ for k,v in next, htmldata.features do
+ if detail["f-"..k] then features[k] = true end
+ end
+ for k=1,#what_options do
+ local v = what_options[k]
+ if detail["o-"..v] then options[k] = true end
+ end
+ end
+ if name == "" then
+ name = "no name"
+ end
+ local storage = loadbase()
+ storage[name] = {
+ font = currentfont, title = title, script = script, language = language, features = features, options = options, text = text,
+ }
+ savebase(storage,name)
+ return format(save_template,name,title,currentfont,script,language,concat(table.sortedkeys(features)," "),concat(table.sortedkeys(options)," "),text)
+end
+
+local function load_font(currentfont)
+ local datafile = file.join(basepath,basename)
+ local storage = loadbase(datafile)
+ local result = {}
+ result[#result+1] = format("<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>")
+ for k,v in table.sortedhash(storage) do
+ local fontname, fontfile = get_specification(v.font)
+ result[#result+1] = format("<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>",
+ k,k,k,v.font,fontname,v.script,v.language,concat(table.sortedkeys(v.features)," "),v.title or "no title",v.text or "")
+ end
+ if #result == 1 then
+ return "nothing saved yet"
+ else
+ return format("<table>%s</table>",concat(result,"\n"))
+ end
+end
+
+local function reset_font(currentfont)
+ return edit_font(currentfont)
+end
+
+local extras_template = [[
+ <a href='mtx-server-ctx-fonttest.lua?extra=reload'>remake font database</a> (take some time)<br/><br/>
+]]
+
+local function do_extras(detail,currentfont,extra)
+ return extras_template
+end
+
+local extras = { }
+
+local function do_extra(detail,currentfont,extra)
+ local e = extras[extra]
+ if e then e(detail,currentfont,extra) end
+ return do_extras(detail,currentfont,extra)
+end
+
+function extras.reload()
+ local command = "mtxrun --script font --reload"
+ report("run command: %s",command)
+ os.execute(command)
+ return do_extras()
+end
+
+
+local status_template = [[
+ <input type="hidden" name="currentfont" value="%s" />
+]]
+
+local variables = {
+ ['color-background-one'] = lmx.get('color-background-green'),
+ ['color-background-two'] = lmx.get('color-background-blue'),
+ ['title'] = 'ConTeXt Font Tester',
+ ['formaction'] = "mtx-server-ctx-fonttest.lua",
+}
+
+function doit(configuration,filename,hashed)
+
+ local start = os.clock()
+
+ local detail = url.query(hashed.query or "")
+
+ local currentfont = detail.currentfont
+ local action = detail.action
+ local selection = detail.selection
+
+ local loadname = detail.loadname
+ local deletename = detail.deletename
+ local extra = detail.extra
+
+ if loadname and loadname ~= "" then
+ detail, currentfont = loadstored(detail,currentfont,loadname)
+ action = "process"
+ elseif deletename and deletename ~= "" then
+ detail, currentfont = deletestored(detail,currentfont,deletename)
+ action = "load"
+ elseif selection and selection ~= "" then
+ currentfont = selection
+ elseif extra and extra ~= "" then
+ do_extra(detail,currentfont,extra)
+ action = "extras"
+ end
+
+ local fontname, fontfile = get_specification(currentfont)
+
+ if fontfile then
+ variables.title = format('ConTeXt Font Tester: %s (%s)',fontname,fontfile)
+ else
+ variables.title = 'ConTeXt Font Tester'
+ end
+
+ -- lua table and adapt
+
+ local buttons = { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras'}
+ local menu = { }
+
+ for i=1,#buttons do
+ local button = buttons[i]
+ menu[#menu+1] = format("<button name='action' value='%s' type='submit'>%s</button>",button,button)
+ end
+
+ variables.menu = concat(menu,"&nbsp;")
+ variables.status = format(status_template,currentfont or "")
+ variables.maintext = ""
+ variables.javascriptdata = ""
+ variables.javascripts = ""
+ variables.javascriptinit = ""
+
+ report("action: %s",action or "no action")
+
+ local result
+
+ if action == "select" then
+ variables.maintext = select_font()
+ elseif action == "info" then
+ variables.maintext = info_about()
+ elseif action == "extras" then
+ variables.maintext = do_extras()
+ elseif currentfont and currentfont ~= "" then
+ if action == "save" then
+ variables.maintext = save_font(currentfont,detail)
+ elseif action == "load" then
+ variables.maintext = load_font(currentfont,detail)
+ elseif action == "source" then
+ variables.maintext = show_source(currentfont,detail)
+ elseif action == "log" then
+ variables.maintext = show_log(currentfont,detail)
+ elseif action == "features" then
+ variables.maintext = show_font(currentfont,detail)
+ else
+ local e, s
+ if action == "process" then
+ e, s = process_font(currentfont,detail)
+ elseif action == "reset" then
+ e, s = reset_font(currentfont)
+ elseif action == "edit" then
+ e, s = edit_font(currentfont,detail)
+ else
+ e, s = process_font(currentfont,detail)
+ end
+ variables.maintext = e
+ variables.javascriptdata = s
+ variables.javascripts = javascripts
+ variables.javascriptinit = "check_form()"
+ end
+ else
+ variables.maintext = select_font()
+ end
+
+ result = { content = lmx.convert('context-fonttest.lmx',false,variables) }
+
+ report("time spent on page: %0.03f seconds",os.clock()-start)
+
+ return result
+
+end
+
+return doit, true
+
+--~ make_lmx_page("test")
diff --git a/scripts/context/lua/mtx-server-ctx-help.lua b/scripts/context/lua/mtx-server-ctx-help.lua
index f0901150a..b8dc0dfb2 100644
--- a/scripts/context/lua/mtx-server-ctx-help.lua
+++ b/scripts/context/lua/mtx-server-ctx-help.lua
@@ -1,705 +1,705 @@
-if not modules then modules = { } end modules ['mtx-server-ctx-help'] = {
- version = 1.001,
- comment = "Basic Definition Browser",
- author = "Hans Hagen",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- todo in lua interface: noargument, oneargument, twoarguments, threearguments
--- todo: pickup translations from mult file
-
-dofile(resolvers.findfile("trac-lmx.lua","tex"))
-
--- problem ... serialize parent stack
-
-local format, match, gsub, find = string.format, string.match, string.gsub, string.find
-local concat = table.concat
-
-local report = logs.reporter("ctx-help")
-
--- -- -- make this a module: cont-xx.lua
-
-document = document or { }
-document.setups = document.setups or { }
-
-document.setups.div = {
- pe = "<div dir='rtl' lang='arabic'>%s</div>"
-}
-
-document.setups.span = {
- pe = "<span dir='rtl' lang='arabic'>%s</span>"
-}
-
-document.setups.translations = document.setups.translations or {
-
- nl = {
- ["title"] = "setup",
- ["formula"] = "formule",
- ["number"] = "getal",
- ["list"] = "lijst",
- ["dimension"] = "maat",
- ["mark"] = "markering",
- ["reference"] = "verwijzing",
- ["command"] = "commando",
- ["file"] = "file",
- ["name"] = "naam",
- ["identifier"] = "naam",
- ["text"] = "tekst",
- ["section"] = "sectie",
- ["singular"] = "naam enkelvoud",
- ["plural"] = "naam meervoud",
- ["matrix"] = "n*m",
- ["see"] = "zie",
- ["inherits"] = "erft van",
- ["optional"] = "optioneel",
- ["displaymath"] = "formule",
- ["index"] = "ingang",
- ["math"] = "formule",
- ["nothing"] = "leeg",
- ["file"] = "file",
- ["position"] = "positie",
- ["reference"] = "verwijzing",
- ["csname"] = "naam",
- ["destination"] = "bestemming",
- ["triplet"] = "triplet",
- ["word"] = "woord",
- ["content"] = "tekst",
- },
-
- en = {
- ["title"] = "setup",
- ["formula"] = "formula",
- ["number"] = "number",
- ["list"] = "list",
- ["dimension"] = "dimension",
- ["mark"] = "mark",
- ["reference"] = "reference",
- ["command"] = "command",
- ["file"] = "file",
- ["name"] = "name",
- ["identifier"] = "identifier",
- ["text"] = "text",
- ["section"] = "section",
- ["singular"] = "singular name",
- ["plural"] = "plural name",
- ["matrix"] = "n*m",
- ["see"] = "see",
- ["inherits"] = "inherits from",
- ["optional"] = "optional",
- ["displaymath"] = "formula",
- ["index"] = "entry",
- ["math"] = "formula",
- ["nothing"] = "empty",
- ["file"] = "file",
- ["position"] = "position",
- ["reference"] = "reference",
- ["csname"] = "name",
- ["destination"] = "destination",
- ["triplet"] = "triplet",
- ["word"] = "word",
- ["content"] = "text",
-
- ["noargument"] = "\\cs",
- ["oneargument"] = "\\cs#1{..}",
- ["twoarguments"] = "\\cs#1#2{..}{..}",
- ["threearguments"] = "\\cs#1#2#3{..}{..}{..}",
-
- },
-
- de = {
- ["title"] = "Setup",
- ["formula"] = "Formel",
- ["number"] = "Nummer",
- ["list"] = "Liste",
- ["dimension"] = "Dimension",
- ["mark"] = "Beschriftung",
- ["reference"] = "Referenz",
- ["command"] = "Befehl",
- ["file"] = "Datei",
- ["name"] = "Name",
- ["identifier"] = "Name",
- ["text"] = "Text",
- ["section"] = "Abschnitt",
- ["singular"] = "singular",
- ["plural"] = "plural",
- ["matrix"] = "n*m",
- ["see"] = "siehe",
- ["inherits"] = "inherits from",
- ["optional"] = "optioneel",
- ["displaymath"] = "formula",
- ["index"] = "entry",
- ["math"] = "formula",
- ["nothing"] = "empty",
- ["file"] = "file",
- ["position"] = "position",
- ["reference"] = "reference",
- ["csname"] = "name",
- ["destination"] = "destination",
- ["triplet"] = "triplet",
- ["word"] = "word",
- ["content"] = "text",
- },
-
- cz = {
- ["title"] = "setup",
- ["formula"] = "rovnice",
- ["number"] = "cislo",
- ["list"] = "seznam",
- ["dimension"] = "dimenze",
- ["mark"] = "znacka",
- ["reference"] = "reference",
- ["command"] = "prikaz",
- ["file"] = "soubor",
- ["name"] = "jmeno",
- ["identifier"] = "jmeno",
- ["text"] = "text",
- ["section"] = "sekce",
- ["singular"] = "jmeno v singularu",
- ["plural"] = "jmeno v pluralu",
- ["matrix"] = "n*m",
- ["see"] = "viz",
- ["inherits"] = "inherits from",
- ["optional"] = "optioneel",
- ["displaymath"] = "formula",
- ["index"] = "entry",
- ["math"] = "formula",
- ["nothing"] = "empty",
- ["file"] = "file",
- ["position"] = "position",
- ["reference"] = "reference",
- ["csname"] = "name",
- ["destination"] = "destination",
- ["triplet"] = "triplet",
- ["word"] = "word",
- ["content"] = "text",
- },
-
- it = {
- ["title"] = "setup",
- ["formula"] = "formula",
- ["number"] = "number",
- ["list"] = "list",
- ["dimension"] = "dimension",
- ["mark"] = "mark",
- ["reference"] = "reference",
- ["command"] = "command",
- ["file"] = "file",
- ["name"] = "name",
- ["identifier"] = "name",
- ["text"] = "text",
- ["section"] = "section",
- ["singular"] = "singular name",
- ["plural"] = "plural name",
- ["matrix"] = "n*m",
- ["see"] = "see",
- ["inherits"] = "inherits from",
- ["optional"] = "optioneel",
- ["displaymath"] = "formula",
- ["index"] = "entry",
- ["math"] = "formula",
- ["nothing"] = "empty",
- ["file"] = "file",
- ["position"] = "position",
- ["reference"] = "reference",
- ["csname"] = "name",
- ["destination"] = "destination",
- ["triplet"] = "triplet",
- ["word"] = "word",
- ["content"] = "text",
- },
-
- ro = {
- ["title"] = "setari",
- ["formula"] = "formula",
- ["number"] = "numar",
- ["list"] = "lista",
- ["dimension"] = "dimensiune",
- ["mark"] = "marcaj",
- ["reference"] = "referinta",
- ["command"] = "comanda",
- ["file"] = "fisier",
- ["name"] = "nume",
- ["identifier"] = "nume",
- ["text"] = "text",
- ["section"] = "sectiune",
- ["singular"] = "nume singular",
- ["plural"] = "nume pluram",
- ["matrix"] = "n*m",
- ["see"] = "vezi",
- ["inherits"] = "inherits from",
- ["optional"] = "optioneel",
- ["displaymath"] = "formula",
- ["index"] = "entry",
- ["math"] = "formula",
- ["nothing"] = "empty",
- ["file"] = "file",
- ["position"] = "position",
- ["reference"] = "reference",
- ["csname"] = "name",
- ["destination"] = "destination",
- ["triplet"] = "triplet",
- ["word"] = "word",
- ["content"] = "text",
- },
-
- fr = {
- ["title"] = "réglage",
- ["formula"] = "formule",
- ["number"] = "numéro",
- ["list"] = "liste",
- ["dimension"] = "dimension",
- ["mark"] = "marquage",
- ["reference"] = "reference",
- ["command"] = "commande",
- ["file"] = "fichier",
- ["name"] = "nom",
- ["identifier"] = "identificateur",
- ["text"] = "texte",
- ["section"] = "section",
- ["singular"] = "nom singulier",
- ["plural"] = "nom pluriel",
- ["matrix"] = "n*m",
- ["see"] = "vois",
- ["inherits"] = "herite de",
- ["optional"] = "optionel",
- ["displaymath"] = "formule",
- ["index"] = "entrée",
- ["math"] = "formule",
- ["nothing"] = "vide",
- ["file"] = "fichier",
- ["position"] = "position",
- ["reference"] = "réference",
- ["csname"] = "nom",
- ["destination"] = "destination",
- ["triplet"] = "triplet",
- ["word"] = "mot",
- ["content"] = "texte",
- }
-
-}
-
-document.setups.formats = {
- open_command = {
- tex = [[\%s]],
- lua = [[context.%s (]],
- },
- close_command = {
- tex = [[]],
- lua = [[ )]],
- },
- connector = {
- tex = [[]],
- lua = [[, ]],
- },
- href_in_list = {
- tex = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>]],
- lua = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>]],
- },
- href_as_command = {
- tex = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>\%s</a>]],
- lua = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>context.%s</a>]],
- },
- modes = {
- tex = [[<a href='mtx-server-ctx-help.lua?mode=lua'>lua mode</a>]],
- lua = [[<a href='mtx-server-ctx-help.lua?mode=tex'>tex mode</a>]],
- },
- optional_single = {
- tex = "[optional string %s]",
- lua = "{optional string %s}",
- },
- optional_list = {
- tex = "[optional list %s]",
- lua = "{optional table %s}" ,
- } ,
- mandate_single = {
- tex = "[mandate string %s]",
- lua = "{mandate string %s}",
- },
- mandate_list = {
- tex = "[mandate list %s]",
- lua = "{mandate list %s}",
- },
- interface = [[<a href='mtx-server-ctx-help.lua?interface=%s&mode=%s'>%s</a>]],
- source = [[<a href='mtx-server-ctx-help.lua?source=%s&mode=%s'>%s</a>]],
- parameter = [[<tr><td width='15%%'>%s</td><td width='15%%'>%s</td><td width='70%%'>%s</td></tr>]],
- parameters = [[<table width='100%%'>%s</table>]],
- listing = [[<pre><t>%s</t></listing>]],
- special = [[<i>%s</i>]],
- default = [[<u>%s</u>]],
-}
-
-local function translate(tag,int,noformat)
- local t = document.setups.translations
- local te = t["en"]
- local ti = t[int] or te
- if noformat then
- return ti[tag] or te[tag] or tag
- else
- return format(document.setups.formats.special,ti[tag] or te[tag] or tag)
- end
-end
-
-local function translated(e,int)
- local attributes = e.at
- local s = attributes.type or "?"
- local tag = match(s,"^cd:(.*)$")
- if attributes.default == "yes" then
- return format(document.setups.formats.default,tag or "?")
- elseif tag then
- return translate(tag,int)
- else
- return s
- end
-end
-
-document.setups.loaded = document.setups.loaded or { }
-
-document.setups.current = { }
-document.setups.showsources = true
-document.setups.mode = "tex"
-
-function document.setups.load(filename)
- filename = resolvers.findfile(filename) or ""
- if filename ~= "" then
- local current = document.setups.loaded[filename]
- if not current then
- local loaded = xml.load(filename)
- if loaded then
- -- xml.inject(document.setups.root,"/",loaded)
- current = {
- file = filename,
- root = loaded,
- names = { },
- used = { },
- }
- document.setups.loaded[filename] = current
- end
- end
- document.setups.current = current or { }
- end
-end
-
-function document.setups.name(ek)
- local at = ek.at
- local name = at.name
- if at.type == 'environment' then
- name = "start" .. name
- end
- if at.variant then
- name = name .. ":" .. at.variant
- end
- if at.generated == "yes" then
- name = name .. "*"
- end
- return name:lower()
-end
-
-function document.setups.csname(ek,int)
- local cs = ""
- local at = ek.at or { }
- if at.type == 'environment' then
- cs = translate("start",int,true) .. cs
- end
- for e in xml.collected(ek,'cd:sequence/(cd:string|variable)') do
- if e.tg == "string" then
- cs = cs .. e.at.value
- else
- cs = cs .. e.at.value -- to be translated
- end
- end
- return cs
-end
-
-function document.setups.names()
- local current = document.setups.current
- local names = current.names
- if not names or #names == 0 then
- names = { }
- local name = document.setups.name
- local csname = document.setups.csname
- for e in xml.collected(current.root,'cd:command') do
- names[#names+1] = { e.at.name, csname(e,int) }
- end
- table.sort(names, function(a,b) return a[2]:lower() < b[2]:lower() end)
- current.names = names
- end
- return names
-end
-
-function document.setups.show(name)
- local current = document.setups.current
- if current.root then
- local name = gsub(name,"[<>]","")
- local setup = xml.first(current.root,"cd:command[@name='" .. name .. "']")
- current.used[#current.used+1] = setup
- xml.sprint(setup)
- end
-end
-
-function document.setups.showused()
- local current = document.setups.current
- if current.root and next(current.used) then
- local sorted = table.sortedkeys(current.used)
- for i=1,#sorted do
- xml.sprint(current.used[sorted[i]])
- end
- end
-end
-function document.setups.showall()
- local current = document.setups.current
- if current.root then
- local list = { }
- for e in xml.collected(current.root,"cd:command") do
- list[document.setups.name(e)] = e
- end
- local sorted = table.sortedkeys(list)
- for i=1,#sorted do
- xml.sprint(list[sorted[i]])
- end
- end
-end
-function document.setups.resolve(name)
- local current = document.setups.current
- if current.root then
- local e = xml.filter(current.root,format("cd:define[@name='%s']/text()",name))
- if e then
- xml.sprint(e)
- end
- end
-end
-
-function document.setups.collect(name,int,lastmode)
- local current = document.setups.current
- local formats = document.setups.formats
- local command = xml.filter(current.root,format("cd:command[@name='%s']/first()",name))
- if command then
- local attributes = command.at or { }
- local data = {
- command = command,
- category = attributes.category or "",
- }
- if document.setups.showsources then
- data.source = (attributes.file and format(formats.source,attributes.file,lastmode,attributes.file)) or ""
- else
- data.source = attributes.file or ""
- end
- local n, sequence, tags = 0, { }, { }
- sequence[#sequence+1] = format(formats.open_command[lastmode],document.setups.csname(command,int))
- local arguments, tag = { }, ""
- for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
- n = n + 1
- local attributes = d[k].at
- if #sequence > 1 then
- local c = formats.connector[lastmode]
- if c ~= "" then
- sequence[#sequence+1] = c
- end
- end
- if attributes.optional == 'yes' then
- if attributes.list == 'yes' then
- tag = format(formats.optional_list[lastmode],n)
- else
- tag = format(formats.optional_single[lastmode],n)
- end
- else
- if attributes.list == 'yes' then
- tag = format(formats.mandate_list[lastmode],n)
- else
- tag = format(formats.mandate_single[lastmode],n)
- end
- end
- sequence[#sequence+1] = tag
- tags[#tags+1] = tag
- end
- sequence[#sequence+1] = formats.close_command[lastmode]
- data.sequence = concat(sequence, " ")
- local parameters, n = { }, 0
- for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
- n = n + 1
- if d[k].tg == "keywords" then
- local left = tags[n]
- local right = { }
- for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do
- local tag = d[k].tg
- if tag == "resolve" then
- local name = d[k].at.name or ""
- if name ~= "" then
- local resolved = xml.filter(current.root,format("cd:define[@name='%s']",name))
- for r, d, k in xml.elements(resolved,"cd:constant") do
- right[#right+1] = translated(d[k],int)
- end
- end
- else
- right[#right+1] = translated(d[k],int)
- end
- end
- parameters[#parameters+1] = format(formats.parameter,left,"",concat(right, ", "))
- else
- local what = tags[n]
- for r, d, k in xml.elements(d[k],"(cd:parameter|cd:inherit)") do
- local tag = d[k].tg
- local left, right = d[k].at.name or "?", { }
- if tag == "inherit" then
- local name = d[k].at.name or "?"
- local goto = format(document.setups.formats.href_as_command[lastmode],name,lastmode,name)
- if #parameters > 0 and not find(parameters[#parameters],"<br/>") then
- parameters[#parameters+1] = format(formats.parameter,"<br/>","","")
- end
- parameters[#parameters+1] = format(formats.parameter,what,format(formats.special,translate("inherits",int)),goto)
- else
- for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do
- local tag = d[k].tg
- if tag == "resolve" then
- local name = d[k].at.name or ""
- if name ~= "" then
- local resolved = xml.filter(current.root,format("cd:define[@name='%s']",name))
- for r, d, k in xml.elements(resolved,"cd:constant") do
- right[#right+1] = translated(d[k],int)
- end
- end
- else
- right[#right+1] = translated(d[k],int)
- end
- end
- parameters[#parameters+1] = format(formats.parameter,what,left,concat(right, ", "))
- end
- what = ""
- end
- end
- parameters[#parameters+1] = format(formats.parameter,"<br/>","","")
- end
- data.parameters = parameters or { }
- data.mode = formats.modes[lastmode or "tex"]
- return data
- else
- return nil
- end
-end
-
--- -- --
-
-tex = tex or { }
-
--- -- --
-
-local interfaces = {
- czech = 'cz',
- dutch = 'nl',
- english = 'en',
- french = 'fr',
- german = 'de',
- italian = 'it',
- persian = 'pe',
- romanian = 'ro',
-}
-
-local lastinterface, lastcommand, lastsource, lastmode = "en", "", "", "tex"
-
-local variables = {
- ['color-background-main-left'] = '#3F3F3F',
- ['color-background-main-right'] = '#5F5F5F',
- ['color-background-one'] = lmx.get('color-background-green'),
- ['color-background-two'] = lmx.get('color-background-blue'),
- ['title'] = 'ConTeXt Help Information',
-}
-
---~ function lmx.loadedfile(filename)
---~ return io.loaddata(resolvers.findfile(filename)) -- return resolvers.texdatablob(filename)
---~ end
-
-local function doit(configuration,filename,hashed)
-
- local formats = document.setups.formats
-
- local start = os.clock()
- local detail = hashed.queries or { }
-
- if detail then
-
- lastinterface = detail.interface or lastinterface
- lastcommand = detail.command or lastcommand
- lastsource = detail.source or lastsource
- lastmode = detail.mode or lastmode or "tex"
-
- lastcommand = gsub(lastcommand,"%s*^\\*(.+)%s*","%1")
-
- if lastinterface then
- report("checking interface: %s",lastinterface)
- document.setups.load(format("cont-%s.xml",lastinterface))
- end
-
- local div = document.setups.div [lastinterface]
- local span = document.setups.span[lastinterface]
-
- local names, refs, ints = document.setups.names(lastinterface), { }, { }
- for k=1,#names do
- local v = names[k]
- refs[k] = format(formats.href_in_list[lastmode],v[1],lastmode,v[2])
- end
- if lastmode ~= "lua" then
- local sorted = table.sortedkeys(interfaces)
- for k=1,#sorted do
- local v = sorted[k]
- ints[k] = format(formats.interface,interfaces[v],lastmode,v)
- end
- end
-
- local n = concat(refs,"<br/>")
- local i = concat(ints,"<br/><br/>")
-
- if div then
- variables.names = format(div,n)
- variables.interfaces = format(div,i)
- else
- variables.names = n
- variables.interfaces = i
- end
-
- -- first we need to add information about mkii/mkiv
-
- variables.maintitle = "no definition"
- variables.maintext = ""
- variables.extra = ""
-
- if document.setups.showsources and lastsource and lastsource ~= "" then
- -- todo: mkii, mkiv, tex (can be different)
- local data = io.loaddata(resolvers.findfile(lastsource))
- variables.maintitle = lastsource
- variables.maintext = format(formats.listing,data)
- lastsource = ""
- elseif lastcommand and lastcommand ~= "" then
- local data = document.setups.collect(lastcommand,lastinterface,lastmode)
- if data then
- local what, extra = { "environment", "category", "source", "mode" }, { }
- for k=1,#what do
- local v = what[k]
- if data[v] and data[v] ~= "" then
- lmx.set(v, data[v])
- extra[#extra+1] = v .. ": " .. data[v]
- end
- end
- variables.maintitle = data.sequence
- variables.maintext = format(formats.parameters,concat(data.parameters))
- variables.extra = concat(extra,"&nbsp;&nbsp;&nbsp;")
- else
- variables.maintext = "select command"
- end
- end
-
- else
-
- variables.maintitle = "no definition"
- variables.maintext = "some error"
- variables.extra = ""
-
- end
-
- local content = lmx.convert('context-help.lmx',false,variables)
-
- report("time spent on page: %0.03f seconds",os.clock()-start)
-
- return { content = content }
-end
-
-return doit, true
+if not modules then modules = { } end modules ['mtx-server-ctx-help'] = {
+ version = 1.001,
+ comment = "Basic Definition Browser",
+ author = "Hans Hagen",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo in lua interface: noargument, oneargument, twoarguments, threearguments
+-- todo: pickup translations from mult file
+
+dofile(resolvers.findfile("trac-lmx.lua","tex"))
+
+-- problem ... serialize parent stack
+
+local format, match, gsub, find = string.format, string.match, string.gsub, string.find
+local concat = table.concat
+
+local report = logs.reporter("ctx-help")
+
+-- -- -- make this a module: cont-xx.lua
+
+document = document or { }
+document.setups = document.setups or { }
+
+document.setups.div = {
+ pe = "<div dir='rtl' lang='arabic'>%s</div>"
+}
+
+document.setups.span = {
+ pe = "<span dir='rtl' lang='arabic'>%s</span>"
+}
+
+document.setups.translations = document.setups.translations or {
+
+ nl = {
+ ["title"] = "setup",
+ ["formula"] = "formule",
+ ["number"] = "getal",
+ ["list"] = "lijst",
+ ["dimension"] = "maat",
+ ["mark"] = "markering",
+ ["reference"] = "verwijzing",
+ ["command"] = "commando",
+ ["file"] = "file",
+ ["name"] = "naam",
+ ["identifier"] = "naam",
+ ["text"] = "tekst",
+ ["section"] = "sectie",
+ ["singular"] = "naam enkelvoud",
+ ["plural"] = "naam meervoud",
+ ["matrix"] = "n*m",
+ ["see"] = "zie",
+ ["inherits"] = "erft van",
+ ["optional"] = "optioneel",
+ ["displaymath"] = "formule",
+ ["index"] = "ingang",
+ ["math"] = "formule",
+ ["nothing"] = "leeg",
+ ["file"] = "file",
+ ["position"] = "positie",
+ ["reference"] = "verwijzing",
+ ["csname"] = "naam",
+ ["destination"] = "bestemming",
+ ["triplet"] = "triplet",
+ ["word"] = "woord",
+ ["content"] = "tekst",
+ },
+
+ en = {
+ ["title"] = "setup",
+ ["formula"] = "formula",
+ ["number"] = "number",
+ ["list"] = "list",
+ ["dimension"] = "dimension",
+ ["mark"] = "mark",
+ ["reference"] = "reference",
+ ["command"] = "command",
+ ["file"] = "file",
+ ["name"] = "name",
+ ["identifier"] = "identifier",
+ ["text"] = "text",
+ ["section"] = "section",
+ ["singular"] = "singular name",
+ ["plural"] = "plural name",
+ ["matrix"] = "n*m",
+ ["see"] = "see",
+ ["inherits"] = "inherits from",
+ ["optional"] = "optional",
+ ["displaymath"] = "formula",
+ ["index"] = "entry",
+ ["math"] = "formula",
+ ["nothing"] = "empty",
+ ["file"] = "file",
+ ["position"] = "position",
+ ["reference"] = "reference",
+ ["csname"] = "name",
+ ["destination"] = "destination",
+ ["triplet"] = "triplet",
+ ["word"] = "word",
+ ["content"] = "text",
+
+ ["noargument"] = "\\cs",
+ ["oneargument"] = "\\cs#1{..}",
+ ["twoarguments"] = "\\cs#1#2{..}{..}",
+ ["threearguments"] = "\\cs#1#2#3{..}{..}{..}",
+
+ },
+
+ de = {
+ ["title"] = "Setup",
+ ["formula"] = "Formel",
+ ["number"] = "Nummer",
+ ["list"] = "Liste",
+ ["dimension"] = "Dimension",
+ ["mark"] = "Beschriftung",
+ ["reference"] = "Referenz",
+ ["command"] = "Befehl",
+ ["file"] = "Datei",
+ ["name"] = "Name",
+ ["identifier"] = "Name",
+ ["text"] = "Text",
+ ["section"] = "Abschnitt",
+ ["singular"] = "singular",
+ ["plural"] = "plural",
+ ["matrix"] = "n*m",
+ ["see"] = "siehe",
+ ["inherits"] = "inherits from",
+ ["optional"] = "optioneel",
+ ["displaymath"] = "formula",
+ ["index"] = "entry",
+ ["math"] = "formula",
+ ["nothing"] = "empty",
+ ["file"] = "file",
+ ["position"] = "position",
+ ["reference"] = "reference",
+ ["csname"] = "name",
+ ["destination"] = "destination",
+ ["triplet"] = "triplet",
+ ["word"] = "word",
+ ["content"] = "text",
+ },
+
+ cz = {
+ ["title"] = "setup",
+ ["formula"] = "rovnice",
+ ["number"] = "cislo",
+ ["list"] = "seznam",
+ ["dimension"] = "dimenze",
+ ["mark"] = "znacka",
+ ["reference"] = "reference",
+ ["command"] = "prikaz",
+ ["file"] = "soubor",
+ ["name"] = "jmeno",
+ ["identifier"] = "jmeno",
+ ["text"] = "text",
+ ["section"] = "sekce",
+ ["singular"] = "jmeno v singularu",
+ ["plural"] = "jmeno v pluralu",
+ ["matrix"] = "n*m",
+ ["see"] = "viz",
+ ["inherits"] = "inherits from",
+ ["optional"] = "optioneel",
+ ["displaymath"] = "formula",
+ ["index"] = "entry",
+ ["math"] = "formula",
+ ["nothing"] = "empty",
+ ["file"] = "file",
+ ["position"] = "position",
+ ["reference"] = "reference",
+ ["csname"] = "name",
+ ["destination"] = "destination",
+ ["triplet"] = "triplet",
+ ["word"] = "word",
+ ["content"] = "text",
+ },
+
+ it = {
+ ["title"] = "setup",
+ ["formula"] = "formula",
+ ["number"] = "number",
+ ["list"] = "list",
+ ["dimension"] = "dimension",
+ ["mark"] = "mark",
+ ["reference"] = "reference",
+ ["command"] = "command",
+ ["file"] = "file",
+ ["name"] = "name",
+ ["identifier"] = "name",
+ ["text"] = "text",
+ ["section"] = "section",
+ ["singular"] = "singular name",
+ ["plural"] = "plural name",
+ ["matrix"] = "n*m",
+ ["see"] = "see",
+ ["inherits"] = "inherits from",
+ ["optional"] = "optioneel",
+ ["displaymath"] = "formula",
+ ["index"] = "entry",
+ ["math"] = "formula",
+ ["nothing"] = "empty",
+ ["file"] = "file",
+ ["position"] = "position",
+ ["reference"] = "reference",
+ ["csname"] = "name",
+ ["destination"] = "destination",
+ ["triplet"] = "triplet",
+ ["word"] = "word",
+ ["content"] = "text",
+ },
+
+ ro = {
+ ["title"] = "setari",
+ ["formula"] = "formula",
+ ["number"] = "numar",
+ ["list"] = "lista",
+ ["dimension"] = "dimensiune",
+ ["mark"] = "marcaj",
+ ["reference"] = "referinta",
+ ["command"] = "comanda",
+ ["file"] = "fisier",
+ ["name"] = "nume",
+ ["identifier"] = "nume",
+ ["text"] = "text",
+ ["section"] = "sectiune",
+ ["singular"] = "nume singular",
+ ["plural"] = "nume pluram",
+ ["matrix"] = "n*m",
+ ["see"] = "vezi",
+ ["inherits"] = "inherits from",
+ ["optional"] = "optioneel",
+ ["displaymath"] = "formula",
+ ["index"] = "entry",
+ ["math"] = "formula",
+ ["nothing"] = "empty",
+ ["file"] = "file",
+ ["position"] = "position",
+ ["reference"] = "reference",
+ ["csname"] = "name",
+ ["destination"] = "destination",
+ ["triplet"] = "triplet",
+ ["word"] = "word",
+ ["content"] = "text",
+ },
+
+ fr = {
+ ["title"] = "réglage",
+ ["formula"] = "formule",
+ ["number"] = "numéro",
+ ["list"] = "liste",
+ ["dimension"] = "dimension",
+ ["mark"] = "marquage",
+ ["reference"] = "reference",
+ ["command"] = "commande",
+ ["file"] = "fichier",
+ ["name"] = "nom",
+ ["identifier"] = "identificateur",
+ ["text"] = "texte",
+ ["section"] = "section",
+ ["singular"] = "nom singulier",
+ ["plural"] = "nom pluriel",
+ ["matrix"] = "n*m",
+ ["see"] = "vois",
+ ["inherits"] = "herite de",
+ ["optional"] = "optionel",
+ ["displaymath"] = "formule",
+ ["index"] = "entrée",
+ ["math"] = "formule",
+ ["nothing"] = "vide",
+ ["file"] = "fichier",
+ ["position"] = "position",
+ ["reference"] = "réference",
+ ["csname"] = "nom",
+ ["destination"] = "destination",
+ ["triplet"] = "triplet",
+ ["word"] = "mot",
+ ["content"] = "texte",
+ }
+
+}
+
+document.setups.formats = {
+ open_command = {
+ tex = [[\%s]],
+ lua = [[context.%s (]],
+ },
+ close_command = {
+ tex = [[]],
+ lua = [[ )]],
+ },
+ connector = {
+ tex = [[]],
+ lua = [[, ]],
+ },
+ href_in_list = {
+ tex = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>]],
+ lua = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>]],
+ },
+ href_as_command = {
+ tex = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>\%s</a>]],
+ lua = [[<a href='mtx-server-ctx-help.lua?command=%s&mode=%s'>context.%s</a>]],
+ },
+ modes = {
+ tex = [[<a href='mtx-server-ctx-help.lua?mode=lua'>lua mode</a>]],
+ lua = [[<a href='mtx-server-ctx-help.lua?mode=tex'>tex mode</a>]],
+ },
+ optional_single = {
+ tex = "[optional string %s]",
+ lua = "{optional string %s}",
+ },
+ optional_list = {
+ tex = "[optional list %s]",
+ lua = "{optional table %s}" ,
+ } ,
+ mandate_single = {
+ tex = "[mandate string %s]",
+ lua = "{mandate string %s}",
+ },
+ mandate_list = {
+ tex = "[mandate list %s]",
+ lua = "{mandate list %s}",
+ },
+ interface = [[<a href='mtx-server-ctx-help.lua?interface=%s&mode=%s'>%s</a>]],
+ source = [[<a href='mtx-server-ctx-help.lua?source=%s&mode=%s'>%s</a>]],
+ parameter = [[<tr><td width='15%%'>%s</td><td width='15%%'>%s</td><td width='70%%'>%s</td></tr>]],
+ parameters = [[<table width='100%%'>%s</table>]],
+ listing = [[<pre><t>%s</t></listing>]],
+ special = [[<i>%s</i>]],
+ default = [[<u>%s</u>]],
+}
+
+local function translate(tag,int,noformat)
+ local t = document.setups.translations
+ local te = t["en"]
+ local ti = t[int] or te
+ if noformat then
+ return ti[tag] or te[tag] or tag
+ else
+ return format(document.setups.formats.special,ti[tag] or te[tag] or tag)
+ end
+end
+
+local function translated(e,int)
+ local attributes = e.at
+ local s = attributes.type or "?"
+ local tag = match(s,"^cd:(.*)$")
+ if attributes.default == "yes" then
+ return format(document.setups.formats.default,tag or "?")
+ elseif tag then
+ return translate(tag,int)
+ else
+ return s
+ end
+end
+
+document.setups.loaded = document.setups.loaded or { }
+
+document.setups.current = { }
+document.setups.showsources = true
+document.setups.mode = "tex"
+
+function document.setups.load(filename)
+ filename = resolvers.findfile(filename) or ""
+ if filename ~= "" then
+ local current = document.setups.loaded[filename]
+ if not current then
+ local loaded = xml.load(filename)
+ if loaded then
+ -- xml.inject(document.setups.root,"/",loaded)
+ current = {
+ file = filename,
+ root = loaded,
+ names = { },
+ used = { },
+ }
+ document.setups.loaded[filename] = current
+ end
+ end
+ document.setups.current = current or { }
+ end
+end
+
+function document.setups.name(ek)
+ local at = ek.at
+ local name = at.name
+ if at.type == 'environment' then
+ name = "start" .. name
+ end
+ if at.variant then
+ name = name .. ":" .. at.variant
+ end
+ if at.generated == "yes" then
+ name = name .. "*"
+ end
+ return name:lower()
+end
+
+function document.setups.csname(ek,int)
+ local cs = ""
+ local at = ek.at or { }
+ if at.type == 'environment' then
+ cs = translate("start",int,true) .. cs
+ end
+ for e in xml.collected(ek,'cd:sequence/(cd:string|variable)') do
+ if e.tg == "string" then
+ cs = cs .. e.at.value
+ else
+ cs = cs .. e.at.value -- to be translated
+ end
+ end
+ return cs
+end
+
+function document.setups.names()
+ local current = document.setups.current
+ local names = current.names
+ if not names or #names == 0 then
+ names = { }
+ local name = document.setups.name
+ local csname = document.setups.csname
+ for e in xml.collected(current.root,'cd:command') do
+ names[#names+1] = { e.at.name, csname(e,int) }
+ end
+ table.sort(names, function(a,b) return a[2]:lower() < b[2]:lower() end)
+ current.names = names
+ end
+ return names
+end
+
+function document.setups.show(name)
+ local current = document.setups.current
+ if current.root then
+ local name = gsub(name,"[<>]","")
+ local setup = xml.first(current.root,"cd:command[@name='" .. name .. "']")
+ current.used[#current.used+1] = setup
+ xml.sprint(setup)
+ end
+end
+
+function document.setups.showused()
+ local current = document.setups.current
+ if current.root and next(current.used) then
+ local sorted = table.sortedkeys(current.used)
+ for i=1,#sorted do
+ xml.sprint(current.used[sorted[i]])
+ end
+ end
+end
+function document.setups.showall()
+ local current = document.setups.current
+ if current.root then
+ local list = { }
+ for e in xml.collected(current.root,"cd:command") do
+ list[document.setups.name(e)] = e
+ end
+ local sorted = table.sortedkeys(list)
+ for i=1,#sorted do
+ xml.sprint(list[sorted[i]])
+ end
+ end
+end
+function document.setups.resolve(name)
+ local current = document.setups.current
+ if current.root then
+ local e = xml.filter(current.root,format("cd:define[@name='%s']/text()",name))
+ if e then
+ xml.sprint(e)
+ end
+ end
+end
+
+function document.setups.collect(name,int,lastmode)
+ local current = document.setups.current
+ local formats = document.setups.formats
+ local command = xml.filter(current.root,format("cd:command[@name='%s']/first()",name))
+ if command then
+ local attributes = command.at or { }
+ local data = {
+ command = command,
+ category = attributes.category or "",
+ }
+ if document.setups.showsources then
+ data.source = (attributes.file and format(formats.source,attributes.file,lastmode,attributes.file)) or ""
+ else
+ data.source = attributes.file or ""
+ end
+ local n, sequence, tags = 0, { }, { }
+ sequence[#sequence+1] = format(formats.open_command[lastmode],document.setups.csname(command,int))
+ local arguments, tag = { }, ""
+ for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
+ n = n + 1
+ local attributes = d[k].at
+ if #sequence > 1 then
+ local c = formats.connector[lastmode]
+ if c ~= "" then
+ sequence[#sequence+1] = c
+ end
+ end
+ if attributes.optional == 'yes' then
+ if attributes.list == 'yes' then
+ tag = format(formats.optional_list[lastmode],n)
+ else
+ tag = format(formats.optional_single[lastmode],n)
+ end
+ else
+ if attributes.list == 'yes' then
+ tag = format(formats.mandate_list[lastmode],n)
+ else
+ tag = format(formats.mandate_single[lastmode],n)
+ end
+ end
+ sequence[#sequence+1] = tag
+ tags[#tags+1] = tag
+ end
+ sequence[#sequence+1] = formats.close_command[lastmode]
+ data.sequence = concat(sequence, " ")
+ local parameters, n = { }, 0
+ for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
+ n = n + 1
+ if d[k].tg == "keywords" then
+ local left = tags[n]
+ local right = { }
+ for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do
+ local tag = d[k].tg
+ if tag == "resolve" then
+ local name = d[k].at.name or ""
+ if name ~= "" then
+ local resolved = xml.filter(current.root,format("cd:define[@name='%s']",name))
+ for r, d, k in xml.elements(resolved,"cd:constant") do
+ right[#right+1] = translated(d[k],int)
+ end
+ end
+ else
+ right[#right+1] = translated(d[k],int)
+ end
+ end
+ parameters[#parameters+1] = format(formats.parameter,left,"",concat(right, ", "))
+ else
+ local what = tags[n]
+ for r, d, k in xml.elements(d[k],"(cd:parameter|cd:inherit)") do
+ local tag = d[k].tg
+ local left, right = d[k].at.name or "?", { }
+ if tag == "inherit" then
+ local name = d[k].at.name or "?"
+ local goto = format(document.setups.formats.href_as_command[lastmode],name,lastmode,name)
+ if #parameters > 0 and not find(parameters[#parameters],"<br/>") then
+ parameters[#parameters+1] = format(formats.parameter,"<br/>","","")
+ end
+ parameters[#parameters+1] = format(formats.parameter,what,format(formats.special,translate("inherits",int)),goto)
+ else
+ for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do
+ local tag = d[k].tg
+ if tag == "resolve" then
+ local name = d[k].at.name or ""
+ if name ~= "" then
+ local resolved = xml.filter(current.root,format("cd:define[@name='%s']",name))
+ for r, d, k in xml.elements(resolved,"cd:constant") do
+ right[#right+1] = translated(d[k],int)
+ end
+ end
+ else
+ right[#right+1] = translated(d[k],int)
+ end
+ end
+ parameters[#parameters+1] = format(formats.parameter,what,left,concat(right, ", "))
+ end
+ what = ""
+ end
+ end
+ parameters[#parameters+1] = format(formats.parameter,"<br/>","","")
+ end
+ data.parameters = parameters or { }
+ data.mode = formats.modes[lastmode or "tex"]
+ return data
+ else
+ return nil
+ end
+end
+
+-- -- --
+
+tex = tex or { }
+
+-- -- --
+
+local interfaces = {
+ czech = 'cz',
+ dutch = 'nl',
+ english = 'en',
+ french = 'fr',
+ german = 'de',
+ italian = 'it',
+ persian = 'pe',
+ romanian = 'ro',
+}
+
+local lastinterface, lastcommand, lastsource, lastmode = "en", "", "", "tex"
+
+local variables = {
+ ['color-background-main-left'] = '#3F3F3F',
+ ['color-background-main-right'] = '#5F5F5F',
+ ['color-background-one'] = lmx.get('color-background-green'),
+ ['color-background-two'] = lmx.get('color-background-blue'),
+ ['title'] = 'ConTeXt Help Information',
+}
+
+--~ function lmx.loadedfile(filename)
+--~ return io.loaddata(resolvers.findfile(filename)) -- return resolvers.texdatablob(filename)
+--~ end
+
+local function doit(configuration,filename,hashed)
+
+ local formats = document.setups.formats
+
+ local start = os.clock()
+ local detail = hashed.queries or { }
+
+ if detail then
+
+ lastinterface = detail.interface or lastinterface
+ lastcommand = detail.command or lastcommand
+ lastsource = detail.source or lastsource
+ lastmode = detail.mode or lastmode or "tex"
+
+ lastcommand = gsub(lastcommand,"%s*^\\*(.+)%s*","%1")
+
+ if lastinterface then
+ report("checking interface: %s",lastinterface)
+ document.setups.load(format("cont-%s.xml",lastinterface))
+ end
+
+ local div = document.setups.div [lastinterface]
+ local span = document.setups.span[lastinterface]
+
+ local names, refs, ints = document.setups.names(lastinterface), { }, { }
+ for k=1,#names do
+ local v = names[k]
+ refs[k] = format(formats.href_in_list[lastmode],v[1],lastmode,v[2])
+ end
+ if lastmode ~= "lua" then
+ local sorted = table.sortedkeys(interfaces)
+ for k=1,#sorted do
+ local v = sorted[k]
+ ints[k] = format(formats.interface,interfaces[v],lastmode,v)
+ end
+ end
+
+ local n = concat(refs,"<br/>")
+ local i = concat(ints,"<br/><br/>")
+
+ if div then
+ variables.names = format(div,n)
+ variables.interfaces = format(div,i)
+ else
+ variables.names = n
+ variables.interfaces = i
+ end
+
+ -- first we need to add information about mkii/mkiv
+
+ variables.maintitle = "no definition"
+ variables.maintext = ""
+ variables.extra = ""
+
+ if document.setups.showsources and lastsource and lastsource ~= "" then
+ -- todo: mkii, mkiv, tex (can be different)
+ local data = io.loaddata(resolvers.findfile(lastsource))
+ variables.maintitle = lastsource
+ variables.maintext = format(formats.listing,data)
+ lastsource = ""
+ elseif lastcommand and lastcommand ~= "" then
+ local data = document.setups.collect(lastcommand,lastinterface,lastmode)
+ if data then
+ local what, extra = { "environment", "category", "source", "mode" }, { }
+ for k=1,#what do
+ local v = what[k]
+ if data[v] and data[v] ~= "" then
+ lmx.set(v, data[v])
+ extra[#extra+1] = v .. ": " .. data[v]
+ end
+ end
+ variables.maintitle = data.sequence
+ variables.maintext = format(formats.parameters,concat(data.parameters))
+ variables.extra = concat(extra,"&nbsp;&nbsp;&nbsp;")
+ else
+ variables.maintext = "select command"
+ end
+ end
+
+ else
+
+ variables.maintitle = "no definition"
+ variables.maintext = "some error"
+ variables.extra = ""
+
+ end
+
+ local content = lmx.convert('context-help.lmx',false,variables)
+
+ report("time spent on page: %0.03f seconds",os.clock()-start)
+
+ return { content = content }
+end
+
+return doit, true
diff --git a/scripts/context/lua/mtx-server-ctx-startup.lua b/scripts/context/lua/mtx-server-ctx-startup.lua
index 8e99e6371..556805113 100644
--- a/scripts/context/lua/mtx-server-ctx-startup.lua
+++ b/scripts/context/lua/mtx-server-ctx-startup.lua
@@ -1,39 +1,39 @@
-if not modules then modules = { } end modules ['mtx-server-ctx-startup'] = {
- version = 1.001,
- comment = "Overview Of Goodies",
- author = "Hans Hagen",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-dofile(resolvers.findfile("trac-lmx.lua","tex"))
-
-function doit(configuration,filename,hashed)
-
- local list = { }
- local root = file.dirname(resolvers.findfile("mtx-server.lua") or ".")
- if root == "" then root = "." end
- local pattern = root .. "/mtx-server-ctx-*.lua"
- local files = dir.glob(pattern)
- for i=1,#files do
- local filename = file.basename(files[i])
- local name = string.match(filename,"mtx%-server%-ctx%-(.-)%.lua$")
- if name and name ~= "startup" then
- list[#list+1] = string.format("<a href='%s' target='ctx-%s'>%s</a><br/><br/>",filename,name,name)
- end
- end
-
- local variables = {
- ['color-background-one'] = lmx.get('color-background-green'),
- ['color-background-two'] = lmx.get('color-background-blue'),
- ['title'] = "Overview Of Goodies",
- ['color-background-one'] = lmx.get('color-background-green'),
- ['color-background-two'] = lmx.get('color-background-blue'),
- ['maintext'] = table.concat(list,"\n"),
- }
-
- return { content = lmx.convert('context-base.lmx',false,variables) }
-
-end
-
-return doit, true
+if not modules then modules = { } end modules ['mtx-server-ctx-startup'] = {
+ version = 1.001,
+ comment = "Overview Of Goodies",
+ author = "Hans Hagen",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+dofile(resolvers.findfile("trac-lmx.lua","tex"))
+
+function doit(configuration,filename,hashed)
+
+ local list = { }
+ local root = file.dirname(resolvers.findfile("mtx-server.lua") or ".")
+ if root == "" then root = "." end
+ local pattern = root .. "/mtx-server-ctx-*.lua"
+ local files = dir.glob(pattern)
+ for i=1,#files do
+ local filename = file.basename(files[i])
+ local name = string.match(filename,"mtx%-server%-ctx%-(.-)%.lua$")
+ if name and name ~= "startup" then
+ list[#list+1] = string.format("<a href='%s' target='ctx-%s'>%s</a><br/><br/>",filename,name,name)
+ end
+ end
+
+ local variables = {
+ ['color-background-one'] = lmx.get('color-background-green'),
+ ['color-background-two'] = lmx.get('color-background-blue'),
+ ['title'] = "Overview Of Goodies",
+ ['color-background-one'] = lmx.get('color-background-green'),
+ ['color-background-two'] = lmx.get('color-background-blue'),
+ ['maintext'] = table.concat(list,"\n"),
+ }
+
+ return { content = lmx.convert('context-base.lmx',false,variables) }
+
+end
+
+return doit, true
diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua
index 675ab2c62..5ec15de70 100644
--- a/scripts/context/lua/mtx-server.lua
+++ b/scripts/context/lua/mtx-server.lua
@@ -1,402 +1,402 @@
-if not modules then modules = { } end modules ['mtx-server'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen & Taco Hoekwater",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-server</entry>
- <entry name="detail">Simple Webserver For Helpers</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="start"><short>start server</short></flag>
- <flag name="port"><short>port to listen to</short></flag>
- <flag name="root"><short>server root</short></flag>
- <flag name="scripts"><short>scripts sub path</short></flag>
- <flag name="index"><short>index file</short></flag>
- <flag name="auto"><short>start on own path</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-server",
- banner = "Simple Webserver For Helpers 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.webserver = scripts.webserver or { }
-
-dofile(resolvers.findfile("luat-soc.lua","tex"))
-
-local socket = socket or require("socket")
-local http = http or require("socket.http") -- not needed
-local format = string.format
-
--- The following two lists are taken from webrick (ruby) and
--- extended with a few extra suffixes.
-
-local mimetypes = {
- ai = 'application/postscript',
- asc = 'text/plain',
- avi = 'video/x-msvideo',
- bin = 'application/octet-stream',
- bmp = 'image/bmp',
- bz2 = 'application/x-bzip2',
- cer = 'application/pkix-cert',
- class = 'application/octet-stream',
- crl = 'application/pkix-crl',
- crt = 'application/x-x509-ca-cert',
- css = 'text/css',
- dms = 'application/octet-stream',
- doc = 'application/msword',
- dvi = 'application/x-dvi',
- eps = 'application/postscript',
- etx = 'text/x-setext',
- exe = 'application/octet-stream',
- gif = 'image/gif',
- gz = 'application/x-tar',
- hqx = 'application/mac-binhex40',
- htm = 'text/html',
- html = 'text/html',
- jpe = 'image/jpeg',
- jpeg = 'image/jpeg',
- jpg = 'image/jpeg',
- lha = 'application/octet-stream',
- lzh = 'application/octet-stream',
- mov = 'video/quicktime',
- mpe = 'video/mpeg',
- mpeg = 'video/mpeg',
- mpg = 'video/mpeg',
- pbm = 'image/x-portable-bitmap',
- pdf = 'application/pdf',
- pgm = 'image/x-portable-graymap',
- png = 'image/png',
- pnm = 'image/x-portable-anymap',
- ppm = 'image/x-portable-pixmap',
- ppt = 'application/vnd.ms-powerpoint',
- ps = 'application/postscript',
- qt = 'video/quicktime',
- ras = 'image/x-cmu-raster',
- rb = 'text/plain',
- rd = 'text/plain',
- rgb = 'image/x-rgb',
- rtf = 'application/rtf',
- sgm = 'text/sgml',
- sgml = 'text/sgml',
- snd = 'audio/basic',
- tar = 'application/x-tar',
- tgz = 'application/x-tar',
- tif = 'image/tiff',
- tiff = 'image/tiff',
- txt = 'text/plain',
- xbm = 'image/x-xbitmap',
- xls = 'application/vnd.ms-excel',
- xml = 'text/xml',
- xpm = 'image/x-xpixmap',
- xwd = 'image/x-xwindowdump',
- zip = 'application/zip',
-}
-
-local messages = {
- [100] = 'Continue',
- [101] = 'Switching Protocols',
- [200] = 'OK',
- [201] = 'Created',
- [202] = 'Accepted',
- [203] = 'Non-Authoritative Information',
- [204] = 'No Content',
- [205] = 'Reset Content',
- [206] = 'Partial Content',
- [300] = 'Multiple Choices',
- [301] = 'Moved Permanently',
- [302] = 'Found',
- [303] = 'See Other',
- [304] = 'Not Modified',
- [305] = 'Use Proxy',
- [307] = 'Temporary Redirect',
- [400] = 'Bad Request',
- [401] = 'Unauthorized',
- [402] = 'Payment Required',
- [403] = 'Forbidden',
- [404] = 'Not Found',
- [405] = 'Method Not Allowed',
- [406] = 'Not Acceptable',
- [407] = 'Proxy Authentication Required',
- [408] = 'Request Timeout',
- [409] = 'Conflict',
- [410] = 'Gone',
- [411] = 'Length Required',
- [412] = 'Precondition Failed',
- [413] = 'Request Entity Too Large',
- [414] = 'Request-URI Too Large',
- [415] = 'Unsupported Media Type',
- [416] = 'Request Range Not Satisfiable',
- [417] = 'Expectation Failed',
- [500] = 'Internal Server Error',
- [501] = 'Not Implemented',
- [502] = 'Bad Gateway',
- [503] = 'Service Unavailable',
- [504] = 'Gateway Timeout',
- [505] = 'HTTP Version Not Supported',
-}
-
-local handlers = { }
-
-local function errormessage(client,configuration,n)
- local data = format("<head><title>%s %s</title></head><html><h2>%s %s</h2></html>",n,messages[n],n,messages[n])
- report("handling error %s: %s",n,messages[n])
- handlers.generic(client,configuration,data,nil,true)
-end
-
-local validpaths, registered = { }, { }
-
-function scripts.webserver.registerpath(name)
- if not registered[name] then
- local cleanname = string.gsub(name,"%.%.","deleted-parent")
- report("registering path '%s'",cleanname)
- validpaths[#validpaths+1] = cleanname
- registered[name] = true
- end
-end
-
-function handlers.generic(client,configuration,data,suffix,iscontent)
- if not iscontent then
- local name = data
- report("requested file '%s'",name)
- local fullname = file.join(configuration.root,name)
- data = io.loaddata(fullname) or ""
- if data == "" then
- for n=1,#validpaths do
- local fullname = file.join(validpaths[n],name)
- data = io.loaddata(fullname) or ""
- if data ~= "" then
- report("sending generic file '%s'",fullname)
- break
- end
- end
- else
- report("sending generic file '%s'",fullname)
- end
- end
- if data and data ~= "" then
- client:send("HTTP/1.1 200 OK\r\n")
- client:send("Connection: close\r\n")
- client:send(format("Content-Length: %s\r\n",#data))
- client:send(format("Content-Type: %s\r\n",(suffix and mimetypes[suffix]) or "text/html"))
- client:send("\r\n")
- client:send(data)
- client:send("\r\n")
- else
- errormessage(client,configuration,404)
- end
-end
-
--- return os.date()
-
--- return { content = "crap" }
-
--- return function(configuration,filename)
--- return { content = filename }
--- end
-
-local loaded = { }
-
-function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) -- filename will disappear, and become hashed.filename
- local filename = file.join(configuration.scripts,filename)
- if not file.is_qualified_path(filename) then
- filename = file.join(configuration.root,filename)
- end
- -- todo: split url in components, see l-url; rather trivial
- local result, keep = loaded[filename], false
- if result then
- report("reusing script: %s",filename)
- else
- report("locating script: %s",filename)
- if lfs.isfile(filename) then
- report("loading script: %s",filename)
- result = loadfile(filename)
- report("return type: %s",type(result))
- if result and type(result) == "function" then
- -- result() should return a table { [type=,] [length=,] content= }, function or string
- result, keep = result()
- if keep then
- report("saving script: %s",type(result))
- loaded[filename] = result
- end
- end
- else
- report("problematic script: %s",filename)
- errormessage(client,configuration,404)
- end
- end
- if result then
- if type(result) == "function" then
- report("running script: %s",filename)
- result = result(configuration,filename,hashed) -- second argument will become query
- end
- if result and type(result) == "string" then
- result = { content = result }
- end
- if result and type(result) == "table" then
- if result.content then
- local suffix = result.type or "text/html"
- local action = handlers[suffix] or handlers.generic
- action(client,configuration,result.content,suffix,true) -- content
- elseif result.filename then
- local suffix = file.suffix(result.filename) or "text/html"
- local action = handlers[suffix] or handlers.generic
- action(client,configuration,result.filename,suffix,false) -- filename
- else
- errormessage(client,configuration,404)
- end
- else
- errormessage(client,configuration,500)
- end
- else
- errormessage(client,configuration,404)
- end
-end
-
-handlers.luc = handlers.lua
-handlers.html = handlers.htm
-
-local indices = { "index.htm", "index.html" }
-local portnumber = 31415 -- pi suits tex
-
-function scripts.webserver.run(configuration)
- -- check configuration
- configuration.port = tonumber(configuration.port or os.getenv("MTX_SERVER_PORT") or portnumber) or portnumber
- if not configuration.root or not lfs.isdir(configuration.root) then
- configuration.root = os.getenv("MTX_SERVER_ROOT") or "."
- end
- -- locate root and index file in tex tree
- if not lfs.isdir(configuration.root) then
- for i=1,#indices do
- local name = indices[i]
- local root = resolvers.resolve("path:" .. name) or ""
- if root ~= "" then
- configuration.root = root
- configuration.index = configuration.index or name
- break
- end
- end
- end
- configuration.root = dir.expandname(configuration.root)
- if not configuration.index then
- for i=1,#indices do
- local name = indices[i]
- if lfs.isfile(file.join(configuration.root,name)) then
- configuration.index = name -- we will prepend the rootpath later
- break
- end
- end
- configuration.index = configuration.index or "unknown"
- end
- if not configuration.scripts or configuration.scripts == "" then
- configuration.scripts = dir.expandname(file.join(configuration.root or ".",configuration.scripts or "."))
- end
- -- so far for checks
- report("running at port: %s",configuration.port)
- report("document root: %s",configuration.root or resolvers.ownpath)
- report("main index file: %s",configuration.index)
- report("scripts subpath: %s",configuration.scripts)
- report("context services: http://localhost:%s/mtx-server-ctx-startup.lua",configuration.port)
- local server = assert(socket.bind("*", configuration.port))
- local script = configuration.script
- while true do -- blocking
- local start = os.clock()
- local client = server:accept()
- client:settimeout(configuration.timeout or 60)
- local request, e = client:receive()
- if e then
- errormessage(client,configuration,404)
- else
- local from = client:getpeername()
- report("request from: %s",tostring(from))
- report("request data: %s",tostring(request))
- local fullurl = string.match(request,"GET (.+) HTTP/.*$") or "" -- todo: more clever / post
- if fullurl == "" then
- report("no url")
- errormessage(client,configuration,404)
- else
- report("requested url: %s",fullurl)
- fullurl = socket.url.unescape(fullurl) -- still needed?
- local hashed = url.hashed(fullurl)
- local query = url.query(hashed.query)
- local filename = hashed.path -- hm, not query?
- if script then
- filename = script
- report("forced script: %s",filename)
- local suffix = file.suffix(filename)
- local action = handlers[suffix] or handlers.generic
- if action then
- report("performing action: %s",filename)
- action(client,configuration,filename,suffix,false,hashed) -- filename and no content
- else
- errormessage(client,configuration,404)
- end
- elseif filename then
- filename = socket.url.unescape(filename)
- report("requested action: %s",filename)
- if string.find(filename,"%.%.") then
- filename = nil -- invalid path
- end
- if filename == nil or filename == "" or filename == "/" then
- filename = configuration.index
- report("invalid filename, forcing: %s",filename)
- end
- local suffix = file.suffix(filename)
- local action = handlers[suffix] or handlers.generic
- if action then
- report("performing action: %s",filename)
- action(client,configuration,filename,suffix,false,hashed) -- filename and no content
- else
- errormessage(client,configuration,404)
- end
- else
- errormessage(client,configuration,404)
- end
- end
- end
- client:close()
- report("time spent with client: %0.03f seconds",os.clock()-start)
- end
-end
-
-if environment.argument("auto") then
- local path = resolvers.findfile("mtx-server.lua") or "."
- scripts.webserver.run {
- port = environment.argument("port"),
- root = environment.argument("root") or file.dirname(path) or ".",
- scripts = environment.argument("scripts") or file.dirname(path) or ".",
- script = environment.argument("script"),
- }
-elseif environment.argument("start") then
- scripts.webserver.run {
- port = environment.argument("port"),
- root = environment.argument("root") or ".", -- "e:/websites/www.pragma-ade.com",
- index = environment.argument("index"),
- scripts = environment.argument("scripts"),
- script = environment.argument("script"),
- }
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
-
--- mtxrun --script server --start => http://localhost:31415/mtx-server-ctx-startup.lua
+if not modules then modules = { } end modules ['mtx-server'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen & Taco Hoekwater",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-server</entry>
+ <entry name="detail">Simple Webserver For Helpers</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="start"><short>start server</short></flag>
+ <flag name="port"><short>port to listen to</short></flag>
+ <flag name="root"><short>server root</short></flag>
+ <flag name="scripts"><short>scripts sub path</short></flag>
+ <flag name="index"><short>index file</short></flag>
+ <flag name="auto"><short>start on own path</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-server",
+ banner = "Simple Webserver For Helpers 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.webserver = scripts.webserver or { }
+
+dofile(resolvers.findfile("luat-soc.lua","tex"))
+
+local socket = socket or require("socket")
+local http = http or require("socket.http") -- not needed
+local format = string.format
+
+-- The following two lists are taken from webrick (ruby) and
+-- extended with a few extra suffixes.
+
+local mimetypes = {
+ ai = 'application/postscript',
+ asc = 'text/plain',
+ avi = 'video/x-msvideo',
+ bin = 'application/octet-stream',
+ bmp = 'image/bmp',
+ bz2 = 'application/x-bzip2',
+ cer = 'application/pkix-cert',
+ class = 'application/octet-stream',
+ crl = 'application/pkix-crl',
+ crt = 'application/x-x509-ca-cert',
+ css = 'text/css',
+ dms = 'application/octet-stream',
+ doc = 'application/msword',
+ dvi = 'application/x-dvi',
+ eps = 'application/postscript',
+ etx = 'text/x-setext',
+ exe = 'application/octet-stream',
+ gif = 'image/gif',
+ gz = 'application/x-tar',
+ hqx = 'application/mac-binhex40',
+ htm = 'text/html',
+ html = 'text/html',
+ jpe = 'image/jpeg',
+ jpeg = 'image/jpeg',
+ jpg = 'image/jpeg',
+ lha = 'application/octet-stream',
+ lzh = 'application/octet-stream',
+ mov = 'video/quicktime',
+ mpe = 'video/mpeg',
+ mpeg = 'video/mpeg',
+ mpg = 'video/mpeg',
+ pbm = 'image/x-portable-bitmap',
+ pdf = 'application/pdf',
+ pgm = 'image/x-portable-graymap',
+ png = 'image/png',
+ pnm = 'image/x-portable-anymap',
+ ppm = 'image/x-portable-pixmap',
+ ppt = 'application/vnd.ms-powerpoint',
+ ps = 'application/postscript',
+ qt = 'video/quicktime',
+ ras = 'image/x-cmu-raster',
+ rb = 'text/plain',
+ rd = 'text/plain',
+ rgb = 'image/x-rgb',
+ rtf = 'application/rtf',
+ sgm = 'text/sgml',
+ sgml = 'text/sgml',
+ snd = 'audio/basic',
+ tar = 'application/x-tar',
+ tgz = 'application/x-tar',
+ tif = 'image/tiff',
+ tiff = 'image/tiff',
+ txt = 'text/plain',
+ xbm = 'image/x-xbitmap',
+ xls = 'application/vnd.ms-excel',
+ xml = 'text/xml',
+ xpm = 'image/x-xpixmap',
+ xwd = 'image/x-xwindowdump',
+ zip = 'application/zip',
+}
+
+local messages = {
+ [100] = 'Continue',
+ [101] = 'Switching Protocols',
+ [200] = 'OK',
+ [201] = 'Created',
+ [202] = 'Accepted',
+ [203] = 'Non-Authoritative Information',
+ [204] = 'No Content',
+ [205] = 'Reset Content',
+ [206] = 'Partial Content',
+ [300] = 'Multiple Choices',
+ [301] = 'Moved Permanently',
+ [302] = 'Found',
+ [303] = 'See Other',
+ [304] = 'Not Modified',
+ [305] = 'Use Proxy',
+ [307] = 'Temporary Redirect',
+ [400] = 'Bad Request',
+ [401] = 'Unauthorized',
+ [402] = 'Payment Required',
+ [403] = 'Forbidden',
+ [404] = 'Not Found',
+ [405] = 'Method Not Allowed',
+ [406] = 'Not Acceptable',
+ [407] = 'Proxy Authentication Required',
+ [408] = 'Request Timeout',
+ [409] = 'Conflict',
+ [410] = 'Gone',
+ [411] = 'Length Required',
+ [412] = 'Precondition Failed',
+ [413] = 'Request Entity Too Large',
+ [414] = 'Request-URI Too Large',
+ [415] = 'Unsupported Media Type',
+ [416] = 'Request Range Not Satisfiable',
+ [417] = 'Expectation Failed',
+ [500] = 'Internal Server Error',
+ [501] = 'Not Implemented',
+ [502] = 'Bad Gateway',
+ [503] = 'Service Unavailable',
+ [504] = 'Gateway Timeout',
+ [505] = 'HTTP Version Not Supported',
+}
+
+local handlers = { }
+
+local function errormessage(client,configuration,n)
+ local data = format("<head><title>%s %s</title></head><html><h2>%s %s</h2></html>",n,messages[n],n,messages[n])
+ report("handling error %s: %s",n,messages[n])
+ handlers.generic(client,configuration,data,nil,true)
+end
+
+local validpaths, registered = { }, { }
+
+function scripts.webserver.registerpath(name)
+ if not registered[name] then
+ local cleanname = string.gsub(name,"%.%.","deleted-parent")
+ report("registering path '%s'",cleanname)
+ validpaths[#validpaths+1] = cleanname
+ registered[name] = true
+ end
+end
+
+function handlers.generic(client,configuration,data,suffix,iscontent)
+ if not iscontent then
+ local name = data
+ report("requested file '%s'",name)
+ local fullname = file.join(configuration.root,name)
+ data = io.loaddata(fullname) or ""
+ if data == "" then
+ for n=1,#validpaths do
+ local fullname = file.join(validpaths[n],name)
+ data = io.loaddata(fullname) or ""
+ if data ~= "" then
+ report("sending generic file '%s'",fullname)
+ break
+ end
+ end
+ else
+ report("sending generic file '%s'",fullname)
+ end
+ end
+ if data and data ~= "" then
+ client:send("HTTP/1.1 200 OK\r\n")
+ client:send("Connection: close\r\n")
+ client:send(format("Content-Length: %s\r\n",#data))
+ client:send(format("Content-Type: %s\r\n",(suffix and mimetypes[suffix]) or "text/html"))
+ client:send("\r\n")
+ client:send(data)
+ client:send("\r\n")
+ else
+ errormessage(client,configuration,404)
+ end
+end
+
+-- return os.date()
+
+-- return { content = "crap" }
+
+-- return function(configuration,filename)
+-- return { content = filename }
+-- end
+
+local loaded = { }
+
+function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) -- filename will disappear, and become hashed.filename
+ local filename = file.join(configuration.scripts,filename)
+ if not file.is_qualified_path(filename) then
+ filename = file.join(configuration.root,filename)
+ end
+ -- todo: split url in components, see l-url; rather trivial
+ local result, keep = loaded[filename], false
+ if result then
+ report("reusing script: %s",filename)
+ else
+ report("locating script: %s",filename)
+ if lfs.isfile(filename) then
+ report("loading script: %s",filename)
+ result = loadfile(filename)
+ report("return type: %s",type(result))
+ if result and type(result) == "function" then
+ -- result() should return a table { [type=,] [length=,] content= }, function or string
+ result, keep = result()
+ if keep then
+ report("saving script: %s",type(result))
+ loaded[filename] = result
+ end
+ end
+ else
+ report("problematic script: %s",filename)
+ errormessage(client,configuration,404)
+ end
+ end
+ if result then
+ if type(result) == "function" then
+ report("running script: %s",filename)
+ result = result(configuration,filename,hashed) -- second argument will become query
+ end
+ if result and type(result) == "string" then
+ result = { content = result }
+ end
+ if result and type(result) == "table" then
+ if result.content then
+ local suffix = result.type or "text/html"
+ local action = handlers[suffix] or handlers.generic
+ action(client,configuration,result.content,suffix,true) -- content
+ elseif result.filename then
+ local suffix = file.suffix(result.filename) or "text/html"
+ local action = handlers[suffix] or handlers.generic
+ action(client,configuration,result.filename,suffix,false) -- filename
+ else
+ errormessage(client,configuration,404)
+ end
+ else
+ errormessage(client,configuration,500)
+ end
+ else
+ errormessage(client,configuration,404)
+ end
+end
+
+handlers.luc = handlers.lua
+handlers.html = handlers.htm
+
+local indices = { "index.htm", "index.html" }
+local portnumber = 31415 -- pi suits tex
+
+function scripts.webserver.run(configuration)
+ -- check configuration
+ configuration.port = tonumber(configuration.port or os.getenv("MTX_SERVER_PORT") or portnumber) or portnumber
+ if not configuration.root or not lfs.isdir(configuration.root) then
+ configuration.root = os.getenv("MTX_SERVER_ROOT") or "."
+ end
+ -- locate root and index file in tex tree
+ if not lfs.isdir(configuration.root) then
+ for i=1,#indices do
+ local name = indices[i]
+ local root = resolvers.resolve("path:" .. name) or ""
+ if root ~= "" then
+ configuration.root = root
+ configuration.index = configuration.index or name
+ break
+ end
+ end
+ end
+ configuration.root = dir.expandname(configuration.root)
+ if not configuration.index then
+ for i=1,#indices do
+ local name = indices[i]
+ if lfs.isfile(file.join(configuration.root,name)) then
+ configuration.index = name -- we will prepend the rootpath later
+ break
+ end
+ end
+ configuration.index = configuration.index or "unknown"
+ end
+ if not configuration.scripts or configuration.scripts == "" then
+ configuration.scripts = dir.expandname(file.join(configuration.root or ".",configuration.scripts or "."))
+ end
+ -- so far for checks
+ report("running at port: %s",configuration.port)
+ report("document root: %s",configuration.root or resolvers.ownpath)
+ report("main index file: %s",configuration.index)
+ report("scripts subpath: %s",configuration.scripts)
+ report("context services: http://localhost:%s/mtx-server-ctx-startup.lua",configuration.port)
+ local server = assert(socket.bind("*", configuration.port))
+ local script = configuration.script
+ while true do -- blocking
+ local start = os.clock()
+ local client = server:accept()
+ client:settimeout(configuration.timeout or 60)
+ local request, e = client:receive()
+ if e then
+ errormessage(client,configuration,404)
+ else
+ local from = client:getpeername()
+ report("request from: %s",tostring(from))
+ report("request data: %s",tostring(request))
+ local fullurl = string.match(request,"GET (.+) HTTP/.*$") or "" -- todo: more clever / post
+ if fullurl == "" then
+ report("no url")
+ errormessage(client,configuration,404)
+ else
+ report("requested url: %s",fullurl)
+ fullurl = socket.url.unescape(fullurl) -- still needed?
+ local hashed = url.hashed(fullurl)
+ local query = url.query(hashed.query)
+ local filename = hashed.path -- hm, not query?
+ if script then
+ filename = script
+ report("forced script: %s",filename)
+ local suffix = file.suffix(filename)
+ local action = handlers[suffix] or handlers.generic
+ if action then
+ report("performing action: %s",filename)
+ action(client,configuration,filename,suffix,false,hashed) -- filename and no content
+ else
+ errormessage(client,configuration,404)
+ end
+ elseif filename then
+ filename = socket.url.unescape(filename)
+ report("requested action: %s",filename)
+ if string.find(filename,"%.%.") then
+ filename = nil -- invalid path
+ end
+ if filename == nil or filename == "" or filename == "/" then
+ filename = configuration.index
+ report("invalid filename, forcing: %s",filename)
+ end
+ local suffix = file.suffix(filename)
+ local action = handlers[suffix] or handlers.generic
+ if action then
+ report("performing action: %s",filename)
+ action(client,configuration,filename,suffix,false,hashed) -- filename and no content
+ else
+ errormessage(client,configuration,404)
+ end
+ else
+ errormessage(client,configuration,404)
+ end
+ end
+ end
+ client:close()
+ report("time spent with client: %0.03f seconds",os.clock()-start)
+ end
+end
+
+if environment.argument("auto") then
+ local path = resolvers.findfile("mtx-server.lua") or "."
+ scripts.webserver.run {
+ port = environment.argument("port"),
+ root = environment.argument("root") or file.dirname(path) or ".",
+ scripts = environment.argument("scripts") or file.dirname(path) or ".",
+ script = environment.argument("script"),
+ }
+elseif environment.argument("start") then
+ scripts.webserver.run {
+ port = environment.argument("port"),
+ root = environment.argument("root") or ".", -- "e:/websites/www.pragma-ade.com",
+ index = environment.argument("index"),
+ scripts = environment.argument("scripts"),
+ script = environment.argument("script"),
+ }
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
+
+-- mtxrun --script server --start => http://localhost:31415/mtx-server-ctx-startup.lua
diff --git a/scripts/context/lua/mtx-texworks.lua b/scripts/context/lua/mtx-texworks.lua
index 8cb7736ac..ae5f2afa4 100644
--- a/scripts/context/lua/mtx-texworks.lua
+++ b/scripts/context/lua/mtx-texworks.lua
@@ -1,121 +1,121 @@
-if not modules then modules = { } end modules ['mtx-texworks'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-texworks</entry>
- <entry name="detail">TeXworks Startup Script</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="start"><short>[<ref name="verbose]"/> start texworks</short></flag>
- <flag name="test"><short>report what will happen</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-texworks",
- banner = "TeXworks Startup Script 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.texworks = scripts.texworks or { }
-
-local texworkspaths = {
- "completion",
- "configuration",
- "dictionaries",
- "translations",
- "scripts",
- "templates",
- "TUG"
-}
-
-local texworkssignal = "texworks-context.rme"
-local texworkininame = "texworks.ini"
-
-function scripts.texworks.start(indeed)
- local workname = (os.type == "windows" and "texworks.exe") or "texworks"
- local fullname = nil
- local binpaths = file.splitpath(os.getenv("PATH")) or file.splitpath(os.getenv("path"))
- local usedsignal = texworkssignal
- local datapath = resolvers.findfile(usedsignal,"other text files") or ""
- if datapath ~= "" then
- datapath = file.dirname(datapath) -- data
- if datapath == "" then
- datapath = resolvers.cleanpath(lfs.currentdir())
- end
- else
- usedsignal = texworkininame
- datapath = resolvers.findfile(usedsignal,"other text files") or ""
- if datapath == "" then
- usedsignal = string.lower(usedsignal)
- datapath = resolvers.findfile(usedsignal,"other text files") or ""
- end
- if datapath ~= "" and lfs.isfile(datapath) then
- datapath = file.dirname(datapath) -- TUG
- datapath = file.dirname(datapath) -- data
- if datapath == "" then
- datapath = resolvers.cleanpath(lfs.currentdir())
- end
- end
- end
- if datapath == "" then
- report("invalid datapath, maybe you need to regenerate the file database")
- return false
- end
- if not binpaths or #binpaths == 0 then
- report("invalid binpath")
- return false
- end
- for i=1,#binpaths do
- local p = file.join(binpaths[i],workname)
- if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub
- fullname = p
- break
- end
- end
- if not fullname then
- report("unable to locate %s",workname)
- return false
- end
- for i=1,#texworkspaths do
- dir.makedirs(file.join(datapath,texworkspaths[i]))
- end
- os.setenv("TW_INIPATH",datapath)
- os.setenv("TW_LIBPATH",datapath)
- if not indeed or environment.argument("verbose") then
- report("used signal: %s", usedsignal)
- report("data path : %s", datapath)
- report("full name : %s", fullname)
- report("set paths : TW_INIPATH TW_LIBPATH")
- end
- if indeed then
- os.launch(fullname)
- end
-end
-
-if environment.argument("start") then
- scripts.texworks.start(true)
-elseif environment.argument("test") then
- scripts.texworks.start()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-texworks'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-texworks</entry>
+ <entry name="detail">TeXworks Startup Script</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="start"><short>[<ref name="verbose]"/> start texworks</short></flag>
+ <flag name="test"><short>report what will happen</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-texworks",
+ banner = "TeXworks Startup Script 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.texworks = scripts.texworks or { }
+
+local texworkspaths = {
+ "completion",
+ "configuration",
+ "dictionaries",
+ "translations",
+ "scripts",
+ "templates",
+ "TUG"
+}
+
+local texworkssignal = "texworks-context.rme"
+local texworkininame = "texworks.ini"
+
+function scripts.texworks.start(indeed)
+ local workname = (os.type == "windows" and "texworks.exe") or "texworks"
+ local fullname = nil
+ local binpaths = file.splitpath(os.getenv("PATH")) or file.splitpath(os.getenv("path"))
+ local usedsignal = texworkssignal
+ local datapath = resolvers.findfile(usedsignal,"other text files") or ""
+ if datapath ~= "" then
+ datapath = file.dirname(datapath) -- data
+ if datapath == "" then
+ datapath = resolvers.cleanpath(lfs.currentdir())
+ end
+ else
+ usedsignal = texworkininame
+ datapath = resolvers.findfile(usedsignal,"other text files") or ""
+ if datapath == "" then
+ usedsignal = string.lower(usedsignal)
+ datapath = resolvers.findfile(usedsignal,"other text files") or ""
+ end
+ if datapath ~= "" and lfs.isfile(datapath) then
+ datapath = file.dirname(datapath) -- TUG
+ datapath = file.dirname(datapath) -- data
+ if datapath == "" then
+ datapath = resolvers.cleanpath(lfs.currentdir())
+ end
+ end
+ end
+ if datapath == "" then
+ report("invalid datapath, maybe you need to regenerate the file database")
+ return false
+ end
+ if not binpaths or #binpaths == 0 then
+ report("invalid binpath")
+ return false
+ end
+ for i=1,#binpaths do
+ local p = file.join(binpaths[i],workname)
+ if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub
+ fullname = p
+ break
+ end
+ end
+ if not fullname then
+ report("unable to locate %s",workname)
+ return false
+ end
+ for i=1,#texworkspaths do
+ dir.makedirs(file.join(datapath,texworkspaths[i]))
+ end
+ os.setenv("TW_INIPATH",datapath)
+ os.setenv("TW_LIBPATH",datapath)
+ if not indeed or environment.argument("verbose") then
+ report("used signal: %s", usedsignal)
+ report("data path : %s", datapath)
+ report("full name : %s", fullname)
+ report("set paths : TW_INIPATH TW_LIBPATH")
+ end
+ if indeed then
+ os.launch(fullname)
+ end
+end
+
+if environment.argument("start") then
+ scripts.texworks.start(true)
+elseif environment.argument("test") then
+ scripts.texworks.start()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-timing.lua b/scripts/context/lua/mtx-timing.lua
index 391232b0a..5ba361e5f 100644
--- a/scripts/context/lua/mtx-timing.lua
+++ b/scripts/context/lua/mtx-timing.lua
@@ -1,218 +1,218 @@
-if not modules then modules = { } end modules ['mtx-timing'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local format, gsub, concat = string.format, string.gsub, table.concat
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-timing</entry>
- <entry name="detail">ConTeXt Timing Tools</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="xhtml"><short>make xhtml file</short></flag>
- <flag name="launch"><short>launch after conversion</short></flag>
- <flag name="remove"><short>remove after launching</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-timing",
- banner = "ConTeXt Timing Tools 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-dofile(resolvers.findfile("node-snp.lua","tex"))
-dofile(resolvers.findfile("trac-tim.lua","tex"))
-dofile(resolvers.findfile("trac-lmx.lua","tex"))
-
-local meta = [[
- beginfig(%s) ;
- begingroup ;
- save p, q, b, h, w ;
- path p, q, b ; numeric h, w ;
- linecap := butt ;
- h := 100 ;
- w := 800pt ;
- p := %s ;
- q := %s ;
- p := p shifted -llcorner p ;
- q := q shifted -llcorner q ;
- q := q xstretched w ;
- p := p xstretched w ;
- b := boundingbox (llcorner p -- llcorner p shifted (w,h)) ;
- draw b withcolor white withpen pencircle scaled 4pt ;
- draw p withcolor red withpen pencircle scaled 4pt ;
- draw q withcolor blue withpen pencircle scaled 2pt ;
- endgroup ;
- endfig ;
-]]
-
-local html_graphic = [[
- <h1><a name='graphic-%s'>%s (red) %s (blue)</a></h1>
- <table>
- <tr>
- <td>%s</td>
- <td valign='top'>
- &nbsp;&nbsp;min: %s<br/>
- &nbsp;&nbsp;max: %s<br/>
- &nbsp;&nbsp;pages: %s<br/>
- &nbsp;&nbsp;average: %s<br/>
- </td>
- </tr>
- </table>
- <br/>
-]]
-
-local html_menu = [[
- <a href='#graphic-%s'>%s</a>
-]]
-
-local directrun = true
-
-local what = { "parameters", "nodes" }
-
-plugins = plugins or { progress = { } } -- brrr, will become moduledata as well
-
-function plugins.progress.make_svg(filename,other)
- local metadata, menudata, c = { }, { }, 0
- metadata[#metadata+1] = 'outputformat := "svg" ;'
- for i=1,#what do
- local kind, mdk = what[i], { }
- menudata[kind] = mdk
- for n, name in next, plugins.progress[kind](filename) do
- local first = plugins.progress.path(filename,name)
- local second = plugins.progress.path(filename,other)
- c = c + 1
- metadata[#metadata+1] = format(meta,c,first,second)
- mdk[#mdk+1] = { name, c }
- end
- end
- metadata[#metadata+1] = "end ."
- metadata = concat(metadata,"\n\n")
- if directrun then
- dofile(resolvers.findfile("mlib-run.lua","tex"))
- commands = commands or { }
- commands.writestatus = report
- local result = metapost.directrun("metafun","timing data","svg",true,metadata)
- return menudata, result
- else
- local mpname = file.replacesuffix(filename,"mp")
- io.savedata(mpname,metadata)
- os.execute(format("mpost --progname=context --mem=metafun.mem %s",mpname))
- os.remove(mpname)
- os.remove(file.removesuffix(filename).."-mpgraph.mpo") -- brr
- os.remove(file.removesuffix(filename)..".log") -- brr
- return menudata
- end
-end
-
-function plugins.progress.makehtml(filename,other,menudata,metadata)
- local graphics = { }
- local result = { graphics = graphics }
- for i=1,#what do
- local kind, menu = what[i], { }
- local md = menudata[kind]
- result[kind] = menu
- for k=1,#md do
- local v = md[k]
- local name, number = v[1], v[2]
- local min = plugins.progress.bot(filename,name)
- local max = plugins.progress.top(filename,name)
- local pages = plugins.progress.pages(filename)
- local average = math.round(max/pages)
- if directrun then
- local data = metadata[number]
- menu[#menu+1] = format(html_menu,name,name)
- graphics[#graphics+1] = format(html_graphic,name,name,other,data,min,max,pages,average)
- else
- local mpname = file.replacesuffix(filename,number)
- local data = io.loaddata(mpname) or ""
- -- data = gsub(data,"<!%-%-(.-)%-%->[\n\r]*","")
- data = gsub(data,"<%?xml.->","")
- menu[#menu+1] = format(html_menu,name,name)
- graphics[#graphics+1] = format(html_graphic,name,name,other,data,min,max,pages,average)
- os.remove(mpname)
- end
- end
- end
- return result
-end
-
-function plugins.progress.valid_file(name)
- return name and name ~= "" and lfs.isfile(name .. "-luatex-progress.lut")
-end
-
-function plugins.progress.make_lmx_page(name,launch,remove)
-
- local filename = name .. "-luatex-progress"
- local other = "elapsed_time"
- local template = 'context-timing.lmx'
-
- plugins.progress.convert(filename)
-
- local menudata, metadata = plugins.progress.make_svg(filename,other)
- local htmldata = plugins.progress.makehtml(filename,other,menudata,metadata)
-
- lmx.htmfile = function(name) return name .. "-timing.xhtml" end
- lmx.lmxfile = function(name) return resolvers.findfile(name,'tex') end
-
- local variables = {
- ['title-default'] = 'ConTeXt Timing Information',
- ['title'] = format('ConTeXt Timing Information: %s',file.basename(name)),
- ['parametersmenu'] = concat(htmldata.parameters, "&nbsp;&nbsp;"),
- ['nodesmenu'] = concat(htmldata.nodes, "&nbsp;&nbsp;"),
- ['graphics'] = concat(htmldata.graphics, "\n\n"),
- ['color-background-one'] = lmx.get('color-background-green'),
- ['color-background-two'] = lmx.get('color-background-blue'),
- }
-
- if launch then
- local htmfile = lmx.show(template,variables)
- if remove then
- os.sleep(1) -- give time to launch
- os.remove(htmfile)
- end
- else
- lmx.make(template,variables)
- end
-
-end
-
-scripts = scripts or { }
-scripts.timings = scripts.timings or { }
-
-function scripts.timings.xhtml(filename)
- if filename == "" then
- report("provide filename")
- elseif not plugins.progress.valid_file(filename) then
- report("first run context again with the --timing option")
- else
- local basename = file.removesuffix(filename)
- local launch = environment.argument("launch")
- local remove = environment.argument("remove")
- plugins.progress.make_lmx_page(basename,launch,remove)
- end
-end
-
-if environment.argument("xhtml") then
- scripts.timings.xhtml(environment.files[1] or "")
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-timing'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, gsub, concat = string.format, string.gsub, table.concat
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-timing</entry>
+ <entry name="detail">ConTeXt Timing Tools</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="xhtml"><short>make xhtml file</short></flag>
+ <flag name="launch"><short>launch after conversion</short></flag>
+ <flag name="remove"><short>remove after launching</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-timing",
+ banner = "ConTeXt Timing Tools 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+dofile(resolvers.findfile("node-snp.lua","tex"))
+dofile(resolvers.findfile("trac-tim.lua","tex"))
+dofile(resolvers.findfile("trac-lmx.lua","tex"))
+
+local meta = [[
+ beginfig(%s) ;
+ begingroup ;
+ save p, q, b, h, w ;
+ path p, q, b ; numeric h, w ;
+ linecap := butt ;
+ h := 100 ;
+ w := 800pt ;
+ p := %s ;
+ q := %s ;
+ p := p shifted -llcorner p ;
+ q := q shifted -llcorner q ;
+ q := q xstretched w ;
+ p := p xstretched w ;
+ b := boundingbox (llcorner p -- llcorner p shifted (w,h)) ;
+ draw b withcolor white withpen pencircle scaled 4pt ;
+ draw p withcolor red withpen pencircle scaled 4pt ;
+ draw q withcolor blue withpen pencircle scaled 2pt ;
+ endgroup ;
+ endfig ;
+]]
+
+local html_graphic = [[
+ <h1><a name='graphic-%s'>%s (red) %s (blue)</a></h1>
+ <table>
+ <tr>
+ <td>%s</td>
+ <td valign='top'>
+ &nbsp;&nbsp;min: %s<br/>
+ &nbsp;&nbsp;max: %s<br/>
+ &nbsp;&nbsp;pages: %s<br/>
+ &nbsp;&nbsp;average: %s<br/>
+ </td>
+ </tr>
+ </table>
+ <br/>
+]]
+
+local html_menu = [[
+ <a href='#graphic-%s'>%s</a>
+]]
+
+local directrun = true
+
+local what = { "parameters", "nodes" }
+
+plugins = plugins or { progress = { } } -- brrr, will become moduledata as well
+
+function plugins.progress.make_svg(filename,other)
+ local metadata, menudata, c = { }, { }, 0
+ metadata[#metadata+1] = 'outputformat := "svg" ;'
+ for i=1,#what do
+ local kind, mdk = what[i], { }
+ menudata[kind] = mdk
+ for n, name in next, plugins.progress[kind](filename) do
+ local first = plugins.progress.path(filename,name)
+ local second = plugins.progress.path(filename,other)
+ c = c + 1
+ metadata[#metadata+1] = format(meta,c,first,second)
+ mdk[#mdk+1] = { name, c }
+ end
+ end
+ metadata[#metadata+1] = "end ."
+ metadata = concat(metadata,"\n\n")
+ if directrun then
+ dofile(resolvers.findfile("mlib-run.lua","tex"))
+ commands = commands or { }
+ commands.writestatus = report
+ local result = metapost.directrun("metafun","timing data","svg",true,metadata)
+ return menudata, result
+ else
+ local mpname = file.replacesuffix(filename,"mp")
+ io.savedata(mpname,metadata)
+ os.execute(format("mpost --progname=context --mem=metafun.mem %s",mpname))
+ os.remove(mpname)
+ os.remove(file.removesuffix(filename).."-mpgraph.mpo") -- brr
+ os.remove(file.removesuffix(filename)..".log") -- brr
+ return menudata
+ end
+end
+
+function plugins.progress.makehtml(filename,other,menudata,metadata)
+ local graphics = { }
+ local result = { graphics = graphics }
+ for i=1,#what do
+ local kind, menu = what[i], { }
+ local md = menudata[kind]
+ result[kind] = menu
+ for k=1,#md do
+ local v = md[k]
+ local name, number = v[1], v[2]
+ local min = plugins.progress.bot(filename,name)
+ local max = plugins.progress.top(filename,name)
+ local pages = plugins.progress.pages(filename)
+ local average = math.round(max/pages)
+ if directrun then
+ local data = metadata[number]
+ menu[#menu+1] = format(html_menu,name,name)
+ graphics[#graphics+1] = format(html_graphic,name,name,other,data,min,max,pages,average)
+ else
+ local mpname = file.replacesuffix(filename,number)
+ local data = io.loaddata(mpname) or ""
+ -- data = gsub(data,"<!%-%-(.-)%-%->[\n\r]*","")
+ data = gsub(data,"<%?xml.->","")
+ menu[#menu+1] = format(html_menu,name,name)
+ graphics[#graphics+1] = format(html_graphic,name,name,other,data,min,max,pages,average)
+ os.remove(mpname)
+ end
+ end
+ end
+ return result
+end
+
+function plugins.progress.valid_file(name)
+ return name and name ~= "" and lfs.isfile(name .. "-luatex-progress.lut")
+end
+
+function plugins.progress.make_lmx_page(name,launch,remove)
+
+ local filename = name .. "-luatex-progress"
+ local other = "elapsed_time"
+ local template = 'context-timing.lmx'
+
+ plugins.progress.convert(filename)
+
+ local menudata, metadata = plugins.progress.make_svg(filename,other)
+ local htmldata = plugins.progress.makehtml(filename,other,menudata,metadata)
+
+ lmx.htmfile = function(name) return name .. "-timing.xhtml" end
+ lmx.lmxfile = function(name) return resolvers.findfile(name,'tex') end
+
+ local variables = {
+ ['title-default'] = 'ConTeXt Timing Information',
+ ['title'] = format('ConTeXt Timing Information: %s',file.basename(name)),
+ ['parametersmenu'] = concat(htmldata.parameters, "&nbsp;&nbsp;"),
+ ['nodesmenu'] = concat(htmldata.nodes, "&nbsp;&nbsp;"),
+ ['graphics'] = concat(htmldata.graphics, "\n\n"),
+ ['color-background-one'] = lmx.get('color-background-green'),
+ ['color-background-two'] = lmx.get('color-background-blue'),
+ }
+
+ if launch then
+ local htmfile = lmx.show(template,variables)
+ if remove then
+ os.sleep(1) -- give time to launch
+ os.remove(htmfile)
+ end
+ else
+ lmx.make(template,variables)
+ end
+
+end
+
+scripts = scripts or { }
+scripts.timings = scripts.timings or { }
+
+function scripts.timings.xhtml(filename)
+ if filename == "" then
+ report("provide filename")
+ elseif not plugins.progress.valid_file(filename) then
+ report("first run context again with the --timing option")
+ else
+ local basename = file.removesuffix(filename)
+ local launch = environment.argument("launch")
+ local remove = environment.argument("remove")
+ plugins.progress.make_lmx_page(basename,launch,remove)
+ end
+end
+
+if environment.argument("xhtml") then
+ scripts.timings.xhtml(environment.files[1] or "")
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-tools.lua b/scripts/context/lua/mtx-tools.lua
index 0ef194285..19b7458a1 100644
--- a/scripts/context/lua/mtx-tools.lua
+++ b/scripts/context/lua/mtx-tools.lua
@@ -1,199 +1,199 @@
-if not modules then modules = { } end modules ['mtx-tools'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local find, format, sub, rep, gsub, lower = string.find, string.format, string.sub, string.rep, string.gsub, string.lower
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-tools</entry>
- <entry name="detail">Some File Related Goodies</entry>
- <entry name="version">1.01</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="disarmutfbomb"><short>remove utf bomb if present</short></flag>
- <flag name="force"><short>remove indeed</short></flag>
- </subcategory>
- <subcategory>
- <flag name="dirtoxml"><short>glob directory into xml</short></flag>
- <flag name="pattern"><short>glob pattern (default: *)</short></flag>
- <flag name="url"><short>url attribute (no processing)</short></flag>
- <flag name="root"><short>the root of the globbed path (default: .)</short></flag>
- <flag name="output"><short>output filename (console by default)</short></flag>
- <flag name="recurse"><short>recurse into subdirecories</short></flag>
- <flag name="stripname"><short>take pathpart of given pattern</short></flag>
- <flag name="longname"><short>set name attributes to full path name</short></flag>
- </subcategory>
- <subcategory>
- <flag name="pattern"><short>glob pattern (default: *)</short></flag>
- <flag name="recurse"><short>recurse into subdirecories</short></flag>
- <flag name="force"><short>downcase indeed</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-tools",
- banner = "Some File Related Goodies 1.01",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.tools = scripts.tools or { }
-
-local bomb_1, bomb_2 = "^\254\255", "^\239\187\191"
-
-function scripts.tools.disarmutfbomb()
- local force, done = environment.argument("force"), false
- local files = environment.files
- for i=1,#files do
- local name = files[i]
- if lfs.isfile(name) then
- local data = io.loaddata(name)
- if not data then
- -- just skip
- elseif find(data,bomb_1) then
- report("file '%s' has a 2 character utf bomb",name)
- if force then
- io.savedata(name,(gsub(data,bomb_1,"")))
- end
- done = true
- elseif find(data,bomb_2) then
- report("file '%s' has a 3 character utf bomb",name)
- if force then
- io.savedata(name,(gsub(data,bomb_2,"")))
- end
- done = true
- else
- -- report("file '%s' has no utf bomb",name)
- end
- end
- end
- if done and not force then
- report("use --force to do a real disarming")
- end
-end
-
-function scripts.tools.downcase()
- local pattern = environment.argument('pattern') or "*"
- local recurse = environment.argument('recurse')
- local force = environment.argument('force')
- local n = 0
- if recurse and not find(pattern,"^%*%*%/") then
- pattern = "**/*" .. pattern
- end
- dir.glob(pattern,function(name)
- local basename = file.basename(name)
- if lower(basename) ~= basename then
- n = n + 1
- if force then
- os.rename(name,lower(name))
- end
- end
- end)
- if n > 0 then
- if force then
- report("%s files renamed",n)
- else
- report("use --force to do a real rename (%s files involved)",n)
- end
- else
- report("nothing to do")
- end
-end
-
-
-function scripts.tools.dirtoxml()
-
- local join, removesuffix, suffixonly, date = file.join, file.removesuffix, file.suffixonly, os.date
-
- local xmlns = "http://www.pragma-ade.com/rlg/xmldir.rng"
- local timestamp = "%Y-%m-%d %H:%M"
-
- local pattern = environment.argument('pattern') or ".*"
- local url = environment.argument('url') or "no-url"
- local root = environment.argument('root') or "."
- local outputfile = environment.argument('output')
-
- local recurse = environment.argument('recurse') or false
- local stripname = environment.argument('stripname')
- local longname = environment.argument('longname')
-
- local function flush(list,result,n,path)
- n, result = n or 1, result or { }
- local d = rep(" ",n)
- for name, attr in table.sortedhash(list) do
- local mode = attr.mode
- if mode == "file" then
- result[#result+1] = format("%s<file name='%s'>",d,(longname and path and join(path,name)) or name)
- result[#result+1] = format("%s <base>%s</base>",d,removesuffix(name))
- result[#result+1] = format("%s <type>%s</type>",d,suffixonly(name))
- result[#result+1] = format("%s <size>%s</size>",d,attr.size)
- result[#result+1] = format("%s <permissions>%s</permissions>",d,sub(attr.permissions,7,9))
- result[#result+1] = format("%s <date>%s</date>",d,date(timestamp,attr.modification))
- result[#result+1] = format("%s</file>",d)
- elseif mode == "directory" then
- result[#result+1] = format("%s<directory name='%s'>",d,name)
- flush(attr.list,result,n+1,(path and join(path,name)) or name)
- result[#result+1] = format("%s</directory>",d)
- end
- end
- end
-
- if not pattern or pattern == "" then
- report('provide --pattern=')
- return
- end
-
- if stripname then
- pattern = file.dirname(pattern)
- end
-
- local luapattern = string.topattern(pattern,true)
-
- lfs.chdir(root)
-
- local list = dir.collectpattern(root,luapattern,recurse)
-
- if list[outputfile] then
- list[outputfile] = nil
- end
-
- local result = { "<?xml version='1.0'?>" }
- result[#result+1] = format("<files url=%q root=%q pattern=%q luapattern=%q xmlns='%s' timestamp='%s'>",url,root,pattern,luapattern,xmlns,date(timestamp))
- flush(list,result)
- result[#result+1] = "</files>"
-
- result = table.concat(result,"\n")
-
- if not outputfile or outputfile == "" then
- texio.write_nl(result)
- else
- io.savedata(outputfile,result)
- end
-
-end
-
-if environment.argument("disarmutfbomb") then
- scripts.tools.disarmutfbomb()
-elseif environment.argument("dirtoxml") then
- scripts.tools.dirtoxml()
-elseif environment.argument("downcase") then
- scripts.tools.downcase()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-tools'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local find, format, sub, rep, gsub, lower = string.find, string.format, string.sub, string.rep, string.gsub, string.lower
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-tools</entry>
+ <entry name="detail">Some File Related Goodies</entry>
+ <entry name="version">1.01</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="disarmutfbomb"><short>remove utf bomb if present</short></flag>
+ <flag name="force"><short>remove indeed</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="dirtoxml"><short>glob directory into xml</short></flag>
+ <flag name="pattern"><short>glob pattern (default: *)</short></flag>
+ <flag name="url"><short>url attribute (no processing)</short></flag>
+ <flag name="root"><short>the root of the globbed path (default: .)</short></flag>
+ <flag name="output"><short>output filename (console by default)</short></flag>
+ <flag name="recurse"><short>recurse into subdirecories</short></flag>
+ <flag name="stripname"><short>take pathpart of given pattern</short></flag>
+ <flag name="longname"><short>set name attributes to full path name</short></flag>
+ </subcategory>
+ <subcategory>
+ <flag name="pattern"><short>glob pattern (default: *)</short></flag>
+ <flag name="recurse"><short>recurse into subdirecories</short></flag>
+ <flag name="force"><short>downcase indeed</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-tools",
+ banner = "Some File Related Goodies 1.01",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.tools = scripts.tools or { }
+
+local bomb_1, bomb_2 = "^\254\255", "^\239\187\191"
+
+function scripts.tools.disarmutfbomb()
+ local force, done = environment.argument("force"), false
+ local files = environment.files
+ for i=1,#files do
+ local name = files[i]
+ if lfs.isfile(name) then
+ local data = io.loaddata(name)
+ if not data then
+ -- just skip
+ elseif find(data,bomb_1) then
+ report("file '%s' has a 2 character utf bomb",name)
+ if force then
+ io.savedata(name,(gsub(data,bomb_1,"")))
+ end
+ done = true
+ elseif find(data,bomb_2) then
+ report("file '%s' has a 3 character utf bomb",name)
+ if force then
+ io.savedata(name,(gsub(data,bomb_2,"")))
+ end
+ done = true
+ else
+ -- report("file '%s' has no utf bomb",name)
+ end
+ end
+ end
+ if done and not force then
+ report("use --force to do a real disarming")
+ end
+end
+
+function scripts.tools.downcase()
+ local pattern = environment.argument('pattern') or "*"
+ local recurse = environment.argument('recurse')
+ local force = environment.argument('force')
+ local n = 0
+ if recurse and not find(pattern,"^%*%*%/") then
+ pattern = "**/*" .. pattern
+ end
+ dir.glob(pattern,function(name)
+ local basename = file.basename(name)
+ if lower(basename) ~= basename then
+ n = n + 1
+ if force then
+ os.rename(name,lower(name))
+ end
+ end
+ end)
+ if n > 0 then
+ if force then
+ report("%s files renamed",n)
+ else
+ report("use --force to do a real rename (%s files involved)",n)
+ end
+ else
+ report("nothing to do")
+ end
+end
+
+
+function scripts.tools.dirtoxml()
+
+ local join, removesuffix, suffixonly, date = file.join, file.removesuffix, file.suffixonly, os.date
+
+ local xmlns = "http://www.pragma-ade.com/rlg/xmldir.rng"
+ local timestamp = "%Y-%m-%d %H:%M"
+
+ local pattern = environment.argument('pattern') or ".*"
+ local url = environment.argument('url') or "no-url"
+ local root = environment.argument('root') or "."
+ local outputfile = environment.argument('output')
+
+ local recurse = environment.argument('recurse') or false
+ local stripname = environment.argument('stripname')
+ local longname = environment.argument('longname')
+
+ local function flush(list,result,n,path)
+ n, result = n or 1, result or { }
+ local d = rep(" ",n)
+ for name, attr in table.sortedhash(list) do
+ local mode = attr.mode
+ if mode == "file" then
+ result[#result+1] = format("%s<file name='%s'>",d,(longname and path and join(path,name)) or name)
+ result[#result+1] = format("%s <base>%s</base>",d,removesuffix(name))
+ result[#result+1] = format("%s <type>%s</type>",d,suffixonly(name))
+ result[#result+1] = format("%s <size>%s</size>",d,attr.size)
+ result[#result+1] = format("%s <permissions>%s</permissions>",d,sub(attr.permissions,7,9))
+ result[#result+1] = format("%s <date>%s</date>",d,date(timestamp,attr.modification))
+ result[#result+1] = format("%s</file>",d)
+ elseif mode == "directory" then
+ result[#result+1] = format("%s<directory name='%s'>",d,name)
+ flush(attr.list,result,n+1,(path and join(path,name)) or name)
+ result[#result+1] = format("%s</directory>",d)
+ end
+ end
+ end
+
+ if not pattern or pattern == "" then
+ report('provide --pattern=')
+ return
+ end
+
+ if stripname then
+ pattern = file.dirname(pattern)
+ end
+
+ local luapattern = string.topattern(pattern,true)
+
+ lfs.chdir(root)
+
+ local list = dir.collectpattern(root,luapattern,recurse)
+
+ if list[outputfile] then
+ list[outputfile] = nil
+ end
+
+ local result = { "<?xml version='1.0'?>" }
+ result[#result+1] = format("<files url=%q root=%q pattern=%q luapattern=%q xmlns='%s' timestamp='%s'>",url,root,pattern,luapattern,xmlns,date(timestamp))
+ flush(list,result)
+ result[#result+1] = "</files>"
+
+ result = table.concat(result,"\n")
+
+ if not outputfile or outputfile == "" then
+ texio.write_nl(result)
+ else
+ io.savedata(outputfile,result)
+ end
+
+end
+
+if environment.argument("disarmutfbomb") then
+ scripts.tools.disarmutfbomb()
+elseif environment.argument("dirtoxml") then
+ scripts.tools.dirtoxml()
+elseif environment.argument("downcase") then
+ scripts.tools.downcase()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-unzip.lua b/scripts/context/lua/mtx-unzip.lua
index 6514d709a..02d9676bc 100644
--- a/scripts/context/lua/mtx-unzip.lua
+++ b/scripts/context/lua/mtx-unzip.lua
@@ -1,132 +1,132 @@
-if not modules then modules = { } end modules ['mtx-unzip'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- maybe --pattern
-
-local format = string.format
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-unzip</entry>
- <entry name="detail">Simple Unzipper</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="list"><short>list files in archive</short></flag>
- <flag name="junk"><short>flatten unzipped directory structure</short></flag>
- <flag name="extract"><short>extract files</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-unzip",
- banner = "Simple Unzipper 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.unzipper = scripts.unzipper or { }
-
-function scripts.unzipper.opened()
- local filename = environment.files[1]
- if filename and filename ~= "" then
- filename = file.addsuffix(filename,'zip')
- local zipfile = zip.open(filename)
- if zipfile then
- return zipfile
- end
- end
- report("no zip file: %s",filename)
- return false
-end
-
-function scripts.unzipper.list()
- local zipfile = scripts.unzipper.opened()
- if zipfile then
- local n = 0
- for k in zipfile:files() do
- if #k.filename > n then n = #k.filename end
- end
- local files, paths, compressed, uncompressed = 0, 0, 0, 0
- local template_a = "%-"..n.."s"
- local template_b = "%-"..n.."s % 9i % 9i"
- local template_c = "\n%-"..n.."s % 9i % 9i"
- for k in zipfile:files() do
- if k.filename:find("/$") then
- paths = paths + 1
- print(format(template_a, k.filename))
- else
- files = files + 1
- local cs, us = k.compressed_size, k.uncompressed_size
- if cs > compressed then
- compressed = cs
- end
- if us > uncompressed then
- uncompressed = us
- end
- print(format(template_b,k.filename,cs,us))
- end
- end -- check following pattern, n is not enough
- print(format(template_c,files .. " files, " .. paths .. " directories",compressed,uncompressed))
- end
-end
-
-function zip.loaddata(zipfile,filename)
- local f = zipfile:open(filename)
- if f then
- local data = f:read("*a")
- f:close()
- return data
- end
- return nil
-end
-
-function scripts.unzipper.extract()
- local zipfile = scripts.unzipper.opened()
- if zipfile then
- local junk = environment.arguments["j"] or environment.arguments["junk"]
- for k in zipfile:files() do
- local filename = k.filename
- if filename:find("/$") then
- if not junk then
- lfs.mkdir(filename)
- end
- else
- local data = zip.loaddata(zipfile,filename)
- if data then
- if junk then
- filename = file.basename(filename)
- end
- io.savedata(filename,data)
- print(filename)
- end
- end
- end
- end
-end
-
-if environment.arguments["h"] or environment.arguments["help"] then
- application.help()
-elseif environment.arguments["l"] or environment.arguments["list"] then
- scripts.unzipper.list(zipfile)
-elseif environment.arguments["exporthelp"] then
- application.export(environment.arguments["exporthelp"],environment.files[1])
-elseif environment.files[1] then -- implicit --extract
- scripts.unzipper.extract(zipfile)
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-unzip'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- maybe --pattern
+
+local format = string.format
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-unzip</entry>
+ <entry name="detail">Simple Unzipper</entry>
+ <entry name="version">0.10</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="list"><short>list files in archive</short></flag>
+ <flag name="junk"><short>flatten unzipped directory structure</short></flag>
+ <flag name="extract"><short>extract files</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-unzip",
+ banner = "Simple Unzipper 0.10",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.unzipper = scripts.unzipper or { }
+
+function scripts.unzipper.opened()
+ local filename = environment.files[1]
+ if filename and filename ~= "" then
+ filename = file.addsuffix(filename,'zip')
+ local zipfile = zip.open(filename)
+ if zipfile then
+ return zipfile
+ end
+ end
+ report("no zip file: %s",filename)
+ return false
+end
+
+function scripts.unzipper.list()
+ local zipfile = scripts.unzipper.opened()
+ if zipfile then
+ local n = 0
+ for k in zipfile:files() do
+ if #k.filename > n then n = #k.filename end
+ end
+ local files, paths, compressed, uncompressed = 0, 0, 0, 0
+ local template_a = "%-"..n.."s"
+ local template_b = "%-"..n.."s % 9i % 9i"
+ local template_c = "\n%-"..n.."s % 9i % 9i"
+ for k in zipfile:files() do
+ if k.filename:find("/$") then
+ paths = paths + 1
+ print(format(template_a, k.filename))
+ else
+ files = files + 1
+ local cs, us = k.compressed_size, k.uncompressed_size
+ if cs > compressed then
+ compressed = cs
+ end
+ if us > uncompressed then
+ uncompressed = us
+ end
+ print(format(template_b,k.filename,cs,us))
+ end
+ end -- check following pattern, n is not enough
+ print(format(template_c,files .. " files, " .. paths .. " directories",compressed,uncompressed))
+ end
+end
+
+function zip.loaddata(zipfile,filename)
+ local f = zipfile:open(filename)
+ if f then
+ local data = f:read("*a")
+ f:close()
+ return data
+ end
+ return nil
+end
+
+function scripts.unzipper.extract()
+ local zipfile = scripts.unzipper.opened()
+ if zipfile then
+ local junk = environment.arguments["j"] or environment.arguments["junk"]
+ for k in zipfile:files() do
+ local filename = k.filename
+ if filename:find("/$") then
+ if not junk then
+ lfs.mkdir(filename)
+ end
+ else
+ local data = zip.loaddata(zipfile,filename)
+ if data then
+ if junk then
+ filename = file.basename(filename)
+ end
+ io.savedata(filename,data)
+ print(filename)
+ end
+ end
+ end
+ end
+end
+
+if environment.arguments["h"] or environment.arguments["help"] then
+ application.help()
+elseif environment.arguments["l"] or environment.arguments["list"] then
+ scripts.unzipper.list(zipfile)
+elseif environment.arguments["exporthelp"] then
+ application.export(environment.arguments["exporthelp"],environment.files[1])
+elseif environment.files[1] then -- implicit --extract
+ scripts.unzipper.extract(zipfile)
+else
+ application.help()
+end
diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua
index 5141bdf7a..64203d3e3 100644
--- a/scripts/context/lua/mtx-update.lua
+++ b/scripts/context/lua/mtx-update.lua
@@ -1,676 +1,676 @@
-if not modules then modules = { } end modules ['mtx-update'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- This script is dedicated to Mojca Miklavec, who is the driving force behind
--- moving minimal generation from our internal machines to the context garden.
--- Together with Arthur Reutenauer she made sure that it worked well on all
--- platforms that matter.
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-update</entry>
- <entry name="detail">ConTeXt Minimals Updater</entry>
- <entry name="version">0.31</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="platform" value="string"><short>platform (windows, linux, linux-64, osx-intel, osx-ppc, linux-ppc)</short></flag>
- <flag name="server" value="string"><short>repository url (rsync://contextgarden.net)</short></flag>
- <flag name="module" value="string"><short>repository url (minimals)</short></flag>
- <flag name="repository" value="string"><short>specify version (current, experimental)</short></flag>
- <flag name="context" value="string"><short>specify version (current, latest, beta, yyyy.mm.dd)</short></flag>
- <flag name="rsync" value="string"><short>rsync binary (rsync)</short></flag>
- <flag name="texroot" value="string"><short>installation directory (not guessed for the moment)</short></flag>
- <flag name="engine" value="string"><short>tex engine (luatex, pdftex, xetex)</short></flag>
- <flag name="modules" value="string"><short>extra modules (can be list or 'all')</short></flag>
- <flag name="fonts" value="string"><short>additional fonts (can be list or 'all')</short></flag>
- <flag name="goodies" value="string"><short>extra binaries (like scite and texworks)</short></flag>
- <flag name="force"><short>instead of a dryrun, do the real thing</short></flag>
- <flag name="update"><short>update minimal tree</short></flag>
- <flag name="make"><short>also make formats and generate file databases</short></flag>
- <flag name="keep"><short>don't delete unused or obsolete files</short></flag>
- <flag name="state"><short>update tree using saved state</short></flag>
- <flag name="cygwin"><short>adapt drive specs to cygwin</short></flag>
- <flag name="mingw"><short>assume mingw binaries being used</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-update",
- banner = "ConTeXt Minimals Updater 0.31",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-local format, concat, gmatch, gsub, find = string.format, table.concat, string.gmatch, string.gsub, string.find
-
-scripts = scripts or { }
-scripts.update = scripts.update or { }
-
-minimals = minimals or { }
-minimals.config = minimals.config or { }
-
--- this is needed under windows
--- else rsync fails to set the right chmod flags to files
-
-os.setenv("CYGWIN","nontsec")
-
-scripts.update.texformats = {
- "cont-en",
- "cont-nl",
- "cont-cz",
- "cont-de",
- "cont-fa",
- "cont-it",
- "cont-ro",
- "cont-uk",
- "cont-pe",
- -- "cont-xp",
- "mptopdf",
- "plain"
-}
-
-scripts.update.mpformats = {
- -- "metafun",
- -- "mpost",
-}
-
--- experimental is not functional at the moment
-
-scripts.update.repositories = {
- "current",
- "experimental"
-}
-
--- more options than just these two are available (no idea why this is here)
-
-scripts.update.versions = {
- "current",
- "latest"
-}
-
--- list of basic folders that are needed to make a functional distribution
-
-scripts.update.base = {
- { "base/tex/", "texmf" },
- { "base/metapost/", "texmf" },
- { "fonts/common/", "texmf" },
- { "fonts/other/", "texmf" }, -- not *really* needed, but helpful
- { "context/<version>/", "texmf-context" },
- { "misc/setuptex/", "." },
- { "misc/web2c", "texmf" },
- { "bin/common/<platform>/", "texmf-<platform>" },
- { "bin/context/<platform>/", "texmf-<platform>" },
- { "bin/metapost/<platform>/", "texmf-<platform>" },
- { "bin/man/", "texmf-<platform>" },
-}
-
--- binaries and font-related files
--- for pdftex we don't need OpenType fonts, for LuaTeX/XeTeX we don't need TFM files
-
-scripts.update.engines = {
- ["luatex"] = {
- { "fonts/new/", "texmf" },
- { "bin/luatex/<platform>/", "texmf-<platform>" },
- { "bin/luajittex/<platform>/","texmf-<platform>" },
- },
- ["xetex"] = {
- { "base/xetex/", "texmf" },
- { "fonts/new/", "texmf" },
- { "bin/luatex/<platform>/", "texmf-<platform>" }, -- tools
- { "bin/xetex/<platform>/", "texmf-<platform>" },
- },
- ["pdftex"] = {
- { "fonts/old/", "texmf" },
- { "bin/luatex/<platform>/", "texmf-<platform>" }, -- tools
- { "bin/pdftex/<platform>/", "texmf-<platform>" },
- },
- ["all"] = {
- { "fonts/new/", "texmf" },
- { "fonts/old/", "texmf" },
- { "base/xetex/", "texmf" },
- { "bin/luatex/<platform>/", "texmf-<platform>" },
- { "bin/luajittex/<platform>/","texmf-<platform>" },
- { "bin/xetex/<platform>/", "texmf-<platform>" },
- { "bin/pdftex/<platform>/", "texmf-<platform>" },
- },
-}
-
-scripts.update.goodies = {
- ["scite"] = {
- { "bin/<platform>/scite/", "texmf-<platform>" },
- },
- ["texworks"] = {
- { "bin/<platform>/texworks/", "texmf-<platform>" },
- },
-}
-
-scripts.update.platforms = {
- ["mswin"] = "mswin",
- ["windows"] = "mswin",
- ["win32"] = "mswin",
- ["win"] = "mswin",
- ["linux"] = "linux",
- ["freebsd"] = "freebsd",
- ["freebsd-amd64"] = "freebsd-amd64",
- ["kfreebsd"] = "kfreebsd-i386",
- ["kfreebsd-i386"] = "kfreebsd-i386",
- ["kfreebsd-amd64"] = "kfreebsd-amd64",
- ["linux-32"] = "linux",
- ["linux-64"] = "linux-64",
- ["linux32"] = "linux",
- ["linux64"] = "linux-64",
- ["linux-ppc"] = "linux-ppc",
- ["ppc"] = "linux-ppc",
- ["osx"] = "osx-intel",
- ["macosx"] = "osx-intel",
- ["osx-intel"] = "osx-intel",
- ["osx-ppc"] = "osx-ppc",
- ["osx-powerpc"] = "osx-ppc",
- ["osx-64"] = "osx-64",
- ["osxintel"] = "osx-intel",
- ["osxppc"] = "osx-ppc",
- ["osxpowerpc"] = "osx-ppc",
- ["solaris-intel"] = "solaris-intel",
- ["solaris-sparc"] = "solaris-sparc",
- ["solaris"] = "solaris-sparc",
-}
-
-scripts.update.selfscripts = {
- "mtxrun",
- -- "luatools",
-}
-
--- the list is filled up later (when we know what modules to download)
-
-scripts.update.modules = {
-}
-
-scripts.update.fonts = {
-}
-
-function scripts.update.run(str)
- -- important, otherwise formats fly to a weird place
- -- (texlua sets luatex as the engine, we need to reset that or to fix texexec :)
- os.setenv("engine",nil)
- if environment.argument("force") then
- report("run, %s",str)
- os.execute(str)
- else
- report("dry run, %s",str)
- end
-end
-
-function scripts.update.fullpath(path)
- if file.is_rootbased_path(path) then
- return path
- else
- return lfs.currentdir() .. "/" .. path
- end
-end
-
-local rsync_variant = "cygwin" -- will be come mingw
-
-local function drive(d)
- if rsync_variant == "cygwin" then
- d = gsub(d,[[([a-zA-Z]):/]], "/cygdrive/%1/")
- else
- d = gsub(d,[[([a-zA-Z]):/]], "/%1/")
- end
- return d
-end
-
-function scripts.update.synchronize()
-
- report("update, start")
-
- local texroot = scripts.update.fullpath(states.get("paths.root"))
- local engines = states.get('engines') or { }
- local platforms = states.get('platforms') or { }
- local repositories = states.get('repositories') -- minimals
- local bin = states.get("rsync.program") -- rsync
- local url = states.get("rsync.server") -- contextgarden.net
- local version = states.get("context.version") -- current (or beta)
- local modules = states.get("modules") -- modules (third party)
- local fonts = states.get("fonts") -- fonts (experimental or special)
- local goodies = states.get("goodies") -- goodies (like editors)
- local force = environment.argument("force")
-
- bin = gsub(bin,"\\","/")
-
- if not url:find("::$") then url = url .. "::" end
- local ok = lfs.attributes(texroot,"mode") == "directory"
- if not ok and force then
- dir.mkdirs(texroot)
- ok = lfs.attributes(texroot,"mode") == "directory"
- end
-
- if force then
- dir.mkdirs(format("%s/%s", texroot, "texmf-cache"))
- dir.mkdirs(format("%s/%s", texroot, "texmf-local"))
- dir.mkdirs(format("%s/%s", texroot, "texmf-project"))
- dir.mkdirs(format("%s/%s", texroot, "texmf-fonts"))
- dir.mkdirs(format("%s/%s", texroot, "texmf-modules"))
- end
-
- if ok or not force then
-
- local fetched, individual, osplatform = { }, { }, os.platform
-
- -- takes a collection as argument and returns a list of folders
-
- local function collection_to_list_of_folders(collection, platform)
- local archives = {}
- for i=1,#collection do
- local archive = collection[i][1]
- archive = gsub(archive,"<platform>",platform)
- archive = gsub(archive,"<version>",version)
- archives[#archives+1] = archive
- end
- return archives
- end
-
- -- takes a list of folders as argument and returns a string for rsync
- -- sample input:
- -- {'bin/common', 'bin/context'}
- -- output:
- -- 'minimals/current/bin/common minimals/current/bin/context'
-
- local function list_of_folders_to_rsync_string(list_of_folders)
- local repository = 'current'
- local prefix = format("%s/%s/", states.get('rsync.module'), repository) -- minimals/current/
-
- return prefix .. concat(list_of_folders, format(" %s", prefix))
- end
-
- -- example of usage: print(list_of_folders_to_rsync_string(collection_to_list_of_folders(scripts.update.base, os.platform)))
-
- -- rename function and add some more functionality:
- -- * recursive/non-recursive (default: non-recursive)
- -- * filter folders or regular files only (default: no filter)
- -- * grep for size of included files (with --stats switch)
-
- local function get_list_of_files_from_rsync(list_of_folders)
- -- temporary file to store the output of rsync (could be a more random name; watch for overwrites)
- local temp_file = "rsync.tmp.txt"
- -- a set of folders
- local folders = {}
- local command = format("%s %s'%s' > %s", bin, url, list_of_folders_to_rsync_string(list_of_folders), temp_file)
- os.execute(command)
- -- read output of rsync
- local data = io.loaddata(temp_file) or ""
- -- for every line extract the filename
- for chmod, s in data:gmatch("([d%-][rwx%-]+).-(%S+)[\n\r]") do
- -- skip "current" folder
- if s ~= '.' and chmod:len() == 10 then
- folders[#folders+1] = s
- end
- end
- -- delete the file to which we have put output of rsync
- os.remove(temp_file)
- return folders
- end
-
- -- rsync://contextgarden.net/minimals/current/modules/
-
- if modules and type(modules) == "table" then
- -- fetch the list of available modules from rsync server
- local available_modules = get_list_of_files_from_rsync({"modules/"})
- -- hash of requested modules
- -- local h = table.tohash(modules:split(","))
- local asked = table.copy(modules)
- asked.all = nil
- for i=1,#available_modules do
- local s = available_modules[i]
- if modules.all or modules[s] then
- scripts.update.modules[#scripts.update.modules+1] = { format("modules/%s/",s), "texmf-modules" }
- end
- asked[s] = nil
- end
- if next(asked) then
- report("skipping unknown modules: %s",table.concat(table.sortedkeys(asked),", "))
- end
- end
-
- -- rsync://contextgarden.net/minimals/current/fonts/extra/
-
- if fonts and type(fonts) == "table" then
- local available_fonts = get_list_of_files_from_rsync({"fonts/extra/"})
- local asked = table.copy(fonts)
- asked.all = nil
- for i=1,#available_fonts do
- local s = available_fonts[i]
- if fonts.all or fonts[s] then
- scripts.update.fonts[#scripts.update.fonts+1] = { format("fonts/extra/%s/",s), "texmf" }
- end
- asked[s] = nil
- end
- if next(asked) then
- report("skipping unknown fonts: %s",table.concat(table.sortedkeys(asked),", "))
- end
- end
-
- local function add_collection(collection,platform)
- if collection and platform then
- platform = scripts.update.platforms[platform]
- if platform then
- for i=1,#collection do
- local c = collection[i]
- local archive = gsub(c[1],"<platform>",platform)
- local destination = format("%s/%s", texroot, gsub(c[2],"<platform>", platform))
- destination = gsub(destination,"\\","/")
- archive = gsub(archive,"<version>",version)
- if osplatform == "windows" or osplatform == "mswin" then
- destination = drive(destination)
- end
- individual[#individual+1] = { archive, destination }
- end
- end
- end
- end
-
- for platform, _ in next, platforms do
- add_collection(scripts.update.base,platform)
- end
- for platform, _ in next, platforms do
- add_collection(scripts.update.modules,platform)
- end
- for platform, _ in next, platforms do
- add_collection(scripts.update.fonts,platform)
- end
- for engine, _ in next, engines do
- for platform, _ in next, platforms do
- add_collection(scripts.update.engines[engine],platform)
- end
- end
-
- if goodies and type(goodies) == "table" then
- for goodie, _ in next, goodies do
- for platform, _ in next, platforms do
- add_collection(scripts.update.goodies[goodie],platform)
- end
- end
- end
-
- local combined = { }
- local update_repositories = scripts.update.repositories
- for i=1,#update_repositories do
- local repository = update_repositories[i]
- if repositories[repository] then
- for _, v in next, individual do
- local archive, destination = v[1], v[2]
- local cd = combined[destination]
- if not cd then
- cd = { }
- combined[destination] = cd
- end
- cd[#cd+1] = format("%s/%s/%s",states.get('rsync.module'),repository,archive)
- end
- end
- end
- for destination, archive in next, combined do
- local archives, command = concat(archive," "), ""
- local normalflags, deleteflags = states.get("rsync.flags.normal"), ""
- if os.name == "windows" then
- normalflags = normalflags .. " -L" -- no symlinks
- end
- local dryrunflags = ""
- if not environment.argument("force") then
- dryrunflags = "--dry-run"
- end
- if (destination:find("texmf$") or destination:find("texmf%-context$") or destination:find("texmf%-modules$")) and (not environment.argument("keep")) then
- deleteflags = states.get("rsync.flags.delete")
- end
- command = format("%s %s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, dryrunflags, url, archives, destination)
- -- report("running command: %s",command)
- if not fetched[command] then
- scripts.update.run(command,true)
- fetched[command] = command
- end
- end
-
- local function update_script(script, platform)
- local bin = gsub(bin,"\\","/")
- local texroot = gsub(texroot,"\\","/")
- platform = scripts.update.platforms[platform]
- if platform then
- local command
- if platform == 'mswin' then
- bin = drive(bin)
- texroot = drive(texroot)
- command = format([[%s -t "%s/texmf-context/scripts/context/lua/%s.lua" "%s/texmf-mswin/bin/"]], bin, texroot, script, texroot)
- else
- command = format([[%s -tgo --chmod=a+x '%s/texmf-context/scripts/context/lua/%s.lua' '%s/texmf-%s/bin/%s']], bin, texroot, script, texroot, platform, script)
- end
- report("updating %s for %s: %s", script, platform, command)
- scripts.update.run(command)
- end
- end
-
- for platform, _ in next, platforms do
- for i=1, #scripts.update.selfscripts do
- update_script(scripts.update.selfscripts[i],platform)
- end
- end
-
- else
- report("no valid texroot: %s",texroot)
- end
- if not force then
- report("use --force to really update files")
- end
-
- resolvers.load_tree(texroot) -- else we operate in the wrong tree
-
- -- update filename database for pdftex/xetex
- scripts.update.run(format('mtxrun --tree="%s" --direct --resolve mktexlsr',texroot))
- -- update filename database for luatex
- scripts.update.run(format('mtxrun --tree="%s" --generate',texroot))
-
- report("update, done")
-end
-
-function table.fromhash(t)
- local h = { }
- for k, v in next, t do -- not indexed
- if v then h[#h+1] = k end
- end
- return h
-end
-
--- make the ConTeXt formats
-function scripts.update.make()
-
- report("make, start")
-
- local force = environment.argument("force")
- local texroot = scripts.update.fullpath(states.get("paths.root"))
- local engines = states.get('engines')
- local goodies = states.get('goodies')
- local platforms = states.get('platforms')
- local formats = states.get('formats')
-
- resolvers.load_tree(texroot)
-
- scripts.update.run(format('mtxrun --tree="%s" --direct --resolve mktexlsr',texroot))
- scripts.update.run(format('mtxrun --tree="%s" --generate',texroot))
-
- local askedformats = formats
- local texformats = table.tohash(scripts.update.texformats)
- local mpformats = table.tohash(scripts.update.mpformats)
- for k,v in next, texformats do
- if not askedformats[k] then
- texformats[k] = nil
- end
- end
- for k,v in next, mpformats do
- if not askedformats[k] then
- mpformats[k] = nil
- end
- end
- local formatlist = concat(table.fromhash(texformats), " ")
- if formatlist ~= "" then
- for engine in next, engines do
- if engine == "luatex" then
- scripts.update.run(format('mtxrun --tree="%s" --script context --autogenerate --make',texroot))
- elseif engine == "luajittex" then
- scripts.update.run(format('mtxrun --tree="%s" --script context --autogenerate --make --engine=luajittex',texroot))
- else
- scripts.update.run(format('mtxrun --tree="%s" --script texexec --make --all --%s %s',texroot,engine,formatlist))
- end
- end
- end
- local formatlist = concat(table.fromhash(mpformats), " ")
- if formatlist ~= "" then
- scripts.update.run(format('mtxrun --tree="%s" --script texexec --make --all %s',texroot,formatlist))
- end
- if not force then
- report("make, use --force to really make formats")
- end
-
- scripts.update.run(format('mtxrun --tree="%s" --direct --resolve mktexlsr',texroot)) -- needed for mpost
- scripts.update.run(format('mtxrun --tree="%s" --generate',texroot))
-
- report("make, done")
-end
-
-scripts.savestate = true
-
-if scripts.savestate then
-
- states.load("status-of-update.lua")
-
- -- tag, value, default, persistent
-
- statistics.starttiming(states)
-
- states.set("info.version",0.1) -- ok
- states.set("info.count",(states.get("info.count") or 0) + 1,1,false) -- ok
- states.set("info.comment","this file contains the settings of the last 'mtxrun --script update' run",false) -- ok
- states.set("info.date",os.date("!%Y-%m-%d %H:%M:%S")) -- ok
-
- states.set("rsync.program", environment.argument("rsync"), "rsync", true) -- ok
- states.set("rsync.server", environment.argument("server"), "contextgarden.net::", true) -- ok
- states.set("rsync.module", environment.argument("module"), "minimals", true) -- ok
- states.set("rsync.flags.normal", environment.argument("flags"), "-rpztlv", true) -- ok
- states.set("rsync.flags.delete", nil, "--delete", true) -- ok
-
- states.set("paths.root", environment.argument("texroot"), "tex", true) -- ok
-
- states.set("context.version", environment.argument("context"), "current", true) -- ok
-
- local valid = table.tohash(scripts.update.repositories)
- for r in gmatch(environment.argument("repository") or "current","([^, ]+)") do
- if valid[r] then states.set("repositories." .. r, true) end
- end
-
- local valid = scripts.update.engines
- local engine = environment.argument("engine") or ""
- if engine == "" then
- local e = states.get("engines")
- if not e or not next(e) then
- engine = "all"
- end
- end
- if engine ~= "" then
- for r in gmatch(engine,"([^, ]+)") do
- if r == "all" then
- for k, v in next, valid do
- if k ~= "all" then
- states.set("engines." .. k, true)
- end
- end
- break
- elseif valid[r] then
- states.set("engines." .. r, true)
- end
- end
- end
-
- local valid = scripts.update.platforms
- for r in gmatch(environment.argument("platform") or os.platform,"([^, ]+)") do
- if valid[r] then states.set("platforms." .. r, true) end
- end
-
- local valid = table.tohash(scripts.update.texformats)
- for r in gmatch(environment.argument("formats") or "","([^, ]+)") do
- if valid[r] then states.set("formats." .. r, true) end
- end
- local valid = table.tohash(scripts.update.mpformats)
- for r in gmatch(environment.argument("formats") or "","([^, ]+)") do
- if valid[r] then states.set("formats." .. r, true) end
- end
-
- states.set("formats.cont-en", true)
- states.set("formats.cont-nl", true)
- states.set("formats.metafun", true)
-
- for r in gmatch(environment.argument("extras") or "","([^, ]+)") do -- for old times sake
- if r ~= "all" and not find(r,"^[a-z]%-") then
- r = "t-" .. r
- end
- states.set("modules." .. r, true)
- end
- for r in gmatch(environment.argument("modules") or "","([^, ]+)") do
- if r ~= "all" and not find(r,"^[a-z]%-") then
- r = "t-" .. r
- end
- states.set("modules." .. r, true)
- end
- for r in gmatch(environment.argument("fonts") or "","([^, ]+)") do
- states.set("fonts." .. r, true)
- end
- for r in gmatch(environment.argument("goodies") or "","([^, ]+)") do
- states.set("goodies." .. r, true)
- end
-
- report("state, loaded")
- report()
-
-end
-
-if environment.argument("state") then
- environment.setargument("update",true)
- environment.setargument("force",true)
- environment.setargument("make",true)
-end
-
-if environment.argument("mingw") then
- rsync_variant = "mingw"
-elseif environment.argument("cygwin") then
- rsync_variant = "cygwin"
-end
-
-if environment.argument("update") then
- scripts.update.synchronize()
- if environment.argument("make") then
- scripts.update.make()
- end
-elseif environment.argument("make") then
- scripts.update.make()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
-
-if scripts.savestate then
- statistics.stoptiming(states)
- states.set("info.runtime",tonumber(statistics.elapsedtime(states)))
- if environment.argument("force") then
- states.save()
- report("state","saved")
- end
-end
+if not modules then modules = { } end modules ['mtx-update'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This script is dedicated to Mojca Miklavec, who is the driving force behind
+-- moving minimal generation from our internal machines to the context garden.
+-- Together with Arthur Reutenauer she made sure that it worked well on all
+-- platforms that matter.
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-update</entry>
+ <entry name="detail">ConTeXt Minimals Updater</entry>
+ <entry name="version">0.31</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="platform" value="string"><short>platform (windows, linux, linux-64, osx-intel, osx-ppc, linux-ppc)</short></flag>
+ <flag name="server" value="string"><short>repository url (rsync://contextgarden.net)</short></flag>
+ <flag name="module" value="string"><short>repository url (minimals)</short></flag>
+ <flag name="repository" value="string"><short>specify version (current, experimental)</short></flag>
+ <flag name="context" value="string"><short>specify version (current, latest, beta, yyyy.mm.dd)</short></flag>
+ <flag name="rsync" value="string"><short>rsync binary (rsync)</short></flag>
+ <flag name="texroot" value="string"><short>installation directory (not guessed for the moment)</short></flag>
+ <flag name="engine" value="string"><short>tex engine (luatex, pdftex, xetex)</short></flag>
+ <flag name="modules" value="string"><short>extra modules (can be list or 'all')</short></flag>
+ <flag name="fonts" value="string"><short>additional fonts (can be list or 'all')</short></flag>
+ <flag name="goodies" value="string"><short>extra binaries (like scite and texworks)</short></flag>
+ <flag name="force"><short>instead of a dryrun, do the real thing</short></flag>
+ <flag name="update"><short>update minimal tree</short></flag>
+ <flag name="make"><short>also make formats and generate file databases</short></flag>
+ <flag name="keep"><short>don't delete unused or obsolete files</short></flag>
+ <flag name="state"><short>update tree using saved state</short></flag>
+ <flag name="cygwin"><short>adapt drive specs to cygwin</short></flag>
+ <flag name="mingw"><short>assume mingw binaries being used</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-update",
+ banner = "ConTeXt Minimals Updater 0.31",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+local format, concat, gmatch, gsub, find = string.format, table.concat, string.gmatch, string.gsub, string.find
+
+scripts = scripts or { }
+scripts.update = scripts.update or { }
+
+minimals = minimals or { }
+minimals.config = minimals.config or { }
+
+-- this is needed under windows
+-- else rsync fails to set the right chmod flags to files
+
+os.setenv("CYGWIN","nontsec")
+
+scripts.update.texformats = {
+ "cont-en",
+ "cont-nl",
+ "cont-cz",
+ "cont-de",
+ "cont-fa",
+ "cont-it",
+ "cont-ro",
+ "cont-uk",
+ "cont-pe",
+ -- "cont-xp",
+ "mptopdf",
+ "plain"
+}
+
+scripts.update.mpformats = {
+ -- "metafun",
+ -- "mpost",
+}
+
+-- experimental is not functional at the moment
+
+scripts.update.repositories = {
+ "current",
+ "experimental"
+}
+
+-- more options than just these two are available (no idea why this is here)
+
+scripts.update.versions = {
+ "current",
+ "latest"
+}
+
+-- list of basic folders that are needed to make a functional distribution
+
+scripts.update.base = {
+ { "base/tex/", "texmf" },
+ { "base/metapost/", "texmf" },
+ { "fonts/common/", "texmf" },
+ { "fonts/other/", "texmf" }, -- not *really* needed, but helpful
+ { "context/<version>/", "texmf-context" },
+ { "misc/setuptex/", "." },
+ { "misc/web2c", "texmf" },
+ { "bin/common/<platform>/", "texmf-<platform>" },
+ { "bin/context/<platform>/", "texmf-<platform>" },
+ { "bin/metapost/<platform>/", "texmf-<platform>" },
+ { "bin/man/", "texmf-<platform>" },
+}
+
+-- binaries and font-related files
+-- for pdftex we don't need OpenType fonts, for LuaTeX/XeTeX we don't need TFM files
+
+scripts.update.engines = {
+ ["luatex"] = {
+ { "fonts/new/", "texmf" },
+ { "bin/luatex/<platform>/", "texmf-<platform>" },
+ { "bin/luajittex/<platform>/","texmf-<platform>" },
+ },
+ ["xetex"] = {
+ { "base/xetex/", "texmf" },
+ { "fonts/new/", "texmf" },
+ { "bin/luatex/<platform>/", "texmf-<platform>" }, -- tools
+ { "bin/xetex/<platform>/", "texmf-<platform>" },
+ },
+ ["pdftex"] = {
+ { "fonts/old/", "texmf" },
+ { "bin/luatex/<platform>/", "texmf-<platform>" }, -- tools
+ { "bin/pdftex/<platform>/", "texmf-<platform>" },
+ },
+ ["all"] = {
+ { "fonts/new/", "texmf" },
+ { "fonts/old/", "texmf" },
+ { "base/xetex/", "texmf" },
+ { "bin/luatex/<platform>/", "texmf-<platform>" },
+ { "bin/luajittex/<platform>/","texmf-<platform>" },
+ { "bin/xetex/<platform>/", "texmf-<platform>" },
+ { "bin/pdftex/<platform>/", "texmf-<platform>" },
+ },
+}
+
+scripts.update.goodies = {
+ ["scite"] = {
+ { "bin/<platform>/scite/", "texmf-<platform>" },
+ },
+ ["texworks"] = {
+ { "bin/<platform>/texworks/", "texmf-<platform>" },
+ },
+}
+
+scripts.update.platforms = {
+ ["mswin"] = "mswin",
+ ["windows"] = "mswin",
+ ["win32"] = "mswin",
+ ["win"] = "mswin",
+ ["linux"] = "linux",
+ ["freebsd"] = "freebsd",
+ ["freebsd-amd64"] = "freebsd-amd64",
+ ["kfreebsd"] = "kfreebsd-i386",
+ ["kfreebsd-i386"] = "kfreebsd-i386",
+ ["kfreebsd-amd64"] = "kfreebsd-amd64",
+ ["linux-32"] = "linux",
+ ["linux-64"] = "linux-64",
+ ["linux32"] = "linux",
+ ["linux64"] = "linux-64",
+ ["linux-ppc"] = "linux-ppc",
+ ["ppc"] = "linux-ppc",
+ ["osx"] = "osx-intel",
+ ["macosx"] = "osx-intel",
+ ["osx-intel"] = "osx-intel",
+ ["osx-ppc"] = "osx-ppc",
+ ["osx-powerpc"] = "osx-ppc",
+ ["osx-64"] = "osx-64",
+ ["osxintel"] = "osx-intel",
+ ["osxppc"] = "osx-ppc",
+ ["osxpowerpc"] = "osx-ppc",
+ ["solaris-intel"] = "solaris-intel",
+ ["solaris-sparc"] = "solaris-sparc",
+ ["solaris"] = "solaris-sparc",
+}
+
+scripts.update.selfscripts = {
+ "mtxrun",
+ -- "luatools",
+}
+
+-- the list is filled up later (when we know what modules to download)
+
+scripts.update.modules = {
+}
+
+scripts.update.fonts = {
+}
+
+function scripts.update.run(str)
+ -- important, otherwise formats fly to a weird place
+ -- (texlua sets luatex as the engine, we need to reset that or to fix texexec :)
+ os.setenv("engine",nil)
+ if environment.argument("force") then
+ report("run, %s",str)
+ os.execute(str)
+ else
+ report("dry run, %s",str)
+ end
+end
+
+function scripts.update.fullpath(path)
+ if file.is_rootbased_path(path) then
+ return path
+ else
+ return lfs.currentdir() .. "/" .. path
+ end
+end
+
+local rsync_variant = "cygwin" -- will be come mingw
+
+local function drive(d)
+ if rsync_variant == "cygwin" then
+ d = gsub(d,[[([a-zA-Z]):/]], "/cygdrive/%1/")
+ else
+ d = gsub(d,[[([a-zA-Z]):/]], "/%1/")
+ end
+ return d
+end
+
+function scripts.update.synchronize()
+
+ report("update, start")
+
+ local texroot = scripts.update.fullpath(states.get("paths.root"))
+ local engines = states.get('engines') or { }
+ local platforms = states.get('platforms') or { }
+ local repositories = states.get('repositories') -- minimals
+ local bin = states.get("rsync.program") -- rsync
+ local url = states.get("rsync.server") -- contextgarden.net
+ local version = states.get("context.version") -- current (or beta)
+ local modules = states.get("modules") -- modules (third party)
+ local fonts = states.get("fonts") -- fonts (experimental or special)
+ local goodies = states.get("goodies") -- goodies (like editors)
+ local force = environment.argument("force")
+
+ bin = gsub(bin,"\\","/")
+
+ if not url:find("::$") then url = url .. "::" end
+ local ok = lfs.attributes(texroot,"mode") == "directory"
+ if not ok and force then
+ dir.mkdirs(texroot)
+ ok = lfs.attributes(texroot,"mode") == "directory"
+ end
+
+ if force then
+ dir.mkdirs(format("%s/%s", texroot, "texmf-cache"))
+ dir.mkdirs(format("%s/%s", texroot, "texmf-local"))
+ dir.mkdirs(format("%s/%s", texroot, "texmf-project"))
+ dir.mkdirs(format("%s/%s", texroot, "texmf-fonts"))
+ dir.mkdirs(format("%s/%s", texroot, "texmf-modules"))
+ end
+
+ if ok or not force then
+
+ local fetched, individual, osplatform = { }, { }, os.platform
+
+ -- takes a collection as argument and returns a list of folders
+
+ local function collection_to_list_of_folders(collection, platform)
+ local archives = {}
+ for i=1,#collection do
+ local archive = collection[i][1]
+ archive = gsub(archive,"<platform>",platform)
+ archive = gsub(archive,"<version>",version)
+ archives[#archives+1] = archive
+ end
+ return archives
+ end
+
+ -- takes a list of folders as argument and returns a string for rsync
+ -- sample input:
+ -- {'bin/common', 'bin/context'}
+ -- output:
+ -- 'minimals/current/bin/common minimals/current/bin/context'
+
+ local function list_of_folders_to_rsync_string(list_of_folders)
+ local repository = 'current'
+ local prefix = format("%s/%s/", states.get('rsync.module'), repository) -- minimals/current/
+
+ return prefix .. concat(list_of_folders, format(" %s", prefix))
+ end
+
+ -- example of usage: print(list_of_folders_to_rsync_string(collection_to_list_of_folders(scripts.update.base, os.platform)))
+
+ -- rename function and add some more functionality:
+ -- * recursive/non-recursive (default: non-recursive)
+ -- * filter folders or regular files only (default: no filter)
+ -- * grep for size of included files (with --stats switch)
+
+ local function get_list_of_files_from_rsync(list_of_folders)
+ -- temporary file to store the output of rsync (could be a more random name; watch for overwrites)
+ local temp_file = "rsync.tmp.txt"
+ -- a set of folders
+ local folders = {}
+ local command = format("%s %s'%s' > %s", bin, url, list_of_folders_to_rsync_string(list_of_folders), temp_file)
+ os.execute(command)
+ -- read output of rsync
+ local data = io.loaddata(temp_file) or ""
+ -- for every line extract the filename
+ for chmod, s in data:gmatch("([d%-][rwx%-]+).-(%S+)[\n\r]") do
+ -- skip "current" folder
+ if s ~= '.' and chmod:len() == 10 then
+ folders[#folders+1] = s
+ end
+ end
+ -- delete the file to which we have put output of rsync
+ os.remove(temp_file)
+ return folders
+ end
+
+ -- rsync://contextgarden.net/minimals/current/modules/
+
+ if modules and type(modules) == "table" then
+ -- fetch the list of available modules from rsync server
+ local available_modules = get_list_of_files_from_rsync({"modules/"})
+ -- hash of requested modules
+ -- local h = table.tohash(modules:split(","))
+ local asked = table.copy(modules)
+ asked.all = nil
+ for i=1,#available_modules do
+ local s = available_modules[i]
+ if modules.all or modules[s] then
+ scripts.update.modules[#scripts.update.modules+1] = { format("modules/%s/",s), "texmf-modules" }
+ end
+ asked[s] = nil
+ end
+ if next(asked) then
+ report("skipping unknown modules: %s",table.concat(table.sortedkeys(asked),", "))
+ end
+ end
+
+ -- rsync://contextgarden.net/minimals/current/fonts/extra/
+
+ if fonts and type(fonts) == "table" then
+ local available_fonts = get_list_of_files_from_rsync({"fonts/extra/"})
+ local asked = table.copy(fonts)
+ asked.all = nil
+ for i=1,#available_fonts do
+ local s = available_fonts[i]
+ if fonts.all or fonts[s] then
+ scripts.update.fonts[#scripts.update.fonts+1] = { format("fonts/extra/%s/",s), "texmf" }
+ end
+ asked[s] = nil
+ end
+ if next(asked) then
+ report("skipping unknown fonts: %s",table.concat(table.sortedkeys(asked),", "))
+ end
+ end
+
+ local function add_collection(collection,platform)
+ if collection and platform then
+ platform = scripts.update.platforms[platform]
+ if platform then
+ for i=1,#collection do
+ local c = collection[i]
+ local archive = gsub(c[1],"<platform>",platform)
+ local destination = format("%s/%s", texroot, gsub(c[2],"<platform>", platform))
+ destination = gsub(destination,"\\","/")
+ archive = gsub(archive,"<version>",version)
+ if osplatform == "windows" or osplatform == "mswin" then
+ destination = drive(destination)
+ end
+ individual[#individual+1] = { archive, destination }
+ end
+ end
+ end
+ end
+
+ for platform, _ in next, platforms do
+ add_collection(scripts.update.base,platform)
+ end
+ for platform, _ in next, platforms do
+ add_collection(scripts.update.modules,platform)
+ end
+ for platform, _ in next, platforms do
+ add_collection(scripts.update.fonts,platform)
+ end
+ for engine, _ in next, engines do
+ for platform, _ in next, platforms do
+ add_collection(scripts.update.engines[engine],platform)
+ end
+ end
+
+ if goodies and type(goodies) == "table" then
+ for goodie, _ in next, goodies do
+ for platform, _ in next, platforms do
+ add_collection(scripts.update.goodies[goodie],platform)
+ end
+ end
+ end
+
+ local combined = { }
+ local update_repositories = scripts.update.repositories
+ for i=1,#update_repositories do
+ local repository = update_repositories[i]
+ if repositories[repository] then
+ for _, v in next, individual do
+ local archive, destination = v[1], v[2]
+ local cd = combined[destination]
+ if not cd then
+ cd = { }
+ combined[destination] = cd
+ end
+ cd[#cd+1] = format("%s/%s/%s",states.get('rsync.module'),repository,archive)
+ end
+ end
+ end
+ for destination, archive in next, combined do
+ local archives, command = concat(archive," "), ""
+ local normalflags, deleteflags = states.get("rsync.flags.normal"), ""
+ if os.name == "windows" then
+ normalflags = normalflags .. " -L" -- no symlinks
+ end
+ local dryrunflags = ""
+ if not environment.argument("force") then
+ dryrunflags = "--dry-run"
+ end
+ if (destination:find("texmf$") or destination:find("texmf%-context$") or destination:find("texmf%-modules$")) and (not environment.argument("keep")) then
+ deleteflags = states.get("rsync.flags.delete")
+ end
+ command = format("%s %s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, dryrunflags, url, archives, destination)
+ -- report("running command: %s",command)
+ if not fetched[command] then
+ scripts.update.run(command,true)
+ fetched[command] = command
+ end
+ end
+
+ local function update_script(script, platform)
+ local bin = gsub(bin,"\\","/")
+ local texroot = gsub(texroot,"\\","/")
+ platform = scripts.update.platforms[platform]
+ if platform then
+ local command
+ if platform == 'mswin' then
+ bin = drive(bin)
+ texroot = drive(texroot)
+ command = format([[%s -t "%s/texmf-context/scripts/context/lua/%s.lua" "%s/texmf-mswin/bin/"]], bin, texroot, script, texroot)
+ else
+ command = format([[%s -tgo --chmod=a+x '%s/texmf-context/scripts/context/lua/%s.lua' '%s/texmf-%s/bin/%s']], bin, texroot, script, texroot, platform, script)
+ end
+ report("updating %s for %s: %s", script, platform, command)
+ scripts.update.run(command)
+ end
+ end
+
+ for platform, _ in next, platforms do
+ for i=1, #scripts.update.selfscripts do
+ update_script(scripts.update.selfscripts[i],platform)
+ end
+ end
+
+ else
+ report("no valid texroot: %s",texroot)
+ end
+ if not force then
+ report("use --force to really update files")
+ end
+
+ resolvers.load_tree(texroot) -- else we operate in the wrong tree
+
+ -- update filename database for pdftex/xetex
+ scripts.update.run(format('mtxrun --tree="%s" --direct --resolve mktexlsr',texroot))
+ -- update filename database for luatex
+ scripts.update.run(format('mtxrun --tree="%s" --generate',texroot))
+
+ report("update, done")
+end
+
+function table.fromhash(t)
+ local h = { }
+ for k, v in next, t do -- not indexed
+ if v then h[#h+1] = k end
+ end
+ return h
+end
+
+-- make the ConTeXt formats
+function scripts.update.make()
+
+ report("make, start")
+
+ local force = environment.argument("force")
+ local texroot = scripts.update.fullpath(states.get("paths.root"))
+ local engines = states.get('engines')
+ local goodies = states.get('goodies')
+ local platforms = states.get('platforms')
+ local formats = states.get('formats')
+
+ resolvers.load_tree(texroot)
+
+ scripts.update.run(format('mtxrun --tree="%s" --direct --resolve mktexlsr',texroot))
+ scripts.update.run(format('mtxrun --tree="%s" --generate',texroot))
+
+ local askedformats = formats
+ local texformats = table.tohash(scripts.update.texformats)
+ local mpformats = table.tohash(scripts.update.mpformats)
+ for k,v in next, texformats do
+ if not askedformats[k] then
+ texformats[k] = nil
+ end
+ end
+ for k,v in next, mpformats do
+ if not askedformats[k] then
+ mpformats[k] = nil
+ end
+ end
+ local formatlist = concat(table.fromhash(texformats), " ")
+ if formatlist ~= "" then
+ for engine in next, engines do
+ if engine == "luatex" then
+ scripts.update.run(format('mtxrun --tree="%s" --script context --autogenerate --make',texroot))
+ elseif engine == "luajittex" then
+ scripts.update.run(format('mtxrun --tree="%s" --script context --autogenerate --make --engine=luajittex',texroot))
+ else
+ scripts.update.run(format('mtxrun --tree="%s" --script texexec --make --all --%s %s',texroot,engine,formatlist))
+ end
+ end
+ end
+ local formatlist = concat(table.fromhash(mpformats), " ")
+ if formatlist ~= "" then
+ scripts.update.run(format('mtxrun --tree="%s" --script texexec --make --all %s',texroot,formatlist))
+ end
+ if not force then
+ report("make, use --force to really make formats")
+ end
+
+ scripts.update.run(format('mtxrun --tree="%s" --direct --resolve mktexlsr',texroot)) -- needed for mpost
+ scripts.update.run(format('mtxrun --tree="%s" --generate',texroot))
+
+ report("make, done")
+end
+
+scripts.savestate = true
+
+if scripts.savestate then
+
+ states.load("status-of-update.lua")
+
+ -- tag, value, default, persistent
+
+ statistics.starttiming(states)
+
+ states.set("info.version",0.1) -- ok
+ states.set("info.count",(states.get("info.count") or 0) + 1,1,false) -- ok
+ states.set("info.comment","this file contains the settings of the last 'mtxrun --script update' run",false) -- ok
+ states.set("info.date",os.date("!%Y-%m-%d %H:%M:%S")) -- ok
+
+ states.set("rsync.program", environment.argument("rsync"), "rsync", true) -- ok
+ states.set("rsync.server", environment.argument("server"), "contextgarden.net::", true) -- ok
+ states.set("rsync.module", environment.argument("module"), "minimals", true) -- ok
+ states.set("rsync.flags.normal", environment.argument("flags"), "-rpztlv", true) -- ok
+ states.set("rsync.flags.delete", nil, "--delete", true) -- ok
+
+ states.set("paths.root", environment.argument("texroot"), "tex", true) -- ok
+
+ states.set("context.version", environment.argument("context"), "current", true) -- ok
+
+ local valid = table.tohash(scripts.update.repositories)
+ for r in gmatch(environment.argument("repository") or "current","([^, ]+)") do
+ if valid[r] then states.set("repositories." .. r, true) end
+ end
+
+ local valid = scripts.update.engines
+ local engine = environment.argument("engine") or ""
+ if engine == "" then
+ local e = states.get("engines")
+ if not e or not next(e) then
+ engine = "all"
+ end
+ end
+ if engine ~= "" then
+ for r in gmatch(engine,"([^, ]+)") do
+ if r == "all" then
+ for k, v in next, valid do
+ if k ~= "all" then
+ states.set("engines." .. k, true)
+ end
+ end
+ break
+ elseif valid[r] then
+ states.set("engines." .. r, true)
+ end
+ end
+ end
+
+ local valid = scripts.update.platforms
+ for r in gmatch(environment.argument("platform") or os.platform,"([^, ]+)") do
+ if valid[r] then states.set("platforms." .. r, true) end
+ end
+
+ local valid = table.tohash(scripts.update.texformats)
+ for r in gmatch(environment.argument("formats") or "","([^, ]+)") do
+ if valid[r] then states.set("formats." .. r, true) end
+ end
+ local valid = table.tohash(scripts.update.mpformats)
+ for r in gmatch(environment.argument("formats") or "","([^, ]+)") do
+ if valid[r] then states.set("formats." .. r, true) end
+ end
+
+ states.set("formats.cont-en", true)
+ states.set("formats.cont-nl", true)
+ states.set("formats.metafun", true)
+
+ for r in gmatch(environment.argument("extras") or "","([^, ]+)") do -- for old times sake
+ if r ~= "all" and not find(r,"^[a-z]%-") then
+ r = "t-" .. r
+ end
+ states.set("modules." .. r, true)
+ end
+ for r in gmatch(environment.argument("modules") or "","([^, ]+)") do
+ if r ~= "all" and not find(r,"^[a-z]%-") then
+ r = "t-" .. r
+ end
+ states.set("modules." .. r, true)
+ end
+ for r in gmatch(environment.argument("fonts") or "","([^, ]+)") do
+ states.set("fonts." .. r, true)
+ end
+ for r in gmatch(environment.argument("goodies") or "","([^, ]+)") do
+ states.set("goodies." .. r, true)
+ end
+
+ report("state, loaded")
+ report()
+
+end
+
+if environment.argument("state") then
+ environment.setargument("update",true)
+ environment.setargument("force",true)
+ environment.setargument("make",true)
+end
+
+if environment.argument("mingw") then
+ rsync_variant = "mingw"
+elseif environment.argument("cygwin") then
+ rsync_variant = "cygwin"
+end
+
+if environment.argument("update") then
+ scripts.update.synchronize()
+ if environment.argument("make") then
+ scripts.update.make()
+ end
+elseif environment.argument("make") then
+ scripts.update.make()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end
+
+if scripts.savestate then
+ statistics.stoptiming(states)
+ states.set("info.runtime",tonumber(statistics.elapsedtime(states)))
+ if environment.argument("force") then
+ states.save()
+ report("state","saved")
+ end
+end
diff --git a/scripts/context/lua/mtx-watch.lua b/scripts/context/lua/mtx-watch.lua
index aa9b9262d..95323f571 100644
--- a/scripts/context/lua/mtx-watch.lua
+++ b/scripts/context/lua/mtx-watch.lua
@@ -1,431 +1,431 @@
-if not modules then modules = { } end modules ['mtx-watch'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-watch</entry>
- <entry name="detail">ConTeXt Request Watchdog</entry>
- <entry name="version">1.00</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="logpath"><short>optional path for log files</short></flag>
- <flag name="watch"><short>watch given path [<ref name="delay]"/></short></flag>
- <flag name="pipe"><short>use pipe instead of execute</short></flag>
- <flag name="delay"><short>delay between sweeps</short></flag>
- <flag name="automachine"><short>replace /machine/ in path /servername/</short></flag>
- <flag name="collect"><short>condense log files</short></flag>
- <flag name="cleanup" value="delay"><short>remove files in given path [<ref name="force]"/></short></flag>
- <flag name="showlog"><short>show log data</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-watch",
- banner = "ConTeXt Request Watchdog 1.00",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.watch = scripts.watch or { }
-
-local format, concat, difftime, time = string.format, table.concat, os.difftime, os.time
-local next, type = next, type
-local basename, dirname, joinname = file.basename, file.dirname, file.join
-local lfsdir, lfsattributes = lfs.dir, lfs.attributes
-
--- the machine/instance matches the server app we use
-
-local machine = socket.dns.gethostname() or "unknown-machine"
-local instance = string.match(machine,"(%d+)$") or "0"
-
-function scripts.watch.save_exa_modes(joblog,ctmname)
- local values = joblog and joblog.values
- if values then
- local t= { }
- t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n"
- t[#t+1] = "<exa:variables xmlns:exa='htpp://www.pragma-ade.com/schemas/exa-variables.rng'>"
- for k, v in next, joblog.values do
- t[#t+1] = format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v))
- end
- t[#t+1] = "</exa:variables>"
- io.savedata(ctmname,concat(t,"\n"))
- else
- os.remove(ctmname)
- end
-end
-
-local function toset(t)
- if type(t) == "table" then
- return concat(t,",")
- else
- return t
- end
-end
-
-local function noset(t)
- if type(t) == "table" then
- return t[1]
- else
- return t
- end
-end
-
--- todo: split order (o-name.luj) and combine with atime to determine sort order.
-
-local function glob(files,path) -- some day: sort by name (order prefix) and atime
- for name in lfsdir(path) do
- if name:find("^%.") then
- -- skip . and ..
- else
- name = path .. "/" .. name
- local a = lfsattributes(name)
- if not a then
- -- weird
- elseif a.mode == "directory" then
- if name:find("graphics$") or name:find("figures$") or name:find("resources$") then
- -- skip these too
- else
- glob(files,name)
- end
- elseif name:find(".%luj$") then
- local bname = basename(name)
- local dname = dirname(name)
- local order = tonumber(bname:match("^(%d+)")) or 0
- files[#files+1] = { dname, bname, order }
- end
- end
- end
-end
-
-local clock = os.gettimeofday or (socket and socket.gettime) or os.time -- we cannot trust os.clock on linux
-
--- local function filenamesort(a,b)
--- local fa, da = a[1], a[2]
--- local fb, db = b[1], b[2]
--- if da == db then
--- return fa < fb
--- else
--- return da < db
--- end
--- end
-
-local function filenamesort(a,b)
- local fa, oa = a[2], a[3]
- local fb, ob = b[2], b[3]
- if fa == fb then
- if oa == ob then
- return a[1] < b[1] -- order file dir
- else
- return oa < ob -- order file
- end
- else
- if oa == ob then
- return fa < fb -- order file
- else
- return oa < ob -- order file
- end
- end
-end
-
-function scripts.watch.watch()
- local delay = tonumber(environment.argument("delay") or 5) or 5
- if delay == 0 then
- delay = .25
- end
- local logpath = environment.argument("logpath") or ""
- local pipe = environment.argument("pipe") or false
- local watcher = "mtxwatch.run"
- local paths = environment.files
- if #paths > 0 then
- if environment.argument("automachine") then
- logpath = string.gsub(logpath,"/machine/","/"..machine.."/")
- for i=1,#paths do
- paths[i] = string.gsub(paths[i],"/machine/","/"..machine.."/")
- end
- end
- for i=1,#paths do
- report("watching path %s",paths[i])
- end
- local function process()
- local done = false
- for i=1,#paths do
- local path = paths[i]
- lfs.chdir(path)
- local files = { }
- glob(files,path)
- table.sort(files,filenamesort)
--- for name, time in next, files do
- for i=1,#files do
- local f = files[i]
- local dirname = f[1]
- local basename = f[2] -- we can use that later on
- local name = joinname(dirname,basename)
- --~ local ok, joblog = xpcall(function() return dofile(name) end, function() end )
- local ok, joblog = pcall(dofile,name)
- if ok and joblog then
- if joblog.status == "processing" then
- report("aborted job, %s added to queue",name)
- joblog.status = "queued"
- io.savedata(name, table.serialize(joblog,true))
- elseif joblog.status == "queued" then
- local command = joblog.command
- if command then
- local replacements = {
- inputpath = toset((joblog.paths and joblog.paths.input ) or "."),
- outputpath = noset((joblog.paths and joblog.paths.output) or "."),
- filename = joblog.filename or "",
- }
- -- todo: revision path etc
- command = command:gsub("%%(.-)%%", replacements)
- if command ~= "" then
- joblog.status = "processing"
- joblog.runtime = clock()
- io.savedata(name, table.serialize(joblog,true))
- report("running: %s", command)
- local newpath = file.dirname(name)
- io.flush()
- local result = ""
- local ctmname = file.basename(replacements.filename)
- if ctmname == "" then ctmname = name end -- use self as fallback
- ctmname = file.replacesuffix(ctmname,"ctm")
- if newpath ~= "" and newpath ~= "." then
- local oldpath = lfs.currentdir()
- lfs.chdir(newpath)
- scripts.watch.save_exa_modes(joblog,ctmname)
- if pipe then result = os.resultof(command) else result = os.spawn(command) end
- lfs.chdir(oldpath)
- else
- scripts.watch.save_exa_modes(joblog,ctmname)
- if pipe then result = os.resultof(command) else result = os.spawn(command) end
- end
- report("return value: %s", result)
- done = true
- local path, base = replacements.outputpath, file.basename(replacements.filename)
- joblog.runtime = clock() - joblog.runtime
- if base ~= "" then
- joblog.result = file.replacesuffix(file.join(path,base),"pdf")
- joblog.size = lfs.attributes(joblog.result,"size")
- end
- joblog.status = "finished"
- else
- joblog.status = "invalid command"
- end
- else
- joblog.status = "no command"
- end
- -- pcall, when error sleep + again
- -- todo: just one log file and append
- io.savedata(name, table.serialize(joblog,true))
- if logpath and logpath ~= "" then
- local name = file.join(logpath,os.uuid() .. ".lua")
- io.savedata(name, table.serialize(joblog,true))
- report("saving joblog in %s",name)
- end
- end
- end
- end
- end
- end
- local n, start = 0, time()
- local wtime = 0
- local function wait()
- io.flush()
- if not done then
- n = n + 1
- if n >= 10 then
- report("run time: %i seconds, memory usage: %0.3g MB", difftime(time(),start), (status.luastate_bytes/1024)/1000)
- n = 0
- end
- local ttime = 0
- while ttime <= delay do
- local wt = lfs.attributes(watcher,"mtime")
- if wt and wt ~= wtime then
- -- fast signal that there is a request
- wtime = wt
- break
- end
- ttime = ttime + 0.2
- os.sleep(0.2)
- end
- end
- end
- local cleanupdelay, cleanup = environment.argument("cleanup"), false
- if cleanupdelay then
- local lasttime = time()
- cleanup = function()
- local currenttime = time()
- local delta = difftime(currenttime,lasttime)
- if delta > cleanupdelay then
- lasttime = currenttime
- for i=1,#paths do
- local path = paths[i]
- if string.find(path,"%.") then
- -- safeguard, we want a fully qualified path
- else
- local files = dir.glob(file.join(path,"*"))
- for i=1,#files do
- local name = files[i]
- local filetime = lfs.attributes(name,"modification")
- local delta = difftime(currenttime,filetime)
- if delta > cleanupdelay then
- -- report("cleaning up '%s'",name)
- os.remove(name)
- end
- end
- end
- end
- end
- end
- else
- cleanup = function()
- -- nothing
- end
- end
- while true do
- if false then
---~ if true then
- process()
- cleanup()
- wait()
- else
- pcall(process)
- pcall(cleanup)
- pcall(wait)
- end
- end
- else
- report("no paths to watch")
- end
-end
-
-function scripts.watch.collect_logs(path) -- clean 'm up too
- path = path or environment.argument("logpath") or ""
- path = (path == "" and ".") or path
- local files = dir.globfiles(path,false,"^%d+%.lua$")
- local collection = { }
- local valid = table.tohash({"filename","result","runtime","size","status"})
- for i=1,#files do
- local name = files[i]
- local t = dofile(name)
- if t and type(t) == "table" and t.status then
- for k, v in next, t do
- if not valid[k] then
- t[k] = nil
- end
- end
- collection[name:gsub("[^%d]","")] = t
- end
- end
- return collection
-end
-
-function scripts.watch.save_logs(collection,path) -- play safe
- if collection and next(collection) then
- path = path or environment.argument("logpath") or ""
- path = (path == "" and ".") or path
- local filename = format("%s/collected-%s.lua",path,tostring(time()))
- io.savedata(filename,table.serialize(collection,true))
- local check = dofile(filename)
- for k,v in next, check do
- if not collection[k] then
- report("error in saving file")
- os.remove(filename)
- return false
- end
- end
- for k,v in next, check do
- os.remove(format("%s.lua",k))
- end
- return true
- else
- return false
- end
-end
-
-function scripts.watch.collect_collections(path) -- removes duplicates
- path = path or environment.argument("logpath") or ""
- path = (path == "" and ".") or path
- local files = dir.globfiles(path,false,"^collected%-%d+%.lua$")
- local collection = { }
- for i=1,#files do
- local name = files[i]
- local t = dofile(name)
- if t and type(t) == "table" then
- for k, v in next, t do
- collection[k] = v
- end
- end
- end
- return collection
-end
-
-function scripts.watch.show_logs(path) -- removes duplicates
- local collection = scripts.watch.collect_collections(path) or { }
- local max = 0
- for k,v in next, collection do
- v = v.filename or "?"
- if #v > max then max = #v end
- end
- -- print(max)
- local sorted = table.sortedkeys(collection)
- for k=1,#sorted do
- local v = sorted[k]
- local c = collection[v]
- local f, s, r, n = c.filename or "?", c.status or "?", c.runtime or 0, c.size or 0
- report("%s %s %3i %8i %s",string.padd(f,max," "),string.padd(s,10," "),r,n,v)
- end
-end
-
-function scripts.watch.cleanup_stale_files() -- removes duplicates
- local path = environment.files[1]
- local delay = tonumber(environment.argument("cleanup"))
- local force = environment.argument("force")
- if not path or path == "." then
- report("provide qualified path")
- elseif not delay then
- report("missing --cleanup=delay")
- else
- report("dryrun, use --force for real cleanup")
- local files = dir.glob(file.join(path,"*"))
- local rtime = time()
- for i=1,#files do
- local name = files[i]
- local mtime = lfs.attributes(name,"modification")
- local delta = difftime(rtime,mtime)
- if delta > delay then
- report("cleaning up '%s'",name)
- if force then
- os.remove(name)
- end
- end
- end
- end
-end
-
-if environment.argument("watch") then
- scripts.watch.watch()
-elseif environment.argument("collect") then
- scripts.watch.save_logs(scripts.watch.collect_logs())
-elseif environment.argument("cleanup") then
- scripts.watch.save_logs(scripts.watch.cleanup_stale_files())
-elseif environment.argument("showlog") then
- scripts.watch.show_logs()
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-else
- application.help()
-end
+if not modules then modules = { } end modules ['mtx-watch'] = {
+ version = 1.001,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-watch</entry>
+ <entry name="detail">ConTeXt Request Watchdog</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="logpath"><short>optional path for log files</short></flag>
+ <flag name="watch"><short>watch given path [<ref name="delay]"/></short></flag>
+ <flag name="pipe"><short>use pipe instead of execute</short></flag>
+ <flag name="delay"><short>delay between sweeps</short></flag>
+ <flag name="automachine"><short>replace /machine/ in path /servername/</short></flag>
+ <flag name="collect"><short>condense log files</short></flag>
+ <flag name="cleanup" value="delay"><short>remove files in given path [<ref name="force]"/></short></flag>
+ <flag name="showlog"><short>show log data</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-watch",
+ banner = "ConTeXt Request Watchdog 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.watch = scripts.watch or { }
+
+local format, concat, difftime, time = string.format, table.concat, os.difftime, os.time
+local next, type = next, type
+local basename, dirname, joinname = file.basename, file.dirname, file.join
+local lfsdir, lfsattributes = lfs.dir, lfs.attributes
+
+-- the machine/instance matches the server app we use
+
+local machine = socket.dns.gethostname() or "unknown-machine"
+local instance = string.match(machine,"(%d+)$") or "0"
+
+function scripts.watch.save_exa_modes(joblog,ctmname)
+ local values = joblog and joblog.values
+ if values then
+ local t= { }
+ t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n"
+ t[#t+1] = "<exa:variables xmlns:exa='htpp://www.pragma-ade.com/schemas/exa-variables.rng'>"
+ for k, v in next, joblog.values do
+ t[#t+1] = format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v))
+ end
+ t[#t+1] = "</exa:variables>"
+ io.savedata(ctmname,concat(t,"\n"))
+ else
+ os.remove(ctmname)
+ end
+end
+
+local function toset(t)
+ if type(t) == "table" then
+ return concat(t,",")
+ else
+ return t
+ end
+end
+
+local function noset(t)
+ if type(t) == "table" then
+ return t[1]
+ else
+ return t
+ end
+end
+
+-- todo: split order (o-name.luj) and combine with atime to determine sort order.
+
+local function glob(files,path) -- some day: sort by name (order prefix) and atime
+ for name in lfsdir(path) do
+ if name:find("^%.") then
+ -- skip . and ..
+ else
+ name = path .. "/" .. name
+ local a = lfsattributes(name)
+ if not a then
+ -- weird
+ elseif a.mode == "directory" then
+ if name:find("graphics$") or name:find("figures$") or name:find("resources$") then
+ -- skip these too
+ else
+ glob(files,name)
+ end
+ elseif name:find(".%luj$") then
+ local bname = basename(name)
+ local dname = dirname(name)
+ local order = tonumber(bname:match("^(%d+)")) or 0
+ files[#files+1] = { dname, bname, order }
+ end
+ end
+ end
+end
+
+local clock = os.gettimeofday or (socket and socket.gettime) or os.time -- we cannot trust os.clock on linux
+
+-- local function filenamesort(a,b)
+-- local fa, da = a[1], a[2]
+-- local fb, db = b[1], b[2]
+-- if da == db then
+-- return fa < fb
+-- else
+-- return da < db
+-- end
+-- end
+
+local function filenamesort(a,b)
+ local fa, oa = a[2], a[3]
+ local fb, ob = b[2], b[3]
+ if fa == fb then
+ if oa == ob then
+ return a[1] < b[1] -- order file dir
+ else
+ return oa < ob -- order file
+ end
+ else
+ if oa == ob then
+ return fa < fb -- order file
+ else
+ return oa < ob -- order file
+ end
+ end
+end
+
+function scripts.watch.watch()
+ local delay = tonumber(environment.argument("delay") or 5) or 5
+ if delay == 0 then
+ delay = .25
+ end
+ local logpath = environment.argument("logpath") or ""
+ local pipe = environment.argument("pipe") or false
+ local watcher = "mtxwatch.run"
+ local paths = environment.files
+ if #paths > 0 then
+ if environment.argument("automachine") then
+ logpath = string.gsub(logpath,"/machine/","/"..machine.."/")
+ for i=1,#paths do
+ paths[i] = string.gsub(paths[i],"/machine/","/"..machine.."/")
+ end
+ end
+ for i=1,#paths do
+ report("watching path %s",paths[i])
+ end
+ local function process()
+ local done = false
+ for i=1,#paths do
+ local path = paths[i]
+ lfs.chdir(path)
+ local files = { }
+ glob(files,path)
+ table.sort(files,filenamesort)
+-- for name, time in next, files do
+ for i=1,#files do
+ local f = files[i]
+ local dirname = f[1]
+ local basename = f[2] -- we can use that later on
+ local name = joinname(dirname,basename)
+ --~ local ok, joblog = xpcall(function() return dofile(name) end, function() end )
+ local ok, joblog = pcall(dofile,name)
+ if ok and joblog then
+ if joblog.status == "processing" then
+ report("aborted job, %s added to queue",name)
+ joblog.status = "queued"
+ io.savedata(name, table.serialize(joblog,true))
+ elseif joblog.status == "queued" then
+ local command = joblog.command
+ if command then
+ local replacements = {
+ inputpath = toset((joblog.paths and joblog.paths.input ) or "."),
+ outputpath = noset((joblog.paths and joblog.paths.output) or "."),
+ filename = joblog.filename or "",
+ }
+ -- todo: revision path etc
+ command = command:gsub("%%(.-)%%", replacements)
+ if command ~= "" then
+ joblog.status = "processing"
+ joblog.runtime = clock()
+ io.savedata(name, table.serialize(joblog,true))
+ report("running: %s", command)
+ local newpath = file.dirname(name)
+ io.flush()
+ local result = ""
+ local ctmname = file.basename(replacements.filename)
+ if ctmname == "" then ctmname = name end -- use self as fallback
+ ctmname = file.replacesuffix(ctmname,"ctm")
+ if newpath ~= "" and newpath ~= "." then
+ local oldpath = lfs.currentdir()
+ lfs.chdir(newpath)
+ scripts.watch.save_exa_modes(joblog,ctmname)
+ if pipe then result = os.resultof(command) else result = os.spawn(command) end
+ lfs.chdir(oldpath)
+ else
+ scripts.watch.save_exa_modes(joblog,ctmname)
+ if pipe then result = os.resultof(command) else result = os.spawn(command) end
+ end
+ report("return value: %s", result)
+ done = true
+ local path, base = replacements.outputpath, file.basename(replacements.filename)
+ joblog.runtime = clock() - joblog.runtime
+ if base ~= "" then
+ joblog.result = file.replacesuffix(file.join(path,base),"pdf")
+ joblog.size = lfs.attributes(joblog.result,"size")
+ end
+ joblog.status = "finished"
+ else
+ joblog.status = "invalid command"
+ end
+ else
+ joblog.status = "no command"
+ end
+ -- pcall, when error sleep + again
+ -- todo: just one log file and append
+ io.savedata(name, table.serialize(joblog,true))
+ if logpath and logpath ~= "" then
+ local name = file.join(logpath,os.uuid() .. ".lua")
+ io.savedata(name, table.serialize(joblog,true))
+ report("saving joblog in %s",name)
+ end
+ end
+ end
+ end
+ end
+ end
+ local n, start = 0, time()
+ local wtime = 0
+ local function wait()
+ io.flush()
+ if not done then
+ n = n + 1
+ if n >= 10 then
+ report("run time: %i seconds, memory usage: %0.3g MB", difftime(time(),start), (status.luastate_bytes/1024)/1000)
+ n = 0
+ end
+ local ttime = 0
+ while ttime <= delay do
+ local wt = lfs.attributes(watcher,"mtime")
+ if wt and wt ~= wtime then
+ -- fast signal that there is a request
+ wtime = wt
+ break
+ end
+ ttime = ttime + 0.2
+ os.sleep(0.2)
+ end
+ end
+ end
+ local cleanupdelay, cleanup = environment.argument("cleanup"), false
+ if cleanupdelay then
+ local lasttime = time()
+ cleanup = function()
+ local currenttime = time()
+ local delta = difftime(currenttime,lasttime)
+ if delta > cleanupdelay then
+ lasttime = currenttime
+ for i=1,#paths do
+ local path = paths[i]
+ if string.find(path,"%.") then
+ -- safeguard, we want a fully qualified path
+ else
+ local files = dir.glob(file.join(path,"*"))
+ for i=1,#files do
+ local name = files[i]
+ local filetime = lfs.attributes(name,"modification")
+ local delta = difftime(currenttime,filetime)
+ if delta > cleanupdelay then
+ -- report("cleaning up '%s'",name)
+ os.remove(name)
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ cleanup = function()
+ -- nothing
+ end
+ end
+ while true do
+ if false then
+--~ if true then
+ process()
+ cleanup()
+ wait()
+ else
+ pcall(process)
+ pcall(cleanup)
+ pcall(wait)
+ end
+ end
+ else
+ report("no paths to watch")
+ end
+end
+
+function scripts.watch.collect_logs(path) -- clean 'm up too
+ path = path or environment.argument("logpath") or ""
+ path = (path == "" and ".") or path
+ local files = dir.globfiles(path,false,"^%d+%.lua$")
+ local collection = { }
+ local valid = table.tohash({"filename","result","runtime","size","status"})
+ for i=1,#files do
+ local name = files[i]
+ local t = dofile(name)
+ if t and type(t) == "table" and t.status then
+ for k, v in next, t do
+ if not valid[k] then
+ t[k] = nil
+ end
+ end
+ collection[name:gsub("[^%d]","")] = t
+ end
+ end
+ return collection
+end
+
+function scripts.watch.save_logs(collection,path) -- play safe
+ if collection and next(collection) then
+ path = path or environment.argument("logpath") or ""
+ path = (path == "" and ".") or path
+ local filename = format("%s/collected-%s.lua",path,tostring(time()))
+ io.savedata(filename,table.serialize(collection,true))
+ local check = dofile(filename)
+ for k,v in next, check do
+ if not collection[k] then
+ report("error in saving file")
+ os.remove(filename)
+ return false
+ end
+ end
+ for k,v in next, check do
+ os.remove(format("%s.lua",k))
+ end
+ return true
+ else
+ return false
+ end
+end
+
+function scripts.watch.collect_collections(path) -- removes duplicates
+ path = path or environment.argument("logpath") or ""
+ path = (path == "" and ".") or path
+ local files = dir.globfiles(path,false,"^collected%-%d+%.lua$")
+ local collection = { }
+ for i=1,#files do
+ local name = files[i]
+ local t = dofile(name)
+ if t and type(t) == "table" then
+ for k, v in next, t do
+ collection[k] = v
+ end
+ end
+ end
+ return collection
+end
+
+function scripts.watch.show_logs(path) -- removes duplicates
+ local collection = scripts.watch.collect_collections(path) or { }
+ local max = 0
+ for k,v in next, collection do
+ v = v.filename or "?"
+ if #v > max then max = #v end
+ end
+ -- print(max)
+ local sorted = table.sortedkeys(collection)
+ for k=1,#sorted do
+ local v = sorted[k]
+ local c = collection[v]
+ local f, s, r, n = c.filename or "?", c.status or "?", c.runtime or 0, c.size or 0
+ report("%s %s %3i %8i %s",string.padd(f,max," "),string.padd(s,10," "),r,n,v)
+ end
+end
+
+function scripts.watch.cleanup_stale_files() -- removes duplicates
+ local path = environment.files[1]
+ local delay = tonumber(environment.argument("cleanup"))
+ local force = environment.argument("force")
+ if not path or path == "." then
+ report("provide qualified path")
+ elseif not delay then
+ report("missing --cleanup=delay")
+ else
+ report("dryrun, use --force for real cleanup")
+ local files = dir.glob(file.join(path,"*"))
+ local rtime = time()
+ for i=1,#files do
+ local name = files[i]
+ local mtime = lfs.attributes(name,"modification")
+ local delta = difftime(rtime,mtime)
+ if delta > delay then
+ report("cleaning up '%s'",name)
+ if force then
+ os.remove(name)
+ end
+ end
+ end
+ end
+end
+
+if environment.argument("watch") then
+ scripts.watch.watch()
+elseif environment.argument("collect") then
+ scripts.watch.save_logs(scripts.watch.collect_logs())
+elseif environment.argument("cleanup") then
+ scripts.watch.save_logs(scripts.watch.cleanup_stale_files())
+elseif environment.argument("showlog") then
+ scripts.watch.show_logs()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+end