From ed637df24cc8435fc78d30bc08c89f7db60b39c9 Mon Sep 17 00:00:00 2001
From: Marius <mariausol@gmail.com>
Date: Wed, 9 Feb 2011 16:40:14 +0200
Subject: beta 2011.02.09 15:29

---
 scripts/context/lua/mtx-context.lua    |  78 ++++++++++++++---
 scripts/context/lua/mtxrun.lua         | 151 ++++++++++++++++++++++++++-------
 scripts/context/stubs/mswin/mtxrun.lua | 151 ++++++++++++++++++++++++++-------
 scripts/context/stubs/unix/mtxrun      | 151 ++++++++++++++++++++++++++-------
 4 files changed, 426 insertions(+), 105 deletions(-)

(limited to 'scripts')

diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index 98935adce..2ffab155a 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -153,7 +153,7 @@ do
     function ctxrunner.reflag(flags)
         local t = { }
         for _, flag in next, flags do
-            local key, value = flag:match("^(.-)=(.+)$")
+            local key, value = match(flag,"^(.-)=(.+)$")
             if key and value then
                 t[key] = value
             else
@@ -502,7 +502,7 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr
             else
                 local a = someflag(flag) or (plural and someflag(flag.."s"))
                 if a and a ~= "" then
-                    for v in a:gmatch("%s*([^,]+)") do
+                    for v in gmatch(a,"%s*([^,]+)") do
                         f:write(format(template,v),"\n")
                     end
                 end
@@ -643,9 +643,9 @@ local function analyze(filename) -- only files on current path
     if f then
         local t = { }
         local line = f:read("*line") or ""
-        local preamble = line:match("[\254\255]*%%%s+(.+)$") -- there can be an utf bomb in front
+        local preamble = match(line,"[\254\255]*%%%s+(.+)$") -- there can be an utf bomb in front
         if preamble then
-            for key, value in preamble:gmatch("(%S+)=(%S+)") do
+            for key, value in gmatch(preamble,"(%S+)=(%S+)") do
                 t[key] = value
             end
             t.type = "tex"
@@ -1160,7 +1160,7 @@ function scripts.context.version()
         report("main context file: %s",name)
         local data = io.loaddata(name)
         if data then
-            local version = data:match("\\edef\\contextversion{(.-)}")
+            local version = match(data,"\\edef\\contextversion{(.-)}")
             if version then
                 report("current version: %s",version)
             else
@@ -1310,22 +1310,74 @@ function scripts.context.touch()
     end
 end
 
+-- modules
+
+local labels = { "title", "comment", "status" }
+
+function scripts.context.modules(pattern)
+    local list = { }
+    local found = resolvers.findfile("context.mkiv")
+    if not pattern or pattern == "" then
+        -- official files in the tree
+        resolvers.findwildcardfiles("*.tex",list)
+        resolvers.findwildcardfiles("*.mkiv",list)
+        -- my dev path
+        dir.glob(file.join(file.dirname(found),"*.tex"),list)
+        dir.glob(file.join(file.dirname(found),"*.mkiv"),list)
+    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" 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
     local found = resolvers.findfile("context.mkiv")
-    if found == "" then
-        report("unknown extra: %s", extra)
-    else
+    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")
+            data = match(data,"%% begin help(.-)%% end help")
             if data then
                 report()
-                report(format("extra: %s (%s)",gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1"),v))
+                report("extra: %s (%s)",(gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1")),v)
                 for s in gmatch(data,"%% *(.-)[\n\r]") do
                     report(s)
                 end
@@ -1464,8 +1516,8 @@ function scripts.context.update()
         end
         local oldfile = io.loaddata(resolvers.findfile("context.mkiv")) or ""
         local function versiontonumber(what,str)
-            local version = str:match("\\edef\\contextversion{(.-)}") or ""
-            local year, month, day, hour, minute = str:match("\\edef\\contextversion{(%d+)%.(%d+)%.(%d+) *(%d+)%:(%d+)}")
+            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)
@@ -1567,6 +1619,8 @@ elseif environment.argument("update") then
     scripts.context.update()
 elseif environment.argument("expert") then
     application.help("expert", "special")
+elseif environment.argument("modules") then
+    scripts.context.modules()
 elseif environment.argument("extras") then
     scripts.context.extras()
 elseif environment.argument("extra") then
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 27e0cbfa6..fed0e13f4 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -5004,43 +5004,78 @@ local function ignore() end
 
 setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
 
-local report, subreport, status, settarget
+local report, subreport, status, settarget, setformatter
+
+local direct, subdirect, writer
 
 if tex and tex.jobname or tex.formatname then
 
-    local target = "term and log"
+    local valueiskey   = { __index = function(t,k) t[k] = k return k end } -- will be helper
+
+    local target       = "term and log"
+
+    local formats      = { } setmetatable(formats,     valueiskey)
+    local translations = { } setmetatable(translations,valueiskey)
+
+    writer = function(...)
+        write_nl(target,...)
+    end
 
     report = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s > %s\n",a,format(b,c,...)))
+            write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...)))
         elseif b then
-            write_nl(target,format("%-15s > %s\n",a,b))
+            write_nl(target,format("%-15s > %s\n",translations[a],formats[b]))
         elseif a then
-            write_nl(target,format("%-15s >\n",   a))
+            write_nl(target,format("%-15s >\n",   translations[a]))
         else
             write_nl(target,"\n")
         end
     end
 
-    subreport = function(a,sub,b,c,...)
+    direct = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...)))
+            return format("%-15s > %s",translations[a],format(formats[b],c,...))
         elseif b then
-            write_nl(target,format("%-15s > %s > %s\n",a,sub,b))
+            return format("%-15s > %s",translations[a],formats[b])
         elseif a then
-            write_nl(target,format("%-15s > %s >\n",   a,sub))
+            return format("%-15s >",   translations[a])
+        else
+            return ""
+        end
+    end
+
+    subreport = function(a,s,b,c,...)
+        if c then
+            write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...)))
+        elseif b then
+            write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b]))
+        elseif a then
+            write_nl(target,format("%-15s > %s >\n",   translations[a],translations[s]))
         else
             write_nl(target,"\n")
         end
     end
 
+    subdirect = function(a,s,b,c,...)
+        if c then
+            return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...))
+        elseif b then
+            return format("%-15s > %s > %s",translations[a],translations[s],formats[b])
+        elseif a then
+            return format("%-15s > %s >",   translations[a],translations[s])
+        else
+            return ""
+        end
+    end
+
     status = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s : %s\n",a,format(b,c,...)))
+            write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...)))
         elseif b then
-            write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s
+            write_nl(target,format("%-15s : %s\n",translations[a],formats[b]))
         elseif a then
-            write_nl(target,format("%-15s :\n",   a))
+            write_nl(target,format("%-15s :\n",   translations[a]))
         else
             write_nl(target,"\n")
         end
@@ -5072,8 +5107,18 @@ if tex and tex.jobname or tex.formatname then
         end
     end
 
+    setformats = function(f)
+        formats = f
+    end
+
+    settranslations = function(t)
+        translations = t
+    end
+
 else
 
+    writer = write_nl
+
     report = function(a,b,c,...)
         if c then
             write_nl(format("%-15s | %s",a,format(b,c,...)))
@@ -5110,18 +5155,29 @@ else
         end
     end
 
-    settarget  = ignore
-    pushtarget = ignore
-    poptarget  = ignore
+    direct          = ignore
+    subdirect       = ignore
+
+    settarget       = ignore
+    pushtarget      = ignore
+    poptarget       = ignore
+    setformats      = ignore
+    settranslations = ignore
 
 end
 
-logs.report     = report
-logs.subreport  = subreport
-logs.status     = status
-logs.settarget  = settarget
-logs.pushtarget = pushtarget
-logs.poptarget  = poptarget
+logs.report          = report
+logs.subreport       = subreport
+logs.status          = status
+logs.settarget       = settarget
+logs.pushtarget      = pushtarget
+logs.poptarget       = poptarget
+logs.setformats      = setformats
+logs.settranslations = settranslations
+
+logs.direct          = direct
+logs.subdirect       = subdirect
+logs.writer          = writer
 
 -- installer
 
@@ -5171,7 +5227,30 @@ function logs.reporter(category,subcategory)
     return reporter
 end
 
-logs.new = logs.reporter
+logs.new = logs.reporter -- for old times sake
+
+-- context specicific: this ends up in the macro stream
+
+local ctxreport = logs.writer
+
+function logs.setmessenger(m)
+    ctxreport = m
+end
+
+function logs.messenger(category,subcategory)
+    -- we need to avoid catcode mess (todo: fast context)
+    if subcategory then
+        return function(...)
+            ctxreport(subdirect(category,subcategory,...))
+        end
+    else
+        return function(...)
+            ctxreport(direct(category,...))
+        end
+    end
+end
+
+-- so far
 
 local function doset(category,value)
     if category == true then
@@ -11851,17 +11930,20 @@ end
 local function doit(path,blist,bname,tag,kind,result,allresults)
     local done = false
     if blist and kind then
+        local resolve = resolvers.resolve -- added
         if type(blist) == 'string' then
             -- make function and share code
             if find(lower(blist),path) then
-                result[#result+1] = methodhandler('concatinators',kind,tag,blist,bname) or ""
+                local full = methodhandler('concatinators',kind,tag,blist,bname) or ""
+                result[#result+1] = resolve(full)
                 done = true
             end
         else
             for kk=1,#blist do
                 local vv = blist[kk]
                 if find(lower(vv),path) then
-                    result[#result+1] = methodhandler('concatinators',kind,tag,vv,bname) or ""
+                    local full = methodhandler('concatinators',kind,tag,vv,bname) or ""
+                    result[#result+1] = resolve(full)
                     done = true
                     if not allresults then break end
                 end
@@ -11871,15 +11953,22 @@ local function doit(path,blist,bname,tag,kind,result,allresults)
     return done
 end
 
+
 local makewildcard = Cs(
     (P("^")^0 * P("/") * P(-1) + P(-1)) /".*"
-  + (P("^")^0 * P("/") / "") * (P("*")/".*" + P("-")/"%%-" + P("?")/"."+ P("\\")/"/" + P(1))^0
+  + (P("^")^0 * P("/") / "")^0 * (P("*")/".*" + P("-")/"%%-" + P(".")/"%%." + P("?")/"."+ P("\\")/"/" + P(1))^0
 )
 
-local function findwildcardfiles(filename,allresults) -- todo: remap: and lpeg
-    local result = { }
-    local path = lower(lpegmatch(makewildcard,filedirname (filename)))
-    local name = lower(lpegmatch(makewildcard,filebasename(filename)))
+function resolvers.wildcardpattern(pattern)
+    return lpegmatch(makewildcard,pattern) or pattern
+end
+
+local function findwildcardfiles(filename,allresults,result) -- todo: remap: and lpeg
+    result = result or { }
+    local base = filebasename(filename)
+    local dirn = filedirname(filename)
+    local path = lower(lpegmatch(makewildcard,dirn) or dirn)
+    local name = lower(lpegmatch(makewildcard,base) or base)
     local files, done = instance.files, false
     if find(name,"%*") then
         local hashes = instance.hashes
@@ -11909,8 +11998,8 @@ local function findwildcardfiles(filename,allresults) -- todo: remap: and lpeg
     return result
 end
 
-function resolvers.findwildcardfiles(filename)
-    return findwildcardfiles(filename,true)
+function resolvers.findwildcardfiles(filename,result)
+    return findwildcardfiles(filename,true,result)
 end
 
 function resolvers.findwildcardfile(filename)
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 27e0cbfa6..fed0e13f4 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -5004,43 +5004,78 @@ local function ignore() end
 
 setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
 
-local report, subreport, status, settarget
+local report, subreport, status, settarget, setformatter
+
+local direct, subdirect, writer
 
 if tex and tex.jobname or tex.formatname then
 
-    local target = "term and log"
+    local valueiskey   = { __index = function(t,k) t[k] = k return k end } -- will be helper
+
+    local target       = "term and log"
+
+    local formats      = { } setmetatable(formats,     valueiskey)
+    local translations = { } setmetatable(translations,valueiskey)
+
+    writer = function(...)
+        write_nl(target,...)
+    end
 
     report = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s > %s\n",a,format(b,c,...)))
+            write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...)))
         elseif b then
-            write_nl(target,format("%-15s > %s\n",a,b))
+            write_nl(target,format("%-15s > %s\n",translations[a],formats[b]))
         elseif a then
-            write_nl(target,format("%-15s >\n",   a))
+            write_nl(target,format("%-15s >\n",   translations[a]))
         else
             write_nl(target,"\n")
         end
     end
 
-    subreport = function(a,sub,b,c,...)
+    direct = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...)))
+            return format("%-15s > %s",translations[a],format(formats[b],c,...))
         elseif b then
-            write_nl(target,format("%-15s > %s > %s\n",a,sub,b))
+            return format("%-15s > %s",translations[a],formats[b])
         elseif a then
-            write_nl(target,format("%-15s > %s >\n",   a,sub))
+            return format("%-15s >",   translations[a])
+        else
+            return ""
+        end
+    end
+
+    subreport = function(a,s,b,c,...)
+        if c then
+            write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...)))
+        elseif b then
+            write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b]))
+        elseif a then
+            write_nl(target,format("%-15s > %s >\n",   translations[a],translations[s]))
         else
             write_nl(target,"\n")
         end
     end
 
+    subdirect = function(a,s,b,c,...)
+        if c then
+            return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...))
+        elseif b then
+            return format("%-15s > %s > %s",translations[a],translations[s],formats[b])
+        elseif a then
+            return format("%-15s > %s >",   translations[a],translations[s])
+        else
+            return ""
+        end
+    end
+
     status = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s : %s\n",a,format(b,c,...)))
+            write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...)))
         elseif b then
-            write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s
+            write_nl(target,format("%-15s : %s\n",translations[a],formats[b]))
         elseif a then
-            write_nl(target,format("%-15s :\n",   a))
+            write_nl(target,format("%-15s :\n",   translations[a]))
         else
             write_nl(target,"\n")
         end
@@ -5072,8 +5107,18 @@ if tex and tex.jobname or tex.formatname then
         end
     end
 
+    setformats = function(f)
+        formats = f
+    end
+
+    settranslations = function(t)
+        translations = t
+    end
+
 else
 
+    writer = write_nl
+
     report = function(a,b,c,...)
         if c then
             write_nl(format("%-15s | %s",a,format(b,c,...)))
@@ -5110,18 +5155,29 @@ else
         end
     end
 
-    settarget  = ignore
-    pushtarget = ignore
-    poptarget  = ignore
+    direct          = ignore
+    subdirect       = ignore
+
+    settarget       = ignore
+    pushtarget      = ignore
+    poptarget       = ignore
+    setformats      = ignore
+    settranslations = ignore
 
 end
 
-logs.report     = report
-logs.subreport  = subreport
-logs.status     = status
-logs.settarget  = settarget
-logs.pushtarget = pushtarget
-logs.poptarget  = poptarget
+logs.report          = report
+logs.subreport       = subreport
+logs.status          = status
+logs.settarget       = settarget
+logs.pushtarget      = pushtarget
+logs.poptarget       = poptarget
+logs.setformats      = setformats
+logs.settranslations = settranslations
+
+logs.direct          = direct
+logs.subdirect       = subdirect
+logs.writer          = writer
 
 -- installer
 
@@ -5171,7 +5227,30 @@ function logs.reporter(category,subcategory)
     return reporter
 end
 
-logs.new = logs.reporter
+logs.new = logs.reporter -- for old times sake
+
+-- context specicific: this ends up in the macro stream
+
+local ctxreport = logs.writer
+
+function logs.setmessenger(m)
+    ctxreport = m
+end
+
+function logs.messenger(category,subcategory)
+    -- we need to avoid catcode mess (todo: fast context)
+    if subcategory then
+        return function(...)
+            ctxreport(subdirect(category,subcategory,...))
+        end
+    else
+        return function(...)
+            ctxreport(direct(category,...))
+        end
+    end
+end
+
+-- so far
 
 local function doset(category,value)
     if category == true then
@@ -11851,17 +11930,20 @@ end
 local function doit(path,blist,bname,tag,kind,result,allresults)
     local done = false
     if blist and kind then
+        local resolve = resolvers.resolve -- added
         if type(blist) == 'string' then
             -- make function and share code
             if find(lower(blist),path) then
-                result[#result+1] = methodhandler('concatinators',kind,tag,blist,bname) or ""
+                local full = methodhandler('concatinators',kind,tag,blist,bname) or ""
+                result[#result+1] = resolve(full)
                 done = true
             end
         else
             for kk=1,#blist do
                 local vv = blist[kk]
                 if find(lower(vv),path) then
-                    result[#result+1] = methodhandler('concatinators',kind,tag,vv,bname) or ""
+                    local full = methodhandler('concatinators',kind,tag,vv,bname) or ""
+                    result[#result+1] = resolve(full)
                     done = true
                     if not allresults then break end
                 end
@@ -11871,15 +11953,22 @@ local function doit(path,blist,bname,tag,kind,result,allresults)
     return done
 end
 
+
 local makewildcard = Cs(
     (P("^")^0 * P("/") * P(-1) + P(-1)) /".*"
-  + (P("^")^0 * P("/") / "") * (P("*")/".*" + P("-")/"%%-" + P("?")/"."+ P("\\")/"/" + P(1))^0
+  + (P("^")^0 * P("/") / "")^0 * (P("*")/".*" + P("-")/"%%-" + P(".")/"%%." + P("?")/"."+ P("\\")/"/" + P(1))^0
 )
 
-local function findwildcardfiles(filename,allresults) -- todo: remap: and lpeg
-    local result = { }
-    local path = lower(lpegmatch(makewildcard,filedirname (filename)))
-    local name = lower(lpegmatch(makewildcard,filebasename(filename)))
+function resolvers.wildcardpattern(pattern)
+    return lpegmatch(makewildcard,pattern) or pattern
+end
+
+local function findwildcardfiles(filename,allresults,result) -- todo: remap: and lpeg
+    result = result or { }
+    local base = filebasename(filename)
+    local dirn = filedirname(filename)
+    local path = lower(lpegmatch(makewildcard,dirn) or dirn)
+    local name = lower(lpegmatch(makewildcard,base) or base)
     local files, done = instance.files, false
     if find(name,"%*") then
         local hashes = instance.hashes
@@ -11909,8 +11998,8 @@ local function findwildcardfiles(filename,allresults) -- todo: remap: and lpeg
     return result
 end
 
-function resolvers.findwildcardfiles(filename)
-    return findwildcardfiles(filename,true)
+function resolvers.findwildcardfiles(filename,result)
+    return findwildcardfiles(filename,true,result)
 end
 
 function resolvers.findwildcardfile(filename)
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 27e0cbfa6..fed0e13f4 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -5004,43 +5004,78 @@ local function ignore() end
 
 setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end })
 
-local report, subreport, status, settarget
+local report, subreport, status, settarget, setformatter
+
+local direct, subdirect, writer
 
 if tex and tex.jobname or tex.formatname then
 
-    local target = "term and log"
+    local valueiskey   = { __index = function(t,k) t[k] = k return k end } -- will be helper
+
+    local target       = "term and log"
+
+    local formats      = { } setmetatable(formats,     valueiskey)
+    local translations = { } setmetatable(translations,valueiskey)
+
+    writer = function(...)
+        write_nl(target,...)
+    end
 
     report = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s > %s\n",a,format(b,c,...)))
+            write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...)))
         elseif b then
-            write_nl(target,format("%-15s > %s\n",a,b))
+            write_nl(target,format("%-15s > %s\n",translations[a],formats[b]))
         elseif a then
-            write_nl(target,format("%-15s >\n",   a))
+            write_nl(target,format("%-15s >\n",   translations[a]))
         else
             write_nl(target,"\n")
         end
     end
 
-    subreport = function(a,sub,b,c,...)
+    direct = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...)))
+            return format("%-15s > %s",translations[a],format(formats[b],c,...))
         elseif b then
-            write_nl(target,format("%-15s > %s > %s\n",a,sub,b))
+            return format("%-15s > %s",translations[a],formats[b])
         elseif a then
-            write_nl(target,format("%-15s > %s >\n",   a,sub))
+            return format("%-15s >",   translations[a])
+        else
+            return ""
+        end
+    end
+
+    subreport = function(a,s,b,c,...)
+        if c then
+            write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...)))
+        elseif b then
+            write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b]))
+        elseif a then
+            write_nl(target,format("%-15s > %s >\n",   translations[a],translations[s]))
         else
             write_nl(target,"\n")
         end
     end
 
+    subdirect = function(a,s,b,c,...)
+        if c then
+            return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...))
+        elseif b then
+            return format("%-15s > %s > %s",translations[a],translations[s],formats[b])
+        elseif a then
+            return format("%-15s > %s >",   translations[a],translations[s])
+        else
+            return ""
+        end
+    end
+
     status = function(a,b,c,...)
         if c then
-            write_nl(target,format("%-15s : %s\n",a,format(b,c,...)))
+            write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...)))
         elseif b then
-            write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s
+            write_nl(target,format("%-15s : %s\n",translations[a],formats[b]))
         elseif a then
-            write_nl(target,format("%-15s :\n",   a))
+            write_nl(target,format("%-15s :\n",   translations[a]))
         else
             write_nl(target,"\n")
         end
@@ -5072,8 +5107,18 @@ if tex and tex.jobname or tex.formatname then
         end
     end
 
+    setformats = function(f)
+        formats = f
+    end
+
+    settranslations = function(t)
+        translations = t
+    end
+
 else
 
+    writer = write_nl
+
     report = function(a,b,c,...)
         if c then
             write_nl(format("%-15s | %s",a,format(b,c,...)))
@@ -5110,18 +5155,29 @@ else
         end
     end
 
-    settarget  = ignore
-    pushtarget = ignore
-    poptarget  = ignore
+    direct          = ignore
+    subdirect       = ignore
+
+    settarget       = ignore
+    pushtarget      = ignore
+    poptarget       = ignore
+    setformats      = ignore
+    settranslations = ignore
 
 end
 
-logs.report     = report
-logs.subreport  = subreport
-logs.status     = status
-logs.settarget  = settarget
-logs.pushtarget = pushtarget
-logs.poptarget  = poptarget
+logs.report          = report
+logs.subreport       = subreport
+logs.status          = status
+logs.settarget       = settarget
+logs.pushtarget      = pushtarget
+logs.poptarget       = poptarget
+logs.setformats      = setformats
+logs.settranslations = settranslations
+
+logs.direct          = direct
+logs.subdirect       = subdirect
+logs.writer          = writer
 
 -- installer
 
@@ -5171,7 +5227,30 @@ function logs.reporter(category,subcategory)
     return reporter
 end
 
-logs.new = logs.reporter
+logs.new = logs.reporter -- for old times sake
+
+-- context specicific: this ends up in the macro stream
+
+local ctxreport = logs.writer
+
+function logs.setmessenger(m)
+    ctxreport = m
+end
+
+function logs.messenger(category,subcategory)
+    -- we need to avoid catcode mess (todo: fast context)
+    if subcategory then
+        return function(...)
+            ctxreport(subdirect(category,subcategory,...))
+        end
+    else
+        return function(...)
+            ctxreport(direct(category,...))
+        end
+    end
+end
+
+-- so far
 
 local function doset(category,value)
     if category == true then
@@ -11851,17 +11930,20 @@ end
 local function doit(path,blist,bname,tag,kind,result,allresults)
     local done = false
     if blist and kind then
+        local resolve = resolvers.resolve -- added
         if type(blist) == 'string' then
             -- make function and share code
             if find(lower(blist),path) then
-                result[#result+1] = methodhandler('concatinators',kind,tag,blist,bname) or ""
+                local full = methodhandler('concatinators',kind,tag,blist,bname) or ""
+                result[#result+1] = resolve(full)
                 done = true
             end
         else
             for kk=1,#blist do
                 local vv = blist[kk]
                 if find(lower(vv),path) then
-                    result[#result+1] = methodhandler('concatinators',kind,tag,vv,bname) or ""
+                    local full = methodhandler('concatinators',kind,tag,vv,bname) or ""
+                    result[#result+1] = resolve(full)
                     done = true
                     if not allresults then break end
                 end
@@ -11871,15 +11953,22 @@ local function doit(path,blist,bname,tag,kind,result,allresults)
     return done
 end
 
+
 local makewildcard = Cs(
     (P("^")^0 * P("/") * P(-1) + P(-1)) /".*"
-  + (P("^")^0 * P("/") / "") * (P("*")/".*" + P("-")/"%%-" + P("?")/"."+ P("\\")/"/" + P(1))^0
+  + (P("^")^0 * P("/") / "")^0 * (P("*")/".*" + P("-")/"%%-" + P(".")/"%%." + P("?")/"."+ P("\\")/"/" + P(1))^0
 )
 
-local function findwildcardfiles(filename,allresults) -- todo: remap: and lpeg
-    local result = { }
-    local path = lower(lpegmatch(makewildcard,filedirname (filename)))
-    local name = lower(lpegmatch(makewildcard,filebasename(filename)))
+function resolvers.wildcardpattern(pattern)
+    return lpegmatch(makewildcard,pattern) or pattern
+end
+
+local function findwildcardfiles(filename,allresults,result) -- todo: remap: and lpeg
+    result = result or { }
+    local base = filebasename(filename)
+    local dirn = filedirname(filename)
+    local path = lower(lpegmatch(makewildcard,dirn) or dirn)
+    local name = lower(lpegmatch(makewildcard,base) or base)
     local files, done = instance.files, false
     if find(name,"%*") then
         local hashes = instance.hashes
@@ -11909,8 +11998,8 @@ local function findwildcardfiles(filename,allresults) -- todo: remap: and lpeg
     return result
 end
 
-function resolvers.findwildcardfiles(filename)
-    return findwildcardfiles(filename,true)
+function resolvers.findwildcardfiles(filename,result)
+    return findwildcardfiles(filename,true,result)
 end
 
 function resolvers.findwildcardfile(filename)
-- 
cgit v1.2.3