texlive[49982] Master/texmf-dist: lualibs (7feb19)

commits+karl at tug.org commits+karl at tug.org
Sat Feb 9 00:01:17 CET 2019


Revision: 49982
          http://tug.org/svn/texlive?view=revision&revision=49982
Author:   karl
Date:     2019-02-09 00:01:17 +0100 (Sat, 09 Feb 2019)
Log Message:
-----------
lualibs (7feb19)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS
    trunk/Master/texmf-dist/doc/luatex/lualibs/README
    trunk/Master/texmf-dist/doc/luatex/lualibs/lualibs.pdf
    trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-lua.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
    trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua

Modified: trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/doc/luatex/lualibs/NEWS	2019-02-08 23:01:17 UTC (rev 49982)
@@ -1,6 +1,9 @@
                         History of the lualibs package
-2018-12-19 v2.62/ (upload 2019-01-16)
-    * sync with Context beta as of 2018-12-19
+2019/01/28 v2.63/
+    * sync with Context beta as of 2019/01/28
+
+2019/01/28 v2.62/
+    * sync with Context beta as of 2018/12/19
                         
 2018/10/18 v2.61/
     * sync with Context beta as of 2018-10-18

Modified: trunk/Master/texmf-dist/doc/luatex/lualibs/README
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/lualibs/README	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/doc/luatex/lualibs/README	2019-02-08 23:01:17 UTC (rev 49982)
@@ -11,8 +11,8 @@
 This package has been developed by the LuaLaTeX development team on
 <http://github.com/lualatex/lualibs>. 
 
-The current verson 2.62 has been build by Ulrike Fischer on
-<https://github.com/u-fischer/lualibs> from context 2018-12-19. 
+The current verson 2.63 has been build by Ulrike Fischer on
+<https://github.com/u-fischer/lualibs> from context 2019-01-28. 
 
 See the 'NEWS' file for version history.
 

Modified: trunk/Master/texmf-dist/doc/luatex/lualibs/lualibs.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx
===================================================================
--- trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/source/luatex/lualibs/lualibs.dtx	2019-02-08 23:01:17 UTC (rev 49982)
@@ -37,7 +37,7 @@
 \input docstrip.tex
 \Msg{************************************************************************}
 \Msg{* Installation}
-\Msg{* Package: lualibs 2018-12-19 v2.62 Lua additional functions.}
+\Msg{* Package: lualibs 2019-01-28 v2.63 Lua additional functions.}
 \Msg{************************************************************************}
 
 \keepsilent
@@ -107,7 +107,7 @@
 %<*driver>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{lualibs.drv}
-  [2018/12/07 v2.62 Lua Libraries.]
+  [2010/01/28 v2.63 Lua Libraries.]
 \documentclass{ltxdoc}
 \usepackage{fancyvrb,xspace}
 \usepackage[x11names]{xcolor}
@@ -208,7 +208,7 @@
 % \GetFileInfo{lualibs.drv}
 %
 % \title{The \identifier{lualibs} package}
-% \date{2018/12/07 v2.62}
+% \date{2019/01/28 v2.63}
 % \author{Élie Roux      · \email{elie.roux at telecom-bretagne.eu}\\
 %         Philipp Gesang · \email{phg at phi-gamma.net}\\
 %         Ulrike Fischer · \email{fischer at troubleshooting-tex.de}\\
@@ -429,8 +429,8 @@
 
 lualibs.module_info = {
   name          = "lualibs",
-  version       = 2.62,
-  date          = "2018-12-19",
+  version       = 2.63,
+  date          = "2019-01-28",
   description   = "ConTeXt Lua standard libraries.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",
@@ -584,8 +584,8 @@
 
 local lualibs_basic_module = {
   name          = "lualibs-basic",
-  version       = 2.62,
-  date          = "2018-12-19",
+  version       = 2.63,
+  date          = "2019-01-28",
   description   = "ConTeXt Lua libraries -- basic collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",
@@ -666,8 +666,8 @@
 
 local lualibs_extended_module = {
   name          = "lualibs-extended",
-  version       = 2.62,
-  date          = "2018-12-19",
+  version       = 2.63,
+  date          = "2019-01-28",
   description   = "ConTeXt Lua libraries -- extended collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -1,15 +1,15 @@
 -- merged file : lualibs-basic-merged.lua
 -- parent file : lualibs-basic.lua
--- merge date  : Tue Dec 25 16:21:45 2018
+-- merge date  : Wed Jan 30 23:25:49 2019
 
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-lua']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local next,type,tonumber=next,type,tonumber
 LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -17,111 +17,110 @@
 LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
 LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
 if LUAVERSION<5.2 and jit then
-  MINORVERSION=2
-  LUAVERSION=5.2
+ MINORVERSION=2
+ LUAVERSION=5.2
 end
-_LUAVERSION=LUAVERSION
 if not lpeg then
-  lpeg=require("lpeg")
+ lpeg=require("lpeg")
 end
 if loadstring then
-  local loadnormal=load
-  function load(first,...)
-    if type(first)=="string" then
-      return loadstring(first,...)
-    else
-      return loadnormal(first,...)
-    end
+ local loadnormal=load
+ function load(first,...)
+  if type(first)=="string" then
+   return loadstring(first,...)
+  else
+   return loadnormal(first,...)
   end
+ end
 else
-  loadstring=load
+ loadstring=load
 end
 if not ipairs then
-  local function iterate(a,i)
-    i=i+1
-    local v=a[i]
-    if v~=nil then
-      return i,v 
-    end
+ local function iterate(a,i)
+  i=i+1
+  local v=a[i]
+  if v~=nil then
+   return i,v 
   end
-  function ipairs(a)
-    return iterate,a,0
-  end
+ end
+ function ipairs(a)
+  return iterate,a,0
+ end
 end
 if not pairs then
-  function pairs(t)
-    return next,t 
-  end
+ function pairs(t)
+  return next,t 
+ end
 end
 if not table.unpack then
-  table.unpack=_G.unpack
+ table.unpack=_G.unpack
 elseif not unpack then
-  _G.unpack=table.unpack
+ _G.unpack=table.unpack
 end
 if not package.loaders then 
-  package.loaders=package.searchers
+ package.loaders=package.searchers
 end
 local print,select,tostring=print,select,tostring
 local inspectors={}
 function setinspector(kind,inspector) 
-  inspectors[kind]=inspector
+ inspectors[kind]=inspector
 end
 function inspect(...) 
-  for s=1,select("#",...) do
-    local value=select(s,...)
-    if value==nil then
-      print("nil")
-    else
-      local done=false
-      local kind=type(value)
-      local inspector=inspectors[kind]
-      if inspector then
-        done=inspector(value)
-        if done then
-          break
-        end
-      end
-      for kind,inspector in next,inspectors do
-        done=inspector(value)
-        if done then
-          break
-        end
-      end
-      if not done then
-        print(tostring(value))
-      end
+ for s=1,select("#",...) do
+  local value=select(s,...)
+  if value==nil then
+   print("nil")
+  else
+   local done=false
+   local kind=type(value)
+   local inspector=inspectors[kind]
+   if inspector then
+    done=inspector(value)
+    if done then
+     break
     end
+   end
+   for kind,inspector in next,inspectors do
+    done=inspector(value)
+    if done then
+     break
+    end
+   end
+   if not done then
+    print(tostring(value))
+   end
   end
+ end
 end
 local dummy=function() end
 function optionalrequire(...)
-  local ok,result=xpcall(require,dummy,...)
-  if ok then
-    return result
-  end
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+  return result
+ end
 end
 if lua then
-  lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
 end
 local flush=io.flush
 if flush then
-  local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
-  local exec=os.exec  if exec  then function os.exec  (...) flush() return exec  (...) end end
-  local spawn=os.spawn  if spawn  then function os.spawn (...) flush() return spawn (...) end end
-  local popen=io.popen  if popen  then function io.popen (...) flush() return popen (...) end end
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec   (...) flush() return exec   (...) end end
+ local spawn=os.spawn   if spawn   then function os.spawn  (...) flush() return spawn  (...) end end
+ local popen=io.popen   if popen   then function io.popen  (...) flush() return popen  (...) end end
 end
 FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
 if not FFISUPPORTED then
-  local okay;okay,ffi=pcall(require,"ffi")
-  FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
 end
 if not FFISUPPORTED then
-  ffi=nil
+ ffi=nil
 elseif not ffi.number then
-  ffi.number=tonumber
+ ffi.number=tonumber
 end
 if not bit32 then
-  bit32=require("l-bit32")
+ bit32=require("l-bit32")
 end
 
 end -- closure
@@ -129,11 +128,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-package']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local type=type
 local gsub,format,find=string.gsub,string.format,string.find
@@ -141,40 +140,40 @@
 local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
 local package=package
 local searchers=package.searchers or package.loaders
-local filejoin=file and file.join    or function(path,name)  return path.."/"..name end
-local isreadable=file and file.is_readable or function(name)    local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix  or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join  or function(path,name)   return path.."/"..name end
+local isreadable=file and file.is_readable or function(name)  local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix   or function(name,suffix) return name.."."..suffix end
 local function cleanpath(path) 
-  return path
+ return path
 end
 local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
 local function lualibfile(name)
-  return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
 end
 local offset=luarocks and 1 or 0 
 local helpers=package.helpers or {
-  cleanpath=cleanpath,
-  lualibfile=lualibfile,
-  trace=false,
-  report=function(...) print(format(...)) end,
-  builtin={
-    ["preload table"]=searchers[1+offset],
-    ["path specification"]=searchers[2+offset],
-    ["cpath specification"]=searchers[3+offset],
-    ["all in one fallback"]=searchers[4+offset],
-  },
-  methods={},
-  sequence={
-    "already loaded",
-    "preload table",
-    "qualified path",
-    "lua extra list",
-    "lib extra list",
-    "path specification",
-    "cpath specification",
-    "all in one fallback",
-    "not loaded",
-  }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+  ["preload table"]=searchers[1+offset],
+  ["path specification"]=searchers[2+offset],
+  ["cpath specification"]=searchers[3+offset],
+  ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+  "already loaded",
+  "preload table",
+  "qualified path",
+  "lua extra list",
+  "lib extra list",
+  "path specification",
+  "cpath specification",
+  "all in one fallback",
+  "not loaded",
+ }
 }
 package.helpers=helpers
 local methods=helpers.methods
@@ -190,51 +189,51 @@
 local nofpathlua=-1
 local nofpathlib=-1
 local function listpaths(what,paths)
-  local nofpaths=#paths
-  if nofpaths>0 then
-    for i=1,nofpaths do
-      helpers.report("using %s path %i: %s",what,i,paths[i])
-    end
-  else
-    helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+  for i=1,nofpaths do
+   helpers.report("using %s path %i: %s",what,i,paths[i])
   end
-  return nofpaths
+ else
+  helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
 end
 local function getextraluapaths()
-  if helpers.trace and #extraluapaths~=nofextralua then
-    nofextralua=listpaths("extra lua",extraluapaths)
-  end
-  return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+  nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
 end
 local function getextralibpaths()
-  if helpers.trace and #extralibpaths~=nofextralib then
-    nofextralib=listpaths("extra lib",extralibpaths)
-  end
-  return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+  nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
 end
 local function getluapaths()
-  local luapath=package.path or ""
-  if oldluapath~=luapath then
-    luapaths=file.splitpath(luapath,";")
-    oldluapath=luapath
-    nofpathlua=-1
-  end
-  if helpers.trace and #luapaths~=nofpathlua then
-    nofpathlua=listpaths("builtin lua",luapaths)
-  end
-  return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+  luapaths=file.splitpath(luapath,";")
+  oldluapath=luapath
+  nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+  nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
 end
 local function getlibpaths()
-  local libpath=package.cpath or ""
-  if oldlibpath~=libpath then
-    libpaths=file.splitpath(libpath,";")
-    oldlibpath=libpath
-    nofpathlib=-1
-  end
-  if helpers.trace and #libpaths~=nofpathlib then
-    nofpathlib=listpaths("builtin lib",libpaths)
-  end
-  return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+  libpaths=file.splitpath(libpath,";")
+  oldlibpath=libpath
+  nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+  nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
 end
 package.luapaths=getluapaths
 package.libpaths=getlibpaths
@@ -241,204 +240,204 @@
 package.extraluapaths=getextraluapaths
 package.extralibpaths=getextralibpaths
 local hashes={
-  lua={},
-  lib={},
+ lua={},
+ lib={},
 }
 local function registerpath(tag,what,target,...)
-  local pathlist={... }
-  local cleanpath=helpers.cleanpath
-  local trace=helpers.trace
-  local report=helpers.report
-  local hash=hashes[what]
-  local function add(path)
-    local path=cleanpath(path)
-    if not hash[path] then
-      target[#target+1]=path
-      hash[path]=true
-      if trace then
-        report("registered %s path %s: %s",tag,#target,path)
-      end
-    else
-      if trace then
-        report("duplicate %s path: %s",tag,path)
-      end
-    end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+  local path=cleanpath(path)
+  if not hash[path] then
+   target[#target+1]=path
+   hash[path]=true
+   if trace then
+    report("registered %s path %s: %s",tag,#target,path)
+   end
+  else
+   if trace then
+    report("duplicate %s path: %s",tag,path)
+   end
   end
-  for p=1,#pathlist do
-    local path=pathlist[p]
-    if type(path)=="table" then
-      for i=1,#path do
-        add(path[i])
-      end
-    else
-      add(path)
-    end
+ end
+ for p=1,#pathlist do
+  local path=pathlist[p]
+  if type(path)=="table" then
+   for i=1,#path do
+    add(path[i])
+   end
+  else
+   add(path)
   end
+ end
 end
 local function pushpath(tag,what,target,path)
-  local path=helpers.cleanpath(path)
-  insert(target,1,path)
-  if helpers.trace then
-    helpers.report("pushing %s path in front: %s",tag,path)
-  end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+  helpers.report("pushing %s path in front: %s",tag,path)
+ end
 end
 local function poppath(tag,what,target)
-  local path=remove(target,1)
-  if helpers.trace then
-    if path then
-      helpers.report("popping %s path from front: %s",tag,path)
-    else
-      helpers.report("no %s path to pop",tag)
-    end
+ local path=remove(target,1)
+ if helpers.trace then
+  if path then
+   helpers.report("popping %s path from front: %s",tag,path)
+  else
+   helpers.report("no %s path to pop",tag)
   end
+ end
 end
 helpers.registerpath=registerpath
 function package.extraluapath(...)
-  registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
 end
 function package.pushluapath(path)
-  pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
 end
 function package.popluapath()
-  poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
 end
 function package.extralibpath(...)
-  registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
 end
 function package.pushlibpath(path)
-  pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
 end
 function package.poplibpath()
-  poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
 end
 local function loadedaslib(resolved,rawname) 
-  local base=gsub(rawname,"%.","_")
-  local init="luaopen_"..gsub(base,"%.","_")
-  if helpers.trace then
-    helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
-  end
-  return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+  helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
 end
 helpers.loadedaslib=loadedaslib
 local function loadedbypath(name,rawname,paths,islib,what)
-  local trace=helpers.trace
-  for p=1,#paths do
-    local path=paths[p]
-    local resolved=filejoin(path,name)
-    if trace then
-      helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
-    end
-    if isreadable(resolved) then
-      if trace then
-        helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
-      end
-      if islib then
-        return loadedaslib(resolved,rawname)
-      else
-        return loadfile(resolved)
-      end
-    end
+ local trace=helpers.trace
+ for p=1,#paths do
+  local path=paths[p]
+  local resolved=filejoin(path,name)
+  if trace then
+   helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
   end
+  if isreadable(resolved) then
+   if trace then
+    helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+   end
+   if islib then
+    return loadedaslib(resolved,rawname)
+   else
+    return loadfile(resolved)
+   end
+  end
+ end
 end
 helpers.loadedbypath=loadedbypath
 local function loadedbyname(name,rawname)
-  if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
-    local trace=helpers.trace
-    if trace then
-      helpers.report("qualified name, identifying '%s'",what,name)
-    end
-    if isreadable(name) then
-      if trace then
-        helpers.report("qualified name, '%s' found",what,name)
-      end
-      return loadfile(name)
-    end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+  local trace=helpers.trace
+  if trace then
+   helpers.report("qualified name, identifying '%s'",what,name)
   end
+  if isreadable(name) then
+   if trace then
+    helpers.report("qualified name, '%s' found",what,name)
+   end
+   return loadfile(name)
+  end
+ end
 end
 helpers.loadedbyname=loadedbyname
 methods["already loaded"]=function(name)
-  return package.loaded[name]
+ return package.loaded[name]
 end
 methods["preload table"]=function(name)
-  return builtin["preload table"](name)
+ return builtin["preload table"](name)
 end
 methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+  return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
 end
 methods["lua extra list"]=function(name)
-  return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
 end
 methods["lib extra list"]=function(name)
-  return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
 end
 methods["path specification"]=function(name)
-  getluapaths() 
-  return builtin["path specification"](name)
+ getluapaths() 
+ return builtin["path specification"](name)
 end
 methods["cpath specification"]=function(name)
-  getlibpaths() 
-  return builtin["cpath specification"](name)
+ getlibpaths() 
+ return builtin["cpath specification"](name)
 end
 methods["all in one fallback"]=function(name)
-  return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
 end
 methods["not loaded"]=function(name)
-  if helpers.trace then
-    helpers.report("unable to locate '%s'",name or "?")
-  end
-  return nil
+ if helpers.trace then
+  helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
 end
 local level=0
 local used={}
 helpers.traceused=false
 function helpers.loaded(name)
-  local sequence=helpers.sequence
-  level=level+1
-  for i=1,#sequence do
-    local method=sequence[i]
-    if helpers.trace then
-      helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
-    end
-    local result,rest=methods[method](name)
-    if type(result)=="function" then
-      if helpers.trace then
-        helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
-      end
-      if helpers.traceused then
-        used[#used+1]={ level=level,name=name }
-      end
-      level=level-1
-      return result,rest
-    end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+  local method=sequence[i]
+  if helpers.trace then
+   helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
   end
-  level=level-1
-  return nil
+  local result,rest=methods[method](name)
+  if type(result)=="function" then
+   if helpers.trace then
+    helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+   end
+   if helpers.traceused then
+    used[#used+1]={ level=level,name=name }
+   end
+   level=level-1
+   return result,rest
+  end
+ end
+ level=level-1
+ return nil
 end
 function helpers.showused()
-  local n=#used
-  if n>0 then
-    helpers.report("%s libraries loaded:",n)
-    helpers.report()
-    for i=1,n do
-      local u=used[i]
-      helpers.report("%i %a",u.level,u.name)
-    end
-    helpers.report()
-   end
+ local n=#used
+ if n>0 then
+  helpers.report("%s libraries loaded:",n)
+  helpers.report()
+  for i=1,n do
+   local u=used[i]
+   helpers.report("%i %a",u.level,u.name)
+  end
+  helpers.report()
+  end
 end
 function helpers.unload(name)
-  if helpers.trace then
-    if package.loaded[name] then
-      helpers.report("unloading, name '%s', %s",name,"done")
-    else
-      helpers.report("unloading, name '%s', %s",name,"not loaded")
-    end
+ if helpers.trace then
+  if package.loaded[name] then
+   helpers.report("unloading, name '%s', %s",name,"done")
+  else
+   helpers.report("unloading, name '%s', %s",name,"not loaded")
   end
-  package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
 end
 table.insert(searchers,1,helpers.loaded)
 if context then
-  package.path=""
+ package.path=""
 end
 
 end -- closure
@@ -446,11 +445,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-lpeg']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 lpeg=require("lpeg") 
 local lpeg=lpeg
@@ -461,7 +460,7 @@
 local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
 local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
 if setinspector then
-  setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
 end
 lpeg.patterns=lpeg.patterns or {} 
 local patterns=lpeg.patterns
@@ -484,7 +483,7 @@
 local hexdigit=digit+lowercase+uppercase
 local hexdigits=hexdigit^1
 local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n") 
+local newline=P("\r")*(P("\n")+P(true))+P("\n")  
 local escaped=P("\\")*anything
 local squote=P("'")
 local dquote=P('"')
@@ -493,9 +492,9 @@
 local comma=P(",")
 local utfbom_32_be=P('\000\000\254\255') 
 local utfbom_32_le=P('\255\254\000\000') 
-local utfbom_16_be=P('\254\255')     
-local utfbom_16_le=P('\255\254')     
-local utfbom_8=P('\239\187\191')   
+local utfbom_16_be=P('\254\255')   
+local utfbom_16_le=P('\255\254')   
+local utfbom_8=P('\239\187\191')  
 local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
 local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8") 
 local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -527,7 +526,7 @@
 patterns.validutf8=validutf8char
 patterns.validutf8char=validutf8char
 local eol=S("\n\r")
-local spacer=S(" \t\f\v") 
+local spacer=S(" \t\f\v")  
 local whitespace=eol+spacer
 local nonspacer=1-spacer
 local nonwhitespace=1-whitespace
@@ -536,7 +535,7 @@
 patterns.whitespace=whitespace
 patterns.nonspacer=nonspacer
 patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)   
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)  
 local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
 local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
 local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
@@ -613,83 +612,83 @@
 patterns.beginline=#(1-newline)
 patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
 function anywhere(pattern) 
-  return (1-P(pattern))^0*P(pattern)
+ return (1-P(pattern))^0*P(pattern)
 end
 lpeg.anywhere=anywhere
 function lpeg.instringchecker(p)
-  p=anywhere(p)
-  return function(str)
-    return lpegmatch(p,str) and true or false
-  end
+ p=anywhere(p)
+ return function(str)
+  return lpegmatch(p,str) and true or false
+ end
 end
 function lpeg.splitter(pattern,action)
-  if action then
-    return (((1-P(pattern))^1)/action+1)^0
-  else
-    return (Cs((1-P(pattern))^1)+1)^0
-  end
+ if action then
+  return (((1-P(pattern))^1)/action+1)^0
+ else
+  return (Cs((1-P(pattern))^1)+1)^0
+ end
 end
 function lpeg.tsplitter(pattern,action)
-  if action then
-    return Ct((((1-P(pattern))^1)/action+1)^0)
-  else
-    return Ct((Cs((1-P(pattern))^1)+1)^0)
-  end
+ if action then
+  return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+  return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
 end
 local splitters_s,splitters_m,splitters_t={},{},{}
 local function splitat(separator,single)
-  local splitter=(single and splitters_s[separator]) or splitters_m[separator]
-  if not splitter then
-    separator=P(separator)
-    local other=C((1-separator)^0)
-    if single then
-      local any=anything
-      splitter=other*(separator*C(any^0)+"") 
-      splitters_s[separator]=splitter
-    else
-      splitter=other*(separator*other)^0
-      splitters_m[separator]=splitter
-    end
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+  separator=P(separator)
+  local other=C((1-separator)^0)
+  if single then
+   local any=anything
+   splitter=other*(separator*C(any^0)+"") 
+   splitters_s[separator]=splitter
+  else
+   splitter=other*(separator*other)^0
+   splitters_m[separator]=splitter
   end
-  return splitter
+ end
+ return splitter
 end
 local function tsplitat(separator)
-  local splitter=splitters_t[separator]
-  if not splitter then
-    splitter=Ct(splitat(separator))
-    splitters_t[separator]=splitter
-  end
-  return splitter
+ local splitter=splitters_t[separator]
+ if not splitter then
+  splitter=Ct(splitat(separator))
+  splitters_t[separator]=splitter
+ end
+ return splitter
 end
 lpeg.splitat=splitat
 lpeg.tsplitat=tsplitat
 function string.splitup(str,separator)
-  if not separator then
-    separator=","
-  end
-  return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ if not separator then
+  separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
 end
 local cache={}
 function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+  c=tsplitat(separator)
+  cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
   local c=cache[separator]
   if not c then
-    c=tsplitat(separator)
-    cache[separator]=c
+   c=tsplitat(separator)
+   cache[separator]=c
   end
   return lpegmatch(c,str)
+ else
+  return { str }
+ end
 end
-function string.split(str,separator)
-  if separator then
-    local c=cache[separator]
-    if not c then
-      c=tsplitat(separator)
-      cache[separator]=c
-    end
-    return lpegmatch(c,str)
-  else
-    return { str }
-  end
-end
 local spacing=patterns.spacer^0*newline 
 local empty=spacing*Cc("")
 local nonempty=Cs((1-spacing)^1)*spacing^-1
@@ -698,276 +697,276 @@
 local linesplitter=tsplitat(newline)
 patterns.linesplitter=linesplitter
 function string.splitlines(str)
-  return lpegmatch(linesplitter,str)
+ return lpegmatch(linesplitter,str)
 end
 local cache={}
 function lpeg.checkedsplit(separator,str)
-  local c=cache[separator]
-  if not c then
-    separator=P(separator)
-    local other=C((1-separator)^1)
-    c=Ct(separator^0*other*(separator^1*other)^0)
-    cache[separator]=c
-  end
-  return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+  separator=P(separator)
+  local other=C((1-separator)^1)
+  c=Ct(separator^0*other*(separator^1*other)^0)
+  cache[separator]=c
+ end
+ return lpegmatch(c,str)
 end
 function string.checkedsplit(str,separator)
-  local c=cache[separator]
-  if not c then
-    separator=P(separator)
-    local other=C((1-separator)^1)
-    c=Ct(separator^0*other*(separator^1*other)^0)
-    cache[separator]=c
-  end
-  return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+  separator=P(separator)
+  local other=C((1-separator)^1)
+  c=Ct(separator^0*other*(separator^1*other)^0)
+  cache[separator]=c
+ end
+ return lpegmatch(c,str)
 end
-local function f2(s) local c1,c2=byte(s,1,2) return  c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+local function f2(s) local c1,c2=byte(s,1,2) return   c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return  (c1*64+c2)*64+c3-925824 end
 local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
 local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
 patterns.utf8byte=utf8byte
 local cache={}
 function lpeg.stripper(str)
-  if type(str)=="string" then
-    local s=cache[str]
-    if not s then
-      s=Cs(((S(str)^1)/""+1)^0)
-      cache[str]=s
-    end
-    return s
-  else
-    return Cs(((str^1)/""+1)^0)
+ if type(str)=="string" then
+  local s=cache[str]
+  if not s then
+   s=Cs(((S(str)^1)/""+1)^0)
+   cache[str]=s
   end
+  return s
+ else
+  return Cs(((str^1)/""+1)^0)
+ end
 end
 local cache={}
 function lpeg.keeper(str)
-  if type(str)=="string" then
-    local s=cache[str]
-    if not s then
-      s=Cs((((1-S(str))^1)/""+1)^0)
-      cache[str]=s
-    end
-    return s
-  else
-    return Cs((((1-str)^1)/""+1)^0)
+ if type(str)=="string" then
+  local s=cache[str]
+  if not s then
+   s=Cs((((1-S(str))^1)/""+1)^0)
+   cache[str]=s
   end
+  return s
+ else
+  return Cs((((1-str)^1)/""+1)^0)
+ end
 end
 function lpeg.frontstripper(str) 
-  return (P(str)+P(true))*Cs(anything^0)
+ return (P(str)+P(true))*Cs(anything^0)
 end
 function lpeg.endstripper(str) 
-  return Cs((1-P(str)*endofstring)^0)
+ return Cs((1-P(str)*endofstring)^0)
 end
 function lpeg.replacer(one,two,makefunction,isutf) 
-  local pattern
-  local u=isutf and utf8char or 1
-  if type(one)=="table" then
-    local no=#one
-    local p=P(false)
-    if no==0 then
-      for k,v in next,one do
-        p=p+P(k)/v
-      end
-      pattern=Cs((p+u)^0)
-    elseif no==1 then
-      local o=one[1]
-      one,two=P(o[1]),o[2]
-      pattern=Cs((one/two+u)^0)
-    else
-      for i=1,no do
-        local o=one[i]
-        p=p+P(o[1])/o[2]
-      end
-      pattern=Cs((p+u)^0)
-    end
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+  local no=#one
+  local p=P(false)
+  if no==0 then
+   for k,v in next,one do
+    p=p+P(k)/v
+   end
+   pattern=Cs((p+u)^0)
+  elseif no==1 then
+   local o=one[1]
+   one,two=P(o[1]),o[2]
+   pattern=Cs((one/two+u)^0)
   else
-    pattern=Cs((P(one)/(two or "")+u)^0)
+   for i=1,no do
+    local o=one[i]
+    p=p+P(o[1])/o[2]
+   end
+   pattern=Cs((p+u)^0)
   end
-  if makefunction then
-    return function(str)
-      return lpegmatch(pattern,str)
-    end
-  else
-    return pattern
+ else
+  pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+  return function(str)
+   return lpegmatch(pattern,str)
   end
+ else
+  return pattern
+ end
 end
 function lpeg.finder(lst,makefunction,isutf) 
-  local pattern
-  if type(lst)=="table" then
-    pattern=P(false)
-    if #lst==0 then
-      for k,v in next,lst do
-        pattern=pattern+P(k) 
-      end
-    else
-      for i=1,#lst do
-        pattern=pattern+P(lst[i])
-      end
-    end
+ local pattern
+ if type(lst)=="table" then
+  pattern=P(false)
+  if #lst==0 then
+   for k,v in next,lst do
+    pattern=pattern+P(k) 
+   end
   else
-    pattern=P(lst)
+   for i=1,#lst do
+    pattern=pattern+P(lst[i])
+   end
   end
-  if isutf then
-    pattern=((utf8char or 1)-pattern)^0*pattern
-  else
-    pattern=(1-pattern)^0*pattern
+ else
+  pattern=P(lst)
+ end
+ if isutf then
+  pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+  pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+  return function(str)
+   return lpegmatch(pattern,str)
   end
-  if makefunction then
-    return function(str)
-      return lpegmatch(pattern,str)
-    end
-  else
-    return pattern
-  end
+ else
+  return pattern
+ end
 end
 local splitters_f,splitters_s={},{}
 function lpeg.firstofsplit(separator) 
-  local splitter=splitters_f[separator]
-  if not splitter then
-    local pattern=P(separator)
-    splitter=C((1-pattern)^0)
-    splitters_f[separator]=splitter
-  end
-  return splitter
+ local splitter=splitters_f[separator]
+ if not splitter then
+  local pattern=P(separator)
+  splitter=C((1-pattern)^0)
+  splitters_f[separator]=splitter
+ end
+ return splitter
 end
 function lpeg.secondofsplit(separator) 
-  local splitter=splitters_s[separator]
-  if not splitter then
-    local pattern=P(separator)
-    splitter=(1-pattern)^0*pattern*C(anything^0)
-    splitters_s[separator]=splitter
-  end
-  return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+  local pattern=P(separator)
+  splitter=(1-pattern)^0*pattern*C(anything^0)
+  splitters_s[separator]=splitter
+ end
+ return splitter
 end
 local splitters_s,splitters_p={},{}
 function lpeg.beforesuffix(separator) 
-  local splitter=splitters_s[separator]
-  if not splitter then
-    local pattern=P(separator)
-    splitter=C((1-pattern)^0)*pattern*endofstring
-    splitters_s[separator]=splitter
-  end
-  return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+  local pattern=P(separator)
+  splitter=C((1-pattern)^0)*pattern*endofstring
+  splitters_s[separator]=splitter
+ end
+ return splitter
 end
 function lpeg.afterprefix(separator) 
-  local splitter=splitters_p[separator]
-  if not splitter then
-    local pattern=P(separator)
-    splitter=pattern*C(anything^0)
-    splitters_p[separator]=splitter
-  end
-  return splitter
+ local splitter=splitters_p[separator]
+ if not splitter then
+  local pattern=P(separator)
+  splitter=pattern*C(anything^0)
+  splitters_p[separator]=splitter
+ end
+ return splitter
 end
 function lpeg.balancer(left,right)
-  left,right=P(left),P(right)
-  return P { left*((1-left-right)+V(1))^0*right }
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
 end
 function lpeg.counter(pattern,action)
-  local n=0
-  local pattern=(P(pattern)/function() n=n+1 end+anything)^0
-  if action then
-    return function(str) n=0;lpegmatch(pattern,str);action(n) end
-  else
-    return function(str) n=0;lpegmatch(pattern,str);return n end
-  end
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+  return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+  return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
 end
 function lpeg.is_lpeg(p)
-  return p and lpegtype(p)=="pattern"
+ return p and lpegtype(p)=="pattern"
 end
 function lpeg.oneof(list,...) 
-  if type(list)~="table" then
-    list={ list,... }
-  end
-  local p=P(list[1])
-  for l=2,#list do
-    p=p+P(list[l])
-  end
-  return p
+ if type(list)~="table" then
+  list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+  p=p+P(list[l])
+ end
+ return p
 end
 local sort=table.sort
 local function copyindexed(old)
-  local new={}
-  for i=1,#old do
-    new[i]=old
-  end
-  return new
+ local new={}
+ for i=1,#old do
+  new[i]=old
+ end
+ return new
 end
 local function sortedkeys(tab)
-  local keys,s={},0
-  for key,_ in next,tab do
-    s=s+1
-    keys[s]=key
-  end
-  sort(keys)
-  return keys
+ local keys,s={},0
+ for key,_ in next,tab do
+  s=s+1
+  keys[s]=key
+ end
+ sort(keys)
+ return keys
 end
 function lpeg.append(list,pp,delayed,checked)
-  local p=pp
-  if #list>0 then
-    local keys=copyindexed(list)
-    sort(keys)
-    for i=#keys,1,-1 do
-      local k=keys[i]
-      if p then
-        p=P(k)+p
-      else
-        p=P(k)
-      end
-    end
-  elseif delayed then 
-    local keys=sortedkeys(list)
+ local p=pp
+ if #list>0 then
+  local keys=copyindexed(list)
+  sort(keys)
+  for i=#keys,1,-1 do
+   local k=keys[i]
+   if p then
+    p=P(k)+p
+   else
+    p=P(k)
+   end
+  end
+ elseif delayed then 
+  local keys=sortedkeys(list)
+  if p then
+   for i=1,#keys,1 do
+    local k=keys[i]
+    local v=list[k]
+    p=P(k)/list+p
+   end
+  else
+   for i=1,#keys do
+    local k=keys[i]
+    local v=list[k]
     if p then
-      for i=1,#keys,1 do
-        local k=keys[i]
-        local v=list[k]
-        p=P(k)/list+p
-      end
+     p=P(k)+p
     else
-      for i=1,#keys do
-        local k=keys[i]
-        local v=list[k]
-        if p then
-          p=P(k)+p
-        else
-          p=P(k)
-        end
-      end
-      if p then
-        p=p/list
-      end
+     p=P(k)
     end
-  elseif checked then
-    local keys=sortedkeys(list)
-    for i=1,#keys do
-      local k=keys[i]
-      local v=list[k]
-      if p then
-        if k==v then
-          p=P(k)+p
-        else
-          p=P(k)/v+p
-        end
-      else
-        if k==v then
-          p=P(k)
-        else
-          p=P(k)/v
-        end
-      end
+   end
+   if p then
+    p=p/list
+   end
+  end
+ elseif checked then
+  local keys=sortedkeys(list)
+  for i=1,#keys do
+   local k=keys[i]
+   local v=list[k]
+   if p then
+    if k==v then
+     p=P(k)+p
+    else
+     p=P(k)/v+p
     end
-  else
-    local keys=sortedkeys(list)
-    for i=1,#keys do
-      local k=keys[i]
-      local v=list[k]
-      if p then
-        p=P(k)/v+p
-      else
-        p=P(k)/v
-      end
+   else
+    if k==v then
+     p=P(k)
+    else
+     p=P(k)/v
     end
+   end
   end
-  return p
+ else
+  local keys=sortedkeys(list)
+  for i=1,#keys do
+   local k=keys[i]
+   local v=list[k]
+   if p then
+    p=P(k)/v+p
+   else
+    p=P(k)/v
+   end
+  end
+ end
+ return p
 end
 local p_false=P(false)
 local p_true=P(true)
@@ -974,172 +973,172 @@
 local lower=utf and utf.lower or string.lower
 local upper=utf and utf.upper or string.upper
 function lpeg.setutfcasers(l,u)
-  lower=l or lower
-  upper=u or upper
+ lower=l or lower
+ upper=u or upper
 end
 local function make1(t,rest)
-  local p=p_false
-  local keys=sortedkeys(t)
-  for i=1,#keys do
-    local k=keys[i]
-    if k~="" then
-      local v=t[k]
-      if v==true then
-        p=p+P(k)*p_true
-      elseif v==false then
-      else
-        p=p+P(k)*make1(v,v[""])
-      end
-    end
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+  local k=keys[i]
+  if k~="" then
+   local v=t[k]
+   if v==true then
+    p=p+P(k)*p_true
+   elseif v==false then
+   else
+    p=p+P(k)*make1(v,v[""])
+   end
   end
-  if rest then
-    p=p+p_true
-  end
-  return p
+ end
+ if rest then
+  p=p+p_true
+ end
+ return p
 end
 local function make2(t,rest) 
-  local p=p_false
-  local keys=sortedkeys(t)
-  for i=1,#keys do
-    local k=keys[i]
-    if k~="" then
-      local v=t[k]
-      if v==true then
-        p=p+(P(lower(k))+P(upper(k)))*p_true
-      elseif v==false then
-      else
-        p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
-      end
-    end
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+  local k=keys[i]
+  if k~="" then
+   local v=t[k]
+   if v==true then
+    p=p+(P(lower(k))+P(upper(k)))*p_true
+   elseif v==false then
+   else
+    p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+   end
   end
-  if rest then
-    p=p+p_true
-  end
-  return p
+ end
+ if rest then
+  p=p+p_true
+ end
+ return p
 end
 local function utfchartabletopattern(list,insensitive) 
-  local tree={}
-  local n=#list
-  if n==0 then
-    for s in next,list do
-      local t=tree
-      local p,pk
-      for c in gmatch(s,".") do
-        if t==true then
-          t={ [c]=true,[""]=true }
-          p[pk]=t
-          p=t
-          t=false
-        elseif t==false then
-          t={ [c]=false }
-          p[pk]=t
-          p=t
-          t=false
-        else
-          local tc=t[c]
-          if not tc then
-            tc=false
-            t[c]=false
-          end
-          p=t
-          t=tc
-        end
-        pk=c
-      end
-      if t==false then
-        p[pk]=true
-      elseif t==true then
-      else
-        t[""]=true
-      end
+ local tree={}
+ local n=#list
+ if n==0 then
+  for s in next,list do
+   local t=tree
+   local p,pk
+   for c in gmatch(s,".") do
+    if t==true then
+     t={ [c]=true,[""]=true }
+     p[pk]=t
+     p=t
+     t=false
+    elseif t==false then
+     t={ [c]=false }
+     p[pk]=t
+     p=t
+     t=false
+    else
+     local tc=t[c]
+     if not tc then
+      tc=false
+      t[c]=false
+     end
+     p=t
+     t=tc
     end
-  else
-    for i=1,n do
-      local s=list[i]
-      local t=tree
-      local p,pk
-      for c in gmatch(s,".") do
-        if t==true then
-          t={ [c]=true,[""]=true }
-          p[pk]=t
-          p=t
-          t=false
-        elseif t==false then
-          t={ [c]=false }
-          p[pk]=t
-          p=t
-          t=false
-        else
-          local tc=t[c]
-          if not tc then
-            tc=false
-            t[c]=false
-          end
-          p=t
-          t=tc
-        end
-        pk=c
-      end
-      if t==false then
-        p[pk]=true
-      elseif t==true then
-      else
-        t[""]=true
-      end
+    pk=c
+   end
+   if t==false then
+    p[pk]=true
+   elseif t==true then
+   else
+    t[""]=true
+   end
+  end
+ else
+  for i=1,n do
+   local s=list[i]
+   local t=tree
+   local p,pk
+   for c in gmatch(s,".") do
+    if t==true then
+     t={ [c]=true,[""]=true }
+     p[pk]=t
+     p=t
+     t=false
+    elseif t==false then
+     t={ [c]=false }
+     p[pk]=t
+     p=t
+     t=false
+    else
+     local tc=t[c]
+     if not tc then
+      tc=false
+      t[c]=false
+     end
+     p=t
+     t=tc
     end
+    pk=c
+   end
+   if t==false then
+    p[pk]=true
+   elseif t==true then
+   else
+    t[""]=true
+   end
   end
-  return (insensitive and make2 or make1)(tree)
+ end
+ return (insensitive and make2 or make1)(tree)
 end
 lpeg.utfchartabletopattern=utfchartabletopattern
 function lpeg.utfreplacer(list,insensitive)
-  local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
-  return function(str)
-    return lpegmatch(pattern,str) or str
-  end
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+  return lpegmatch(pattern,str) or str
+ end
 end
 patterns.containseol=lpeg.finder(eol)
 local function nextstep(n,step,result)
-  local m=n%step   
-  local d=floor(n/step) 
-  if d>0 then
-    local v=V(tostring(step))
-    local s=result.start
-    for i=1,d do
-      if s then
-        s=v*s
-      else
-        s=v
-      end
-    end
-    result.start=s
+ local m=n%step   
+ local d=floor(n/step) 
+ if d>0 then
+  local v=V(tostring(step))
+  local s=result.start
+  for i=1,d do
+   if s then
+    s=v*s
+   else
+    s=v
+   end
   end
-  if step>1 and result.start then
-    local v=V(tostring(step/2))
-    result[tostring(step)]=v*v
-  end
-  if step>0 then
-    return nextstep(m,step/2,result)
-  else
-    return result
-  end
+  result.start=s
+ end
+ if step>1 and result.start then
+  local v=V(tostring(step/2))
+  result[tostring(step)]=v*v
+ end
+ if step>0 then
+  return nextstep(m,step/2,result)
+ else
+  return result
+ end
 end
 function lpeg.times(pattern,n)
-  return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
 end
 do
-  local trailingzeros=zero^0*-digit 
-  local stripper=Cs((
-    digits*(
-      period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
-    )+1
-  )^0)
-  lpeg.patterns.stripzeros=stripper 
-  local nonzero=digit-zero
-  local trailingzeros=zero^1*endofstring
-  local stripper=Cs((1-period)^0*(
-    period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
-  ))
-  lpeg.patterns.stripzero=stripper
+ local trailingzeros=zero^0*-digit 
+ local stripper=Cs((
+  digits*(
+   period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+  )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper 
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+  period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
 end
 local byte_to_HEX={}
 local byte_to_hex={}
@@ -1146,15 +1145,15 @@
 local byte_to_dec={} 
 local hex_to_byte={}
 for i=0,255 do
-  local H=format("%02X",i)
-  local h=format("%02x",i)
-  local d=format("%03i",i)
-  local c=char(i)
-  byte_to_HEX[c]=H
-  byte_to_hex[c]=h
-  byte_to_dec[c]=d
-  hex_to_byte[h]=c
-  hex_to_byte[H]=c
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
 end
 local hextobyte=P(2)/hex_to_byte
 local bytetoHEX=P(1)/byte_to_HEX
@@ -1173,47 +1172,47 @@
 patterns.bytestohex=bytestohex
 patterns.bytestodec=bytestodec
 function string.toHEX(s)
-  if not s or s=="" then
-    return s
-  else
-    return lpegmatch(bytestoHEX,s)
-  end
+ if not s or s=="" then
+  return s
+ else
+  return lpegmatch(bytestoHEX,s)
+ end
 end
 function string.tohex(s)
-  if not s or s=="" then
-    return s
-  else
-    return lpegmatch(bytestohex,s)
-  end
+ if not s or s=="" then
+  return s
+ else
+  return lpegmatch(bytestohex,s)
+ end
 end
 function string.todec(s)
-  if not s or s=="" then
-    return s
-  else
-    return lpegmatch(bytestodec,s)
-  end
+ if not s or s=="" then
+  return s
+ else
+  return lpegmatch(bytestodec,s)
+ end
 end
 function string.tobytes(s)
-  if not s or s=="" then
-    return s
-  else
-    return lpegmatch(hextobytes,s)
-  end
+ if not s or s=="" then
+  return s
+ else
+  return lpegmatch(hextobytes,s)
+ end
 end
 local patterns={} 
 local function containsws(what)
-  local p=patterns[what]
-  if not p then
-    local p1=P(what)*(whitespace+endofstring)*Cc(true)
-    local p2=whitespace*P(p1)
-    p=P(p1)+P(1-p2)^0*p2+Cc(false)
-    patterns[what]=p
-  end
-  return p
+ local p=patterns[what]
+ if not p then
+  local p1=P(what)*(whitespace+endofstring)*Cc(true)
+  local p2=whitespace*P(p1)
+  p=P(p1)+P(1-p2)^0*p2+Cc(false)
+  patterns[what]=p
+ end
+ return p
 end
 lpeg.containsws=containsws
 function string.containsws(str,what)
-  return lpegmatch(patterns[what] or containsws(what),str)
+ return lpegmatch(patterns[what] or containsws(what),str)
 end
 
 end -- closure
@@ -1221,11 +1220,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-functions']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 functions=functions or {}
 function functions.dummy() end
@@ -1235,11 +1234,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-string']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local string=string
 local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -1247,25 +1246,25 @@
 local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
 local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
 function string.unquoted(str)
-  return lpegmatch(unquoted,str) or str
+ return lpegmatch(unquoted,str) or str
 end
 function string.quoted(str)
-  return format("%q",str) 
+ return format("%q",str) 
 end
 function string.count(str,pattern) 
-  local n=0
-  for _ in gmatch(str,pattern) do 
-    n=n+1
-  end
-  return n
+ local n=0
+ for _ in gmatch(str,pattern) do 
+  n=n+1
+ end
+ return n
 end
 function string.limit(str,n,sentinel) 
-  if #str>n then
-    sentinel=sentinel or "..."
-    return sub(str,1,(n-#sentinel))..sentinel
-  else
-    return str
-  end
+ if #str>n then
+  sentinel=sentinel or "..."
+  return sub(str,1,(n-#sentinel))..sentinel
+ else
+  return str
+ end
 end
 local stripper=patterns.stripper
 local fullstripper=patterns.fullstripper
@@ -1273,81 +1272,81 @@
 local nospacer=patterns.nospacer
 local longtostring=patterns.longtostring
 function string.strip(str)
-  return str and lpegmatch(stripper,str) or ""
+ return str and lpegmatch(stripper,str) or ""
 end
 function string.fullstrip(str)
-  return str and lpegmatch(fullstripper,str) or ""
+ return str and lpegmatch(fullstripper,str) or ""
 end
 function string.collapsespaces(str)
-  return str and lpegmatch(collapser,str) or ""
+ return str and lpegmatch(collapser,str) or ""
 end
 function string.nospaces(str)
-  return str and lpegmatch(nospacer,str) or ""
+ return str and lpegmatch(nospacer,str) or ""
 end
 function string.longtostring(str)
-  return str and lpegmatch(longtostring,str) or ""
+ return str and lpegmatch(longtostring,str) or ""
 end
 local pattern=P(" ")^0*P(-1)
 function string.is_empty(str)
-  if not str or str=="" then
-    return true
-  else
-    return lpegmatch(pattern,str) and true or false
-  end
+ if not str or str=="" then
+  return true
+ else
+  return lpegmatch(pattern,str) and true or false
+ end
 end
 local anything=patterns.anything
 local allescapes=Cc("%")*S(".-+%?()[]*") 
-local someescapes=Cc("%")*S(".-+%()[]")  
-local matchescapes=Cc(".")*S("*?")     
+local someescapes=Cc("%")*S(".-+%()[]")   
+local matchescapes=Cc(".")*S("*?")   
 local pattern_a=Cs ((allescapes+anything )^0 )
 local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
 local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
 function string.escapedpattern(str,simple)
-  return lpegmatch(simple and pattern_b or pattern_a,str)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
 end
 function string.topattern(str,lowercase,strict)
-  if str=="" or type(str)~="string" then
-    return ".*"
-  elseif strict then
-    str=lpegmatch(pattern_c,str)
-  else
-    str=lpegmatch(pattern_b,str)
-  end
-  if lowercase then
-    return lower(str)
-  else
-    return str
-  end
+ if str=="" or type(str)~="string" then
+  return ".*"
+ elseif strict then
+  str=lpegmatch(pattern_c,str)
+ else
+  str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+  return lower(str)
+ else
+  return str
+ end
 end
 function string.valid(str,default)
-  return (type(str)=="string" and str~="" and str) or default or nil
+ return (type(str)=="string" and str~="" and str) or default or nil
 end
 string.itself=function(s) return s end
 local pattern_c=Ct(C(1)^0) 
 local pattern_b=Ct((C(1)/byte)^0)
 function string.totable(str,bytes)
-  return lpegmatch(bytes and pattern_b or pattern_c,str)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
 end
 local replacer=lpeg.replacer("@","%%") 
 function string.tformat(fmt,...)
-  return format(lpegmatch(replacer,fmt),...)
+ return format(lpegmatch(replacer,fmt),...)
 end
 string.quote=string.quoted
 string.unquote=string.unquoted
 if not string.bytetable then 
-  local limit=5000 
-  function string.bytetable(str) 
-    local n=#str
-    if n>limit then
-      local t={ byte(str,1,limit) }
-      for i=limit+1,n do
-        t[i]=byte(str,i)
-      end
-      return t
-    else
-      return { byte(str,1,n) }
-    end
+ local limit=5000 
+ function string.bytetable(str) 
+  local n=#str
+  if n>limit then
+   local t={ byte(str,1,limit) }
+   for i=limit+1,n do
+    t[i]=byte(str,i)
+   end
+   return t
+  else
+   return { byte(str,1,n) }
   end
+ end
 end
 
 end -- closure
@@ -1355,11 +1354,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-table']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
 local table,string=table,string
@@ -1370,147 +1369,147 @@
 local floor=math.floor
 local stripper=patterns.stripper
 function table.getn(t)
-  return t and #t 
+ return t and #t 
 end
 function table.strip(tab)
-  local lst,l={},0
-  for i=1,#tab do
-    local s=lpegmatch(stripper,tab[i]) or ""
-    if s=="" then
-    else
-      l=l+1
-      lst[l]=s
-    end
+ local lst,l={},0
+ for i=1,#tab do
+  local s=lpegmatch(stripper,tab[i]) or ""
+  if s=="" then
+  else
+   l=l+1
+   lst[l]=s
   end
-  return lst
+ end
+ return lst
 end
 function table.keys(t)
-  if t then
-    local keys,k={},0
-    for key in next,t do
-      k=k+1
-      keys[k]=key
-    end
-    return keys
-  else
-    return {}
+ if t then
+  local keys,k={},0
+  for key in next,t do
+   k=k+1
+   keys[k]=key
   end
+  return keys
+ else
+  return {}
+ end
 end
 local function compare(a,b)
-  local ta=type(a) 
-  if ta=="number" then
-    local tb=type(b) 
-    if ta==tb then
-      return a<b
-    elseif tb=="string" then
-      return tostring(a)<b
-    end
-  elseif ta=="string" then
-    local tb=type(b) 
-    if ta==tb then
-      return a<b
-    else
-      return a<tostring(b)
-    end
+ local ta=type(a) 
+ if ta=="number" then
+  local tb=type(b) 
+  if ta==tb then
+   return a<b
+  elseif tb=="string" then
+   return tostring(a)<b
   end
-  return tostring(a)<tostring(b) 
+ elseif ta=="string" then
+  local tb=type(b) 
+  if ta==tb then
+   return a<b
+  else
+   return a<tostring(b)
+  end
+ end
+ return tostring(a)<tostring(b) 
 end
 local function sortedkeys(tab)
-  if tab then
-    local srt,category,s={},0,0 
-    for key in next,tab do
-      s=s+1
-      srt[s]=key
-      if category==3 then
-      elseif category==1 then
-        if type(key)~="string" then
-          category=3
-        end
-      elseif category==2 then
-        if type(key)~="number" then
-          category=3
-        end
-      else
-        local tkey=type(key)
-        if tkey=="string" then
-          category=1
-        elseif tkey=="number" then
-          category=2
-        else
-          category=3
-        end
-      end
+ if tab then
+  local srt,category,s={},0,0 
+  for key in next,tab do
+   s=s+1
+   srt[s]=key
+   if category==3 then
+   elseif category==1 then
+    if type(key)~="string" then
+     category=3
     end
-    if s<2 then
-    elseif category==3 then
-      sort(srt,compare)
+   elseif category==2 then
+    if type(key)~="number" then
+     category=3
+    end
+   else
+    local tkey=type(key)
+    if tkey=="string" then
+     category=1
+    elseif tkey=="number" then
+     category=2
     else
-      sort(srt)
+     category=3
     end
-    return srt
+   end
+  end
+  if s<2 then
+  elseif category==3 then
+   sort(srt,compare)
   else
-    return {}
+   sort(srt)
   end
+  return srt
+ else
+  return {}
+ end
 end
 local function sortedhashonly(tab)
-  if tab then
-    local srt,s={},0
-    for key in next,tab do
-      if type(key)=="string" then
-        s=s+1
-        srt[s]=key
-      end
-    end
-    if s>1 then
-      sort(srt)
-    end
-    return srt
-  else
-    return {}
+ if tab then
+  local srt,s={},0
+  for key in next,tab do
+   if type(key)=="string" then
+    s=s+1
+    srt[s]=key
+   end
   end
+  if s>1 then
+   sort(srt)
+  end
+  return srt
+ else
+  return {}
+ end
 end
 local function sortedindexonly(tab)
-  if tab then
-    local srt,s={},0
-    for key in next,tab do
-      if type(key)=="number" then
-        s=s+1
-        srt[s]=key
-      end
-    end
-    if s>1 then
-      sort(srt)
-    end
-    return srt
-  else
-    return {}
+ if tab then
+  local srt,s={},0
+  for key in next,tab do
+   if type(key)=="number" then
+    s=s+1
+    srt[s]=key
+   end
   end
+  if s>1 then
+   sort(srt)
+  end
+  return srt
+ else
+  return {}
+ end
 end
 local function sortedhashkeys(tab,cmp) 
-  if tab then
-    local srt,s={},0
-    for key in next,tab do
-      if key then
-        s=s+1
-        srt[s]=key
-      end
-    end
-    if s>1 then
-      sort(srt,cmp)
-    end
-    return srt
-  else
-    return {}
+ if tab then
+  local srt,s={},0
+  for key in next,tab do
+   if key then
+    s=s+1
+    srt[s]=key
+   end
   end
+  if s>1 then
+   sort(srt,cmp)
+  end
+  return srt
+ else
+  return {}
+ end
 end
 function table.allkeys(t)
-  local keys={}
-  for k,v in next,t do
-    for k in next,v do
-      keys[k]=true
-    end
+ local keys={}
+ for k,v in next,t do
+  for k in next,v do
+   keys[k]=true
   end
-  return sortedkeys(keys)
+ end
+ return sortedkeys(keys)
 end
 table.sortedkeys=sortedkeys
 table.sortedhashonly=sortedhashonly
@@ -1518,927 +1517,927 @@
 table.sortedhashkeys=sortedhashkeys
 local function nothing() end
 local function sortedhash(t,cmp)
-  if t then
-    local s
-    if cmp then
-      s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
-    else
-      s=sortedkeys(t) 
+ if t then
+  local s
+  if cmp then
+   s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+  else
+   s=sortedkeys(t) 
+  end
+  local m=#s
+  if m==1 then
+   return next,t
+  elseif m>0 then
+   local n=0
+   return function()
+    if n<m then
+     n=n+1
+     local k=s[n]
+     return k,t[k]
     end
-    local m=#s
-    if m==1 then
-      return next,t
-    elseif m>0 then
-      local n=0
-      return function()
-        if n<m then
-          n=n+1
-          local k=s[n]
-          return k,t[k]
-        end
-      end
-    end
+   end
   end
-  return nothing
+ end
+ return nothing
 end
 table.sortedhash=sortedhash
 table.sortedpairs=sortedhash 
 function table.append(t,list)
-  local n=#t
-  for i=1,#list do
-    n=n+1
-    t[n]=list[i]
-  end
-  return t
+ local n=#t
+ for i=1,#list do
+  n=n+1
+  t[n]=list[i]
+ end
+ return t
 end
 function table.prepend(t,list)
-  local nl=#list
-  local nt=nl+#t
-  for i=#t,1,-1 do
-    t[nt]=t[i]
-    nt=nt-1
-  end
-  for i=1,#list do
-    t[i]=list[i]
-  end
-  return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+  t[nt]=t[i]
+  nt=nt-1
+ end
+ for i=1,#list do
+  t[i]=list[i]
+ end
+ return t
 end
 function table.merge(t,...) 
-  t=t or {}
-  for i=1,select("#",...) do
-    for k,v in next,(select(i,...)) do
-      t[k]=v
-    end
+ t=t or {}
+ for i=1,select("#",...) do
+  for k,v in next,(select(i,...)) do
+   t[k]=v
   end
-  return t
+ end
+ return t
 end
 function table.merged(...)
-  local t={}
-  for i=1,select("#",...) do
-    for k,v in next,(select(i,...)) do
-      t[k]=v
-    end
+ local t={}
+ for i=1,select("#",...) do
+  for k,v in next,(select(i,...)) do
+   t[k]=v
   end
-  return t
+ end
+ return t
 end
 function table.imerge(t,...)
-  local nt=#t
-  for i=1,select("#",...) do
-    local nst=select(i,...)
-    for j=1,#nst do
-      nt=nt+1
-      t[nt]=nst[j]
-    end
+ local nt=#t
+ for i=1,select("#",...) do
+  local nst=select(i,...)
+  for j=1,#nst do
+   nt=nt+1
+   t[nt]=nst[j]
   end
-  return t
+ end
+ return t
 end
 function table.imerged(...)
-  local tmp,ntmp={},0
-  for i=1,select("#",...) do
-    local nst=select(i,...)
-    for j=1,#nst do
-      ntmp=ntmp+1
-      tmp[ntmp]=nst[j]
-    end
+ local tmp,ntmp={},0
+ for i=1,select("#",...) do
+  local nst=select(i,...)
+  for j=1,#nst do
+   ntmp=ntmp+1
+   tmp[ntmp]=nst[j]
   end
-  return tmp
+ end
+ return tmp
 end
 local function fastcopy(old,metatabletoo) 
-  if old then
-    local new={}
-    for k,v in next,old do
-      if type(v)=="table" then
-        new[k]=fastcopy(v,metatabletoo) 
-      else
-        new[k]=v
-      end
-    end
-    if metatabletoo then
-      local mt=getmetatable(old)
-      if mt then
-        setmetatable(new,mt)
-      end
-    end
-    return new
-  else
-    return {}
+ if old then
+  local new={}
+  for k,v in next,old do
+   if type(v)=="table" then
+    new[k]=fastcopy(v,metatabletoo) 
+   else
+    new[k]=v
+   end
   end
+  if metatabletoo then
+   local mt=getmetatable(old)
+   if mt then
+    setmetatable(new,mt)
+   end
+  end
+  return new
+ else
+  return {}
+ end
 end
 local function copy(t,tables) 
-  tables=tables or {}
-  local tcopy={}
-  if not tables[t] then
-    tables[t]=tcopy
+ tables=tables or {}
+ local tcopy={}
+ if not tables[t] then
+  tables[t]=tcopy
+ end
+ for i,v in next,t do 
+  if type(i)=="table" then
+   if tables[i] then
+    i=tables[i]
+   else
+    i=copy(i,tables)
+   end
   end
-  for i,v in next,t do 
-    if type(i)=="table" then
-      if tables[i] then
-        i=tables[i]
-      else
-        i=copy(i,tables)
-      end
-    end
-    if type(v)~="table" then
-      tcopy[i]=v
-    elseif tables[v] then
-      tcopy[i]=tables[v]
-    else
-      tcopy[i]=copy(v,tables)
-    end
+  if type(v)~="table" then
+   tcopy[i]=v
+  elseif tables[v] then
+   tcopy[i]=tables[v]
+  else
+   tcopy[i]=copy(v,tables)
   end
-  local mt=getmetatable(t)
-  if mt then
-    setmetatable(tcopy,mt)
-  end
-  return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+  setmetatable(tcopy,mt)
+ end
+ return tcopy
 end
 table.fastcopy=fastcopy
 table.copy=copy
 function table.derive(parent) 
-  local child={}
-  if parent then
-    setmetatable(child,{ __index=parent })
-  end
-  return child
+ local child={}
+ if parent then
+  setmetatable(child,{ __index=parent })
+ end
+ return child
 end
 function table.tohash(t,value)
-  local h={}
-  if t then
-    if value==nil then value=true end
-    for _,v in next,t do
-      h[v]=value
-    end
+ local h={}
+ if t then
+  if value==nil then value=true end
+  for _,v in next,t do
+   h[v]=value
   end
-  return h
+ end
+ return h
 end
 function table.fromhash(t)
-  local hsh,h={},0
-  for k,v in next,t do
-    if v then
-      h=h+1
-      hsh[h]=k
-    end
+ local hsh,h={},0
+ for k,v in next,t do
+  if v then
+   h=h+1
+   hsh[h]=k
   end
-  return hsh
+ end
+ return hsh
 end
 local noquotes,hexify,handle,compact,inline,functions,metacheck
 local reserved=table.tohash { 
-  'and','break','do','else','elseif','end','false','for','function','if',
-  'in','local','nil','not','or','repeat','return','then','true','until','while',
-  'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
 }
 local function is_simple_table(t,hexify) 
-  local nt=#t
-  if nt>0 then
-    local n=0
-    for _,v in next,t do
-      n=n+1
-      if type(v)=="table" then
-        return nil
-      end
+ local nt=#t
+ if nt>0 then
+  local n=0
+  for _,v in next,t do
+   n=n+1
+   if type(v)=="table" then
+    return nil
+   end
+  end
+  local haszero=rawget(t,0) 
+  if n==nt then
+   local tt={}
+   for i=1,nt do
+    local v=t[i]
+    local tv=type(v)
+    if tv=="number" then
+     if hexify then
+      tt[i]=format("0x%X",v)
+     else
+      tt[i]=v 
+     end
+    elseif tv=="string" then
+     tt[i]=format("%q",v) 
+    elseif tv=="boolean" then
+     tt[i]=v and "true" or "false"
+    else
+     return nil
     end
-    local haszero=rawget(t,0) 
-    if n==nt then
-      local tt={}
-      for i=1,nt do
-        local v=t[i]
-        local tv=type(v)
-        if tv=="number" then
-          if hexify then
-            tt[i]=format("0x%X",v)
-          else
-            tt[i]=v 
-          end
-        elseif tv=="string" then
-          tt[i]=format("%q",v) 
-        elseif tv=="boolean" then
-          tt[i]=v and "true" or "false"
-        else
-          return nil
-        end
-      end
-      return tt
-    elseif haszero and (n==nt+1) then
-      local tt={}
-      for i=0,nt do
-        local v=t[i]
-        local tv=type(v)
-        if tv=="number" then
-          if hexify then
-            tt[i+1]=format("0x%X",v)
-          else
-            tt[i+1]=v 
-          end
-        elseif tv=="string" then
-          tt[i+1]=format("%q",v) 
-        elseif tv=="boolean" then
-          tt[i+1]=v and "true" or "false"
-        else
-          return nil
-        end
-      end
-      tt[1]="[0] = "..tt[1]
-      return tt
+   end
+   return tt
+  elseif haszero and (n==nt+1) then
+   local tt={}
+   for i=0,nt do
+    local v=t[i]
+    local tv=type(v)
+    if tv=="number" then
+     if hexify then
+      tt[i+1]=format("0x%X",v)
+     else
+      tt[i+1]=v 
+     end
+    elseif tv=="string" then
+     tt[i+1]=format("%q",v) 
+    elseif tv=="boolean" then
+     tt[i+1]=v and "true" or "false"
+    else
+     return nil
     end
+   end
+   tt[1]="[0] = "..tt[1]
+   return tt
   end
-  return nil
+ end
+ return nil
 end
 table.is_simple_table=is_simple_table
 local propername=patterns.propername 
 local function dummy() end
 local function do_serialize(root,name,depth,level,indexed)
-  if level>0 then
-    depth=depth.." "
-    if indexed then
-      handle(format("%s{",depth))
+ if level>0 then
+  depth=depth.." "
+  if indexed then
+   handle(format("%s{",depth))
+  else
+   local tn=type(name)
+   if tn=="number" then
+    if hexify then
+     handle(format("%s[0x%X]={",depth,name))
     else
-      local tn=type(name)
-      if tn=="number" then
-        if hexify then
-          handle(format("%s[0x%X]={",depth,name))
-        else
-          handle(format("%s[%s]={",depth,name))
-        end
-      elseif tn=="string" then
-        if noquotes and not reserved[name] and lpegmatch(propername,name) then
-          handle(format("%s%s={",depth,name))
-        else
-          handle(format("%s[%q]={",depth,name))
-        end
-      elseif tn=="boolean" then
-        handle(format("%s[%s]={",depth,name and "true" or "false"))
-      else
-        handle(format("%s{",depth))
-      end
+     handle(format("%s[%s]={",depth,name))
     end
+   elseif tn=="string" then
+    if noquotes and not reserved[name] and lpegmatch(propername,name) then
+     handle(format("%s%s={",depth,name))
+    else
+     handle(format("%s[%q]={",depth,name))
+    end
+   elseif tn=="boolean" then
+    handle(format("%s[%s]={",depth,name and "true" or "false"))
+   else
+    handle(format("%s{",depth))
+   end
   end
-  if root and next(root)~=nil then
-    local first,last=nil,0
-    if compact then
-      last=#root
-      for k=1,last do
-        if rawget(root,k)==nil then
-          last=k-1
-          break
-        end
-      end
-      if last>0 then
-        first=1
-      end
+ end
+ if root and next(root)~=nil then
+  local first,last=nil,0
+  if compact then
+   last=#root
+   for k=1,last do
+    if rawget(root,k)==nil then
+     last=k-1
+     break
     end
-    local sk=sortedkeys(root)
-    for i=1,#sk do
-      local k=sk[i]
-      local v=root[k]
-      local tv=type(v)
-      local tk=type(k)
-      if compact and first and tk=="number" and k>=first and k<=last then
-        if tv=="number" then
-          if hexify then
-            handle(format("%s 0x%X,",depth,v))
-          else
-            handle(format("%s %s,",depth,v)) 
-          end
-        elseif tv=="string" then
-          handle(format("%s %q,",depth,v))
-        elseif tv=="table" then
-          if next(v)==nil then
-            handle(format("%s {},",depth))
-          elseif inline then 
-            local st=is_simple_table(v,hexify)
-            if st then
-              handle(format("%s { %s },",depth,concat(st,", ")))
-            else
-              do_serialize(v,k,depth,level+1,true)
-            end
-          else
-            do_serialize(v,k,depth,level+1,true)
-          end
-        elseif tv=="boolean" then
-          handle(format("%s %s,",depth,v and "true" or "false"))
-        elseif tv=="function" then
-          if functions then
-            handle(format('%s load(%q),',depth,dump(v))) 
-          else
-            handle(format('%s "function",',depth))
-          end
-        else
-          handle(format("%s %q,",depth,tostring(v)))
-        end
-      elseif k=="__p__" then 
-        if false then
-          handle(format("%s __p__=nil,",depth))
-        end
-      elseif tv=="number" then
-        if tk=="number" then
-          if hexify then
-            handle(format("%s [0x%X]=0x%X,",depth,k,v))
-          else
-            handle(format("%s [%s]=%s,",depth,k,v)) 
-          end
-        elseif tk=="boolean" then
-          if hexify then
-            handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
-          else
-            handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) 
-          end
-        elseif tk~="string" then
-        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-          if hexify then
-            handle(format("%s %s=0x%X,",depth,k,v))
-          else
-            handle(format("%s %s=%s,",depth,k,v)) 
-          end
-        else
-          if hexify then
-            handle(format("%s [%q]=0x%X,",depth,k,v))
-          else
-            handle(format("%s [%q]=%s,",depth,k,v)) 
-          end
-        end
-      elseif tv=="string" then
-        if tk=="number" then
-          if hexify then
-            handle(format("%s [0x%X]=%q,",depth,k,v))
-          else
-            handle(format("%s [%s]=%q,",depth,k,v))
-          end
-        elseif tk=="boolean" then
-          handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
-        elseif tk~="string" then
-        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-          handle(format("%s %s=%q,",depth,k,v))
-        else
-          handle(format("%s [%q]=%q,",depth,k,v))
-        end
-      elseif tv=="table" then
-        if next(v)==nil then
-          if tk=="number" then
-            if hexify then
-              handle(format("%s [0x%X]={},",depth,k))
-            else
-              handle(format("%s [%s]={},",depth,k))
-            end
-          elseif tk=="boolean" then
-            handle(format("%s [%s]={},",depth,k and "true" or "false"))
-          elseif tk~="string" then
-          elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-            handle(format("%s %s={},",depth,k))
-          else
-            handle(format("%s [%q]={},",depth,k))
-          end
-        elseif inline then
-          local st=is_simple_table(v,hexify)
-          if st then
-            if tk=="number" then
-              if hexify then
-                handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
-              else
-                handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
-              end
-            elseif tk=="boolean" then
-              handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
-            elseif tk~="string" then
-            elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-              handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
-            else
-              handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
-            end
-          else
-            do_serialize(v,k,depth,level+1)
-          end
-        else
-          do_serialize(v,k,depth,level+1)
-        end
-      elseif tv=="boolean" then
-        if tk=="number" then
-          if hexify then
-            handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
-          else
-            handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
-          end
-        elseif tk=="boolean" then
-          handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
-        elseif tk~="string" then
-        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-          handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
-        else
-          handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
-        end
-      elseif tv=="function" then
-        if functions then
-          local getinfo=debug and debug.getinfo
-          if getinfo then
-            local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
-            if tk=="number" then
-              if hexify then
-                handle(format("%s [0x%X]=load(%q),",depth,k,f))
-              else
-                handle(format("%s [%s]=load(%q),",depth,k,f))
-              end
-            elseif tk=="boolean" then
-              handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
-            elseif tk~="string" then
-            elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-              handle(format("%s %s=load(%q),",depth,k,f))
-            else
-              handle(format("%s [%q]=load(%q),",depth,k,f))
-            end
-          end
-        end
+   end
+   if last>0 then
+    first=1
+   end
+  end
+  local sk=sortedkeys(root)
+  for i=1,#sk do
+   local k=sk[i]
+   local v=root[k]
+   local tv=type(v)
+   local tk=type(k)
+   if compact and first and tk=="number" and k>=first and k<=last then
+    if tv=="number" then
+     if hexify then
+      handle(format("%s 0x%X,",depth,v))
+     else
+      handle(format("%s %s,",depth,v)) 
+     end
+    elseif tv=="string" then
+     handle(format("%s %q,",depth,v))
+    elseif tv=="table" then
+     if next(v)==nil then
+      handle(format("%s {},",depth))
+     elseif inline then 
+      local st=is_simple_table(v,hexify)
+      if st then
+       handle(format("%s { %s },",depth,concat(st,", ")))
       else
-        if tk=="number" then
-          if hexify then
-            handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
-          else
-            handle(format("%s [%s]=%q,",depth,k,tostring(v)))
-          end
-        elseif tk=="boolean" then
-          handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
-        elseif tk~="string" then
-        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-          handle(format("%s %s=%q,",depth,k,tostring(v)))
-        else
-          handle(format("%s [%q]=%q,",depth,k,tostring(v)))
-        end
+       do_serialize(v,k,depth,level+1,true)
       end
+     else
+      do_serialize(v,k,depth,level+1,true)
+     end
+    elseif tv=="boolean" then
+     handle(format("%s %s,",depth,v and "true" or "false"))
+    elseif tv=="function" then
+     if functions then
+      handle(format('%s load(%q),',depth,dump(v))) 
+     else
+      handle(format('%s "function",',depth))
+     end
+    else
+     handle(format("%s %q,",depth,tostring(v)))
     end
-  end
-  if level>0 then
-    handle(format("%s},",depth))
-  end
-end
-local function serialize(_handle,root,name,specification) 
-  local tname=type(name)
-  if type(specification)=="table" then
-    noquotes=specification.noquotes
-    hexify=specification.hexify
-    handle=_handle or specification.handle or print
-    functions=specification.functions
-    compact=specification.compact
-    inline=specification.inline and compact
-    metacheck=specification.metacheck
-    if functions==nil then
-      functions=true
+   elseif k=="__p__" then 
+    if false then
+     handle(format("%s __p__=nil,",depth))
     end
-    if compact==nil then
-      compact=true
+   elseif tv=="number" then
+    if tk=="number" then
+     if hexify then
+      handle(format("%s [0x%X]=0x%X,",depth,k,v))
+     else
+      handle(format("%s [%s]=%s,",depth,k,v)) 
+     end
+    elseif tk=="boolean" then
+     if hexify then
+      handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+     else
+      handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) 
+     end
+    elseif tk~="string" then
+    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+     if hexify then
+      handle(format("%s %s=0x%X,",depth,k,v))
+     else
+      handle(format("%s %s=%s,",depth,k,v)) 
+     end
+    else
+     if hexify then
+      handle(format("%s [%q]=0x%X,",depth,k,v))
+     else
+      handle(format("%s [%q]=%s,",depth,k,v)) 
+     end
     end
-    if inline==nil then
-      inline=compact
+   elseif tv=="string" then
+    if tk=="number" then
+     if hexify then
+      handle(format("%s [0x%X]=%q,",depth,k,v))
+     else
+      handle(format("%s [%s]=%q,",depth,k,v))
+     end
+    elseif tk=="boolean" then
+     handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+    elseif tk~="string" then
+    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+     handle(format("%s %s=%q,",depth,k,v))
+    else
+     handle(format("%s [%q]=%q,",depth,k,v))
     end
-    if metacheck==nil then
-      metacheck=true
-    end
-  else
-    noquotes=false
-    hexify=false
-    handle=_handle or print
-    compact=true
-    inline=true
-    functions=true
-    metacheck=true
-  end
-  if tname=="string" then
-    if name=="return" then
-      handle("return {")
+   elseif tv=="table" then
+    if next(v)==nil then
+     if tk=="number" then
+      if hexify then
+       handle(format("%s [0x%X]={},",depth,k))
+      else
+       handle(format("%s [%s]={},",depth,k))
+      end
+     elseif tk=="boolean" then
+      handle(format("%s [%s]={},",depth,k and "true" or "false"))
+     elseif tk~="string" then
+     elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+      handle(format("%s %s={},",depth,k))
+     else
+      handle(format("%s [%q]={},",depth,k))
+     end
+    elseif inline then
+     local st=is_simple_table(v,hexify)
+     if st then
+      if tk=="number" then
+       if hexify then
+        handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+       else
+        handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+       end
+      elseif tk=="boolean" then
+       handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+      elseif tk~="string" then
+      elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+       handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+      else
+       handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+      end
+     else
+      do_serialize(v,k,depth,level+1)
+     end
     else
-      handle(name.."={")
+     do_serialize(v,k,depth,level+1)
     end
-  elseif tname=="number" then
-    if hexify then
-      handle(format("[0x%X]={",name))
+   elseif tv=="boolean" then
+    if tk=="number" then
+     if hexify then
+      handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+     else
+      handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+     end
+    elseif tk=="boolean" then
+     handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+    elseif tk~="string" then
+    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+     handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
     else
-      handle("["..name.."]={")
+     handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
     end
-  elseif tname=="boolean" then
-    if name then
-      handle("return {")
+   elseif tv=="function" then
+    if functions then
+     local getinfo=debug and debug.getinfo
+     if getinfo then
+      local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+      if tk=="number" then
+       if hexify then
+        handle(format("%s [0x%X]=load(%q),",depth,k,f))
+       else
+        handle(format("%s [%s]=load(%q),",depth,k,f))
+       end
+      elseif tk=="boolean" then
+       handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+      elseif tk~="string" then
+      elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+       handle(format("%s %s=load(%q),",depth,k,f))
+      else
+       handle(format("%s [%q]=load(%q),",depth,k,f))
+      end
+     end
+    end
+   else
+    if tk=="number" then
+     if hexify then
+      handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+     else
+      handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+     end
+    elseif tk=="boolean" then
+     handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+    elseif tk~="string" then
+    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+     handle(format("%s %s=%q,",depth,k,tostring(v)))
     else
-      handle("{")
+     handle(format("%s [%q]=%q,",depth,k,tostring(v)))
     end
+   end
+  end
+ end
+ if level>0 then
+  handle(format("%s},",depth))
+ end
+end
+local function serialize(_handle,root,name,specification) 
+ local tname=type(name)
+ if type(specification)=="table" then
+  noquotes=specification.noquotes
+  hexify=specification.hexify
+  handle=_handle or specification.handle or print
+  functions=specification.functions
+  compact=specification.compact
+  inline=specification.inline and compact
+  metacheck=specification.metacheck
+  if functions==nil then
+   functions=true
+  end
+  if compact==nil then
+   compact=true
+  end
+  if inline==nil then
+   inline=compact
+  end
+  if metacheck==nil then
+   metacheck=true
+  end
+ else
+  noquotes=false
+  hexify=false
+  handle=_handle or print
+  compact=true
+  inline=true
+  functions=true
+  metacheck=true
+ end
+ if tname=="string" then
+  if name=="return" then
+   handle("return {")
   else
-    handle("t={")
+   handle(name.."={")
   end
-  if root then
-    if metacheck and getmetatable(root) then
-      local dummy=root._w_h_a_t_e_v_e_r_
-      root._w_h_a_t_e_v_e_r_=nil
-    end
-    if next(root)~=nil then
-      do_serialize(root,name,"",0)
-    end
+ elseif tname=="number" then
+  if hexify then
+   handle(format("[0x%X]={",name))
+  else
+   handle("["..name.."]={")
   end
-  handle("}")
+ elseif tname=="boolean" then
+  if name then
+   handle("return {")
+  else
+   handle("{")
+  end
+ else
+  handle("t={")
+ end
+ if root then
+  if metacheck and getmetatable(root) then
+   local dummy=root._w_h_a_t_e_v_e_r_
+   root._w_h_a_t_e_v_e_r_=nil
+  end
+  if next(root)~=nil then
+   do_serialize(root,name,"",0)
+  end
+ end
+ handle("}")
 end
 function table.serialize(root,name,specification)
-  local t,n={},0
-  local function flush(s)
-    n=n+1
-    t[n]=s
-  end
-  serialize(flush,root,name,specification)
-  return concat(t,"\n")
+ local t,n={},0
+ local function flush(s)
+  n=n+1
+  t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
 end
 table.tohandle=serialize
 local maxtab=2*1024
 function table.tofile(filename,root,name,specification)
-  local f=io.open(filename,'w')
-  if f then
-    if maxtab>1 then
-      local t,n={},0
-      local function flush(s)
-        n=n+1
-        t[n]=s
-        if n>maxtab then
-          f:write(concat(t,"\n"),"\n") 
-          t,n={},0 
-        end
-      end
-      serialize(flush,root,name,specification)
-      f:write(concat(t,"\n"),"\n")
-    else
-      local function flush(s)
-        f:write(s,"\n")
-      end
-      serialize(flush,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+  if maxtab>1 then
+   local t,n={},0
+   local function flush(s)
+    n=n+1
+    t[n]=s
+    if n>maxtab then
+     f:write(concat(t,"\n"),"\n") 
+     t,n={},0 
     end
-    f:close()
-    io.flush()
+   end
+   serialize(flush,root,name,specification)
+   f:write(concat(t,"\n"),"\n")
+  else
+   local function flush(s)
+    f:write(s,"\n")
+   end
+   serialize(flush,root,name,specification)
   end
+  f:close()
+  io.flush()
+ end
 end
 local function flattened(t,f,depth) 
-  if f==nil then
-    f={}
-    depth=0xFFFF
-  elseif tonumber(f) then
-    depth=f
-    f={}
-  elseif not depth then
-    depth=0xFFFF
+ if f==nil then
+  f={}
+  depth=0xFFFF
+ elseif tonumber(f) then
+  depth=f
+  f={}
+ elseif not depth then
+  depth=0xFFFF
+ end
+ for k,v in next,t do
+  if type(k)~="number" then
+   if depth>0 and type(v)=="table" then
+    flattened(v,f,depth-1)
+   else
+    f[#f+1]=v
+   end
   end
-  for k,v in next,t do
-    if type(k)~="number" then
-      if depth>0 and type(v)=="table" then
-        flattened(v,f,depth-1)
-      else
-        f[#f+1]=v
-      end
-    end
+ end
+ for k=1,#t do
+  local v=t[k]
+  if depth>0 and type(v)=="table" then
+   flattened(v,f,depth-1)
+  else
+   f[#f+1]=v
   end
-  for k=1,#t do
-    local v=t[k]
-    if depth>0 and type(v)=="table" then
-      flattened(v,f,depth-1)
-    else
-      f[#f+1]=v
-    end
-  end
-  return f
+ end
+ return f
 end
 table.flattened=flattened
 local function collapsed(t,f,h)
-  if f==nil then
-    f={}
-    h={}
+ if f==nil then
+  f={}
+  h={}
+ end
+ for k=1,#t do
+  local v=t[k]
+  if type(v)=="table" then
+   collapsed(v,f,h)
+  elseif not h[v] then
+   f[#f+1]=v
+   h[v]=true
   end
-  for k=1,#t do
-    local v=t[k]
-    if type(v)=="table" then
-      collapsed(v,f,h)
-    elseif not h[v] then
-      f[#f+1]=v
-      h[v]=true
-    end
-  end
-  return f
+ end
+ return f
 end
 local function collapsedhash(t,h)
-  if h==nil then
-    h={}
+ if h==nil then
+  h={}
+ end
+ for k=1,#t do
+  local v=t[k]
+  if type(v)=="table" then
+   collapsedhash(v,h)
+  else
+   h[v]=true
   end
-  for k=1,#t do
-    local v=t[k]
-    if type(v)=="table" then
-      collapsedhash(v,h)
-    else
-      h[v]=true
-    end
-  end
-  return h
+ end
+ return h
 end
-table.collapsed=collapsed   
+table.collapsed=collapsed  
 table.collapsedhash=collapsedhash
 local function unnest(t,f) 
-  if not f then     
-    f={}      
+ if not f then    
+  f={}   
+ end
+ for i=1,#t do
+  local v=t[i]
+  if type(v)=="table" then
+   if type(v[1])=="table" then
+    unnest(v,f)
+   else
+    f[#f+1]=v
+   end
+  else
+   f[#f+1]=v
   end
-  for i=1,#t do
-    local v=t[i]
-    if type(v)=="table" then
-      if type(v[1])=="table" then
-        unnest(v,f)
-      else
-        f[#f+1]=v
-      end
-    else
-      f[#f+1]=v
-    end
-  end
-  return f
+ end
+ return f
 end
 function table.unnest(t) 
-  return unnest(t)
+ return unnest(t)
 end
 local function are_equal(a,b,n,m) 
-  if a==b then
-    return true
-  elseif a and b and #a==#b then
-    n=n or 1
-    m=m or #a
-    for i=n,m do
-      local ai,bi=a[i],b[i]
-      if ai==bi then
-      elseif type(ai)=="table" and type(bi)=="table" then
-        if not are_equal(ai,bi) then
-          return false
-        end
-      else
-        return false
-      end
+ if a==b then
+  return true
+ elseif a and b and #a==#b then
+  n=n or 1
+  m=m or #a
+  for i=n,m do
+   local ai,bi=a[i],b[i]
+   if ai==bi then
+   elseif type(ai)=="table" and type(bi)=="table" then
+    if not are_equal(ai,bi) then
+     return false
     end
-    return true
-  else
+   else
     return false
+   end
   end
+  return true
+ else
+  return false
+ end
 end
 local function identical(a,b) 
-  if a~=b then
-    for ka,va in next,a do
-      local vb=b[ka]
-      if va==vb then
-      elseif type(va)=="table" and type(vb)=="table" then
-        if not identical(va,vb) then
-          return false
-        end
-      else
-        return false
-      end
+ if a~=b then
+  for ka,va in next,a do
+   local vb=b[ka]
+   if va==vb then
+   elseif type(va)=="table" and  type(vb)=="table" then
+    if not identical(va,vb) then
+     return false
     end
+   else
+    return false
+   end
   end
-  return true
+ end
+ return true
 end
 table.identical=identical
 table.are_equal=are_equal
 local function sparse(old,nest,keeptables)
-  local new={}
-  for k,v in next,old do
-    if not (v=="" or v==false) then
-      if nest and type(v)=="table" then
-        v=sparse(v,nest)
-        if keeptables or next(v)~=nil then
-          new[k]=v
-        end
-      else
-        new[k]=v
-      end
+ local new={}
+ for k,v in next,old do
+  if not (v=="" or v==false) then
+   if nest and type(v)=="table" then
+    v=sparse(v,nest)
+    if keeptables or next(v)~=nil then
+     new[k]=v
     end
+   else
+    new[k]=v
+   end
   end
-  return new
+ end
+ return new
 end
 table.sparse=sparse
 function table.compact(t)
-  return sparse(t,true,true)
+ return sparse(t,true,true)
 end
 function table.contains(t,v)
-  if t then
-    for i=1,#t do
-      if t[i]==v then
-        return i
-      end
-    end
+ if t then
+  for i=1,#t do
+   if t[i]==v then
+    return i
+   end
   end
-  return false
+ end
+ return false
 end
 function table.count(t)
-  local n=0
-  for k,v in next,t do
-    n=n+1
-  end
-  return n
+ local n=0
+ for k,v in next,t do
+  n=n+1
+ end
+ return n
 end
 function table.swapped(t,s) 
-  local n={}
-  if s then
-    for k,v in next,s do
-      n[k]=v
-    end
+ local n={}
+ if s then
+  for k,v in next,s do
+   n[k]=v
   end
-  for k,v in next,t do
-    n[v]=k
-  end
-  return n
+ end
+ for k,v in next,t do
+  n[v]=k
+ end
+ return n
 end
 function table.hashed(t) 
-  for i=1,#t do
-    t[t[i]]=i
-  end
-  return t
+ for i=1,#t do
+  t[t[i]]=i
+ end
+ return t
 end
 function table.mirrored(t) 
-  local n={}
-  for k,v in next,t do
-    n[v]=k
-    n[k]=v
-  end
-  return n
+ local n={}
+ for k,v in next,t do
+  n[v]=k
+  n[k]=v
+ end
+ return n
 end
 function table.reversed(t)
-  if t then
-    local tt,tn={},#t
-    if tn>0 then
-      local ttn=0
-      for i=tn,1,-1 do
-        ttn=ttn+1
-        tt[ttn]=t[i]
-      end
-    end
-    return tt
+ if t then
+  local tt,tn={},#t
+  if tn>0 then
+   local ttn=0
+   for i=tn,1,-1 do
+    ttn=ttn+1
+    tt[ttn]=t[i]
+   end
   end
+  return tt
+ end
 end
 function table.reverse(t) 
-  if t then
-    local n=#t
-    local m=n+1
-    for i=1,floor(n/2) do 
-      local j=m-i
-      t[i],t[j]=t[j],t[i]
-    end
-    return t
+ if t then
+  local n=#t
+  local m=n+1
+  for i=1,floor(n/2) do 
+   local j=m-i
+   t[i],t[j]=t[j],t[i]
   end
+  return t
+ end
 end
 local function sequenced(t,sep,simple)
-  if not t then
-    return ""
-  elseif type(t)=="string" then
-    return t 
+ if not t then
+  return ""
+ elseif type(t)=="string" then
+  return t 
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+  for i=1,n do
+   local v=t[i]
+   if type(v)=="table" then
+    s[i]="{"..sequenced(v,sep,simple).."}"
+   else
+    s[i]=tostring(t[i])
+   end
   end
-  local n=#t
-  local s={}
-  if n>0 then
-    for i=1,n do
-      local v=t[i]
-      if type(v)=="table" then
-        s[i]="{"..sequenced(v,sep,simple).."}"
-      else
-        s[i]=tostring(t[i])
-      end
+ else
+  n=0
+  for k,v in sortedhash(t) do
+   if simple then
+    if v==true then
+     n=n+1
+     s[n]=k
+    elseif v and v~="" then
+     n=n+1
+     if type(v)=="table" then
+      s[n]=k.."={"..sequenced(v,sep,simple).."}"
+     else
+      s[n]=k.."="..tostring(v)
+     end
     end
-  else
-    n=0
-    for k,v in sortedhash(t) do
-      if simple then
-        if v==true then
-          n=n+1
-          s[n]=k
-        elseif v and v~="" then
-          n=n+1
-          if type(v)=="table" then
-            s[n]=k.."={"..sequenced(v,sep,simple).."}"
-          else
-            s[n]=k.."="..tostring(v)
-          end
-        end
-      else
-        n=n+1
-        if type(v)=="table" then
-          s[n]=k.."={"..sequenced(v,sep,simple).."}"
-        else
-          s[n]=k.."="..tostring(v)
-        end
-      end
+   else
+    n=n+1
+    if type(v)=="table" then
+     s[n]=k.."={"..sequenced(v,sep,simple).."}"
+    else
+     s[n]=k.."="..tostring(v)
     end
+   end
   end
-  return concat(s,sep or " | ")
+ end
+ return concat(s,sep or " | ")
 end
 table.sequenced=sequenced
 function table.print(t,...)
-  if type(t)~="table" then
-    print(tostring(t))
-  else
-    serialize(print,t,...)
-  end
+ if type(t)~="table" then
+  print(tostring(t))
+ else
+  serialize(print,t,...)
+ end
 end
 if setinspector then
-  setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
 end
 function table.sub(t,i,j)
-  return { unpack(t,i,j) }
+ return { unpack(t,i,j) }
 end
 function table.is_empty(t)
-  return not t or next(t)==nil
+ return not t or next(t)==nil
 end
 function table.has_one_entry(t)
-  return t and next(t,next(t))==nil
+ return t and next(t,next(t))==nil
 end
 function table.loweredkeys(t) 
-  local l={}
-  for k,v in next,t do
-    l[lower(k)]=v
-  end
-  return l
+ local l={}
+ for k,v in next,t do
+  l[lower(k)]=v
+ end
+ return l
 end
 function table.unique(old)
-  local hash={}
-  local new={}
-  local n=0
-  for i=1,#old do
-    local oi=old[i]
-    if not hash[oi] then
-      n=n+1
-      new[n]=oi
-      hash[oi]=true
-    end
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+  local oi=old[i]
+  if not hash[oi] then
+   n=n+1
+   new[n]=oi
+   hash[oi]=true
   end
-  return new
+ end
+ return new
 end
 function table.sorted(t,...)
-  sort(t,...)
-  return t 
+ sort(t,...)
+ return t 
 end
 function table.values(t,s) 
-  if t then
-    local values,keys,v={},{},0
-    for key,value in next,t do
-      if not keys[value] then
-        v=v+1
-        values[v]=value
-        keys[k]=key
-      end
-    end
-    if s then
-      sort(values)
-    end
-    return values
-  else
-    return {}
+ if t then
+  local values,keys,v={},{},0
+  for key,value in next,t do
+   if not keys[value] then
+    v=v+1
+    values[v]=value
+    keys[k]=key
+   end
   end
+  if s then
+   sort(values)
+  end
+  return values
+ else
+  return {}
+ end
 end
 function table.filtered(t,pattern,sort,cmp)
-  if t and type(pattern)=="string" then
-    if sort then
-      local s
-      if cmp then
-        s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
-      else
-        s=sortedkeys(t) 
-      end
-      local n=0
-      local m=#s
-      local function kv(s)
-        while n<m do
-          n=n+1
-          local k=s[n]
-          if find(k,pattern) then
-            return k,t[k]
-          end
-        end
-      end
-      return kv,s
-    else
-      local n=next(t)
-      local function iterator()
-        while n~=nil do
-          local k=n
-          n=next(t,k)
-          if find(k,pattern) then
-            return k,t[k]
-          end
-        end
-      end
-      return iterator,t
+ if t and type(pattern)=="string" then
+  if sort then
+   local s
+   if cmp then
+    s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+   else
+    s=sortedkeys(t) 
+   end
+   local n=0
+   local m=#s
+   local function kv(s)
+    while n<m do
+     n=n+1
+     local k=s[n]
+     if find(k,pattern) then
+      return k,t[k]
+     end
     end
+   end
+   return kv,s
   else
-    return nothing
+   local n=next(t)
+   local function iterator()
+    while n~=nil do
+     local k=n
+     n=next(t,k)
+     if find(k,pattern) then
+      return k,t[k]
+     end
+    end
+   end
+   return iterator,t
   end
+ else
+  return nothing
+ end
 end
 if not table.move then
-  function table.move(a1,f,e,t,a2)
-    if a2 and a1~=a2 then
-      for i=f,e do
-        a2[t]=a1[i]
-        t=t+1
-      end
-      return a2
-    else
-      t=t+e-f
-      for i=e,f,-1 do
-        a1[t]=a1[i]
-        t=t-1
-      end
-      return a1
-    end
+ function table.move(a1,f,e,t,a2)
+  if a2 and a1~=a2 then
+   for i=f,e do
+    a2[t]=a1[i]
+    t=t+1
+   end
+   return a2
+  else
+   t=t+e-f
+   for i=e,f,-1 do
+    a1[t]=a1[i]
+    t=t-1
+   end
+   return a1
   end
+ end
 end
 
 end -- closure
@@ -2446,66 +2445,66 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-boolean']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local type,tonumber=type,tonumber
 boolean=boolean or {}
 local boolean=boolean
 function boolean.tonumber(b)
-  if b then return 1 else return 0 end 
+ if b then return 1 else return 0 end 
 end
 function toboolean(str,tolerant) 
-  if str==nil then
-    return false
-  elseif str==false then
-    return false
-  elseif str==true then
-    return true
-  elseif str=="true" then
-    return true
-  elseif str=="false" then
-    return false
-  elseif not tolerant then
-    return false
-  elseif str==0 then
-    return false
-  elseif (tonumber(str) or 0)>0 then
-    return true
-  else
-    return str=="yes" or str=="on" or str=="t"
-  end
+ if  str==nil then
+  return false
+ elseif str==false then
+  return false
+ elseif str==true then
+  return true
+ elseif str=="true" then
+  return true
+ elseif str=="false" then
+  return false
+ elseif not tolerant then
+  return false
+ elseif str==0 then
+  return false
+ elseif (tonumber(str) or 0)>0 then
+  return true
+ else
+  return str=="yes" or str=="on" or str=="t"
+ end
 end
 string.toboolean=toboolean
 function string.booleanstring(str)
-  if str=="0" then
-    return false
-  elseif str=="1" then
-    return true
-  elseif str=="" then
-    return false
-  elseif str=="false" then
-    return false
-  elseif str=="true" then
-    return true
-  elseif (tonumber(str) or 0)>0 then
-    return true
-  else
-    return str=="yes" or str=="on" or str=="t"
-  end
+ if str=="0" then
+  return false
+ elseif str=="1" then
+  return true
+ elseif str=="" then
+  return false
+ elseif str=="false" then
+  return false
+ elseif str=="true" then
+  return true
+ elseif (tonumber(str) or 0)>0 then
+  return true
+ else
+  return str=="yes" or str=="on" or str=="t"
+ end
 end
 function string.is_boolean(str,default,strict)
-  if type(str)=="string" then
-    if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
-      return true
-    elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
-      return false
-    end
+ if type(str)=="string" then
+  if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+   return true
+  elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+   return false
   end
-  return default
+ end
+ return default
 end
 
 end -- closure
@@ -2513,11 +2512,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-number']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local tostring,tonumber=tostring,tonumber
 local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -2527,107 +2526,107 @@
 number=number or {}
 local number=number
 if bit32 then
-  local bextract=bit32.extract
-  local t={
-    "0","0","0","0","0","0","0","0",
-    "0","0","0","0","0","0","0","0",
-    "0","0","0","0","0","0","0","0",
-    "0","0","0","0","0","0","0","0",
-  }
-  function number.tobitstring(b,m,w)
-    if not w then
-      w=32
-    end
-    local n=w
-    for i=0,w-1 do
-      local v=bextract(b,i)
-      local k=w-i
-      if v==1 then
-        n=k
-        t[k]="1"
-      else
-        t[k]="0"
-      end
-    end
-    if w then
-      return concat(t,"",1,w)
-    elseif m then
-      m=33-m*8
-      if m<1 then
-        m=1
-      end
-      return concat(t,"",1,m)
-    elseif n<8 then
-      return concat(t)
-    elseif n<16 then
-      return concat(t,"",9)
-    elseif n<24 then
-      return concat(t,"",17)
-    else
-      return concat(t,"",25)
-    end
+ local bextract=bit32.extract
+ local t={
+  "0","0","0","0","0","0","0","0",
+  "0","0","0","0","0","0","0","0",
+  "0","0","0","0","0","0","0","0",
+  "0","0","0","0","0","0","0","0",
+ }
+ function number.tobitstring(b,m,w)
+  if not w then
+   w=32
   end
+  local n=w
+  for i=0,w-1 do
+   local v=bextract(b,i)
+   local k=w-i
+   if v==1 then
+    n=k
+    t[k]="1"
+   else
+    t[k]="0"
+   end
+  end
+  if w then
+   return concat(t,"",1,w)
+  elseif m then
+   m=33-m*8
+   if m<1 then
+    m=1
+   end
+   return concat(t,"",1,m)
+  elseif n<8 then
+   return concat(t)
+  elseif n<16 then
+   return concat(t,"",9)
+  elseif n<24 then
+   return concat(t,"",17)
+  else
+   return concat(t,"",25)
+  end
+ end
 else
-  function number.tobitstring(n,m)
-    if n>0 then
-      local t={}
-      while n>0 do
-        insert(t,1,n%2>0 and 1 or 0)
-        n=floor(n/2)
-      end
-      local nn=8-#t%8
-      if nn>0 and nn<8 then
-        for i=1,nn do
-          insert(t,1,0)
-        end
-      end
-      if m then
-        m=m*8-#t
-        if m>0 then
-          insert(t,1,rep("0",m))
-        end
-      end
-      return concat(t)
-    elseif m then
-      rep("00000000",m)
-    else
-      return "00000000"
+ function number.tobitstring(n,m)
+  if n>0 then
+   local t={}
+   while n>0 do
+    insert(t,1,n%2>0 and 1 or 0)
+    n=floor(n/2)
+   end
+   local nn=8-#t%8
+   if nn>0 and nn<8 then
+    for i=1,nn do
+     insert(t,1,0)
     end
+   end
+   if m then
+    m=m*8-#t
+    if m>0 then
+     insert(t,1,rep("0",m))
+    end
+   end
+   return concat(t)
+  elseif m then
+   rep("00000000",m)
+  else
+   return "00000000"
   end
+ end
 end
 function number.valid(str,default)
-  return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
 end
 function number.toevenhex(n)
-  local s=format("%X",n)
-  if #s%2==0 then
-    return s
-  else
-    return "0"..s
-  end
+ local s=format("%X",n)
+ if #s%2==0 then
+  return s
+ else
+  return "0"..s
+ end
 end
 function number.bytetodecimal(b)
-  local d=floor(b*100/255+0.5)
-  if d>100 then
-    return 100
-  elseif d<-100 then
-    return -100
-  else
-    return d
-  end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+  return 100
+ elseif d<-100 then
+  return -100
+ else
+  return d
+ end
 end
 function number.decimaltobyte(d)
-  local b=floor(d*255/100+0.5)
-  if b>255 then
-    return 255
-  elseif b<-255 then
-    return -255
-  else
-    return b
-  end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+  return 255
+ elseif b<-255 then
+  return -255
+ else
+  return b
+ end
 end
 function number.idiv(i,d)
-  return floor(i/d) 
+ return floor(i/d) 
 end
 
 end -- closure
@@ -2635,90 +2634,90 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-math']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 if not math.ceiling then
-  math.ceiling=math.ceil
+ math.ceiling=math.ceil
 end
 if not math.round then
-  local floor=math.floor
-  function math.round(x) return floor(x+0.5) end
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
 end
 if not math.div then
-  local floor=math.floor
-  function math.div(n,m) return floor(n/m) end
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
 end
 if not math.mod then
-  function math.mod(n,m) return n%m end
+ function math.mod(n,m) return n%m end
 end
 if not math.sind then
-  local sin,cos,tan=math.sin,math.cos,math.tan
-  local pipi=2*math.pi/360
-  function math.sind(d) return sin(d*pipi) end
-  function math.cosd(d) return cos(d*pipi) end
-  function math.tand(d) return tan(d*pipi) end
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
 end
 if not math.odd then
-  function math.odd (n) return n%2~=0 end
-  function math.even(n) return n%2==0 end
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
 end
 if not math.cosh then
-  local exp=math.exp
-  function math.cosh(x)
-    local xx=exp(x)
-    return (xx+1/xx)/2
-  end
-  function math.sinh(x)
-    local xx=exp(x)
-    return (xx-1/xx)/2
-  end
-  function math.tanh(x)
-    local xx=exp(x)
-    return (xx-1/xx)/(xx+1/xx)
-  end
+ local exp=math.exp
+ function math.cosh(x)
+  local xx=exp(x)
+  return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+  local xx=exp(x)
+  return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+  local xx=exp(x)
+  return (xx-1/xx)/(xx+1/xx)
+ end
 end
 if not math.pow then
-  function math.pow(x,y)
-    return x^y
-  end
+ function math.pow(x,y)
+  return x^y
+ end
 end
 if not math.atan2 then
-  math.atan2=math.atan
+ math.atan2=math.atan
 end
 if not math.ldexp then
-  function math.ldexp(x,e)
-    return x*2.0^e
-  end
+ function math.ldexp(x,e)
+  return x*2.0^e
+ end
 end
 if not math.log10 then
-  local log=math.log
-  function math.log10(x)
-    return log(x,10)
-  end
+ local log=math.log
+ function math.log10(x)
+  return log(x,10)
+ end
 end
 if not math.type then
-  function math.type()
-    return "float"
-  end
+ function math.type()
+  return "float"
+ end
 end
 if not math.tointeger then
-  math.mininteger=-0x4FFFFFFFFFFF
-  math.maxinteger=0x4FFFFFFFFFFF
-  local floor=math.floor
-  function math.tointeger(n)
-    local f=floor(n)
-    return f==n and f or nil
-  end
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+  local f=floor(n)
+  return f==n and f or nil
+ end
 end
 if not math.ult then
-  local floor=math.floor
-  function math.tointeger(m,n)
-    return floor(m)<floor(n) 
-  end
+ local floor=math.floor
+ function math.tointeger(m,n)
+  return floor(m)<floor(n) 
+ end
 end
 
 end -- closure
@@ -2726,11 +2725,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-io']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local io=io
 local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -2738,334 +2737,334 @@
 local concat=table.concat
 local type=type
 if string.find(os.getenv("PATH"),";",1,true) then
-  io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
 else
-  io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
 end
 local large=0x01000000 
 local medium=0x00100000 
 local small=0x00020000
 local function readall(f)
-  local size=f:seek("end")
-  if size>0 then
-    f:seek("set",0)
-    return f:read(size)
-  else
-    return ""
-  end
+ local size=f:seek("end")
+ if size>0 then
+  f:seek("set",0)
+  return f:read(size)
+ else
+  return ""
+ end
 end
 io.readall=readall
 function io.loaddata(filename,textmode) 
-  local f=open(filename,(textmode and 'r') or 'rb')
-  if f then
-    local size=f:seek("end")
-    local data=nil
-    if size>0 then
-      f:seek("set",0)
-      data=f:read(size)
-    end
-    f:close()
-    return data
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+  local size=f:seek("end")
+  local data=nil
+  if size>0 then
+   f:seek("set",0)
+   data=f:read(size)
   end
+  f:close()
+  return data
+ end
 end
 function io.copydata(source,target,action)
-  local f=open(source,"rb")
-  if f then
-    local g=open(target,"wb")
-    if g then
-      local size=f:seek("end")
-      if size>0 then
-        f:seek("set",0)
-        local data=f:read(size)
-        if action then
-          data=action(data)
-        end
-        if data then
-          g:write(data)
-        end
-      end
-      g:close()
+ local f=open(source,"rb")
+ if f then
+  local g=open(target,"wb")
+  if g then
+   local size=f:seek("end")
+   if size>0 then
+    f:seek("set",0)
+    local data=f:read(size)
+    if action then
+     data=action(data)
     end
-    f:close()
-    flush()
+    if data then
+     g:write(data)
+    end
+   end
+   g:close()
   end
+  f:close()
+  flush()
+ end
 end
 function io.savedata(filename,data,joiner)
-  local f=open(filename,"wb")
-  if f then
-    if type(data)=="table" then
-      f:write(concat(data,joiner or ""))
-    elseif type(data)=="function" then
-      data(f)
-    else
-      f:write(data or "")
-    end
-    f:close()
-    flush()
-    return true
+ local f=open(filename,"wb")
+ if f then
+  if type(data)=="table" then
+   f:write(concat(data,joiner or ""))
+  elseif type(data)=="function" then
+   data(f)
   else
-    return false
+   f:write(data or "")
   end
+  f:close()
+  flush()
+  return true
+ else
+  return false
+ end
 end
 if fio and fio.readline then
-  local readline=fio.readline
-  function io.loadlines(filename,n) 
-    local f=open(filename,'r')
-    if not f then
-    elseif n then
-      local lines={}
-      for i=1,n do
-        local line=readline(f)
-        if line then
-          lines[i]=line
-        else
-          break
-        end
-      end
-      f:close()
-      lines=concat(lines,"\n")
-      if #lines>0 then
-        return lines
-      end
+ local readline=fio.readline
+ function io.loadlines(filename,n) 
+  local f=open(filename,'r')
+  if not f then
+  elseif n then
+   local lines={}
+   for i=1,n do
+    local line=readline(f)
+    if line then
+     lines[i]=line
     else
-      local line=readline(f)
-      f:close()
-      if line and #line>0 then
-        return line
-      end
+     break
     end
+   end
+   f:close()
+   lines=concat(lines,"\n")
+   if #lines>0 then
+    return lines
+   end
+  else
+   local line=readline(f)
+   f:close()
+   if line and #line>0 then
+    return line
+   end
   end
+ end
 else
-  function io.loadlines(filename,n) 
-    local f=open(filename,'r')
-    if not f then
-    elseif n then
-      local lines={}
-      for i=1,n do
-        local line=f:read("*lines")
-        if line then
-          lines[i]=line
-        else
-          break
-        end
-      end
-      f:close()
-      lines=concat(lines,"\n")
-      if #lines>0 then
-        return lines
-      end
+ function io.loadlines(filename,n) 
+  local f=open(filename,'r')
+  if not f then
+  elseif n then
+   local lines={}
+   for i=1,n do
+    local line=f:read("*lines")
+    if line then
+     lines[i]=line
     else
-      local line=f:read("*line") or ""
-      f:close()
-      if #line>0 then
-        return line
-      end
+     break
     end
+   end
+   f:close()
+   lines=concat(lines,"\n")
+   if #lines>0 then
+    return lines
+   end
+  else
+   local line=f:read("*line") or ""
+   f:close()
+   if #line>0 then
+    return line
+   end
   end
+ end
 end
 function io.loadchunk(filename,n)
-  local f=open(filename,'rb')
-  if f then
-    local data=f:read(n or 1024)
-    f:close()
-    if #data>0 then
-      return data
-    end
+ local f=open(filename,'rb')
+ if f then
+  local data=f:read(n or 1024)
+  f:close()
+  if #data>0 then
+   return data
   end
+ end
 end
 function io.exists(filename)
-  local f=open(filename)
-  if f==nil then
-    return false
-  else
-    f:close()
-    return true
-  end
+ local f=open(filename)
+ if f==nil then
+  return false
+ else
+  f:close()
+  return true
+ end
 end
 function io.size(filename)
-  local f=open(filename)
-  if f==nil then
-    return 0
-  else
-    local s=f:seek("end")
-    f:close()
-    return s
-  end
+ local f=open(filename)
+ if f==nil then
+  return 0
+ else
+  local s=f:seek("end")
+  f:close()
+  return s
+ end
 end
 local function noflines(f)
-  if type(f)=="string" then
-    local f=open(filename)
-    if f then
-      local n=f and noflines(f) or 0
-      f:close()
-      return n
-    else
-      return 0
-    end
+ if type(f)=="string" then
+  local f=open(filename)
+  if f then
+   local n=f and noflines(f) or 0
+   f:close()
+   return n
   else
-    local n=0
-    for _ in f:lines() do
-      n=n+1
-    end
-    f:seek('set',0)
-    return n
+   return 0
   end
+ else
+  local n=0
+  for _ in f:lines() do
+   n=n+1
+  end
+  f:seek('set',0)
+  return n
+ end
 end
 io.noflines=noflines
 local nextchar={
-  [ 4]=function(f)
-    return f:read(1,1,1,1)
-  end,
-  [ 2]=function(f)
-    return f:read(1,1)
-  end,
-  [ 1]=function(f)
-    return f:read(1)
-  end,
-  [-2]=function(f)
-    local a,b=f:read(1,1)
-    return b,a
-  end,
-  [-4]=function(f)
-    local a,b,c,d=f:read(1,1,1,1)
-    return d,c,b,a
-  end
+ [ 4]=function(f)
+  return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+  return f:read(1,1)
+ end,
+ [ 1]=function(f)
+  return f:read(1)
+ end,
+ [-2]=function(f)
+  local a,b=f:read(1,1)
+  return b,a
+ end,
+ [-4]=function(f)
+  local a,b,c,d=f:read(1,1,1,1)
+  return d,c,b,a
+ end
 }
 function io.characters(f,n)
-  if f then
-    return nextchar[n or 1],f
-  end
+ if f then
+  return nextchar[n or 1],f
+ end
 end
 local nextbyte={
-  [4]=function(f)
-    local a,b,c,d=f:read(1,1,1,1)
-    if d then
-      return byte(a),byte(b),byte(c),byte(d)
-    end
-  end,
-  [3]=function(f)
-    local a,b,c=f:read(1,1,1)
-    if b then
-      return byte(a),byte(b),byte(c)
-    end
-  end,
-  [2]=function(f)
-    local a,b=f:read(1,1)
-    if b then
-      return byte(a),byte(b)
-    end
-  end,
-  [1]=function (f)
-    local a=f:read(1)
-    if a then
-      return byte(a)
-    end
-  end,
-  [-2]=function (f)
-    local a,b=f:read(1,1)
-    if b then
-      return byte(b),byte(a)
-    end
-  end,
-  [-3]=function(f)
-    local a,b,c=f:read(1,1,1)
-    if b then
-      return byte(c),byte(b),byte(a)
-    end
-  end,
-  [-4]=function(f)
-    local a,b,c,d=f:read(1,1,1,1)
-    if d then
-      return byte(d),byte(c),byte(b),byte(a)
-    end
+ [4]=function(f)
+  local a,b,c,d=f:read(1,1,1,1)
+  if d then
+   return byte(a),byte(b),byte(c),byte(d)
   end
+ end,
+ [3]=function(f)
+  local a,b,c=f:read(1,1,1)
+  if b then
+   return byte(a),byte(b),byte(c)
+  end
+ end,
+ [2]=function(f)
+  local a,b=f:read(1,1)
+  if b then
+   return byte(a),byte(b)
+  end
+ end,
+ [1]=function (f)
+  local a=f:read(1)
+  if a then
+   return byte(a)
+  end
+ end,
+ [-2]=function (f)
+  local a,b=f:read(1,1)
+  if b then
+   return byte(b),byte(a)
+  end
+ end,
+ [-3]=function(f)
+  local a,b,c=f:read(1,1,1)
+  if b then
+   return byte(c),byte(b),byte(a)
+  end
+ end,
+ [-4]=function(f)
+  local a,b,c,d=f:read(1,1,1,1)
+  if d then
+   return byte(d),byte(c),byte(b),byte(a)
+  end
+ end
 }
 function io.bytes(f,n)
-  if f then
-    return nextbyte[n or 1],f
-  else
-    return nil,nil
-  end
+ if f then
+  return nextbyte[n or 1],f
+ else
+  return nil,nil
+ end
 end
 function io.ask(question,default,options)
-  while true do
-    write(question)
-    if options then
-      write(format(" [%s]",concat(options,"|")))
+ while true do
+  write(question)
+  if options then
+   write(format(" [%s]",concat(options,"|")))
+  end
+  if default then
+   write(format(" [%s]",default))
+  end
+  write(format(" "))
+  flush()
+  local answer=read()
+  answer=gsub(answer,"^%s*(.*)%s*$","%1")
+  if answer=="" and default then
+   return default
+  elseif not options then
+   return answer
+  else
+   for k=1,#options do
+    if options[k]==answer then
+     return answer
     end
-    if default then
-      write(format(" [%s]",default))
+   end
+   local pattern="^"..answer
+   for k=1,#options do
+    local v=options[k]
+    if find(v,pattern) then
+     return v
     end
-    write(format(" "))
-    flush()
-    local answer=read()
-    answer=gsub(answer,"^%s*(.*)%s*$","%1")
-    if answer=="" and default then
-      return default
-    elseif not options then
-      return answer
-    else
-      for k=1,#options do
-        if options[k]==answer then
-          return answer
-        end
-      end
-      local pattern="^"..answer
-      for k=1,#options do
-        local v=options[k]
-        if find(v,pattern) then
-          return v
-        end
-      end
-    end
+   end
   end
+ end
 end
 local function readnumber(f,n,m) 
-  if m then
-    f:seek("set",n)
-    n=m
-  end
-  if n==1 then
-    return byte(f:read(1))
-  elseif n==2 then
-    local a,b=byte(f:read(2),1,2)
-    return 0x100*a+b
-  elseif n==3 then
-    local a,b,c=byte(f:read(3),1,3)
-    return 0x10000*a+0x100*b+c
-  elseif n==4 then
-    local a,b,c,d=byte(f:read(4),1,4)
-    return 0x1000000*a+0x10000*b+0x100*c+d
-  elseif n==8 then
-    local a,b=readnumber(f,4),readnumber(f,4)
-    return 0x100*a+b
-  elseif n==12 then
-    local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
-    return 0x10000*a+0x100*b+c
-  elseif n==-2 then
-    local b,a=byte(f:read(2),1,2)
-    return 0x100*a+b
-  elseif n==-3 then
-    local c,b,a=byte(f:read(3),1,3)
-    return 0x10000*a+0x100*b+c
-  elseif n==-4 then
-    local d,c,b,a=byte(f:read(4),1,4)
-    return 0x1000000*a+0x10000*b+0x100*c+d
-  elseif n==-8 then
-    local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
-    return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
-  else
-    return 0
-  end
+ if m then
+  f:seek("set",n)
+  n=m
+ end
+ if n==1 then
+  return byte(f:read(1))
+ elseif n==2 then
+  local a,b=byte(f:read(2),1,2)
+  return 0x100*a+b
+ elseif n==3 then
+  local a,b,c=byte(f:read(3),1,3)
+  return 0x10000*a+0x100*b+c
+ elseif n==4 then
+  local a,b,c,d=byte(f:read(4),1,4)
+  return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+  local a,b=readnumber(f,4),readnumber(f,4)
+  return 0x100*a+b
+ elseif n==12 then
+  local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+  return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+  local b,a=byte(f:read(2),1,2)
+  return 0x100*a+b
+ elseif n==-3 then
+  local c,b,a=byte(f:read(3),1,3)
+  return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+  local d,c,b,a=byte(f:read(4),1,4)
+  return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+  local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+  return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+  return 0
+ end
 end
 io.readnumber=readnumber
 function io.readstring(f,n,m)
-  if m then
-    f:seek("set",n)
-    n=m
-  end
-  local str=gsub(f:read(n),"\000","")
-  return str
+ if m then
+  f:seek("set",n)
+  n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
 end
 
 end -- closure
@@ -3073,11 +3072,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-os']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local os=os
 local date,time=os.date,os.time
@@ -3086,304 +3085,304 @@
 local random,ceil,randomseed=math.random,math.ceil,math.randomseed
 local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
 do
-  local selfdir=os.selfdir
-  if selfdir=="" then
-    selfdir=nil
+ local selfdir=os.selfdir
+ if selfdir=="" then
+  selfdir=nil
+ end
+ if not selfdir then
+  if arg then
+   for i=1,#arg do
+    local a=arg[i]
+    if find(a,"^%-%-[c:]*texmfbinpath=") then
+     selfdir=gsub(a,"^.-=","")
+     break
+    end
+   end
   end
   if not selfdir then
-    if arg then
-      for i=1,#arg do
-        local a=arg[i]
-        if find(a,"^%-%-[c:]*texmfbinpath=") then
-          selfdir=gsub(a,"^.-=","")
-          break
-        end
-      end
+   selfdir=os.selfbin or "luatex"
+   if find(selfdir,"[/\\]") then
+    selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
+   elseif os.getenv then
+    local path=os.getenv("PATH")
+    local name=gsub(selfdir,"^.*[/\\][^/\\]","")
+    local patt="[^:]+"
+    if os.type=="windows" then
+     patt="[^;]+"
+     name=name..".exe"
     end
-    if not selfdir then
-      selfdir=os.selfbin or "luatex"
-      if find(selfdir,"[/\\]") then
-        selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
-      elseif os.getenv then
-        local path=os.getenv("PATH")
-        local name=gsub(selfdir,"^.*[/\\][^/\\]","")
-        local patt="[^:]+"
-        if os.type=="windows" then
-          patt="[^;]+"
-          name=name..".exe"
-        end
-        local isfile
-        if lfs then
-          local attributes=lfs.attributes
-          isfile=function(name)
-            local a=attributes(name,"mode")
-            return a=="file" or a=="link" or nil
-          end
-        else
-          local open=io.open
-          isfile=function(name)
-            local f=open(name)
-            if f then
-              f:close()
-              return true
-            end
-          end
-        end
-        for p in gmatch(path,patt) do
-          if isfile(p.."/"..name) then
-            selfdir=p
-            break
-          end
-        end
+    local isfile
+    if lfs then
+     local attributes=lfs.attributes
+     isfile=function(name)
+      local a=attributes(name,"mode")
+      return a=="file" or a=="link" or nil
+     end
+    else
+     local open=io.open
+     isfile=function(name)
+      local f=open(name)
+      if f then
+       f:close()
+       return true
       end
+     end
     end
-    os.selfdir=selfdir or "."
+    for p in gmatch(path,patt) do
+     if isfile(p.."/"..name) then
+      selfdir=p
+      break
+     end
+    end
+   end
   end
+  os.selfdir=selfdir or "."
+ end
 end
 math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
 randomseed(math.initialseed)
 if not os.__getenv__ then
-  os.__getenv__=os.getenv
-  os.__setenv__=os.setenv
-  if os.env then
-    local osgetenv=os.getenv
-    local ossetenv=os.setenv
-    local osenv=os.env   local _=osenv.PATH 
-    function os.setenv(k,v)
-      if v==nil then
-        v=""
-      end
-      local K=upper(k)
-      osenv[K]=v
-      if type(v)=="table" then
-        v=concat(v,";") 
-      end
-      ossetenv(K,v)
-    end
-    function os.getenv(k)
-      local K=upper(k)
-      local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
-      if v=="" then
-        return nil
-      else
-        return v
-      end
-    end
-  else
-    local ossetenv=os.setenv
-    local osgetenv=os.getenv
-    local osenv={}
-    function os.setenv(k,v)
-      if v==nil then
-        v=""
-      end
-      local K=upper(k)
-      osenv[K]=v
-    end
-    function os.getenv(k)
-      local K=upper(k)
-      local v=osenv[K] or osgetenv(K) or osgetenv(k)
-      if v=="" then
-        return nil
-      else
-        return v
-      end
-    end
-    local function __index(t,k)
-      return os.getenv(k)
-    end
-    local function __newindex(t,k,v)
-      os.setenv(k,v)
-    end
-    os.env={}
-    setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+  local osgetenv=os.getenv
+  local ossetenv=os.setenv
+  local osenv=os.env   local _=osenv.PATH 
+  function os.setenv(k,v)
+   if v==nil then
+    v=""
+   end
+   local K=upper(k)
+   osenv[K]=v
+   if type(v)=="table" then
+    v=concat(v,";") 
+   end
+   ossetenv(K,v)
   end
+  function os.getenv(k)
+   local K=upper(k)
+   local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+   if v=="" then
+    return nil
+   else
+    return v
+   end
+  end
+ else
+  local ossetenv=os.setenv
+  local osgetenv=os.getenv
+  local osenv={}
+  function os.setenv(k,v)
+   if v==nil then
+    v=""
+   end
+   local K=upper(k)
+   osenv[K]=v
+  end
+  function os.getenv(k)
+   local K=upper(k)
+   local v=osenv[K] or osgetenv(K) or osgetenv(k)
+   if v=="" then
+    return nil
+   else
+    return v
+   end
+  end
+  local function __index(t,k)
+   return os.getenv(k)
+  end
+  local function __newindex(t,k,v)
+   os.setenv(k,v)
+  end
+  os.env={}
+  setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
 end
 local execute=os.execute
 local iopopen=io.popen
 local function resultof(command)
-  local handle=iopopen(command,"r") 
-  if handle then
-    local result=handle:read("*all") or ""
-    handle:close()
-    return result
-  else
-    return ""
-  end
+ local handle=iopopen(command,"r") 
+ if handle then
+  local result=handle:read("*all") or ""
+  handle:close()
+  return result
+ else
+  return ""
+ end
 end
 os.resultof=resultof
 function os.pipeto(command)
-  return iopopen(command,"w") 
+ return iopopen(command,"w") 
 end
 if not io.fileseparator then
-  if find(os.getenv("PATH"),";",1,true) then
-    io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
-  else
-    io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
-  end
+ if find(os.getenv("PATH"),";",1,true) then
+  io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+  io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
 end
 os.type=os.type or (io.pathseparator==";"    and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin"  ) or "linux"
 if os.type=="windows" then
-  os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
 else
-  os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
 end
 local launchers={
-  windows="start %s",
-  macosx="open %s",
-  unix="xdg-open %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
 }
 function os.launch(str)
-  execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
 end
 if not os.times then
-  function os.times()
-    return {
-      utime=os.gettimeofday(),
-      stime=0,
-      cutime=0,
-      cstime=0,
-    }
-  end
+ function os.times()
+  return {
+   utime=os.gettimeofday(),
+   stime=0,
+   cutime=0,
+   cstime=0,
+  }
+ end
 end
 local gettimeofday=os.gettimeofday or os.clock
 os.gettimeofday=gettimeofday
 local startuptime=gettimeofday()
 function os.runtime()
-  return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
 end
 local resolvers=os.resolvers or {}
 os.resolvers=resolvers
 setmetatable(os,{ __index=function(t,k)
-  local r=resolvers[k]
-  return r and r(t,k) or nil 
+ local r=resolvers[k]
+ return r and r(t,k) or nil 
 end })
 local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
 if platform~="" then
-  os.platform=platform
+ os.platform=platform
 elseif os.type=="windows" then
-  function resolvers.platform(t,k)
-    local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
-    local platform=""
-    if find(architecture,"AMD64",1,true) then
-      platform="win64"
-    else
-      platform="mswin"
-    end
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
+ function resolvers.platform(t,k)
+  local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+  local platform=""
+  if find(architecture,"AMD64",1,true) then
+   platform="win64"
+  else
+   platform="mswin"
   end
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 elseif name=="linux" then
-  function resolvers.platform(t,k)
-    local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
-    local platform=os.getenv("MTX_PLATFORM") or ""
-    local musl=find(os.selfdir or "","linuxmusl")
-    if platform~="" then
-    elseif find(architecture,"x86_64",1,true) then
-      platform=musl and "linuxmusl" or "linux-64"
-    elseif find(architecture,"ppc",1,true) then
-      platform="linux-ppc"
-    else
-      platform=musl and "linuxmusl" or "linux"
-    end
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
+ function resolvers.platform(t,k)
+  local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+  local platform=os.getenv("MTX_PLATFORM") or ""
+  local musl=find(os.selfdir or "","linuxmusl")
+  if platform~="" then
+  elseif find(architecture,"x86_64",1,true) then
+   platform=musl and "linuxmusl" or "linux-64"
+  elseif find(architecture,"ppc",1,true) then
+   platform="linux-ppc"
+  else
+   platform=musl and "linuxmusl" or "linux"
   end
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 elseif name=="macosx" then
-  function resolvers.platform(t,k)
-    local architecture=resultof("echo $HOSTTYPE") or ""
-    local platform=""
-    if architecture=="" then
-      platform="osx-intel"
-    elseif find(architecture,"i386",1,true) then
-      platform="osx-intel"
-    elseif find(architecture,"x86_64",1,true) then
-      platform="osx-64"
-    else
-      platform="osx-ppc"
-    end
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
+ function resolvers.platform(t,k)
+  local architecture=resultof("echo $HOSTTYPE") or ""
+  local platform=""
+  if architecture=="" then
+   platform="osx-intel"
+  elseif find(architecture,"i386",1,true) then
+   platform="osx-intel"
+  elseif find(architecture,"x86_64",1,true) then
+   platform="osx-64"
+  else
+   platform="osx-ppc"
   end
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 elseif name=="sunos" then
-  function resolvers.platform(t,k)
-    local architecture=resultof("uname -m") or ""
-    local platform=""
-    if find(architecture,"sparc",1,true) then
-      platform="solaris-sparc"
-    else 
-      platform="solaris-intel"
-    end
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
+ function resolvers.platform(t,k)
+  local architecture=resultof("uname -m") or ""
+  local platform=""
+  if find(architecture,"sparc",1,true) then
+   platform="solaris-sparc"
+  else 
+   platform="solaris-intel"
   end
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 elseif name=="freebsd" then
-  function resolvers.platform(t,k)
-    local architecture=resultof("uname -m") or ""
-    local platform=""
-    if find(architecture,"amd64",1,true) then
-      platform="freebsd-amd64"
-    else
-      platform="freebsd"
-    end
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
+ function resolvers.platform(t,k)
+  local architecture=resultof("uname -m") or ""
+  local platform=""
+  if find(architecture,"amd64",1,true) then
+   platform="freebsd-amd64"
+  else
+   platform="freebsd"
   end
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 elseif name=="kfreebsd" then
-  function resolvers.platform(t,k)
-    local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
-    local platform=""
-    if find(architecture,"x86_64",1,true) then
-      platform="kfreebsd-amd64"
-    else
-      platform="kfreebsd-i386"
-    end
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
+ function resolvers.platform(t,k)
+  local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+  local platform=""
+  if find(architecture,"x86_64",1,true) then
+   platform="kfreebsd-amd64"
+  else
+   platform="kfreebsd-i386"
   end
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 else
-  function resolvers.platform(t,k)
-    local platform="linux"
-    os.setenv("MTX_PLATFORM",platform)
-    os.platform=platform
-    return platform
-  end
+ function resolvers.platform(t,k)
+  local platform="linux"
+  os.setenv("MTX_PLATFORM",platform)
+  os.platform=platform
+  return platform
+ end
 end
 os.newline=name=="windows" and "\013\010" or "\010" 
 function resolvers.bits(t,k)
-  local bits=find(os.platform,"64",1,true) and 64 or 32
-  os.bits=bits
-  return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
 end
 local t={ 8,9,"a","b" }
 function os.uuid()
-  return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
-    random(0xFFFF),random(0xFFFF),
-    random(0x0FFF),
-    t[ceil(random(4))] or 8,random(0x0FFF),
-    random(0xFFFF),
-    random(0xFFFF),random(0xFFFF),random(0xFFFF)
-  )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+  random(0xFFFF),random(0xFFFF),
+  random(0x0FFF),
+  t[ceil(random(4))] or 8,random(0x0FFF),
+  random(0xFFFF),
+  random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
 end
 local d
 function os.timezone(delta)
-  d=d or tonumber(tonumber(date("%H")-date("!%H")))
-  if delta then
-    if d>0 then
-      return format("+%02i:00",d)
-    else
-      return format("-%02i:00",-d)
-    end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+  if d>0 then
+   return format("+%02i:00",d)
   else
-    return 1
+   return format("-%02i:00",-d)
   end
+ else
+  return 1
+ end
 end
 local timeformat=format("%%s%s",os.timezone(true))
 local dateformat="!%Y-%m-%d %H:%M:%S"
@@ -3390,129 +3389,129 @@
 local lasttime=nil
 local lastdate=nil
 function os.fulltime(t,default)
-  t=t and tonumber(t) or 0
-  if t>0 then
-  elseif default then
-    return default
-  else
-    t=time()
-  end
-  if t~=lasttime then
-    lasttime=t
-    lastdate=format(timeformat,date(dateformat))
-  end
-  return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+  return default
+ else
+  t=time()
+ end
+ if t~=lasttime then
+  lasttime=t
+  lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
 end
 local dateformat="%Y-%m-%d %H:%M:%S"
 local lasttime=nil
 local lastdate=nil
 function os.localtime(t,default)
-  t=t and tonumber(t) or 0
-  if t>0 then
-  elseif default then
-    return default
-  else
-    t=time()
-  end
-  if t~=lasttime then
-    lasttime=t
-    lastdate=date(dateformat,t)
-  end
-  return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+  return default
+ else
+  t=time()
+ end
+ if t~=lasttime then
+  lasttime=t
+  lastdate=date(dateformat,t)
+ end
+ return lastdate
 end
 function os.converttime(t,default)
-  local t=tonumber(t)
-  if t and t>0 then
-    return date(dateformat,t)
-  else
-    return default or "-"
-  end
+ local t=tonumber(t)
+ if t and t>0 then
+  return date(dateformat,t)
+ else
+  return default or "-"
+ end
 end
 local memory={}
 local function which(filename)
-  local fullname=memory[filename]
-  if fullname==nil then
-    local suffix=file.suffix(filename)
-    local suffixes=suffix=="" and os.binsuffixes or { suffix }
-    for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
-      local df=file.join(directory,filename)
-      for i=1,#suffixes do
-        local dfs=file.addsuffix(df,suffixes[i])
-        if io.exists(dfs) then
-          fullname=dfs
-          break
-        end
-      end
+ local fullname=memory[filename]
+ if fullname==nil then
+  local suffix=file.suffix(filename)
+  local suffixes=suffix=="" and os.binsuffixes or { suffix }
+  for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+   local df=file.join(directory,filename)
+   for i=1,#suffixes do
+    local dfs=file.addsuffix(df,suffixes[i])
+    if io.exists(dfs) then
+     fullname=dfs
+     break
     end
-    if not fullname then
-      fullname=false
-    end
-    memory[filename]=fullname
+   end
   end
-  return fullname
+  if not fullname then
+   fullname=false
+  end
+  memory[filename]=fullname
+ end
+ return fullname
 end
 os.which=which
 os.where=which
 function os.today()
-  return date("!*t") 
+ return date("!*t") 
 end
 function os.now()
-  return date("!%Y-%m-%d %H:%M:%S") 
+ return date("!%Y-%m-%d %H:%M:%S") 
 end
 if not os.sleep then
-  local socket=socket
-  function os.sleep(n)
-    if not socket then
-      socket=require("socket")
-    end
-    socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+  if not socket then
+   socket=require("socket")
   end
+  socket.sleep(n)
+ end
 end
 local function isleapyear(year)
-  return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
 end
 os.isleapyear=isleapyear
 local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
 local function nofdays(year,month)
-  if not month then
-    return isleapyear(year) and 365 or 364
-  else
-    return month==2 and isleapyear(year) and 29 or days[month]
-  end
+ if not month then
+  return isleapyear(year) and 365 or 364
+ else
+  return month==2 and isleapyear(year) and 29 or days[month]
+ end
 end
 os.nofdays=nofdays
 function os.weekday(day,month,year)
-  return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
 end
 function os.validdate(year,month,day)
-  if month<1 then
-    month=1
-  elseif month>12 then
-    month=12
+ if month<1 then
+  month=1
+ elseif month>12 then
+  month=12
+ end
+ if day<1 then
+  day=1
+ else
+  local max=nofdays(year,month)
+  if day>max then
+   day=max
   end
-  if day<1 then
-    day=1
-  else
-    local max=nofdays(year,month)
-    if day>max then
-      day=max
-    end
-  end
-  return year,month,day
+ end
+ return year,month,day
 end
 local osexit=os.exit
 local exitcode=nil
 function os.setexitcode(code)
-  exitcode=code
+ exitcode=code
 end
 function os.exit(c)
-  if exitcode~=nil then
-    return osexit(exitcode)
-  end
-  if c~=nil then
-    return osexit(c)
-  end
-  return osexit()
+ if exitcode~=nil then
+  return osexit(exitcode)
+ end
+ if c~=nil then
+  return osexit(c)
+ end
+ return osexit()
 end
 
 end -- closure
@@ -3520,16 +3519,16 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-file']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 file=file or {}
 local file=file
 if not lfs then
-  lfs=optionalrequire("lfs")
+ lfs=optionalrequire("lfs")
 end
 local insert,concat=table.insert,table.concat
 local match,find,gmatch=string.match,string.find,string.gmatch
@@ -3539,20 +3538,20 @@
 local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
 local attributes=lfs.attributes
 function lfs.isdir(name)
-  return attributes(name,"mode")=="directory"
+ return attributes(name,"mode")=="directory"
 end
 function lfs.isfile(name)
-  local a=attributes(name,"mode")
-  return a=="file" or a=="link" or nil
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
 end
 function lfs.isfound(name)
-  local a=attributes(name,"mode")
-  return (a=="file" or a=="link") and name or nil
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
 end
 if sandbox then
-  sandbox.redefine(lfs.isfile,"lfs.isfile")
-  sandbox.redefine(lfs.isdir,"lfs.isdir")
-  sandbox.redefine(lfs.isfound,"lfs.isfound")
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
 end
 local colon=P(":")
 local period=P(".")
@@ -3566,27 +3565,27 @@
 local suffix=period/""*(1-period-slashes)^1*-1
 local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1) 
 local function pathpart(name,default)
-  return name and lpegmatch(pattern,name) or default or ""
+ return name and lpegmatch(pattern,name) or default or ""
 end
 local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
 local function basename(name)
-  return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
 end
 local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
 local function nameonly(name)
-  return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
 end
 local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
 local function suffixonly(name)
-  return name and lpegmatch(pattern,name) or ""
+ return name and lpegmatch(pattern,name) or ""
 end
 local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
 local function suffixesonly(name)
-  if name then
-    return lpegmatch(pattern,name)
-  else
-    return ""
-  end
+ if name then
+  return lpegmatch(pattern,name)
+ else
+  return ""
+ end
 end
 file.pathpart=pathpart
 file.basename=basename
@@ -3595,7 +3594,7 @@
 file.suffix=suffixonly
 file.suffixesonly=suffixesonly
 file.suffixes=suffixesonly
-file.dirname=pathpart  
+file.dirname=pathpart   
 file.extname=suffixonly
 local drive=C(R("az","AZ"))*colon
 local path=C((noslashes^0*slashes)^0)
@@ -3611,142 +3610,142 @@
 local pattern_c=C(drive*path)*C(base*suffix) 
 local pattern_d=path*rest
 function file.splitname(str,splitdrive)
-  if not str then
-  elseif splitdrive then
-    return lpegmatch(pattern_a,str) 
-  else
-    return lpegmatch(pattern_b,str) 
-  end
+ if not str then
+ elseif splitdrive then
+  return lpegmatch(pattern_a,str) 
+ else
+  return lpegmatch(pattern_b,str) 
+ end
 end
 function file.splitbase(str)
-  if str then
-    return lpegmatch(pattern_d,str) 
-  else
-    return "",str 
-  end
+ if str then
+  return lpegmatch(pattern_d,str) 
+ else
+  return "",str 
+ end
 end
 function file.nametotable(str,splitdrive)
-  if str then
-    local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
-    if splitdrive then
-      return {
-        path=path,
-        drive=drive,
-        subpath=subpath,
-        name=name,
-        base=base,
-        suffix=suffix,
-      }
-    else
-      return {
-        path=path,
-        name=name,
-        base=base,
-        suffix=suffix,
-      }
-    end
+ if str then
+  local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+  if splitdrive then
+   return {
+    path=path,
+    drive=drive,
+    subpath=subpath,
+    name=name,
+    base=base,
+    suffix=suffix,
+   }
+  else
+   return {
+    path=path,
+    name=name,
+    base=base,
+    suffix=suffix,
+   }
   end
+ end
 end
 local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
 function file.removesuffix(name)
-  return name and lpegmatch(pattern,name)
+ return name and lpegmatch(pattern,name)
 end
 local suffix=period/""*(1-period-slashes)^1*-1
 local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
 function file.addsuffix(filename,suffix,criterium)
-  if not filename or not suffix or suffix=="" then
-    return filename
-  elseif criterium==true then
-    return filename.."."..suffix
-  elseif not criterium then
-    local n,s=lpegmatch(pattern,filename)
-    if not s or s=="" then
-      return filename.."."..suffix
-    else
+ if not filename or not suffix or suffix=="" then
+  return filename
+ elseif criterium==true then
+  return filename.."."..suffix
+ elseif not criterium then
+  local n,s=lpegmatch(pattern,filename)
+  if not s or s=="" then
+   return filename.."."..suffix
+  else
+   return filename
+  end
+ else
+  local n,s=lpegmatch(pattern,filename)
+  if s and s~="" then
+   local t=type(criterium)
+   if t=="table" then
+    for i=1,#criterium do
+     if s==criterium[i] then
       return filename
+     end
     end
-  else
-    local n,s=lpegmatch(pattern,filename)
-    if s and s~="" then
-      local t=type(criterium)
-      if t=="table" then
-        for i=1,#criterium do
-          if s==criterium[i] then
-            return filename
-          end
-        end
-      elseif t=="string" then
-        if s==criterium then
-          return filename
-        end
-      end
+   elseif t=="string" then
+    if s==criterium then
+     return filename
     end
-    return (n or filename).."."..suffix
+   end
   end
+  return (n or filename).."."..suffix
+ end
 end
 local suffix=period*(1-period-slashes)^1*-1
 local pattern=Cs((1-suffix)^0)
 function file.replacesuffix(name,suffix)
-  if name and suffix and suffix~="" then
-    return lpegmatch(pattern,name).."."..suffix
-  else
-    return name
-  end
+ if name and suffix and suffix~="" then
+  return lpegmatch(pattern,name).."."..suffix
+ else
+  return name
+ end
 end
 local reslasher=lpeg.replacer(P("\\"),"/")
 function file.reslash(str)
-  return str and lpegmatch(reslasher,str)
+ return str and lpegmatch(reslasher,str)
 end
 function file.is_writable(name)
-  if not name then
-  elseif lfs.isdir(name) then
-    name=name.."/m_t_x_t_e_s_t.tmp"
-    local f=io.open(name,"wb")
-    if f then
-      f:close()
-      os.remove(name)
-      return true
-    end
-  elseif lfs.isfile(name) then
-    local f=io.open(name,"ab")
-    if f then
-      f:close()
-      return true
-    end
-  else
-    local f=io.open(name,"ab")
-    if f then
-      f:close()
-      os.remove(name)
-      return true
-    end
+ if not name then
+ elseif lfs.isdir(name) then
+  name=name.."/m_t_x_t_e_s_t.tmp"
+  local f=io.open(name,"wb")
+  if f then
+   f:close()
+   os.remove(name)
+   return true
   end
-  return false
+ elseif lfs.isfile(name) then
+  local f=io.open(name,"ab")
+  if f then
+   f:close()
+   return true
+  end
+ else
+  local f=io.open(name,"ab")
+  if f then
+   f:close()
+   os.remove(name)
+   return true
+  end
+ end
+ return false
 end
 local readable=P("r")*Cc(true)
 function file.is_readable(name)
-  if name then
-    local a=attributes(name)
-    return a and lpegmatch(readable,a.permissions) or false
-  else
-    return false
-  end
+ if name then
+  local a=attributes(name)
+  return a and lpegmatch(readable,a.permissions) or false
+ else
+  return false
+ end
 end
 file.isreadable=file.is_readable 
 file.iswritable=file.is_writable 
 function file.size(name)
-  if name then
-    local a=attributes(name)
-    return a and a.size or 0
-  else
-    return 0
-  end
+ if name then
+  local a=attributes(name)
+  return a and a.size or 0
+ else
+  return 0
+ end
 end
 function file.splitpath(str,separator) 
-  return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
 end
 function file.joinpath(tab,separator) 
-  return tab and concat(tab,separator or io.pathseparator) 
+ return tab and concat(tab,separator or io.pathseparator) 
 end
 local someslash=S("\\/")
 local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -3756,30 +3755,30 @@
 local reslasher=lpeg.replacer(S("\\/"),"/")
 local deslasher=lpeg.replacer(S("\\/")^1,"/")
 function file.join(one,two,three,...)
-  if not two then
-    return one=="" and one or lpegmatch(reslasher,one)
+ if not two then
+  return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+  return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+  local one=lpegmatch(reslasher,one)
+  local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+  if lpegmatch(hasroot,two) then
+   return one..two
+  else
+   return one.."/"..two
   end
-  if one=="" then
-    return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
-  end
-  if lpegmatch(isnetwork,one) then
-    local one=lpegmatch(reslasher,one)
-    local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
-    if lpegmatch(hasroot,two) then
-      return one..two
-    else
-      return one.."/"..two
-    end
-  elseif lpegmatch(isroot,one) then
-    local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
-    if lpegmatch(hasroot,two) then
-      return two
-    else
-      return "/"..two
-    end
+ elseif lpegmatch(isroot,one) then
+  local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+  if lpegmatch(hasroot,two) then
+   return two
   else
-    return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+   return "/"..two
   end
+ else
+  return lpegmatch(deslasher,concat({  one,two,three,... },"/"))
+ end
 end
 local drivespec=R("az","AZ")^1*colon
 local anchors=fwslash+drivespec
@@ -3789,56 +3788,56 @@
 local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
 local absolute=fwslash
 function file.collapsepath(str,anchor) 
-  if not str then
-    return
-  end
-  if anchor==true and not lpegmatch(anchors,str) then
-    str=getcurrentdir().."/"..str
-  end
-  if str=="" or str=="." then
-    return "."
-  elseif lpegmatch(untouched,str) then
-    return lpegmatch(reslasher,str)
-  end
-  local starter,oldelements=lpegmatch(splitstarter,str)
-  local newelements={}
-  local i=#oldelements
-  while i>0 do
-    local element=oldelements[i]
-    if element=='.' then
-    elseif element=='..' then
-      local n=i-1
-      while n>0 do
-        local element=oldelements[n]
-        if element~='..' and element~='.' then
-          oldelements[n]='.'
-          break
-        else
-          n=n-1
-        end
-       end
-      if n<1 then
-        insert(newelements,1,'..')
-      end
-    elseif element~="" then
-      insert(newelements,1,element)
+ if not str then
+  return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+  str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+  return "."
+ elseif lpegmatch(untouched,str) then
+  return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+  local element=oldelements[i]
+  if element=='.' then
+  elseif element=='..' then
+   local n=i-1
+   while n>0 do
+    local element=oldelements[n]
+    if element~='..' and element~='.' then
+     oldelements[n]='.'
+     break
+    else
+     n=n-1
     end
-    i=i-1
+    end
+   if n<1 then
+      insert(newelements,1,'..')
+   end
+  elseif element~="" then
+   insert(newelements,1,element)
   end
-  if #newelements==0 then
-    return starter or "."
-  elseif starter then
-    return starter..concat(newelements,'/')
-  elseif lpegmatch(absolute,str) then
-    return "/"..concat(newelements,'/')
+  i=i-1
+ end
+ if #newelements==0 then
+  return starter or "."
+ elseif starter then
+  return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+  return "/"..concat(newelements,'/')
+ else
+  newelements=concat(newelements,'/')
+  if anchor=="." and find(str,"^%./") then
+   return "./"..newelements
   else
-    newelements=concat(newelements,'/')
-    if anchor=="." and find(str,"^%./") then
-      return "./"..newelements
-    else
-      return newelements
-    end
+   return newelements
   end
+ end
 end
 local validchars=R("az","09","AZ","--","..")
 local pattern_a=lpeg.replacer(1-validchars)
@@ -3846,14 +3845,14 @@
 local whatever=P("-")^0/""
 local pattern_b=Cs(whatever*(1-whatever*-1)^1)
 function file.robustname(str,strict)
-  if str then
-    str=lpegmatch(pattern_a,str) or str
-    if strict then
-      return lpegmatch(pattern_b,str) or str 
-    else
-      return str
-    end
+ if str then
+  str=lpegmatch(pattern_a,str) or str
+  if strict then
+   return lpegmatch(pattern_b,str) or str 
+  else
+   return str
   end
+ end
 end
 local loaddata=io.loaddata
 local savedata=io.savedata
@@ -3860,12 +3859,12 @@
 file.readdata=loaddata
 file.savedata=savedata
 function file.copy(oldname,newname)
-  if oldname and newname then
-    local data=loaddata(oldname)
-    if data and data~="" then
-      savedata(newname,data)
-    end
+ if oldname and newname then
+  local data=loaddata(oldname)
+  if data and data~="" then
+   savedata(newname,data)
   end
+ end
 end
 local letter=R("az","AZ")+S("_-+")
 local separator=P("://")
@@ -3874,44 +3873,44 @@
 lpeg.patterns.qualified=qualified
 lpeg.patterns.rootbased=rootbased
 function file.is_qualified_path(filename)
-  return filename and lpegmatch(qualified,filename)~=nil
+ return filename and lpegmatch(qualified,filename)~=nil
 end
 function file.is_rootbased_path(filename)
-  return filename and lpegmatch(rootbased,filename)~=nil
+ return filename and lpegmatch(rootbased,filename)~=nil
 end
 function file.strip(name,dir)
-  if name then
-    local b,a=match(name,"^(.-)"..dir.."(.*)$")
-    return a~="" and a or name
-  end
+ if name then
+  local b,a=match(name,"^(.-)"..dir.."(.*)$")
+  return a~="" and a or name
+ end
 end
 function lfs.mkdirs(path)
-  local full=""
-  for sub in gmatch(path,"(/*[^\\/]+)") do 
-    full=full..sub
-    lfs.mkdir(full)
-  end
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do 
+  full=full..sub
+  lfs.mkdir(full)
+ end
 end
 function file.withinbase(path) 
-  local l=0
-  if not find(path,"^/") then
-    path="/"..path
+ local l=0
+ if not find(path,"^/") then
+  path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+  if dir==".." then
+   l=l-1
+  elseif dir~="." then
+   l=l+1
   end
-  for dir in gmatch(path,"/([^/]+)") do
-    if dir==".." then
-      l=l-1
-    elseif dir~="." then
-      l=l+1
-    end
-    if l<0 then
-      return false
-    end
+  if l<0 then
+   return false
   end
-  return true
+ end
+ return true
 end
 local symlinkattributes=lfs.symlinkattributes
 function lfs.readlink(name)
-  return symlinkattributes(name,"target") or nil
+ return symlinkattributes(name,"target") or nil
 end
 
 end -- closure
@@ -3919,48 +3918,48 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-gzip']={
-  version=1.001,
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 if not gzip then
-  return
+ return
 end
 local suffix,suffixes=file.suffix,file.suffixes
 function gzip.load(filename)
-  local f=io.open(filename,"rb")
-  if not f then
-  elseif suffix(filename)=="gz" then
-    f:close()
-    local g=gzip.open(filename,"rb")
-    if g then
-      local str=g:read("*all")
-      g:close()
-      return str
-    end
-  else
-    local str=f:read("*all")
-    f:close()
-    return str
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+  f:close()
+  local g=gzip.open(filename,"rb")
+  if g then
+   local str=g:read("*all")
+   g:close()
+   return str
   end
+ else
+  local str=f:read("*all")
+  f:close()
+  return str
+ end
 end
 function gzip.save(filename,data)
-  if suffix(filename)~="gz" then
-    filename=filename..".gz"
-  end
-  local f=io.open(filename,"wb")
-  if f then
-    local s=zlib.compress(data or "",9,nil,15+16)
-    f:write(s)
-    f:close()
-    return #s
-  end
+ if suffix(filename)~="gz" then
+  filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+  local s=zlib.compress(data or "",9,nil,15+16)
+  f:write(s)
+  f:close()
+  return #s
+ end
 end
 function gzip.suffix(filename)
-  local suffix,extra=suffixes(filename)
-  local gzipped=extra=="gz"
-  return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
 end
 
 end -- closure
@@ -3968,84 +3967,84 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-md5']={
-  version=1.001,
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 if not md5 then
-  md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
 end
 if not md5 then
-  md5={
-    sum=function(str) print("error: md5 is not loaded (sum     ignored)") return str end,
-    sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
-  }
+ md5={
+  sum=function(str) print("error: md5 is not loaded (sum     ignored)") return str end,
+  sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
 end
 local md5,file=md5,file
 local gsub=string.gsub
 do
-  local patterns=lpeg and lpeg.patterns
-  if patterns then
-    local bytestoHEX=patterns.bytestoHEX
-    local bytestohex=patterns.bytestohex
-    local bytestodec=patterns.bytestodec
-    local lpegmatch=lpeg.match
-    local md5sum=md5.sum
-    if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
-    if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
-    if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
-    md5.sumhexa=md5.hex
-    md5.sumHEXA=md5.HEX
-  end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+  local bytestoHEX=patterns.bytestoHEX
+  local bytestohex=patterns.bytestohex
+  local bytestodec=patterns.bytestodec
+  local lpegmatch=lpeg.match
+  local md5sum=md5.sum
+  if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+  if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+  if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+  md5.sumhexa=md5.hex
+  md5.sumHEXA=md5.HEX
+ end
 end
 function file.needsupdating(oldname,newname,threshold) 
-  local oldtime=lfs.attributes(oldname,"modification")
-  if oldtime then
-    local newtime=lfs.attributes(newname,"modification")
-    if not newtime then
-      return true 
-    elseif newtime>=oldtime then
-      return false 
-    elseif oldtime-newtime<(threshold or 1) then
-      return false 
-    else
-      return true 
-    end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+  local newtime=lfs.attributes(newname,"modification")
+  if not newtime then
+   return true 
+  elseif newtime>=oldtime then
+   return false 
+  elseif oldtime-newtime<(threshold or 1) then
+   return false 
   else
-    return false 
+   return true 
   end
+ else
+  return false 
+ end
 end
 file.needs_updating=file.needsupdating
 function file.syncmtimes(oldname,newname)
-  local oldtime=lfs.attributes(oldname,"modification")
-  if oldtime and lfs.isfile(newname) then
-    lfs.touch(newname,oldtime,oldtime)
-  end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+  lfs.touch(newname,oldtime,oldtime)
+ end
 end
 function file.checksum(name)
-  if md5 then
-    local data=io.loaddata(name)
-    if data then
-      return md5.HEX(data)
-    end
+ if md5 then
+  local data=io.loaddata(name)
+  if data then
+   return md5.HEX(data)
   end
-  return nil
+ end
+ return nil
 end
 function file.loadchecksum(name)
-  if md5 then
-    local data=io.loaddata(name..".md5")
-    return data and (gsub(data,"%s",""))
-  end
-  return nil
+ if md5 then
+  local data=io.loaddata(name..".md5")
+  return data and (gsub(data,"%s",""))
+ end
+ return nil
 end
 function file.savechecksum(name,checksum)
-  if not checksum then checksum=file.checksum(name) end
-  if checksum then
-    io.savedata(name..".md5",checksum)
-    return checksum
-  end
-  return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+  io.savedata(name..".md5",checksum)
+  return checksum
+ end
+ return nil
 end
 
 end -- closure
@@ -4053,11 +4052,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-dir']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local type,select=type,select
 local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4069,7 +4068,7 @@
 local lfs=lfs
 local attributes=lfs.attributes
 local walkdir=lfs.dir
-local isdir=lfs.isdir 
+local isdir=lfs.isdir  
 local isfile=lfs.isfile 
 local currentdir=lfs.currentdir
 local chdir=lfs.chdir
@@ -4076,471 +4075,471 @@
 local mkdir=lfs.mkdir
 local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
 if onwindows then
-  local tricky=S("/\\")*P(-1)
-  isdir=function(name)
-    if lpegmatch(tricky,name) then
-      return attributes(name,"mode")=="directory"
-    else
-      return attributes(name.."/.","mode")=="directory"
-    end
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+  if lpegmatch(tricky,name) then
+   return attributes(name,"mode")=="directory"
+  else
+   return attributes(name.."/.","mode")=="directory"
   end
-  isfile=function(name)
-    return attributes(name,"mode")=="file"
-  end
-  lfs.isdir=isdir
-  lfs.isfile=isfile
+ end
+ isfile=function(name)
+  return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
 else
-  isdir=function(name)
-    return attributes(name,"mode")=="directory"
-  end
-  isfile=function(name)
-    return attributes(name,"mode")=="file"
-  end
-  lfs.isdir=isdir
-  lfs.isfile=isfile
+ isdir=function(name)
+  return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+  return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
 end
 function dir.current()
-  return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
 end
 local function glob_pattern_function(path,patt,recurse,action)
-  if isdir(path) then
-    local usedpath
-    if path=="/" then
-      usedpath="/."
-    elseif not find(path,"/$") then
-      usedpath=path.."/."
-      path=path.."/"
-    else
-      usedpath=path
-    end
-    local dirs
-    local nofdirs=0
-    for name in walkdir(usedpath) do
-      if name~="." and name~=".." then
-        local full=path..name
-        local mode=attributes(full,'mode')
-        if mode=='file' then
-          if not patt or find(full,patt) then
-            action(full)
-          end
-        elseif recurse and mode=="directory" then
-          if dirs then
-            nofdirs=nofdirs+1
-            dirs[nofdirs]=full
-          else
-            nofdirs=1
-            dirs={ full }
-          end
-        end
-      end
-    end
-    if dirs then
-      for i=1,nofdirs do
-        glob_pattern_function(dirs[i],patt,recurse,action)
-      end
-    end
-  end
-end
-local function glob_pattern_table(path,patt,recurse,result)
-  if not result then
-    result={}
-  end
+ if isdir(path) then
   local usedpath
   if path=="/" then
-    usedpath="/."
+   usedpath="/."
   elseif not find(path,"/$") then
-    usedpath=path.."/."
-    path=path.."/"
+   usedpath=path.."/."
+   path=path.."/"
   else
-    usedpath=path
+   usedpath=path
   end
   local dirs
   local nofdirs=0
-  local noffiles=#result
-  for name,a in walkdir(usedpath) do
-    if name~="." and name~=".." then
-      local full=path..name
-      local mode=attributes(full,'mode')
-      if mode=='file' then
-        if not patt or find(full,patt) then
-          noffiles=noffiles+1
-          result[noffiles]=full
-        end
-      elseif recurse and mode=="directory" then
-        if dirs then
-          nofdirs=nofdirs+1
-          dirs[nofdirs]=full
-        else
-          nofdirs=1
-          dirs={ full }
-        end
-      end
+  for name in walkdir(usedpath) do
+   if name~="." and name~=".." then
+    local full=path..name
+    local mode=attributes(full,'mode')
+    if mode=='file' then
+     if not patt or find(full,patt) then
+      action(full)
+     end
+    elseif recurse and mode=="directory" then
+     if dirs then
+      nofdirs=nofdirs+1
+      dirs[nofdirs]=full
+     else
+      nofdirs=1
+      dirs={ full }
+     end
     end
+   end
   end
   if dirs then
-    for i=1,nofdirs do
-      glob_pattern_table(dirs[i],patt,recurse,result)
-    end
+   for i=1,nofdirs do
+    glob_pattern_function(dirs[i],patt,recurse,action)
+   end
   end
-  return result
+ end
 end
-local function globpattern(path,patt,recurse,method)
-  local kind=type(method)
-  if patt and sub(patt,1,-3)==path then
-    patt=false
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+  result={}
+ end
+ local usedpath
+ if path=="/" then
+  usedpath="/."
+ elseif not find(path,"/$") then
+  usedpath=path.."/."
+  path=path.."/"
+ else
+  usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+  if name~="." and name~=".." then
+   local full=path..name
+   local mode=attributes(full,'mode')
+   if mode=='file' then
+    if not patt or find(full,patt) then
+     noffiles=noffiles+1
+     result[noffiles]=full
+    end
+   elseif recurse and mode=="directory" then
+    if dirs then
+     nofdirs=nofdirs+1
+     dirs[nofdirs]=full
+    else
+     nofdirs=1
+     dirs={ full }
+    end
+   end
   end
-  local okay=isdir(path)
-  if kind=="function" then
-    return okay and glob_pattern_function(path,patt,recurse,method) or {}
-  elseif kind=="table" then
-    return okay and glob_pattern_table(path,patt,recurse,method) or method
-  else
-    return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+ if dirs then
+  for i=1,nofdirs do
+   glob_pattern_table(dirs[i],patt,recurse,result)
   end
+ end
+ return result
 end
+local function globpattern(path,patt,recurse,method)
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+  patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+  return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+  return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+  return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+end
 dir.globpattern=globpattern
 local function collectpattern(path,patt,recurse,result)
-  local ok,scanner
-  result=result or {}
-  if path=="/" then
-    ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end) 
-  else
-    ok,scanner,first=xpcall(function() return walkdir(path)   end,function() end) 
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+  ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end) 
+ else
+  ok,scanner,first=xpcall(function() return walkdir(path)   end,function() end) 
+ end
+ if ok and type(scanner)=="function" then
+  if not find(path,"/$") then
+   path=path..'/'
   end
-  if ok and type(scanner)=="function" then
-    if not find(path,"/$") then
-      path=path..'/'
+  for name in scanner,first do
+   if name=="." then
+   elseif name==".." then
+   else
+    local full=path..name
+    local attr=attributes(full)
+    local mode=attr.mode
+    if mode=='file' then
+     if find(full,patt) then
+      result[name]=attr
+     end
+    elseif recurse and mode=="directory" then
+     attr.list=collectpattern(full,patt,recurse)
+     result[name]=attr
     end
-    for name in scanner,first do
-      if name=="." then
-      elseif name==".." then
-      else
-        local full=path..name
-        local attr=attributes(full)
-        local mode=attr.mode
-        if mode=='file' then
-          if find(full,patt) then
-            result[name]=attr
-          end
-        elseif recurse and mode=="directory" then
-          attr.list=collectpattern(full,patt,recurse)
-          result[name]=attr
-        end
-      end
-    end
+   end
   end
-  return result
+ end
+ return result
 end
 dir.collectpattern=collectpattern
 local separator,pattern
 if onwindows then 
-  local slash=S("/\\")/"/"
-  pattern={
-    [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
-    [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
-    [3]=Cs(P(1)^0)
-  }
+ local slash=S("/\\")/"/"
+ pattern={
+  [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+  [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+  [3]=Cs(P(1)^0)
+ }
 else
-  pattern={
-    [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
-    [2]=C(((1-S("*?/"))^0*P("/"))^0),
-    [3]=C(P(1)^0)
-  }
+ pattern={
+  [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+  [2]=C(((1-S("*?/"))^0*P("/"))^0),
+  [3]=C(P(1)^0)
+ }
 end
 local filter=Cs ((
-  P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
 )^0 )
 local function glob(str,t)
-  if type(t)=="function" then
-    if type(str)=="table" then
-      for s=1,#str do
-        glob(str[s],t)
-      end
-    elseif isfile(str) then
-      t(str)
-    else
-      local root,path,base=lpegmatch(pattern,str) 
-      if root and path and base then
-        local recurse=find(base,"**",1,true) 
-        local start=root..path
-        local result=lpegmatch(filter,start..base)
-        globpattern(start,result,recurse,t)
-      end
-    end
+ if type(t)=="function" then
+  if type(str)=="table" then
+   for s=1,#str do
+    glob(str[s],t)
+   end
+  elseif isfile(str) then
+   t(str)
   else
-    if type(str)=="table" then
-      local t=t or {}
-      for s=1,#str do
-        glob(str[s],t)
-      end
-      return t
-    elseif isfile(str) then
-      if t then
-        t[#t+1]=str
-        return t
-      else
-        return { str }
-      end
-    else
-      local root,path,base=lpegmatch(pattern,str) 
-      if root and path and base then
-        local recurse=find(base,"**",1,true) 
-        local start=root..path
-        local result=lpegmatch(filter,start..base)
-        return globpattern(start,result,recurse,t)
-      else
-        return {}
-      end
-    end
+   local root,path,base=lpegmatch(pattern,str) 
+   if root and path and base then
+    local recurse=find(base,"**",1,true) 
+    local start=root..path
+    local result=lpegmatch(filter,start..base)
+    globpattern(start,result,recurse,t)
+   end
   end
+ else
+  if type(str)=="table" then
+   local t=t or {}
+   for s=1,#str do
+    glob(str[s],t)
+   end
+   return t
+  elseif isfile(str) then
+   if t then
+    t[#t+1]=str
+    return t
+   else
+    return { str }
+   end
+  else
+   local root,path,base=lpegmatch(pattern,str) 
+   if root and path and base then
+    local recurse=find(base,"**",1,true) 
+    local start=root..path
+    local result=lpegmatch(filter,start..base)
+    return globpattern(start,result,recurse,t)
+   else
+    return {}
+   end
+  end
+ end
 end
 dir.glob=glob
 local function globfiles(path,recurse,func,files) 
-  if type(func)=="string" then
-    local s=func
-    func=function(name) return find(name,s) end
-  end
-  files=files or {}
-  local noffiles=#files
-  for name in walkdir(path) do
-    if find(name,"^%.") then
-    else
-      local mode=attributes(name,'mode')
-      if mode=="directory" then
-        if recurse then
-          globfiles(path.."/"..name,recurse,func,files)
-        end
-      elseif mode=="file" then
-        if not func or func(name) then
-          noffiles=noffiles+1
-          files[noffiles]=path.."/"..name
-        end
-      end
+ if type(func)=="string" then
+  local s=func
+  func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+  if find(name,"^%.") then
+  else
+   local mode=attributes(name,'mode')
+   if mode=="directory" then
+    if recurse then
+     globfiles(path.."/"..name,recurse,func,files)
     end
+   elseif mode=="file" then
+    if not func or func(name) then
+     noffiles=noffiles+1
+     files[noffiles]=path.."/"..name
+    end
+   end
   end
-  return files
+ end
+ return files
 end
 dir.globfiles=globfiles
 local function globdirs(path,recurse,func,files) 
-  if type(func)=="string" then
-    local s=func
-    func=function(name) return find(name,s) end
-  end
-  files=files or {}
-  local noffiles=#files
-  for name in walkdir(path) do
-    if find(name,"^%.") then
-    else
-      local mode=attributes(name,'mode')
-      if mode=="directory" then
-        if not func or func(name) then
-          noffiles=noffiles+1
-          files[noffiles]=path.."/"..name
-          if recurse then
-            globdirs(path.."/"..name,recurse,func,files)
-          end
-        end
-      end
+ if type(func)=="string" then
+  local s=func
+  func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+  if find(name,"^%.") then
+  else
+   local mode=attributes(name,'mode')
+   if mode=="directory" then
+    if not func or func(name) then
+     noffiles=noffiles+1
+     files[noffiles]=path.."/"..name
+     if recurse then
+      globdirs(path.."/"..name,recurse,func,files)
+     end
     end
+   end
   end
-  return files
+ end
+ return files
 end
 dir.globdirs=globdirs
 function dir.ls(pattern)
-  return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
 end
 local make_indeed=true 
 if onwindows then
-  function dir.mkdirs(...)
-    local n=select("#",...)
-    local str
-    if n==1 then
-      str=select(1,...)
-      if isdir(str) then
-        return str,true
-      end
+ function dir.mkdirs(...)
+  local n=select("#",...)
+  local str
+  if n==1 then
+   str=select(1,...)
+   if isdir(str) then
+    return str,true
+   end
+  else
+   str=""
+   for i=1,n do
+    local s=select(i,...)
+    if s=="" then
+    elseif str=="" then
+     str=s
     else
-      str=""
-      for i=1,n do
-        local s=select(i,...)
-        if s=="" then
-        elseif str=="" then
-          str=s
-        else
-          str=str.."/"..s
-        end
-      end
+     str=str.."/"..s
     end
-    local pth=""
-    local drive=false
-    local first,middle,last=match(str,"^(//)(//*)(.*)$")
+   end
+  end
+  local pth=""
+  local drive=false
+  local first,middle,last=match(str,"^(//)(//*)(.*)$")
+  if first then
+  else
+   first,last=match(str,"^(//)/*(.-)$")
+   if first then
+    middle,last=match(str,"([^/]+)/+(.-)$")
+    if middle then
+     pth="//"..middle
+    else
+     pth="//"..last
+     last=""
+    end
+   else
+    first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
     if first then
+     pth,drive=first..middle,true
     else
-      first,last=match(str,"^(//)/*(.-)$")
-      if first then
-        middle,last=match(str,"([^/]+)/+(.-)$")
-        if middle then
-          pth="//"..middle
-        else
-          pth="//"..last
-          last=""
-        end
-      else
-        first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
-        if first then
-          pth,drive=first..middle,true
-        else
-          middle,last=match(str,"^(/*)(.-)$")
-          if not middle then
-            last=str
-          end
-        end
-      end
+     middle,last=match(str,"^(/*)(.-)$")
+     if not middle then
+      last=str
+     end
     end
-    for s in gmatch(last,"[^/]+") do
-      if pth=="" then
-        pth=s
-      elseif drive then
-        pth,drive=pth..s,false
-      else
-        pth=pth.."/"..s
-      end
-      if make_indeed and not isdir(pth) then
-        mkdir(pth)
-      end
-    end
-    return pth,(isdir(pth)==true)
+   end
   end
+  for s in gmatch(last,"[^/]+") do
+   if pth=="" then
+    pth=s
+   elseif drive then
+    pth,drive=pth..s,false
+   else
+    pth=pth.."/"..s
+   end
+   if make_indeed and not isdir(pth) then
+    mkdir(pth)
+   end
+  end
+  return pth,(isdir(pth)==true)
+ end
 else
-  function dir.mkdirs(...)
-    local n=select("#",...)
-    local str,pth
-    if n==1 then
-      str=select(1,...)
-      if isdir(str) then
-        return str,true
-      end
-    else
-      str=""
-      for i=1,n do
-        local s=select(i,...)
-        if s and s~="" then 
-          if str~="" then
-            str=str.."/"..s
-          else
-            str=s
-          end
-        end
-      end
+ function dir.mkdirs(...)
+  local n=select("#",...)
+  local str,pth
+  if n==1 then
+   str=select(1,...)
+   if isdir(str) then
+    return str,true
+   end
+  else
+   str=""
+   for i=1,n do
+    local s=select(i,...)
+    if s and s~="" then 
+     if str~="" then
+      str=str.."/"..s
+     else
+      str=s
+     end
     end
-    str=gsub(str,"/+","/")
-    if find(str,"^/") then
-      pth="/"
-      for s in gmatch(str,"[^/]+") do
-        local first=(pth=="/")
-        if first then
-          pth=pth..s
-        else
-          pth=pth.."/"..s
-        end
-        if make_indeed and not first and not isdir(pth) then
-          mkdir(pth)
-        end
-      end
+   end
+  end
+  str=gsub(str,"/+","/")
+  if find(str,"^/") then
+   pth="/"
+   for s in gmatch(str,"[^/]+") do
+    local first=(pth=="/")
+    if first then
+     pth=pth..s
     else
-      pth="."
-      for s in gmatch(str,"[^/]+") do
-        pth=pth.."/"..s
-        if make_indeed and not isdir(pth) then
-          mkdir(pth)
-        end
-      end
+     pth=pth.."/"..s
     end
-    return pth,(isdir(pth)==true)
+    if make_indeed and not first and not isdir(pth) then
+     mkdir(pth)
+    end
+   end
+  else
+   pth="."
+   for s in gmatch(str,"[^/]+") do
+    pth=pth.."/"..s
+    if make_indeed and not isdir(pth) then
+     mkdir(pth)
+    end
+   end
   end
+  return pth,(isdir(pth)==true)
+ end
 end
 dir.makedirs=dir.mkdirs
 do
-  local chdir=sandbox and sandbox.original(chdir) or chdir
-  if onwindows then
-    local xcurrentdir=dir.current
-    function dir.expandname(str) 
-      local first,nothing,last=match(str,"^(//)(//*)(.*)$")
-      if first then
-        first=xcurrentdir().."/" 
-      end
-      if not first then
-        first,last=match(str,"^(//)/*(.*)$")
-      end
-      if not first then
-        first,last=match(str,"^([a-zA-Z]:)(.*)$")
-        if first and not find(last,"^/") then
-          local d=currentdir() 
-          if chdir(first) then
-            first=xcurrentdir() 
-          end
-          chdir(d)
-        end
-      end
-      if not first then
-        first,last=xcurrentdir(),str
-      end
-      last=gsub(last,"//","/")
-      last=gsub(last,"/%./","/")
-      last=gsub(last,"^/*","")
-      first=gsub(first,"/*$","")
-      if last=="" or last=="." then
-        return first
-      else
-        return first.."/"..last
-      end
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+  local xcurrentdir=dir.current
+  function dir.expandname(str) 
+   local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+   if first then
+    first=xcurrentdir().."/" 
+   end
+   if not first then
+    first,last=match(str,"^(//)/*(.*)$")
+   end
+   if not first then
+    first,last=match(str,"^([a-zA-Z]:)(.*)$")
+    if first and not find(last,"^/") then
+     local d=currentdir() 
+     if chdir(first) then
+      first=xcurrentdir() 
+     end
+     chdir(d)
     end
-  else
-    function dir.expandname(str) 
-      if not find(str,"^/") then
-        str=currentdir().."/"..str
-      end
-      str=gsub(str,"//","/")
-      str=gsub(str,"/%./","/")
-      str=gsub(str,"(.)/%.$","%1")
-      return str
-    end
+   end
+   if not first then
+    first,last=xcurrentdir(),str
+   end
+   last=gsub(last,"//","/")
+   last=gsub(last,"/%./","/")
+   last=gsub(last,"^/*","")
+   first=gsub(first,"/*$","")
+   if last=="" or last=="." then
+    return first
+   else
+    return first.."/"..last
+   end
   end
+ else
+  function dir.expandname(str) 
+   if not find(str,"^/") then
+    str=currentdir().."/"..str
+   end
+   str=gsub(str,"//","/")
+   str=gsub(str,"/%./","/")
+   str=gsub(str,"(.)/%.$","%1")
+   return str
+  end
+ end
 end
 file.expandname=dir.expandname 
 local stack={}
 function dir.push(newdir)
-  local curdir=currentdir()
-  insert(stack,curdir)
-  if newdir and newdir~="" then
-    chdir(newdir)
-    return newdir
-  else
-    return curdir
-  end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+  chdir(newdir)
+  return newdir
+ else
+  return curdir
+ end
 end
 function dir.pop()
-  local d=remove(stack)
-  if d then
-    chdir(d)
-  end
-  return d
+ local d=remove(stack)
+ if d then
+  chdir(d)
+ end
+ return d
 end
 local function found(...) 
-  for i=1,select("#",...) do
-    local path=select(i,...)
-    local kind=type(path)
-    if kind=="string" then
-      if isdir(path) then
-        return path
-      end
-    elseif kind=="table" then
-      local path=found(unpack(path))
-      if path then
-        return path
-      end
-    end
+ for i=1,select("#",...) do
+  local path=select(i,...)
+  local kind=type(path)
+  if kind=="string" then
+   if isdir(path) then
+    return path
+   end
+  elseif kind=="table" then
+   local path=found(unpack(path))
+   if path then
+    return path
+   end
   end
+ end
 end
 dir.found=found
 
@@ -4549,18 +4548,18 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-unicode']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 utf=utf or {}
 if not string.utfcharacters then
-  local gmatch=string.gmatch
-  function string.characters(str)
-    return gmatch(str,".[\128-\191]*")
-  end
+ local gmatch=string.gmatch
+ function string.characters(str)
+  return gmatch(str,".[\128-\191]*")
+ end
 end
 utf.characters=string.utfcharacters
 local type=type
@@ -4583,304 +4582,304 @@
 local p_newline=patterns.newline
 local p_whitespace=patterns.whitespace
 if not utf.char then
-  utf.char=string.utfcharacter or (utf8 and utf8.char)
-  if not utf.char then
-    local char=string.char
-    if bit32 then
-      local rshift=bit32.rshift
-      function utf.char(n)
-        if n<0x80 then
-          return char(n)
-        elseif n<0x800 then
-          return char(
-            0xC0+rshift(n,6),
-            0x80+(n%0x40)
-          )
-        elseif n<0x10000 then
-          return char(
-            0xE0+rshift(n,12),
-            0x80+(rshift(n,6)%0x40),
-            0x80+(n%0x40)
-          )
-        elseif n<0x200000 then
-          return char(
-            0xF0+rshift(n,18),
-            0x80+(rshift(n,12)%0x40),
-            0x80+(rshift(n,6)%0x40),
-            0x80+(n%0x40)
-          )
-        else
-          return ""
-        end
-      end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+  local char=string.char
+  if bit32 then
+   local rshift=bit32.rshift
+   function utf.char(n)
+    if n<0x80 then
+     return char(n)
+    elseif n<0x800 then
+     return char(
+      0xC0+rshift(n,6),
+      0x80+(n%0x40)
+     )
+    elseif n<0x10000 then
+     return char(
+      0xE0+rshift(n,12),
+      0x80+(rshift(n,6)%0x40),
+      0x80+(n%0x40)
+     )
+    elseif n<0x200000 then
+     return char(
+      0xF0+rshift(n,18),
+      0x80+(rshift(n,12)%0x40),
+      0x80+(rshift(n,6)%0x40),
+      0x80+(n%0x40)
+     )
     else
-      local floor=math.floor
-      function utf.char(n)
-        if n<0x80 then
-          return char(n)
-        elseif n<0x800 then
-          return char(
-            0xC0+floor(n/0x40),
-            0x80+(n%0x40)
-          )
-        elseif n<0x10000 then
-          return char(
-            0xE0+floor(n/0x1000),
-            0x80+(floor(n/0x40)%0x40),
-            0x80+(n%0x40)
-          )
-        elseif n<0x200000 then
-          return char(
-            0xF0+floor(n/0x40000),
-            0x80+(floor(n/0x1000)%0x40),
-            0x80+(floor(n/0x40)%0x40),
-            0x80+(n%0x40)
-          )
-        else
-          return ""
-        end
-      end
+     return ""
     end
+   end
+  else
+   local floor=math.floor
+   function utf.char(n)
+    if n<0x80 then
+     return char(n)
+    elseif n<0x800 then
+     return char(
+      0xC0+floor(n/0x40),
+      0x80+(n%0x40)
+     )
+    elseif n<0x10000 then
+     return char(
+      0xE0+floor(n/0x1000),
+      0x80+(floor(n/0x40)%0x40),
+      0x80+(n%0x40)
+     )
+    elseif n<0x200000 then
+     return char(
+      0xF0+floor(n/0x40000),
+      0x80+(floor(n/0x1000)%0x40),
+      0x80+(floor(n/0x40)%0x40),
+      0x80+(n%0x40)
+     )
+    else
+     return ""
+    end
+   end
   end
+ end
 end
 if not utf.byte then
-  utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
-  if not utf.byte then
-    function utf.byte(c)
-      return lpegmatch(p_utf8byte,c)
-    end
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+  function utf.byte(c)
+   return lpegmatch(p_utf8byte,c)
   end
+ end
 end
 local utfchar,utfbyte=utf.char,utf.byte
 function utf.filetype(data)
-  return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
 end
 local toentities=Cs (
-  (
-    patterns.utf8one+(
-        patterns.utf8two+patterns.utf8three+patterns.utf8four
-      )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
-  )^0
+ (
+  patterns.utf8one+(
+    patterns.utf8two+patterns.utf8three+patterns.utf8four
+   )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
 )
 patterns.toentities=toentities
 function utf.toentities(str)
-  return lpegmatch(toentities,str)
+ return lpegmatch(toentities,str)
 end
 local one=P(1)
 local two=C(1)*C(1)
 local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
 local pattern=P("\254\255")*Cs((
-          four/function(a,b,c,d)
-                local ab=0xFF*byte(a)+byte(b)
-                local cd=0xFF*byte(c)+byte(d)
-                return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
-              end+two/function(a,b)
-                return utfchar(byte(a)*256+byte(b))
-              end+one
-        )^1 )+P("\255\254")*Cs((
-          four/function(b,a,d,c)
-                local ab=0xFF*byte(a)+byte(b)
-                local cd=0xFF*byte(c)+byte(d)
-                return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
-              end+two/function(b,a)
-                return utfchar(byte(a)*256+byte(b))
-              end+one
-        )^1 )
+     four/function(a,b,c,d)
+        local ab=0xFF*byte(a)+byte(b)
+        local cd=0xFF*byte(c)+byte(d)
+        return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+       end+two/function(a,b)
+        return utfchar(byte(a)*256+byte(b))
+       end+one
+    )^1 )+P("\255\254")*Cs((
+     four/function(b,a,d,c)
+        local ab=0xFF*byte(a)+byte(b)
+        local cd=0xFF*byte(c)+byte(d)
+        return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+       end+two/function(b,a)
+        return utfchar(byte(a)*256+byte(b))
+       end+one
+    )^1 )
 function string.toutf(s) 
-  return lpegmatch(pattern,s) or s 
+ return lpegmatch(pattern,s) or s 
 end
 local validatedutf=Cs (
-  (
-    patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
-  )^0
+ (
+  patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
 )
 patterns.validatedutf=validatedutf
 function utf.is_valid(str)
-  return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
 end
 if not utf.len then
-  utf.len=string.utflength or (utf8 and utf8.len)
-  if not utf.len then
-    local n,f=0,1
-    local utfcharcounter=patterns.utfbom^-1*Cmt (
-      Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
-      function(_,t,d) 
-        n=n+(t-f)/d
-        f=t
-        return true
-      end
-    )^0
-    function utf.len(str)
-      n,f=0,1
-      lpegmatch(utfcharcounter,str or "")
-      return n
-    end
+ utf.len=string.utflength or (utf8 and utf8.len)
+ if not utf.len then
+  local n,f=0,1
+  local utfcharcounter=patterns.utfbom^-1*Cmt (
+   Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+   function(_,t,d) 
+    n=n+(t-f)/d
+    f=t
+    return true
+   end
+  )^0
+  function utf.len(str)
+   n,f=0,1
+   lpegmatch(utfcharcounter,str or "")
+   return n
   end
+ end
 end
 utf.length=utf.len
 if not utf.sub then
-  local utflength=utf.length
-  local b,e,n,first,last=0,0,0,0,0
-  local function slide_zero(s,p)
-    n=n+1
-    if n>=last then
-      e=p-1
-    else
-      return p
-    end
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+  n=n+1
+  if n>=last then
+   e=p-1
+  else
+   return p
   end
-  local function slide_one(s,p)
-    n=n+1
-    if n==first then
-      b=p
-    end
-    if n>=last then
-      e=p-1
-    else
-      return p
-    end
+ end
+ local function slide_one(s,p)
+  n=n+1
+  if n==first then
+   b=p
   end
-  local function slide_two(s,p)
-    n=n+1
-    if n==first then
-      b=p
+  if n>=last then
+   e=p-1
+  else
+   return p
+  end
+ end
+ local function slide_two(s,p)
+  n=n+1
+  if n==first then
+   b=p
+  else
+   return true
+  end
+ end
+ local pattern_zero=Cmt(p_utf8character,slide_zero)^0
+ local pattern_one=Cmt(p_utf8character,slide_one )^0
+ local pattern_two=Cmt(p_utf8character,slide_two )^0
+ local pattern_first=C(p_utf8character)
+ function utf.sub(str,start,stop)
+  if not start then
+   return str
+  end
+  if start==0 then
+   start=1
+  end
+  if not stop then
+   if start<0 then
+    local l=utflength(str) 
+    start=l+start
+   else
+    start=start-1
+   end
+   b,n,first=0,0,start
+   lpegmatch(pattern_two,str)
+   if n>=first then
+    return sub(str,b)
+   else
+    return ""
+   end
+  end
+  if start<0 or stop<0 then
+   local l=utf.length(str)
+   if start<0 then
+    start=l+start
+    if start<=0 then
+     start=1
     else
-      return true
+     start=start+1
     end
-  end
-  local pattern_zero=Cmt(p_utf8character,slide_zero)^0
-  local pattern_one=Cmt(p_utf8character,slide_one )^0
-  local pattern_two=Cmt(p_utf8character,slide_two )^0
-  local pattern_first=C(p_utf8character)
-  function utf.sub(str,start,stop)
-    if not start then
-      return str
-    end
-    if start==0 then
-      start=1
-    end
-    if not stop then
-      if start<0 then
-        local l=utflength(str) 
-        start=l+start
-      else
-        start=start-1
-      end
-      b,n,first=0,0,start
-      lpegmatch(pattern_two,str)
-      if n>=first then
-        return sub(str,b)
-      else
-        return ""
-      end
-    end
-    if start<0 or stop<0 then
-      local l=utf.length(str)
-      if start<0 then
-        start=l+start
-        if start<=0 then
-          start=1
-        else
-          start=start+1
-        end
-      end
-      if stop<0 then
-        stop=l+stop
-        if stop==0 then
-          stop=1
-        else
-          stop=stop+1
-        end
-      end
-    end
-    if start==1 and stop==1 then
-      return lpegmatch(pattern_first,str) or ""
-    elseif start>stop then
-      return ""
-    elseif start>1 then
-      b,e,n,first,last=0,0,0,start-1,stop
-      lpegmatch(pattern_one,str)
-      if n>=first and e==0 then
-        e=#str
-      end
-      return sub(str,b,e)
+   end
+   if stop<0 then
+    stop=l+stop
+    if stop==0 then
+     stop=1
     else
-      b,e,n,last=1,0,0,stop
-      lpegmatch(pattern_zero,str)
-      if e==0 then
-        e=#str
-      end
-      return sub(str,b,e)
+     stop=stop+1
     end
+   end
   end
+  if start==1 and stop==1 then
+   return lpegmatch(pattern_first,str) or ""
+  elseif start>stop then
+   return ""
+  elseif start>1 then
+   b,e,n,first,last=0,0,0,start-1,stop
+   lpegmatch(pattern_one,str)
+   if n>=first and e==0 then
+    e=#str
+   end
+   return sub(str,b,e)
+  else
+   b,e,n,last=1,0,0,stop
+   lpegmatch(pattern_zero,str)
+   if e==0 then
+    e=#str
+   end
+   return sub(str,b,e)
+  end
+ end
 end
 function utf.remapper(mapping,option,action) 
-  local variant=type(mapping)
-  if variant=="table" then
-    action=action or mapping
-    if option=="dynamic" then
-      local pattern=false
-      table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
-      return function(str)
-        if not str or str=="" then
-          return ""
-        else
-          if not pattern then
-            pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
-          end
-          return lpegmatch(pattern,str)
-        end
-      end
-    elseif option=="pattern" then
-      return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ local variant=type(mapping)
+ if variant=="table" then
+  action=action or mapping
+  if option=="dynamic" then
+   local pattern=false
+   table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+   return function(str)
+    if not str or str=="" then
+     return ""
     else
-      local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
-      return function(str)
-        if not str or str=="" then
-          return ""
-        else
-          return lpegmatch(pattern,str)
-        end
-      end,pattern
+     if not pattern then
+      pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+     end
+     return lpegmatch(pattern,str)
     end
-  elseif variant=="function" then
-    if option=="pattern" then
-      return Cs((p_utf8character/mapping+p_utf8character)^0)
+   end
+  elseif option=="pattern" then
+   return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+  else
+   local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+   return function(str)
+    if not str or str=="" then
+     return ""
     else
-      local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
-      return function(str)
-        if not str or str=="" then
-          return ""
-        else
-          return lpegmatch(pattern,str)
-        end
-      end,pattern
+     return lpegmatch(pattern,str)
     end
+   end,pattern
+  end
+ elseif variant=="function" then
+  if option=="pattern" then
+   return Cs((p_utf8character/mapping+p_utf8character)^0)
   else
-    return function(str)
-      return str or ""
+   local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+   return function(str)
+    if not str or str=="" then
+     return ""
+    else
+     return lpegmatch(pattern,str)
     end
+   end,pattern
   end
-end
-function utf.replacer(t) 
-  local r=replacer(t,false,false,true)
+ else
   return function(str)
-    return lpegmatch(r,str)
+   return str or ""
   end
+ end
 end
+function utf.replacer(t) 
+ local r=replacer(t,false,false,true)
+ return function(str)
+  return lpegmatch(r,str)
+ end
+end
 function utf.subtituter(t) 
-  local f=finder (t)
-  local r=replacer(t,false,false,true)
-  return function(str)
-    local i=lpegmatch(f,str)
-    if not i then
-      return str
-    elseif i>#str then
-      return str
-    else
-      return lpegmatch(r,str)
-    end
+ local f=finder  (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+  local i=lpegmatch(f,str)
+  if not i then
+   return str
+  elseif i>#str then
+   return str
+  else
+   return lpegmatch(r,str)
   end
+ end
 end
 local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
 local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
@@ -4888,25 +4887,25 @@
 local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
 patterns.utflinesplitter=utflinesplitter
 function utf.splitlines(str)
-  return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
 end
 function utf.split(str,ignorewhitespace) 
-  if ignorewhitespace then
-    return lpegmatch(utfcharsplitter_iws,str or "")
-  else
-    return lpegmatch(utfcharsplitter_ows,str or "")
-  end
+ if ignorewhitespace then
+  return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+  return lpegmatch(utfcharsplitter_ows,str or "")
+ end
 end
 function utf.totable(str) 
-  return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
 end
 function utf.magic(f) 
-  local str=f:read(4) or ""
-  local off=lpegmatch(p_utfoffset,str)
-  if off<4 then
-    f:seek('set',off)
-  end
-  return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+  f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
 end
 local utf16_to_utf8_be,utf16_to_utf8_le
 local utf32_to_utf8_be,utf32_to_utf8_le
@@ -4920,36 +4919,36 @@
 local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
 local more=0
 local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
-  local now=256*byte(left)+byte(right)
-  if more>0 then
-    now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
-    more=0
-    return utfchar(now)
-  elseif now>=0xD800 and now<=0xDBFF then
-    more=now
-    return "" 
-  else
-    return utfchar(now)
-  end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+  now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+  more=0
+  return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+  more=now
+  return "" 
+ else
+  return utfchar(now)
+ end
 end
 local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
-  local now=256*byte(left)+byte(right)
-  if more>0 then
-    now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
-    more=0
-    return utfchar(now)
-  elseif now>=0xD800 and now<=0xDBFF then
-    more=now
-    return "" 
-  else
-    return utfchar(now)
-  end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+  now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+  more=0
+  return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+  more=now
+  return "" 
+ else
+  return utfchar(now)
+ end
 end
 local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
-  return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
 end
 local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
-  return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
 end
 p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
 p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
@@ -4960,88 +4959,88 @@
 patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
 patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
 utf16_to_utf8_be=function(s)
-  if s and s~="" then
-    return lpegmatch(p_utf16_to_utf8_be,s)
-  else
-    return s
-  end
+ if s and s~="" then
+  return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+  return s
+ end
 end
 local utf16_to_utf8_be_t=function(t)
-  if not t then
-    return nil
-  elseif type(t)=="string" then
-    t=lpegmatch(utf_16_be_linesplitter,t)
+ if not t then
+  return nil
+ elseif type(t)=="string" then
+  t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+  local s=t[i]
+  if s~="" then
+   t[i]=lpegmatch(p_utf16_to_utf8_be,s)
   end
-  for i=1,#t do
-    local s=t[i]
-    if s~="" then
-      t[i]=lpegmatch(p_utf16_to_utf8_be,s)
-    end
-  end
-  return t
+ end
+ return t
 end
 utf16_to_utf8_le=function(s)
-  if s and s~="" then
-    return lpegmatch(p_utf16_to_utf8_le,s)
-  else
-    return s
-  end
+ if s and s~="" then
+  return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+  return s
+ end
 end
 local utf16_to_utf8_le_t=function(t)
-  if not t then
-    return nil
-  elseif type(t)=="string" then
-    t=lpegmatch(utf_16_le_linesplitter,t)
+ if not t then
+  return nil
+ elseif type(t)=="string" then
+  t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+  local s=t[i]
+  if s~="" then
+   t[i]=lpegmatch(p_utf16_to_utf8_le,s)
   end
-  for i=1,#t do
-    local s=t[i]
-    if s~="" then
-      t[i]=lpegmatch(p_utf16_to_utf8_le,s)
-    end
-  end
-  return t
+ end
+ return t
 end
 utf32_to_utf8_be=function(s)
-  if s and s~="" then
-    return lpegmatch(p_utf32_to_utf8_be,s)
-  else
-    return s
-  end
+ if s and s~="" then
+  return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+  return s
+ end
 end
 local utf32_to_utf8_be_t=function(t)
-  if not t then
-    return nil
-  elseif type(t)=="string" then
-    t=lpegmatch(utf_32_be_linesplitter,t)
+ if not t then
+  return nil
+ elseif type(t)=="string" then
+  t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+  local s=t[i]
+  if s~="" then
+   t[i]=lpegmatch(p_utf32_to_utf8_be,s)
   end
-  for i=1,#t do
-    local s=t[i]
-    if s~="" then
-      t[i]=lpegmatch(p_utf32_to_utf8_be,s)
-    end
-  end
-  return t
+ end
+ return t
 end
 utf32_to_utf8_le=function(s)
-  if s and s~="" then
-    return lpegmatch(p_utf32_to_utf8_le,s)
-  else
-    return s
-  end
+ if s and s~="" then
+  return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+  return s
+ end
 end
 local utf32_to_utf8_le_t=function(t)
-  if not t then
-    return nil
-  elseif type(t)=="string" then
-    t=lpegmatch(utf_32_le_linesplitter,t)
+ if not t then
+  return nil
+ elseif type(t)=="string" then
+  t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+  local s=t[i]
+  if s~="" then
+   t[i]=lpegmatch(p_utf32_to_utf8_le,s)
   end
-  for i=1,#t do
-    local s=t[i]
-    if s~="" then
-      t[i]=lpegmatch(p_utf32_to_utf8_le,s)
-    end
-  end
-  return t
+ end
+ return t
 end
 utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
 utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5052,225 +5051,225 @@
 utf.utf32_to_utf8_le=utf32_to_utf8_le
 utf.utf32_to_utf8_be=utf32_to_utf8_be
 function utf.utf8_to_utf8_t(t)
-  return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
 end
 function utf.utf16_to_utf8_t(t,endian)
-  return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
 end
 function utf.utf32_to_utf8_t(t,endian)
-  return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
 end
 local function little(b)
-  if b<0x10000 then
-    return char(b%256,rshift(b,8))
-  else
-    b=b-0x10000
-    local b1=rshift(b,10)+0xD800
-    local b2=b%1024+0xDC00
-    return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
-  end
+ if b<0x10000 then
+  return char(b%256,rshift(b,8))
+ else
+  b=b-0x10000
+  local b1=rshift(b,10)+0xD800
+  local b2=b%1024+0xDC00
+  return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
 end
 local function big(b)
-  if b<0x10000 then
-    return char(rshift(b,8),b%256)
-  else
-    b=b-0x10000
-    local b1=rshift(b,10)+0xD800
-    local b2=b%1024+0xDC00
-    return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
-  end
+ if b<0x10000 then
+  return char(rshift(b,8),b%256)
+ else
+  b=b-0x10000
+  local b1=rshift(b,10)+0xD800
+  local b2=b%1024+0xDC00
+  return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
 end
 local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
 local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
 local function utf8_to_utf16_be(str,nobom)
-  if nobom then
-    return lpegmatch(b_remap,str)
-  else
-    return char(254,255)..lpegmatch(b_remap,str)
-  end
+ if nobom then
+  return lpegmatch(b_remap,str)
+ else
+  return char(254,255)..lpegmatch(b_remap,str)
+ end
 end
 local function utf8_to_utf16_le(str,nobom)
-  if nobom then
-    return lpegmatch(l_remap,str)
-  else
-    return char(255,254)..lpegmatch(l_remap,str)
-  end
+ if nobom then
+  return lpegmatch(l_remap,str)
+ else
+  return char(255,254)..lpegmatch(l_remap,str)
+ end
 end
 utf.utf8_to_utf16_be=utf8_to_utf16_be
 utf.utf8_to_utf16_le=utf8_to_utf16_le
 function utf.utf8_to_utf16(str,littleendian,nobom)
-  if littleendian then
-    return utf8_to_utf16_le(str,nobom)
-  else
-    return utf8_to_utf16_be(str,nobom)
-  end
+ if littleendian then
+  return utf8_to_utf16_le(str,nobom)
+ else
+  return utf8_to_utf16_be(str,nobom)
+ end
 end
 local pattern=Cs (
-  (p_utf8byte/function(unicode     ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+ (p_utf8byte/function(unicode    ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
 )
 function utf.tocodes(str,separator)
-  return lpegmatch(pattern,str,1,separator or " ")
+ return lpegmatch(pattern,str,1,separator or " ")
 end
 function utf.ustring(s)
-  return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
 end
 function utf.xstring(s)
-  return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
 end
 function utf.toeight(str)
-  if not str or str=="" then
-    return nil
-  end
-  local utftype=lpegmatch(p_utfstricttype,str)
-  if utftype=="utf-8" then
-    return sub(str,4)        
-  elseif utftype=="utf-16-be" then
-    return utf16_to_utf8_be(str)  
-  elseif utftype=="utf-16-le" then
-    return utf16_to_utf8_le(str)  
-  else
-    return str
-  end
+ if not str or str=="" then
+  return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+  return sub(str,4)      
+ elseif utftype=="utf-16-be" then
+  return utf16_to_utf8_be(str) 
+ elseif utftype=="utf-16-le" then
+  return utf16_to_utf8_le(str) 
+ else
+  return str
+ end
 end
 do
-  local p_nany=p_utf8character/""
-  local cache={}
-  function utf.count(str,what)
-    if type(what)=="string" then
-      local p=cache[what]
-      if not p then
-        p=Cs((P(what)/" "+p_nany)^0)
-        cache[p]=p
-      end
-      return #lpegmatch(p,str)
-    else 
-      return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
-    end
+ local p_nany=p_utf8character/""
+ local cache={}
+ function utf.count(str,what)
+  if type(what)=="string" then
+   local p=cache[what]
+   if not p then
+    p=Cs((P(what)/" "+p_nany)^0)
+    cache[p]=p
+   end
+   return #lpegmatch(p,str)
+  else 
+   return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
   end
+ end
 end
 if not string.utfvalues then
-  local find=string.find
-  local dummy=function()
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(str)
+  local n=#str
+  if n==0 then
+   return dummy
+  elseif n==1 then
+   return function() return utfbyte(str) end
+  else
+   local p=1
+   return function()
+     local b,e=find(str,".[\128-\191]*",p)
+     if b then
+      p=e+1
+      return utfbyte(sub(str,b,e))
+     end
+   end
   end
-  function string.utfvalues(str)
-    local n=#str
-    if n==0 then
-      return dummy
-    elseif n==1 then
-      return function() return utfbyte(str) end
-    else
-      local p=1
-      return function()
-          local b,e=find(str,".[\128-\191]*",p)
-          if b then
-            p=e+1
-            return utfbyte(sub(str,b,e))
-          end
-      end
-    end
-  end
+ end
 end
 utf.values=string.utfvalues
 function utf.chrlen(u) 
-  return
-    (u<0x80 and 1) or
-    (u<0xE0 and 2) or
-    (u<0xF0 and 3) or
-    (u<0xF8 and 4) or
-    (u<0xFC and 5) or
-    (u<0xFE and 6) or 0
+ return
+  (u<0x80 and 1) or
+  (u<0xE0 and 2) or
+  (u<0xF0 and 3) or
+  (u<0xF8 and 4) or
+  (u<0xFC and 5) or
+  (u<0xFE and 6) or 0
 end
 if bit32 then
-  local extract=bit32.extract
-  local char=string.char
-  function utf.toutf32string(n)
-    if n<=0xFF then
-      return
-        char(n).."\000\000\000"
-    elseif n<=0xFFFF then
-      return
-        char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
-    elseif n<=0xFFFFFF then
-      return
-        char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
-    else
-      return
-        char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
-    end
+ local extract=bit32.extract
+ local char=string.char
+ function utf.toutf32string(n)
+  if n<=0xFF then
+   return
+    char(n).."\000\000\000"
+  elseif n<=0xFFFF then
+   return
+    char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+  elseif n<=0xFFFFFF then
+   return
+    char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+  else
+   return
+    char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
   end
+ end
 end
 local len=utf.len
 local rep=rep
 function string.utfpadd(s,n)
-  if n and n~=0 then
-    local l=len(s)
-    if n>0 then
-      local d=n-l
-      if d>0 then
-        return rep(c or " ",d)..s
-      end
-    else
-      local d=- n-l
-      if d>0 then
-        return s..rep(c or " ",d)
-      end
-    end
+ if n and n~=0 then
+  local l=len(s)
+  if n>0 then
+   local d=n-l
+   if d>0 then
+    return rep(c or " ",d)..s
+   end
+  else
+   local d=- n-l
+   if d>0 then
+    return s..rep(c or " ",d)
+   end
   end
-  return s
+ end
+ return s
 end
 do
-  local utfcharacters=utf.characters or string.utfcharacters
-  local utfchar=utf.char    or string.utfcharacter
-  lpeg.UP=P
-  if utfcharacters then
-    function lpeg.US(str)
-      local p=P(false)
-      for uc in utfcharacters(str) do
-        p=p+P(uc)
-      end
-      return p
-    end
+ local utfcharacters=utf.characters or string.utfcharacters
+ local utfchar=utf.char    or string.utfcharacter
+ lpeg.UP=P
+ if utfcharacters then
+  function lpeg.US(str)
+   local p=P(false)
+   for uc in utfcharacters(str) do
+    p=p+P(uc)
+   end
+   return p
+  end
+ else
+  function lpeg.US(str)
+   local p=P(false)
+   local f=function(uc)
+    p=p+P(uc)
+   end
+   lpegmatch((p_utf8char/f)^0,str)
+   return p
+  end
+ end
+ local range=p_utf8byte*p_utf8byte+Cc(false) 
+ function lpeg.UR(str,more)
+  local first,last
+  if type(str)=="number" then
+   first=str
+   last=more or first
   else
-    function lpeg.US(str)
-      local p=P(false)
-      local f=function(uc)
-        p=p+P(uc)
-      end
-      lpegmatch((p_utf8char/f)^0,str)
-      return p
-    end
+   first,last=lpegmatch(range,str)
+   if not last then
+    return P(str)
+   end
   end
-  local range=p_utf8byte*p_utf8byte+Cc(false) 
-  function lpeg.UR(str,more)
-    local first,last
-    if type(str)=="number" then
-      first=str
-      last=more or first
-    else
-      first,last=lpegmatch(range,str)
-      if not last then
-        return P(str)
-      end
-    end
-    if first==last then
-      return P(str)
-    end
-    if not utfchar then
-      utfchar=utf.char 
-    end
-    if utfchar and (last-first<8) then 
-      local p=P(false)
-      for i=first,last do
-        p=p+P(utfchar(i))
-      end
-      return p 
-    else
-      local f=function(b)
-        return b>=first and b<=last
-      end
-      return p_utf8byte/f 
-    end
+  if first==last then
+   return P(str)
   end
+  if not utfchar then
+   utfchar=utf.char 
+  end
+  if utfchar and (last-first<8) then 
+   local p=P(false)
+   for i=first,last do
+    p=p+P(utfchar(i))
+   end
+   return p 
+  else
+   local f=function(b)
+    return b>=first and b<=last
+   end
+   return p_utf8byte/f 
+  end
+ end
 end
 
 end -- closure
@@ -5278,11 +5277,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-url']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local char,format,byte=string.char,string.format,string.byte
 local concat=table.concat
@@ -5295,14 +5294,14 @@
 local unescapes={}
 local escapes={}
 setmetatable(unescapes,{ __index=function(t,k)
-  local v=char(tonumber(k,16))
-  t[k]=v
-  return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
 end })
 setmetatable(escapes,{ __index=function(t,k)
-  local v=format("%%%02X",byte(k))
-  t[k]=v
-  return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
 end })
 local colon=P(":")
 local qmark=P("?")
@@ -5321,21 +5320,21 @@
 local noslash=P("/")/""
 local plustospace=P("+")/" "
 local decoder=Cs((
-          plustospace+escapedchar+P("\r\n")/"\n"+P(1)
-        )^0 )
+     plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+    )^0 )
 local encoder=Cs((
-          R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
-        )^0 )
+     R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+    )^0 )
 lpegpatterns.urldecoder=decoder
 lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode  (str) return str and lpegmatch(decoder,str) or str end
+function url.encode  (str) return str and lpegmatch(encoder,str) or str end
 function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
 local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
 local authoritystr=Cs((escaped+(1-   slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1-      qmark-hash))^0)
-local querystr=Cs(((1-         hash))^0)
-local fragmentstr=Cs((escaped+(1-      endofstring))^0)
+local pathstr=Cs((escaped+(1-   qmark-hash))^0)
+local querystr=Cs(((1-      hash))^0)
+local fragmentstr=Cs((escaped+(1-     endofstring))^0)
 local scheme=schemestr*colon+nothing
 local authority=slash*slash*authoritystr+nothing
 local path=slash*pathstr+nothing
@@ -5353,19 +5352,19 @@
 lpegpatterns.urlunescaper=unescaper
 lpegpatterns.urlgetcleaner=getcleaner
 function url.unescapeget(str)
-  return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
 end
 local function split(str)
-  return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
 end
 local isscheme=schemestr*colon*slash*slash 
 local function hasscheme(str)
-  if str then
-    local scheme=lpegmatch(isscheme,str) 
-    return scheme~="" and scheme or false
-  else
-    return false
-  end
+ if str then
+  local scheme=lpegmatch(isscheme,str) 
+  return scheme~="" and scheme or false
+ else
+  return false
+ end
 end
 local rootletter=R("az","AZ")+S("_-+")
 local separator=P("://")
@@ -5375,161 +5374,161 @@
 local backslashswapper=replacer("\\","/")
 local equal=P("=")
 local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal       )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal     )^0)
 local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
 local splitquery=Cf (Ct("")*P { "sequence",
-  sequence=V("pair")*(amp*V("pair"))^0,
-  pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
 },rawset)
 local userpart=(1-atsign-colon)^1
 local serverpart=(1-colon)^1
 local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
 local function hashed(str) 
-  if not str or str=="" then
-    return {
-      scheme="invalid",
-      original=str,
-    }
-  end
-  local detailed=split(str)
-  local rawscheme=""
-  local rawquery=""
-  local somescheme=false
-  local somequery=false
-  if detailed then
-    rawscheme=detailed[1]
-    rawquery=detailed[4]
-    somescheme=rawscheme~=""
-    somequery=rawquery~=""
-  end
-  if not somescheme and not somequery then
-    return {
-      scheme="file",
-      authority="",
-      path=str,
-      query="",
-      fragment="",
-      original=str,
-      noscheme=true,
-      filename=str,
-    }
-  end
-  local authority=detailed[2]
-  local path=detailed[3]
-  local filename 
-  local username 
-  local password 
-  local host   
-  local port   
-  if authority~="" then
-    username,password,host,port=lpegmatch(splitauthority,authority)
-  end
-  if authority=="" then
-    filename=path
-  elseif path=="" then
-    filename=""
-  else
-    filename=authority.."/"..path
-  end
+ if not str or str=="" then
   return {
-    scheme=rawscheme,
-    authority=authority,
-    path=path,
-    query=lpegmatch(unescaper,rawquery),
-    queries=lpegmatch(splitquery,rawquery),
-    fragment=detailed[5],
-    original=str,
-    noscheme=false,
-    filename=filename,
-    host=host,
-    port=port,
+   scheme="invalid",
+   original=str,
   }
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+  rawscheme=detailed[1]
+  rawquery=detailed[4]
+  somescheme=rawscheme~=""
+  somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+  return {
+   scheme="file",
+   authority="",
+   path=str,
+   query="",
+   fragment="",
+   original=str,
+   noscheme=true,
+   filename=str,
+  }
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename  
+ local username  
+ local password  
+ local host   
+ local port   
+ if authority~="" then
+  username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+  filename=path
+ elseif path=="" then
+  filename=""
+ else
+  filename=authority.."/"..path
+ end
+ return {
+  scheme=rawscheme,
+  authority=authority,
+  path=path,
+  query=lpegmatch(unescaper,rawquery),
+  queries=lpegmatch(splitquery,rawquery),
+  fragment=detailed[5],
+  original=str,
+  noscheme=false,
+  filename=filename,
+  host=host,
+  port=port,
+ }
 end
 url.split=split
 url.hasscheme=hasscheme
 url.hashed=hashed
 function url.addscheme(str,scheme) 
-  if hasscheme(str) then
-    return str
-  elseif not scheme then
-    return "file:///"..str
-  else
-    return scheme..":///"..str
-  end
+ if hasscheme(str) then
+  return str
+ elseif not scheme then
+  return "file:///"..str
+ else
+  return scheme..":///"..str
+ end
 end
 function url.construct(hash) 
-  local result,r={},0
-  local scheme=hash.scheme
-  local authority=hash.authority
-  local path=hash.path
-  local queries=hash.queries
-  local fragment=hash.fragment
-  if scheme and scheme~="" then
-    r=r+1;result[r]=lpegmatch(escaper,scheme)
-    r=r+1;result[r]="://"
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+  r=r+1;result[r]=lpegmatch(escaper,scheme)
+  r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+  r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+  r=r+1;result[r]="/"
+  r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+  local done=false
+  for k,v in sortedhash(queries) do
+   r=r+1;result[r]=done and "&" or "?"
+   r=r+1;result[r]=lpegmatch(escaper,k) 
+   r=r+1;result[r]="="
+   r=r+1;result[r]=lpegmatch(escaper,v) 
+   done=true
   end
-  if authority and authority~="" then
-    r=r+1;result[r]=lpegmatch(escaper,authority)
-  end
-  if path and path~="" then
-    r=r+1;result[r]="/"
-    r=r+1;result[r]=lpegmatch(escaper,path)
-  end
-  if queries then
-    local done=false
-    for k,v in sortedhash(queries) do
-      r=r+1;result[r]=done and "&" or "?"
-      r=r+1;result[r]=lpegmatch(escaper,k) 
-      r=r+1;result[r]="="
-      r=r+1;result[r]=lpegmatch(escaper,v) 
-      done=true
-    end
-  end
-  if fragment and fragment~="" then
-    r=r+1;result[r]="#"
-    r=r+1;result[r]=lpegmatch(escaper,fragment)
-  end
-  return concat(result)
+ end
+ if fragment and fragment~="" then
+  r=r+1;result[r]="#"
+  r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
 end
 local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
 function url.filename(filename)
-  local spec=hashed(filename)
-  local path=spec.path
-  return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
 end
 local function escapestring(str)
-  return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
 end
 url.escape=escapestring
 function url.query(str)
-  if type(str)=="string" then
-    return lpegmatch(splitquery,str) or ""
-  else
-    return str
-  end
+ if type(str)=="string" then
+  return lpegmatch(splitquery,str) or ""
+ else
+  return str
+ end
 end
 function url.toquery(data)
-  local td=type(data)
-  if td=="string" then
-    return #str and escape(data) or nil 
-  elseif td=="table" then
-    if next(data) then
-      local t={}
-      for k,v in next,data do
-        t[#t+1]=format("%s=%s",k,escapestring(v))
-      end
-      return concat(t,"&")
-    end
-  else
+ local td=type(data)
+ if td=="string" then
+  return #str and escape(data) or nil 
+ elseif td=="table" then
+  if next(data) then
+   local t={}
+   for k,v in next,data do
+    t[#t+1]=format("%s=%s",k,escapestring(v))
+   end
+   return concat(t,"&")
   end
+ else
+ end
 end
 local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
 function url.barepath(path)
-  if not path or path=="" then
-    return ""
-  else
-    return lpegmatch(pattern,path)
-  end
+ if not path or path=="" then
+  return ""
+ else
+  return lpegmatch(pattern,path)
+ end
 end
 
 end -- closure
@@ -5537,11 +5536,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['l-set']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 set=set or {}
 local nums={}
@@ -5550,54 +5549,54 @@
 local next,type=next,type
 set.create=table.tohash
 function set.tonumber(t)
-  if next(t) then
-    local s=""
-    for k,v in next,t do
-      if v then
-        s=s.." "..k
-      end
-    end
-    local n=nums[s]
-    if not n then
-      n=#tabs+1
-      tabs[n]=t
-      nums[s]=n
-    end
-    return n
-  else
-    return 0
+ if next(t) then
+  local s=""
+  for k,v in next,t do
+   if v then
+    s=s.." "..k
+   end
   end
+  local n=nums[s]
+  if not n then
+   n=#tabs+1
+   tabs[n]=t
+   nums[s]=n
+  end
+  return n
+ else
+  return 0
+ end
 end
 function set.totable(n)
-  if n==0 then
-    return {}
-  else
-    return tabs[n] or {}
-  end
+ if n==0 then
+  return {}
+ else
+  return tabs[n] or {}
+ end
 end
 function set.tolist(n)
-  if n==0 or not tabs[n] then
-    return ""
-  else
-    local t,n={},0
-    for k,v in next,tabs[n] do
-      if v then
-        n=n+1
-        t[n]=k
-      end
-    end
-    return concat(t," ")
+ if n==0 or not tabs[n] then
+  return ""
+ else
+  local t,n={},0
+  for k,v in next,tabs[n] do
+   if v then
+    n=n+1
+    t[n]=k
+   end
   end
+  return concat(t," ")
+ end
 end
 function set.contains(n,s)
-  if type(n)=="table" then
-    return n[s]
-  elseif n==0 then
-    return false
-  else
-    local t=tabs[n]
-    return t and t[s]
-  end
+ if type(n)=="table" then
+  return n[s]
+ elseif n==0 then
+  return false
+ else
+  local t=tabs[n]
+  return t and t[s]
+ end
 end
 
 end -- closure

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -29,8 +29,8 @@
 
 local lualibs_basic_module = {
   name          = "lualibs-basic",
-  version       = 2.62,
-  date          = "2018-12-19",
+  version       = 2.63,
+  date          = "2019-01-28",
   description   = "ConTeXt Lua libraries -- basic collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -1,15 +1,15 @@
 -- merged file : lualibs-extended-merged.lua
 -- parent file : lualibs-extended.lua
--- merge date  : Tue Dec 25 16:21:26 2018
+-- merge date  : Wed Jan 30 23:25:40 2019
 
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-str']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 utilities=utilities or {}
 utilities.strings=utilities.strings or {}
@@ -22,20 +22,12 @@
 local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
 local patterns,lpegmatch=lpeg.patterns,lpeg.match
 local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
-local loadstripped=nil
-local oldfashioned=LUAVERSION<5.2
-if oldfashioned then
-  loadstripped=function(str,shortcuts)
-    return load(str)
-  end
-else
-  loadstripped=function(str,shortcuts)
-    if shortcuts then
-      return load(dump(load(str),true),nil,nil,shortcuts)
-    else
-      return load(dump(load(str),true))
-    end
-  end
+local loadstripped=function(str,shortcuts)
+ if shortcuts then
+  return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+  return load(dump(load(str),true))
+ end
 end
 if not number then number={} end 
 local stripzero=patterns.stripzero
@@ -53,32 +45,32 @@
 local ptf=1/65536
 local bpf=(7200/7227)/65536
 local function points(n)
-  if n==0 then
-    return "0pt"
-  end
-  n=tonumber(n)
-  if not n or n==0 then
-    return "0pt"
-  end
-  n=n*ptf
-  if n%1==0 then
-    return format("%ipt",n)
-  end
-  return lpegmatch(stripzeros,format("%.5fpt",n)) 
+ if n==0 then
+  return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+  return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+  return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n)) 
 end
 local function basepoints(n)
-  if n==0 then
-    return "0pt"
-  end
-  n=tonumber(n)
-  if not n or n==0 then
-    return "0pt"
-  end
-  n=n*bpf
-  if n%1==0 then
-    return format("%ibp",n)
-  end
-  return lpegmatch(stripzeros,format("%.5fbp",n)) 
+ if n==0 then
+  return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+  return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+  return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n)) 
 end
 number.points=points
 number.basepoints=basepoints
@@ -90,65 +82,65 @@
 local redundant=rubish^3/"\n"
 local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
 function strings.collapsecrlf(str)
-  return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
 end
 local repeaters={} 
 function strings.newrepeater(str,offset)
-  offset=offset or 0
-  local s=repeaters[str]
-  if not s then
-    s={}
-    repeaters[str]=s
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+  s={}
+  repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
+  return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+  if not k then
+   return ""
   end
-  local t=s[offset]
-  if t then
-    return t
-  end
-  t={}
-  setmetatable(t,{ __index=function(t,k)
-    if not k then
-      return ""
-    end
-    local n=k+offset
-    local s=n>0 and rep(str,n) or ""
-    t[k]=s
-    return s
-  end })
-  s[offset]=t
-  return t
+  local n=k+offset
+  local s=n>0 and rep(str,n) or ""
+  t[k]=s
+  return s
+ end })
+ s[offset]=t
+ return t
 end
 local extra,tab,start=0,0,4,0
 local nspaces=strings.newrepeater(" ")
 string.nspaces=nspaces
 local pattern=Carg(1)/function(t)
-    extra,tab,start=0,t or 7,1
-  end*Cs((
+  extra,tab,start=0,t or 7,1
+ end*Cs((
    Cp()*patterns.tab/function(position)
-     local current=(position-start+1)+extra
-     local spaces=tab-(current-1)%tab
-     if spaces>0 then
-       extra=extra+spaces-1
-       return nspaces[spaces] 
-     else
-       return ""
-     end
+    local current=(position-start+1)+extra
+    local spaces=tab-(current-1)%tab
+    if spaces>0 then
+     extra=extra+spaces-1
+     return nspaces[spaces] 
+    else
+     return ""
+    end
    end+newline*Cp()/function(position)
-     extra,start=0,position
+    extra,start=0,position
    end+anything
- )^1)
+  )^1)
 function strings.tabtospace(str,tab)
-  return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
 end
 function string.utfpadding(s,n)
-  if not n or n==0 then
-    return ""
-  end
-  local l=utflen(s)
-  if n>0 then
-    return nspaces[n-l]
-  else
-    return nspaces[-n-l]
-  end
+ if not n or n==0 then
+  return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+  return nspaces[n-l]
+ else
+  return nspaces[-n-l]
+ end
 end
 local optionalspace=spacer^0
 local nospace=optionalspace/""
@@ -166,130 +158,130 @@
 local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
 local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
 local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1      )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1     )^0 )
 local p_retain_normal=Cs ((normalline+normalempty )^0 )
 local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
 local p_retain_noempty=Cs ((normalline+singleempty )^0 )
 local striplinepatterns={
-  ["prune"]=p_prune_normal,
-  ["prune and collapse"]=p_prune_collapse,
-  ["prune and no empty"]=p_prune_noempty,
-  ["prune and to space"]=p_prune_intospace,
-  ["retain"]=p_retain_normal,
-  ["retain and collapse"]=p_retain_collapse,
-  ["retain and no empty"]=p_retain_noempty,
-  ["collapse"]=patterns.collapser,
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
 }
 setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
 strings.striplinepatterns=striplinepatterns
 function strings.striplines(str,how)
-  return str and lpegmatch(striplinepatterns[how],str) or str
+ return str and lpegmatch(striplinepatterns[how],str) or str
 end
 function strings.collapse(str) 
-  return str and lpegmatch(p_prune_intospace,str) or str
+ return str and lpegmatch(p_prune_intospace,str) or str
 end
 strings.striplong=strings.striplines
 function strings.nice(str)
-  str=gsub(str,"[:%-+_]+"," ") 
-  return str
+ str=gsub(str,"[:%-+_]+"," ") 
+ return str
 end
 local n=0
 local sequenced=table.sequenced
 function string.autodouble(s,sep)
-  if s==nil then
-    return '""'
-  end
-  local t=type(s)
-  if t=="number" then
-    return tostring(s) 
-  end
-  if t=="table" then
-    return ('"'..sequenced(s,sep or ",")..'"')
-  end
-  return ('"'..tostring(s)..'"')
+ if s==nil then
+  return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+  return tostring(s) 
+ end
+ if t=="table" then
+  return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
 end
 function string.autosingle(s,sep)
-  if s==nil then
-    return "''"
-  end
-  local t=type(s)
-  if t=="number" then
-    return tostring(s) 
-  end
-  if t=="table" then
-    return ("'"..sequenced(s,sep or ",").."'")
-  end
-  return ("'"..tostring(s).."'")
+ if s==nil then
+  return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+  return tostring(s) 
+ end
+ if t=="table" then
+  return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
 end
 local tracedchars={ [0]=
-  "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
-  "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
-  "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
-  "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
-  "[space]",
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
 }
 string.tracedchars=tracedchars
 strings.tracers=tracedchars
 function string.tracedchar(b)
-  if type(b)=="number" then
-    return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
-  else
-    local c=utfbyte(b)
-    return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
-  end
+ if type(b)=="number" then
+  return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+  local c=utfbyte(b)
+  return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
 end
 function number.signed(i)
-  if i>0 then
-    return "+",i
-  else
-    return "-",-i
-  end
+ if i>0 then
+  return "+",i
+ else
+  return "-",-i
+ end
 end
 local two=digit*digit
 local three=two*digit
 local prefix=(Carg(1)*three)^1
 local splitter=Cs (
-  (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
 )
 local splitter3=Cs (
-  three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
 )
 patterns.formattednumber=splitter
 function number.formatted(n,sep1,sep2)
-  if sep1==false then
-    if type(n)=="number" then
-      n=tostring(n)
-    end
-    return lpegmatch(splitter3,n,1,sep2 or ".")
+ if sep1==false then
+  if type(n)=="number" then
+   n=tostring(n)
+  end
+  return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+  if type(n)=="number" then
+   n=format("%0.2f",n)
+  end
+  if sep1==true then
+   return lpegmatch(splitter,n,1,".",",")
+  elseif sep1=="." then
+   return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+  elseif sep1=="," then
+   return lpegmatch(splitter,n,1,sep1,sep2 or ".")
   else
-    if type(n)=="number" then
-      n=format("%0.2f",n)
-    end
-    if sep1==true then
-      return lpegmatch(splitter,n,1,".",",")
-    elseif sep1=="." then
-      return lpegmatch(splitter,n,1,sep1,sep2 or ",")
-    elseif sep1=="," then
-      return lpegmatch(splitter,n,1,sep1,sep2 or ".")
-    else
-      return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
-    end
+   return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
   end
+ end
 end
 local p=Cs(
-    P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
-  )
+  P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
 function number.compactfloat(n,fmt)
-  if n==0 then
-    return "0"
-  elseif n==1 then
-    return "1"
-  end
-  n=lpegmatch(p,format(fmt or "%0.3f",n))
-  if n=="." or n=="" or n=="-" then
-    return "0"
-  end
-  return n
+ if n==0 then
+  return "0"
+ elseif n==1 then
+  return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+  return "0"
+ end
+ return n
 end
 local zero=P("0")^1/""
 local plus=P("+")/""
@@ -300,41 +292,41 @@
 local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
 local pattern_b=Cs((exponent+anything)^0)
 function number.sparseexponent(f,n)
-  if not n then
-    n=f
-    f="%e"
+ if not n then
+  n=f
+  f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then 
+  local m=tonumber(n)
+  if m then
+   return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
   end
-  local tn=type(n)
-  if tn=="string" then 
-    local m=tonumber(n)
-    if m then
-      return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
-    end
-  elseif tn=="number" then
-    return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
-  end
-  return tostring(n)
+ elseif tn=="number" then
+  return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
 end
 local hf={}
 local hs={}
 setmetatable(hf,{ __index=function(t,k)
-  local v="%."..k.."f"
-  t[k]=v
-  return v
+ local v="%."..k.."f"
+ t[k]=v
+ return v
 end } )
 setmetatable(hs,{ __index=function(t,k)
-  local v="%"..k.."s"
-  t[k]=v
-  return v
+ local v="%"..k.."s"
+ t[k]=v
+ return v
 end } )
 function number.formattedfloat(n,b,a)
-  local s=format(hf[a],n)
-  local l=(b or 0)+(a or 0)+1
-  if #s<l then
-    return format(hs[l],s)
-  else
-    return s
-  end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+  return format(hs[l],s)
+ else
+  return s
+ end
 end
 local template=[[
 %s
@@ -341,367 +333,341 @@
 %s
 return function(%s) return %s end
 ]]
-local preamble,environment="",{}
-if oldfashioned then
-  preamble=[[
-local lpeg=lpeg
-local type=type
-local tostring=tostring
-local tonumber=tonumber
-local format=string.format
-local concat=table.concat
-local signed=number.signed
-local points=number.points
-local basepoints= number.basepoints
-local utfchar=utf.char
-local utfbyte=utf.byte
-local lpegmatch=lpeg.match
-local nspaces=string.nspaces
-local utfpadding=string.utfpadding
-local tracedchar=string.tracedchar
-local autosingle=string.autosingle
-local autodouble=string.autodouble
-local sequenced=table.sequenced
-local formattednumber=number.formatted
-local sparseexponent=number.sparseexponent
-local formattedfloat=number.formattedfloat
-local stripzero=lpeg.patterns.stripzero
-local stripzeros=lpeg.patterns.stripzeros
-    ]]
-else
-  environment={
-    global=global or _G,
-    lpeg=lpeg,
-    type=type,
-    tostring=tostring,
-    tonumber=tonumber,
-    format=string.format,
-    concat=table.concat,
-    signed=number.signed,
-    points=number.points,
-    basepoints=number.basepoints,
-    utfchar=utf.char,
-    utfbyte=utf.byte,
-    lpegmatch=lpeg.match,
-    nspaces=string.nspaces,
-    utfpadding=string.utfpadding,
-    tracedchar=string.tracedchar,
-    autosingle=string.autosingle,
-    autodouble=string.autodouble,
-    sequenced=table.sequenced,
-    formattednumber=number.formatted,
-    sparseexponent=number.sparseexponent,
-    formattedfloat=number.formattedfloat,
-    stripzero=lpeg.patterns.stripzero,
-    stripzeros=lpeg.patterns.stripzeros,
-  }
-end
+local preamble=""
+local environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=lpeg.patterns.stripzero,
+ stripzeros=lpeg.patterns.stripzeros,
+}
 local arguments={ "a1" } 
 setmetatable(arguments,{ __index=function(t,k)
-    local v=t[k-1]..",a"..k
-    t[k]=v
-    return v
-  end
+  local v=t[k-1]..",a"..k
+  t[k]=v
+  return v
+ end
 })
 local prefix_any=C((sign+space+period+digit)^0)
 local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
 local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
 local format_s=function(f)
-  n=n+1
-  if f and f~="" then
-    return format("format('%%%ss',a%s)",f,n)
-  else 
-    return format("(a%s or '')",n) 
-  end
+ n=n+1
+ if f and f~="" then
+  return format("format('%%%ss',a%s)",f,n)
+ else 
+  return format("(a%s or '')",n) 
+ end
 end
 local format_S=function(f) 
-  n=n+1
-  if f and f~="" then
-    return format("format('%%%ss',tostring(a%s))",f,n)
-  else
-    return format("tostring(a%s)",n)
-  end
+ n=n+1
+ if f and f~="" then
+  return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+  return format("tostring(a%s)",n)
+ end
 end
 local format_right=function(f)
-  n=n+1
-  f=tonumber(f)
-  if not f or f==0 then
-    return format("(a%s or '')",n)
-  elseif f>0 then
-    return format("utfpadding(a%s,%i)..a%s",n,f,n)
-  else
-    return format("a%s..utfpadding(a%s,%i)",n,n,f)
-  end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+  return format("(a%s or '')",n)
+ elseif f>0 then
+  return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+  return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
 end
 local format_left=function(f)
-  n=n+1
-  f=tonumber(f)
-  if not f or f==0 then
-    return format("(a%s or '')",n)
-  end
-  if f<0 then
-    return format("utfpadding(a%s,%i)..a%s",n,-f,n)
-  else
-    return format("a%s..utfpadding(a%s,%i)",n,n,-f)
-  end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+  return format("(a%s or '')",n)
+ end
+ if f<0 then
+  return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+  return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
 end
 local format_q=function()
-  n=n+1
-  return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
 end
 local format_Q=function() 
-  n=n+1
-  return format("format('%%q',tostring(a%s))",n)
+ n=n+1
+ return format("format('%%q',tostring(a%s))",n)
 end
 local format_i=function(f)
-  n=n+1
-  if f and f~="" then
-    return format("format('%%%si',a%s)",f,n)
-  else
-    return format("format('%%i',a%s)",n) 
-  end
+ n=n+1
+ if f and f~="" then
+  return format("format('%%%si',a%s)",f,n)
+ else
+  return format("format('%%i',a%s)",n) 
+ end
 end
 local format_d=format_i
 local format_I=function(f)
-  n=n+1
-  return format("format('%%s%%%si',signed(a%s))",f,n)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
 end
 local format_f=function(f)
-  n=n+1
-  return format("format('%%%sf',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
 end
 local format_F=function(f) 
-  n=n+1
-  if not f or f=="" then
-    return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
-  else
-    return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
-  end
+ n=n+1
+ if not f or f=="" then
+  return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+  return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
 end
 local format_k=function(b,a) 
-  n=n+1
-  return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
 end
 local format_g=function(f)
-  n=n+1
-  return format("format('%%%sg',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
 end
 local format_G=function(f)
-  n=n+1
-  return format("format('%%%sG',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
 end
 local format_e=function(f)
-  n=n+1
-  return format("format('%%%se',a%s)",f,n)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
 end
 local format_E=function(f)
-  n=n+1
-  return format("format('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
 end
 local format_j=function(f)
-  n=n+1
-  return format("sparseexponent('%%%se',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
 end
 local format_J=function(f)
-  n=n+1
-  return format("sparseexponent('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
 end
 local format_x=function(f)
-  n=n+1
-  return format("format('%%%sx',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
 end
 local format_X=function(f)
-  n=n+1
-  return format("format('%%%sX',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
 end
 local format_o=function(f)
-  n=n+1
-  return format("format('%%%so',a%s)",f,n)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
 end
 local format_c=function()
-  n=n+1
-  return format("utfchar(a%s)",n)
+ n=n+1
+ return format("utfchar(a%s)",n)
 end
 local format_C=function()
-  n=n+1
-  return format("tracedchar(a%s)",n)
+ n=n+1
+ return format("tracedchar(a%s)",n)
 end
 local format_r=function(f)
-  n=n+1
-  return format("format('%%%s.0f',a%s)",f,n)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
 end
 local format_h=function(f)
-  n=n+1
-  if f=="-" then
-    f=sub(f,2)
-    return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  else
-    return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  end
+ n=n+1
+ if f=="-" then
+  f=sub(f,2)
+  return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+  return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
 end
 local format_H=function(f)
-  n=n+1
-  if f=="-" then
-    f=sub(f,2)
-    return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  else
-    return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  end
+ n=n+1
+ if f=="-" then
+  f=sub(f,2)
+  return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+  return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
 end
 local format_u=function(f)
-  n=n+1
-  if f=="-" then
-    f=sub(f,2)
-    return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  else
-    return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  end
+ n=n+1
+ if f=="-" then
+  f=sub(f,2)
+  return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+  return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
 end
 local format_U=function(f)
-  n=n+1
-  if f=="-" then
-    f=sub(f,2)
-    return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  else
-    return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
-  end
+ n=n+1
+ if f=="-" then
+  f=sub(f,2)
+  return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+  return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
 end
 local format_p=function()
-  n=n+1
-  return format("points(a%s)",n)
+ n=n+1
+ return format("points(a%s)",n)
 end
 local format_b=function()
-  n=n+1
-  return format("basepoints(a%s)",n)
+ n=n+1
+ return format("basepoints(a%s)",n)
 end
 local format_t=function(f)
-  n=n+1
-  if f and f~="" then
-    return format("concat(a%s,%q)",n,f)
-  else
-    return format("concat(a%s)",n)
-  end
+ n=n+1
+ if f and f~="" then
+  return format("concat(a%s,%q)",n,f)
+ else
+  return format("concat(a%s)",n)
+ end
 end
 local format_T=function(f)
-  n=n+1
-  if f and f~="" then
-    return format("sequenced(a%s,%q)",n,f)
-  else
-    return format("sequenced(a%s)",n)
-  end
+ n=n+1
+ if f and f~="" then
+  return format("sequenced(a%s,%q)",n,f)
+ else
+  return format("sequenced(a%s)",n)
+ end
 end
 local format_l=function()
-  n=n+1
-  return format("(a%s and 'true' or 'false')",n)
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
 end
 local format_L=function()
-  n=n+1
-  return format("(a%s and 'TRUE' or 'FALSE')",n)
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
 end
 local format_n=function() 
-  n=n+1
-  return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
 end
 local format_N=function(f) 
-  n=n+1
-  if not f or f=="" then
-    f=".9"
-  end 
-  return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+ n=n+1
+ if not f or f=="" then
+  f=".9"
+ end 
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
 end
 local format_a=function(f)
-  n=n+1
-  if f and f~="" then
-    return format("autosingle(a%s,%q)",n,f)
-  else
-    return format("autosingle(a%s)",n)
-  end
+ n=n+1
+ if f and f~="" then
+  return format("autosingle(a%s,%q)",n,f)
+ else
+  return format("autosingle(a%s)",n)
+ end
 end
 local format_A=function(f)
-  n=n+1
-  if f and f~="" then
-    return format("autodouble(a%s,%q)",n,f)
-  else
-    return format("autodouble(a%s)",n)
-  end
+ n=n+1
+ if f and f~="" then
+  return format("autodouble(a%s,%q)",n,f)
+ else
+  return format("autodouble(a%s)",n)
+ end
 end
 local format_w=function(f) 
-  n=n+1
-  f=tonumber(f)
-  if f then 
-    return format("nspaces[%s+a%s]",f,n) 
-  else
-    return format("nspaces[a%s]",n) 
-  end
+ n=n+1
+ f=tonumber(f)
+ if f then 
+  return format("nspaces[%s+a%s]",f,n) 
+ else
+  return format("nspaces[a%s]",n) 
+ end
 end
 local format_W=function(f) 
-  return format("nspaces[%s]",tonumber(f) or 0)
+ return format("nspaces[%s]",tonumber(f) or 0)
 end
 local format_m=function(f)
-  n=n+1
-  if not f or f=="" then
-    f=","
-  end
-  if f=="0" then
-    return format([[formattednumber(a%s,false)]],n)
-  else
-    return format([[formattednumber(a%s,%q,".")]],n,f)
-  end
+ n=n+1
+ if not f or f=="" then
+  f=","
+ end
+ if f=="0" then
+  return format([[formattednumber(a%s,false)]],n)
+ else
+  return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
 end
 local format_M=function(f)
-  n=n+1
-  if not f or f=="" then
-    f="."
-  end
-  if f=="0" then
-    return format([[formattednumber(a%s,false)]],n)
-  else
-    return format([[formattednumber(a%s,%q,",")]],n,f)
-  end
+ n=n+1
+ if not f or f=="" then
+  f="."
+ end
+ if f=="0" then
+  return format([[formattednumber(a%s,false)]],n)
+ else
+  return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
 end
 local format_z=function(f)
-  n=n+(tonumber(f) or 1)
-  return "''" 
+ n=n+(tonumber(f) or 1)
+ return "''" 
 end
 local format_rest=function(s)
-  return format("%q",s) 
+ return format("%q",s) 
 end
 local format_extension=function(extensions,f,name)
-  local extension=extensions[name] or "tostring(%s)"
-  local f=tonumber(f) or 1
-  local w=find(extension,"%.%.%.")
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if w then
   if f==0 then
-    if w then
-      extension=gsub(extension,"%.%.%.","")
-    end
-    return extension
+   extension=gsub(extension,"%.%.%.","")
+   return extension
   elseif f==1 then
-    if w then
-      extension=gsub(extension,"%.%.%.","%%s")
-    end
-    n=n+1
-    local a="a"..n
-    return format(extension,a,a) 
+   extension=gsub(extension,"%.%.%.","%%s")
+   n=n+1
+   local a="a"..n
+   return format(extension,a,a) 
   elseif f<0 then
-    local a="a"..(n+f+1)
-    return format(extension,a,a)
+   local a="a"..(n+f+1)
+   return format(extension,a,a)
   else
-    if w then
-      extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
-    end
-    local t={}
-    for i=1,f do
-      n=n+1
-      t[i]="a"..n
-    end
-    return format(extension,unpack(t))
+   extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+   local t={}
+   for i=1,f do
+    n=n+1
+    t[i]="a"..n
+   end
+   return format(extension,unpack(t))
   end
+ else
+  extension=gsub(extension,"%%s",function()
+   n=n+1
+   return "a"..n
+  end)
+  return extension
+ end
 end
 local builder=Cs { "start",
-  start=(
-    (
-      P("%")/""*(
-        V("!") 
+ start=(
+  (
+   P("%")/""*(
+    V("!") 
 +V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
 +V("c")+V("C")+V("S") 
 +V("Q") 
@@ -717,119 +683,117 @@
 +V("z")
 +V(">") 
 +V("<")
-      )+V("*")
-    )*(endofstring+Carg(1))
-  )^0,
-  ["s"]=(prefix_any*P("s"))/format_s,
-  ["q"]=(prefix_any*P("q"))/format_q,
-  ["i"]=(prefix_any*P("i"))/format_i,
-  ["d"]=(prefix_any*P("d"))/format_d,
-  ["f"]=(prefix_any*P("f"))/format_f,
-  ["F"]=(prefix_any*P("F"))/format_F,
-  ["g"]=(prefix_any*P("g"))/format_g,
-  ["G"]=(prefix_any*P("G"))/format_G,
-  ["e"]=(prefix_any*P("e"))/format_e,
-  ["E"]=(prefix_any*P("E"))/format_E,
-  ["x"]=(prefix_any*P("x"))/format_x,
-  ["X"]=(prefix_any*P("X"))/format_X,
-  ["o"]=(prefix_any*P("o"))/format_o,
-  ["S"]=(prefix_any*P("S"))/format_S,
-  ["Q"]=(prefix_any*P("Q"))/format_Q,
-  ["n"]=(prefix_any*P("n"))/format_n,
-  ["N"]=(prefix_any*P("N"))/format_N,
-  ["k"]=(prefix_sub*P("k"))/format_k,
-  ["c"]=(prefix_any*P("c"))/format_c,
-  ["C"]=(prefix_any*P("C"))/format_C,
-  ["r"]=(prefix_any*P("r"))/format_r,
-  ["h"]=(prefix_any*P("h"))/format_h,
-  ["H"]=(prefix_any*P("H"))/format_H,
-  ["u"]=(prefix_any*P("u"))/format_u,
-  ["U"]=(prefix_any*P("U"))/format_U,
-  ["p"]=(prefix_any*P("p"))/format_p,
-  ["b"]=(prefix_any*P("b"))/format_b,
-  ["t"]=(prefix_tab*P("t"))/format_t,
-  ["T"]=(prefix_tab*P("T"))/format_T,
-  ["l"]=(prefix_any*P("l"))/format_l,
-  ["L"]=(prefix_any*P("L"))/format_L,
-  ["I"]=(prefix_any*P("I"))/format_I,
-  ["w"]=(prefix_any*P("w"))/format_w,
-  ["W"]=(prefix_any*P("W"))/format_W,
-  ["j"]=(prefix_any*P("j"))/format_j,
-  ["J"]=(prefix_any*P("J"))/format_J,
-  ["m"]=(prefix_any*P("m"))/format_m,
-  ["M"]=(prefix_any*P("M"))/format_M,
-  ["z"]=(prefix_any*P("z"))/format_z,
-  ["a"]=(prefix_any*P("a"))/format_a,
-  ["A"]=(prefix_any*P("A"))/format_A,
-  ["<"]=(prefix_any*P("<"))/format_left,
-  [">"]=(prefix_any*P(">"))/format_right,
-  ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
-  ["?"]=Cs(((1-P("%"))^1        )^1)/format_rest,
-  ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+   )+V("*")
+  )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1      )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
 }
 local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
 local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
 local preset={
-  ["%02x"]=function(n) return xx[n] end,
-  ["%02X"]=function(n) return XX[n] end,
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
 }
 local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
 local function make(t,str)
-  local f=preset[str]
-  if f then
-    return f
-  end
-  local p=lpegmatch(direct,str)
-  if p then
-    f=loadstripped(p)()
+ local f=preset[str]
+ if f then
+  return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+  f=loadstripped(p)()
+ else
+  n=0
+  p=lpegmatch(builder,str,1,t._connector_,t._extensions_) 
+  if n>0 then
+   p=format(template,preamble,t._preamble_,arguments[n],p)
+   f=loadstripped(p,t._environment_)() 
   else
-    n=0
-    p=lpegmatch(builder,str,1,t._connector_,t._extensions_) 
-    if n>0 then
-      p=format(template,preamble,t._preamble_,arguments[n],p)
-      f=loadstripped(p,t._environment_)() 
-    else
-      f=function() return str end
-    end
+   f=function() return str end
   end
-  t[str]=f
-  return f
+ end
+ t[str]=f
+ return f
 end
 local function use(t,fmt,...)
-  return t[fmt](...)
+ return t[fmt](...)
 end
 strings.formatters={}
-if oldfashioned then
-  function strings.formatters.new(noconcat)
-    local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
-    setmetatable(t,{ __index=make,__call=use })
-    return t
-  end
-else
-  function strings.formatters.new(noconcat)
-    local e={} 
-    for k,v in next,environment do
-      e[k]=v
-    end
-    local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
-    setmetatable(t,{ __index=make,__call=use })
-    return t
-  end
+function strings.formatters.new(noconcat)
+ local e={} 
+ for k,v in next,environment do
+  e[k]=v
+ end
+ local t={
+  _type_="formatter",
+  _connector_=noconcat and "," or "..",
+  _extensions_={},
+  _preamble_="",
+  _environment_=e,
+ }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
 end
 local formatters=strings.formatters.new() 
 string.formatters=formatters 
 string.formatter=function(str,...) return formatters[str](...) end 
 local function add(t,name,template,preamble)
-  if type(t)=="table" and t._type_=="formatter" then
-    t._extensions_[name]=template or "%s"
-    if type(preamble)=="string" then
-      t._preamble_=preamble.."\n"..t._preamble_ 
-    elseif type(preamble)=="table" then
-      for k,v in next,preamble do
-        t._environment_[k]=v
-      end
-    end
+ if type(t)=="table" and t._type_=="formatter" then
+  t._extensions_[name]=template or "%s"
+  if type(preamble)=="string" then
+   t._preamble_=preamble.."\n"..t._preamble_ 
+  elseif type(preamble)=="table" then
+   for k,v in next,preamble do
+    t._environment_[k]=v
+   end
   end
+ end
 end
 strings.formatters.add=add
 patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+anything)^0)
@@ -836,45 +800,39 @@
 patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
 patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) 
 patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
-if oldfashioned then
-  add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
-  add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
-  add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
-else
-  add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
-  add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
-  add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
-end
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
 local dquote=patterns.dquote 
 local equote=patterns.escaped+dquote/'\\"'+1
 local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)          
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)     
 +Cs(cquote*(equote-space)^0*space*equote^0*cquote) 
 function string.optionalquoted(str)
-  return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
 end
 local pattern=Cs((newline/(os.newline or "\r")+1)^0)
 function string.replacenewlines(str)
-  return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
 end
 function strings.newcollector()
-  local result,r={},0
-  return
-    function(fmt,str,...) 
-      r=r+1
-      result[r]=str==nil and fmt or formatters[fmt](str,...)
-    end,
-    function(connector) 
-      if result then
-        local str=concat(result,connector)
-        result,r={},0
-        return str
-      end
-    end
+ local result,r={},0
+ return
+  function(fmt,str,...) 
+   r=r+1
+   result[r]=str==nil and fmt or formatters[fmt](str,...)
+  end,
+  function(connector) 
+   if result then
+    local str=concat(result,connector)
+    result,r={},0
+    return str
+   end
+  end
 end
 local f_16_16=formatters["%0.5N"]
 function number.to16dot16(n)
-  return f_16_16(n/65536.0)
+ return f_16_16(n/65536.0)
 end
 
 end -- closure
@@ -882,11 +840,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-fil']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local byte=string.byte
 local char=string.char
@@ -895,280 +853,280 @@
 utilities.files=files
 local zerobased={}
 function files.open(filename,zb)
-  local f=io.open(filename,"rb")
-  if f then
-    zerobased[f]=zb or false
-  end
-  return f
+ local f=io.open(filename,"rb")
+ if f then
+  zerobased[f]=zb or false
+ end
+ return f
 end
 function files.close(f)
-  zerobased[f]=nil
-  f:close()
+ zerobased[f]=nil
+ f:close()
 end
 function files.size(f)
-  local current=f:seek()
-  local size=f:seek("end")
-  f:seek("set",current)
-  return size
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
 end
 files.getsize=files.size
 function files.setposition(f,n)
-  if zerobased[f] then
-    f:seek("set",n)
-  else
-    f:seek("set",n-1)
-  end
+ if zerobased[f] then
+  f:seek("set",n)
+ else
+  f:seek("set",n-1)
+ end
 end
 function files.getposition(f)
-  if zerobased[f] then
-    return f:seek()
-  else
-    return f:seek()+1
-  end
+ if zerobased[f] then
+  return f:seek()
+ else
+  return f:seek()+1
+ end
 end
 function files.look(f,n,chars)
-  local p=f:seek()
-  local s=f:read(n)
-  f:seek("set",p)
-  if chars then
-    return s
-  else
-    return byte(s,1,#s)
-  end
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+  return s
+ else
+  return byte(s,1,#s)
+ end
 end
 function files.skip(f,n)
-  if n==1 then
-    f:read(n)
-  else
-    f:seek("set",f:seek()+n)
-  end
+ if n==1 then
+  f:read(n)
+ else
+  f:seek("set",f:seek()+n)
+ end
 end
 function files.readbyte(f)
-  return byte(f:read(1))
+ return byte(f:read(1))
 end
 function files.readbytes(f,n)
-  return byte(f:read(n),1,n)
+ return byte(f:read(n),1,n)
 end
 function files.readbytetable(f,n)
-  local s=f:read(n or 1)
-  return { byte(s,1,#s) } 
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) } 
 end
 function files.readchar(f)
-  return f:read(1)
+ return f:read(1)
 end
 function files.readstring(f,n)
-  return f:read(n or 1)
+ return f:read(n or 1)
 end
-function files.readinteger1(f) 
-  local n=byte(f:read(1))
-  if n>=0x80 then
-    return n-0x100
-  else
-    return n
-  end
+function files.readinteger1(f)  
+ local n=byte(f:read(1))
+ if n>=0x80 then
+  return n-0x100
+ else
+  return n
+ end
 end
-files.readcardinal1=files.readbyte 
+files.readcardinal1=files.readbyte  
 files.readcardinal=files.readcardinal1
 files.readinteger=files.readinteger1
 files.readsignedbyte=files.readinteger1
 function files.readcardinal2(f)
-  local a,b=byte(f:read(2),1,2)
-  return 0x100*a+b
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
 end
 function files.readcardinal2le(f)
-  local b,a=byte(f:read(2),1,2)
-  return 0x100*a+b
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
 end
 function files.readinteger2(f)
-  local a,b=byte(f:read(2),1,2)
-  if a>=0x80 then
-    return 0x100*a+b-0x10000
-  else
-    return 0x100*a+b
-  end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+  return 0x100*a+b-0x10000
+ else
+  return 0x100*a+b
+ end
 end
 function files.readinteger2le(f)
-  local b,a=byte(f:read(2),1,2)
-  if a>=0x80 then
-    return 0x100*a+b-0x10000
-  else
-    return 0x100*a+b
-  end
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+  return 0x100*a+b-0x10000
+ else
+  return 0x100*a+b
+ end
 end
 function files.readcardinal3(f)
-  local a,b,c=byte(f:read(3),1,3)
-  return 0x10000*a+0x100*b+c
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
 end
 function files.readcardinal3le(f)
-  local c,b,a=byte(f:read(3),1,3)
-  return 0x10000*a+0x100*b+c
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
 end
 function files.readinteger3(f)
-  local a,b,c=byte(f:read(3),1,3)
-  if a>=0x80 then
-    return 0x10000*a+0x100*b+c-0x1000000
-  else
-    return 0x10000*a+0x100*b+c
-  end
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+  return 0x10000*a+0x100*b+c-0x1000000
+ else
+  return 0x10000*a+0x100*b+c
+ end
 end
 function files.readinteger3le(f)
-  local c,b,a=byte(f:read(3),1,3)
-  if a>=0x80 then
-    return 0x10000*a+0x100*b+c-0x1000000
-  else
-    return 0x10000*a+0x100*b+c
-  end
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+  return 0x10000*a+0x100*b+c-0x1000000
+ else
+  return 0x10000*a+0x100*b+c
+ end
 end
 function files.readcardinal4(f)
-  local a,b,c,d=byte(f:read(4),1,4)
-  return 0x1000000*a+0x10000*b+0x100*c+d
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
 end
 function files.readcardinal4le(f)
-  local d,c,b,a=byte(f:read(4),1,4)
-  return 0x1000000*a+0x10000*b+0x100*c+d
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
 end
 function files.readinteger4(f)
-  local a,b,c,d=byte(f:read(4),1,4)
-  if a>=0x80 then
-    return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
-  else
-    return 0x1000000*a+0x10000*b+0x100*c+d
-  end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+  return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+  return 0x1000000*a+0x10000*b+0x100*c+d
+ end
 end
 function files.readinteger4le(f)
-  local d,c,b,a=byte(f:read(4),1,4)
-  if a>=0x80 then
-    return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
-  else
-    return 0x1000000*a+0x10000*b+0x100*c+d
-  end
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+  return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+  return 0x1000000*a+0x10000*b+0x100*c+d
+ end
 end
 function files.readfixed2(f)
-  local a,b=byte(f:read(2),1,2)
-  if a>=0x80 then
-    return (a-0x100)+b/0x100
-  else
-    return (a    )+b/0x100
-  end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+  return (a-0x100)+b/0x100
+ else
+  return (a  )+b/0x100
+ end
 end
 function files.readfixed4(f)
-  local a,b,c,d=byte(f:read(4),1,4)
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+  return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
+ else
+  return (0x100*a+b    )+(0x100*c+d)/0x10000
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+  local a,b=byte(f:read(2),1,2)
   if a>=0x80 then
-    return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
+   local n=-(0x100*a+b)
+   return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
   else
-    return (0x100*a+b     )+(0x100*c+d)/0x10000
+   local n=0x100*a+b
+   return   (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
   end
+ end
 end
-if bit32 then
-  local extract=bit32.extract
-  local band=bit32.band
-  function files.read2dot14(f)
-    local a,b=byte(f:read(2),1,2)
-    if a>=0x80 then
-      local n=-(0x100*a+b)
-      return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
-    else
-      local n=0x100*a+b
-      return  (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
-    end
-  end
-end
 function files.skipshort(f,n)
-  f:read(2*(n or 1))
+ f:read(2*(n or 1))
 end
 function files.skiplong(f,n)
-  f:read(4*(n or 1))
+ f:read(4*(n or 1))
 end
 if bit32 then
-  local rshift=bit32.rshift
-  function files.writecardinal2(f,n)
-    local a=char(n%256)
-    n=rshift(n,8)
-    local b=char(n%256)
-    f:write(b,a)
-  end
-else
-  local floor=math.floor
-  function files.writecardinal2(f,n)
-    local a=char(n%256)
-    n=floor(n/256)
-    local b=char(n%256)
-    f:write(b,a)
-  end
-end
-function files.writecardinal4(f,n)
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
   local a=char(n%256)
   n=rshift(n,8)
   local b=char(n%256)
-  n=rshift(n,8)
-  local c=char(n%256)
-  n=rshift(n,8)
-  local d=char(n%256)
-  f:write(d,c,b,a)
+  f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+  local a=char(n%256)
+  n=floor(n/256)
+  local b=char(n%256)
+  f:write(b,a)
+ end
 end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
+end
 function files.writestring(f,s)
-  f:write(char(byte(s,1,#s)))
+ f:write(char(byte(s,1,#s)))
 end
 function files.writebyte(f,b)
-  f:write(char(b))
+ f:write(char(b))
 end
 if fio and fio.readcardinal1 then
-  files.readcardinal1=fio.readcardinal1
-  files.readcardinal2=fio.readcardinal2
-  files.readcardinal3=fio.readcardinal3
-  files.readcardinal4=fio.readcardinal4
-  files.readinteger1=fio.readinteger1
-  files.readinteger2=fio.readinteger2
-  files.readinteger3=fio.readinteger3
-  files.readinteger4=fio.readinteger4
-  files.readfixed2=fio.readfixed2
-  files.readfixed4=fio.readfixed4
-  files.read2dot14=fio.read2dot14
-  files.setposition=fio.setposition
-  files.getposition=fio.getposition
-  files.readbyte=files.readcardinal1
-  files.readsignedbyte=files.readinteger1
-  files.readcardinal=files.readcardinal1
-  files.readinteger=files.readinteger1
-  local skipposition=fio.skipposition
-  files.skipposition=skipposition
-  files.readbytes=fio.readbytes
-  files.readbytetable=fio.readbytetable
-  function files.skipshort(f,n)
-    skipposition(f,2*(n or 1))
-  end
-  function files.skiplong(f,n)
-    skipposition(f,4*(n or 1))
-  end
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+  skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+  skipposition(f,4*(n or 1))
+ end
 end
 if fio and fio.readcardinaltable then
-  files.readcardinaltable=fio.readcardinaltable
-  files.readintegertable=fio.readintegertable
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
 else
-  local readcardinal1=files.readcardinal1
-  local readcardinal2=files.readcardinal2
-  local readcardinal3=files.readcardinal3
-  local readcardinal4=files.readcardinal4
-  function files.readcardinaltable(f,n,b)
-    local t={}
-      if b==1 then for i=1,n do t[i]=readcardinal1(f) end
-    elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
-    elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
-    elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
-    return t
-  end
-  local readinteger1=files.readinteger1
-  local readinteger2=files.readinteger2
-  local readinteger3=files.readinteger3
-  local readinteger4=files.readinteger4
-  function files.readintegertable(f,n,b)
-    local t={}
-      if b==1 then for i=1,n do t[i]=readinteger1(f) end
-    elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
-    elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
-    elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
-    return t
-  end
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+  local t={}
+   if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+  elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+  elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+  elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+  return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+  local t={}
+   if b==1 then for i=1,n do t[i]=readinteger1(f) end
+  elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+  elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+  elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+  return t
+ end
 end
 
 end -- closure
@@ -1176,11 +1134,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-tab']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 utilities=utilities or {}
 utilities.tables=utilities.tables or {}
@@ -1195,219 +1153,219 @@
 local utftoeight=utf.toeight
 local splitter=lpeg.tsplitat(".")
 function utilities.tables.definetable(target,nofirst,nolast) 
-  local composed,t=nil,{}
-  local snippets=lpegmatch(splitter,target)
-  for i=1,#snippets-(nolast and 1 or 0) do
-    local name=snippets[i]
-    if composed then
-      composed=composed.."."..name
-        t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
-    else
-      composed=name
-      if not nofirst then
-        t[#t+1]=formatters["%s = %s or { }"](composed,composed)
-      end
-    end
-  end
+ local composed,t=nil,{}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+  local name=snippets[i]
   if composed then
-    if nolast then
-      composed=composed.."."..snippets[#snippets]
-    end
-    return concat(t,"\n"),composed 
+   composed=composed.."."..name
+    t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
   else
-    return "",target
+   composed=name
+   if not nofirst then
+    t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+   end
   end
+ end
+ if composed then
+  if nolast then
+   composed=composed.."."..snippets[#snippets]
+  end
+  return concat(t,"\n"),composed 
+ else
+  return "",target
+ end
 end
 function tables.definedtable(...)
-  local t=_G
-  for i=1,select("#",...) do
-    local li=select(i,...)
-    local tl=t[li]
-    if not tl then
-      tl={}
-      t[li]=tl
-    end
-    t=tl
+ local t=_G
+ for i=1,select("#",...) do
+  local li=select(i,...)
+  local tl=t[li]
+  if not tl then
+   tl={}
+   t[li]=tl
   end
-  return t
+  t=tl
+ end
+ return t
 end
 function tables.accesstable(target,root)
-  local t=root or _G
-  for name in gmatch(target,"([^%.]+)") do
-    t=t[name]
-    if not t then
-      return
-    end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+  t=t[name]
+  if not t then
+   return
   end
-  return t
+ end
+ return t
 end
 function tables.migratetable(target,v,root)
-  local t=root or _G
-  local names=lpegmatch(splitter,target)
-  for i=1,#names-1 do
-    local name=names[i]
-    t[name]=t[name] or {}
-    t=t[name]
-    if not t then
-      return
-    end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+  local name=names[i]
+  t[name]=t[name] or {}
+  t=t[name]
+  if not t then
+   return
   end
-  t[names[#names]]=v
+ end
+ t[names[#names]]=v
 end
 function tables.removevalue(t,value) 
-  if value then
-    for i=1,#t do
-      if t[i]==value then
-        remove(t,i)
-      end
-    end
+ if value then
+  for i=1,#t do
+   if t[i]==value then
+    remove(t,i)
+   end
   end
+ end
 end
 function tables.replacevalue(t,oldvalue,newvalue)
-  if oldvalue and newvalue then
-    for i=1,#t do
-      if t[i]==oldvalue then
-        t[i]=newvalue
-      end
-    end
+ if oldvalue and newvalue then
+  for i=1,#t do
+   if t[i]==oldvalue then
+    t[i]=newvalue
+   end
   end
+ end
 end
 function tables.insertbeforevalue(t,value,extra)
-  for i=1,#t do
-    if t[i]==extra then
-      remove(t,i)
-    end
+ for i=1,#t do
+  if t[i]==extra then
+   remove(t,i)
   end
-  for i=1,#t do
-    if t[i]==value then
-      insert(t,i,extra)
-      return
-    end
+ end
+ for i=1,#t do
+  if t[i]==value then
+   insert(t,i,extra)
+   return
   end
-  insert(t,1,extra)
+ end
+ insert(t,1,extra)
 end
 function tables.insertaftervalue(t,value,extra)
-  for i=1,#t do
-    if t[i]==extra then
-      remove(t,i)
-    end
+ for i=1,#t do
+  if t[i]==extra then
+   remove(t,i)
   end
-  for i=1,#t do
-    if t[i]==value then
-      insert(t,i+1,extra)
-      return
-    end
+ end
+ for i=1,#t do
+  if t[i]==value then
+   insert(t,i+1,extra)
+   return
   end
-  insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
 end
 local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
 function table.tocsv(t,specification)
-  if t and #t>0 then
-    local result={}
-    local r={}
-    specification=specification or {}
-    local fields=specification.fields
-    if type(fields)~="string" then
-      fields=sortedkeys(t[1])
+ if t and #t>0 then
+  local result={}
+  local r={}
+  specification=specification or {}
+  local fields=specification.fields
+  if type(fields)~="string" then
+   fields=sortedkeys(t[1])
+  end
+  local separator=specification.separator or ","
+  local noffields=#fields
+  if specification.preamble==true then
+   for f=1,noffields do
+    r[f]=lpegmatch(escape,tostring(fields[f]))
+   end
+   result[1]=concat(r,separator)
+  end
+  for i=1,#t do
+   local ti=t[i]
+   for f=1,noffields do
+    local field=ti[fields[f]]
+    if type(field)=="string" then
+     r[f]=lpegmatch(escape,field)
+    else
+     r[f]=tostring(field)
     end
-    local separator=specification.separator or ","
-    local noffields=#fields
-    if specification.preamble==true then
-      for f=1,noffields do
-        r[f]=lpegmatch(escape,tostring(fields[f]))
-      end
-      result[1]=concat(r,separator)
-    end
-    for i=1,#t do
-      local ti=t[i]
-      for f=1,noffields do
-        local field=ti[fields[f]]
-        if type(field)=="string" then
-          r[f]=lpegmatch(escape,field)
-        else
-          r[f]=tostring(field)
-        end
-      end
-      result[i+1]=concat(r,separator)
-    end
-    return concat(result,"\n")
-  else
-    return ""
+   end
+   result[i+1]=concat(r,separator)
   end
+  return concat(result,"\n")
+ else
+  return ""
+ end
 end
 local nspaces=utilities.strings.newrepeater(" ")
 local function toxml(t,d,result,step)
-  local r=#result
-  for k,v in sortedpairs(t) do
-    local s=nspaces[d] 
-    local tk=type(k)
-    local tv=type(v)
-    if tv=="table" then
-      if tk=="number" then
-        r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
-        toxml(v,d+step,result,step)
-        r=r+1 result[r]=formatters["%s</entry>"](s,k)
-      else
-        r=r+1 result[r]=formatters["%s<%s>"](s,k)
-        toxml(v,d+step,result,step)
-        r=r+1 result[r]=formatters["%s</%s>"](s,k)
-      end
-    elseif tv=="string" then
-      if tk=="number" then
-        r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
-      else
-        r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
-      end
-    elseif tk=="number" then
-      r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
-    else
-      r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
-    end
+ local r=#result
+ for k,v in sortedpairs(t) do
+  local s=nspaces[d] 
+  local tk=type(k)
+  local tv=type(v)
+  if tv=="table" then
+   if tk=="number" then
+    r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+    toxml(v,d+step,result,step)
+    r=r+1 result[r]=formatters["%s</entry>"](s,k)
+   else
+    r=r+1 result[r]=formatters["%s<%s>"](s,k)
+    toxml(v,d+step,result,step)
+    r=r+1 result[r]=formatters["%s</%s>"](s,k)
+   end
+  elseif tv=="string" then
+   if tk=="number" then
+    r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+   else
+    r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+   end
+  elseif tk=="number" then
+   r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+  else
+   r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
   end
+ end
 end
 function table.toxml(t,specification)
-  specification=specification or {}
-  local name=specification.name
-  local noroot=name==false
-  local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
-  local indent=specification.indent or 0
-  local spaces=specification.spaces or 1
-  if noroot then
-    toxml(t,indent,result,spaces)
-  else
-    toxml({ [name or "data"]=t },indent,result,spaces)
-  end
-  return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+  toxml(t,indent,result,spaces)
+ else
+  toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
 end
 function tables.encapsulate(core,capsule,protect)
-  if type(capsule)~="table" then
-    protect=true
-    capsule={}
+ if type(capsule)~="table" then
+  protect=true
+  capsule={}
+ end
+ for key,value in next,core do
+  if capsule[key] then
+   print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+   os.exit()
+  else
+   capsule[key]=value
   end
+ end
+ if protect then
   for key,value in next,core do
+   core[key]=nil
+  end
+  setmetatable(core,{
+   __index=capsule,
+   __newindex=function(t,key,value)
     if capsule[key] then
-      print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
-      os.exit()
+     print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+     os.exit()
     else
-      capsule[key]=value
+     rawset(t,key,value)
     end
-  end
-  if protect then
-    for key,value in next,core do
-      core[key]=nil
-    end
-    setmetatable(core,{
-      __index=capsule,
-      __newindex=function(t,key,value)
-        if capsule[key] then
-          print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
-          os.exit()
-        else
-          rawset(t,key,value)
-        end
-      end
-    } )
-  end
+   end
+  } )
+ end
 end
 local f_hashed_string=formatters["[%q]=%q,"]
 local f_hashed_number=formatters["[%q]=%s,"]
@@ -1421,157 +1379,157 @@
 local f_ordered_number=formatters["%s,"]
 local f_ordered_boolean=formatters["%l,"]
 function table.fastserialize(t,prefix)
-  local r={ type(prefix)=="string" and prefix or "return" }
-  local m=1
-  local function fastserialize(t,outer) 
-    local n=#t
-    m=m+1
-    r[m]="{"
-    if n>0 then
-      for i=0,n do
-        local v=t[i]
-        local tv=type(v)
-        if tv=="string" then
-          m=m+1 r[m]=f_ordered_string(v)
-        elseif tv=="number" then
-          m=m+1 r[m]=f_ordered_number(v)
-        elseif tv=="table" then
-          fastserialize(v)
-        elseif tv=="boolean" then
-          m=m+1 r[m]=f_ordered_boolean(v)
-        end
-      end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer) 
+  local n=#t
+  m=m+1
+  r[m]="{"
+  if n>0 then
+   for i=0,n do
+    local v=t[i]
+    local tv=type(v)
+    if tv=="string" then
+     m=m+1 r[m]=f_ordered_string(v)
+    elseif tv=="number" then
+     m=m+1 r[m]=f_ordered_number(v)
+    elseif tv=="table" then
+     fastserialize(v)
+    elseif tv=="boolean" then
+     m=m+1 r[m]=f_ordered_boolean(v)
     end
-    for k,v in next,t do
-      local tk=type(k)
-      if tk=="number" then
-        if k>n or k<0 then
-          local tv=type(v)
-          if tv=="string" then
-            m=m+1 r[m]=f_indexed_string(k,v)
-          elseif tv=="number" then
-            m=m+1 r[m]=f_indexed_number(k,v)
-          elseif tv=="table" then
-            m=m+1 r[m]=f_indexed_table(k)
-            fastserialize(v)
-          elseif tv=="boolean" then
-            m=m+1 r[m]=f_indexed_boolean(k,v)
-          end
-        end
-      else
-        local tv=type(v)
-        if tv=="string" then
-          m=m+1 r[m]=f_hashed_string(k,v)
-        elseif tv=="number" then
-          m=m+1 r[m]=f_hashed_number(k,v)
-        elseif tv=="table" then
-          m=m+1 r[m]=f_hashed_table(k)
-          fastserialize(v)
-        elseif tv=="boolean" then
-          m=m+1 r[m]=f_hashed_boolean(k,v)
-        end
-      end
+   end
+  end
+  for k,v in next,t do
+   local tk=type(k)
+   if tk=="number" then
+    if k>n or k<0 then
+     local tv=type(v)
+     if tv=="string" then
+      m=m+1 r[m]=f_indexed_string(k,v)
+     elseif tv=="number" then
+      m=m+1 r[m]=f_indexed_number(k,v)
+     elseif tv=="table" then
+      m=m+1 r[m]=f_indexed_table(k)
+      fastserialize(v)
+     elseif tv=="boolean" then
+      m=m+1 r[m]=f_indexed_boolean(k,v)
+     end
     end
-    m=m+1
-    if outer then
-      r[m]="}"
-    else
-      r[m]="},"
+   else
+    local tv=type(v)
+    if tv=="string" then
+     m=m+1 r[m]=f_hashed_string(k,v)
+    elseif tv=="number" then
+     m=m+1 r[m]=f_hashed_number(k,v)
+    elseif tv=="table" then
+     m=m+1 r[m]=f_hashed_table(k)
+     fastserialize(v)
+    elseif tv=="boolean" then
+     m=m+1 r[m]=f_hashed_boolean(k,v)
     end
-    return r
+   end
   end
-  return concat(fastserialize(t,true))
+  m=m+1
+  if outer then
+   r[m]="}"
+  else
+   r[m]="},"
+  end
+  return r
+ end
+ return concat(fastserialize(t,true))
 end
 function table.deserialize(str)
-  if not str or str=="" then
-    return
-  end
-  local code=load(str)
-  if not code then
-    return
-  end
-  code=code()
-  if not code then
-    return
-  end
-  return code
+ if not str or str=="" then
+  return
+ end
+ local code=load(str)
+ if not code then
+  return
+ end
+ code=code()
+ if not code then
+  return
+ end
+ return code
 end
 function table.load(filename,loader)
-  if filename then
-    local t=(loader or io.loaddata)(filename)
-    if t and t~="" then
-      local t=utftoeight(t)
-      t=load(t)
-      if type(t)=="function" then
-        t=t()
-        if type(t)=="table" then
-          return t
-        end
-      end
+ if filename then
+  local t=(loader or io.loaddata)(filename)
+  if t and t~="" then
+   local t=utftoeight(t)
+   t=load(t)
+   if type(t)=="function" then
+    t=t()
+    if type(t)=="table" then
+     return t
     end
+   end
   end
+ end
 end
 function table.save(filename,t,n,...)
-  io.savedata(filename,table.serialize(t,n==nil and true or n,...)) 
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...)) 
 end
 local f_key_value=formatters["%s=%q"]
 local f_add_table=formatters[" {%t},\n"]
 local f_return_table=formatters["return {\n%t}"]
 local function slowdrop(t) 
-  local r={}
-  local l={}
-  for i=1,#t do
-    local ti=t[i]
-    local j=0
-    for k,v in next,ti do
-      j=j+1
-      l[j]=f_key_value(k,v)
-    end
-    r[i]=f_add_table(l)
+ local r={}
+ local l={}
+ for i=1,#t do
+  local ti=t[i]
+  local j=0
+  for k,v in next,ti do
+   j=j+1
+   l[j]=f_key_value(k,v)
   end
-  return f_return_table(r)
+  r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
 end
 local function fastdrop(t)
-  local r={ "return {\n" }
-  local m=1
-  for i=1,#t do
-    local ti=t[i]
-    m=m+1 r[m]=" {"
-    for k,v in next,ti do
-      m=m+1 r[m]=f_key_value(k,v)
-    end
-    m=m+1 r[m]="},\n"
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+  local ti=t[i]
+  m=m+1 r[m]=" {"
+  for k,v in next,ti do
+   m=m+1 r[m]=f_key_value(k,v)
   end
-  m=m+1
-  r[m]="}"
-  return concat(r)
+  m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
 end
 function table.drop(t,slow) 
-  if #t==0 then
-    return "return { }"
-  elseif slow==true then
-    return slowdrop(t) 
-  else
-    return fastdrop(t) 
-  end
+ if #t==0 then
+  return "return { }"
+ elseif slow==true then
+  return slowdrop(t) 
+ else
+  return fastdrop(t) 
+ end
 end
 local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)  
-  if not t then         
-    t={}          
-  else             
-    local zero=rawget(t,0) 
-    for i=zero and 0 or 1,#t do
-      local ti=t[i]    
-      if ti then
-        local i=tostring(i)
-        t[i]=ti   
-        t[ti]=i    
-      end
-    end
+function table.twowaymapper(t) 
+ if not t then     
+  t={}       
+ else        
+  local zero=rawget(t,0)  
+  for i=zero and 0 or 1,#t do
+   local ti=t[i]    
+   if ti then
+    local i=tostring(i)
+    t[i]=ti   
+    t[ti]=i    
+   end
   end
-  setmetatable(t,selfmapper)
-  return t
+ end
+ setmetatable(t,selfmapper)
+ return t
 end
 local f_start_key_idx=formatters["%w{"]
 local f_start_key_num=formatters["%w[%s]={"]
@@ -1609,188 +1567,224 @@
 local original_serialize=table.serialize
 local is_simple_table=table.is_simple_table
 local function serialize(root,name,specification)
-  if type(specification)=="table" then
-    return original_serialize(root,name,specification) 
+ if type(specification)=="table" then
+  return original_serialize(root,name,specification) 
+ end
+ local t 
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+  if level>0 then
+   n=n+1
+   if indexed then
+    t[n]=f_start_key_idx(depth)
+   else
+    local tn=type(name)
+    if tn=="number" then
+     t[n]=f_start_key_num(depth,name)
+    elseif tn=="string" then
+     t[n]=f_start_key_str(depth,name)
+    elseif tn=="boolean" then
+     t[n]=f_start_key_boo(depth,name)
+    else
+     t[n]=f_start_key_nop(depth)
+    end
+   end
+   depth=depth+1
   end
-  local t  
-  local n=1
-  local unknown=false
-  local function do_serialize(root,name,depth,level,indexed)
-    if level>0 then
-      n=n+1
-      if indexed then
-        t[n]=f_start_key_idx(depth)
+  if root and next(root)~=nil then
+   local first=nil
+   local last=0
+   last=#root
+   for k=1,last do
+    if rawget(root,k)==nil then
+     last=k-1
+     break
+    end
+   end
+   if last>0 then
+    first=1
+   end
+   local sk=sortedkeys(root) 
+   for i=1,#sk do
+    local k=sk[i]
+    local v=root[k]
+    local tv=type(v)
+    local tk=type(k)
+    if first and tk=="number" and k<=last and k>=first then
+     if tv=="number" then
+      n=n+1 t[n]=f_val_num(depth,v)
+     elseif tv=="string" then
+      n=n+1 t[n]=f_val_str(depth,v)
+     elseif tv=="table" then
+      if next(v)==nil then 
+       n=n+1 t[n]=f_val_not(depth)
       else
-        local tn=type(name)
-        if tn=="number" then
-          t[n]=f_start_key_num(depth,name)
-        elseif tn=="string" then
-          t[n]=f_start_key_str(depth,name)
-        elseif tn=="boolean" then
-          t[n]=f_start_key_boo(depth,name)
-        else
-          t[n]=f_start_key_nop(depth)
-        end
+       local st=is_simple_table(v)
+       if st then
+        n=n+1 t[n]=f_val_seq(depth,st)
+       else
+        do_serialize(v,k,depth,level+1,true)
+       end
       end
-      depth=depth+1
-    end
-    if root and next(root)~=nil then
-      local first=nil
-      local last=0
-      last=#root
-      for k=1,last do
-        if rawget(root,k)==nil then
-          last=k-1
-          break
-        end
+     elseif tv=="boolean" then
+      n=n+1 t[n]=f_val_boo(depth,v)
+     elseif unknown then
+      n=n+1 t[n]=f_val_str(depth,tostring(v))
+     end
+    elseif tv=="number" then
+     if tk=="number" then
+      n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+     elseif tk=="string" then
+      n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+     elseif tk=="boolean" then
+      n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+     elseif unknown then
+      n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+     end
+    elseif tv=="string" then
+     if tk=="number" then
+      n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+     elseif tk=="string" then
+      n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+     elseif tk=="boolean" then
+      n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+     elseif unknown then
+      n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+     end
+    elseif tv=="table" then
+     if next(v)==nil then
+      if tk=="number" then
+       n=n+1 t[n]=f_key_num_value_not(depth,k)
+      elseif tk=="string" then
+       n=n+1 t[n]=f_key_str_value_not(depth,k)
+      elseif tk=="boolean" then
+       n=n+1 t[n]=f_key_boo_value_not(depth,k)
+      elseif unknown then
+       n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
       end
-      if last>0 then
-        first=1
+     else
+      local st=is_simple_table(v)
+      if not st then
+       do_serialize(v,k,depth,level+1)
+      elseif tk=="number" then
+       n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+      elseif tk=="string" then
+       n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+      elseif tk=="boolean" then
+       n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+      elseif unknown then
+       n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
       end
-      local sk=sortedkeys(root) 
-      for i=1,#sk do
-        local k=sk[i]
-        local v=root[k]
-        local tv=type(v)
-        local tk=type(k)
-        if first and tk=="number" and k<=last and k>=first then
-          if tv=="number" then
-            n=n+1 t[n]=f_val_num(depth,v)
-          elseif tv=="string" then
-            n=n+1 t[n]=f_val_str(depth,v)
-          elseif tv=="table" then
-            if next(v)==nil then 
-              n=n+1 t[n]=f_val_not(depth)
-            else
-              local st=is_simple_table(v)
-              if st then
-                n=n+1 t[n]=f_val_seq(depth,st)
-              else
-                do_serialize(v,k,depth,level+1,true)
-              end
-            end
-          elseif tv=="boolean" then
-            n=n+1 t[n]=f_val_boo(depth,v)
-          elseif unknown then
-            n=n+1 t[n]=f_val_str(depth,tostring(v))
-          end
-        elseif tv=="number" then
-          if tk=="number" then
-            n=n+1 t[n]=f_key_num_value_num(depth,k,v)
-          elseif tk=="string" then
-            n=n+1 t[n]=f_key_str_value_num(depth,k,v)
-          elseif tk=="boolean" then
-            n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
-          elseif unknown then
-            n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
-          end
-        elseif tv=="string" then
-          if tk=="number" then
-            n=n+1 t[n]=f_key_num_value_str(depth,k,v)
-          elseif tk=="string" then
-            n=n+1 t[n]=f_key_str_value_str(depth,k,v)
-          elseif tk=="boolean" then
-            n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
-          elseif unknown then
-            n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
-          end
-        elseif tv=="table" then
-          if next(v)==nil then
-            if tk=="number" then
-              n=n+1 t[n]=f_key_num_value_not(depth,k)
-            elseif tk=="string" then
-              n=n+1 t[n]=f_key_str_value_not(depth,k)
-            elseif tk=="boolean" then
-              n=n+1 t[n]=f_key_boo_value_not(depth,k)
-            elseif unknown then
-              n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
-            end
-          else
-            local st=is_simple_table(v)
-            if not st then
-              do_serialize(v,k,depth,level+1)
-            elseif tk=="number" then
-              n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
-            elseif tk=="string" then
-              n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
-            elseif tk=="boolean" then
-              n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
-            elseif unknown then
-              n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
-            end
-          end
-        elseif tv=="boolean" then
-          if tk=="number" then
-            n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
-          elseif tk=="string" then
-            n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
-          elseif tk=="boolean" then
-            n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
-          elseif unknown then
-            n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
-          end
-        else
-          if tk=="number" then
-            n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
-          elseif tk=="string" then
-            n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
-          elseif tk=="boolean" then
-            n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
-          elseif unknown then
-            n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
-          end
-        end
-      end
+     end
+    elseif tv=="boolean" then
+     if tk=="number" then
+      n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+     elseif tk=="string" then
+      n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+     elseif tk=="boolean" then
+      n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+     elseif unknown then
+      n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+     end
+    else
+     if tk=="number" then
+      n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+     elseif tk=="string" then
+      n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+     elseif tk=="boolean" then
+      n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+     elseif unknown then
+      n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+     end
     end
-    if level>0 then
-      n=n+1 t[n]=f_stop(depth-1)
-    end
+   end
   end
-  local tname=type(name)
-  if tname=="string" then
-    if name=="return" then
-      t={ f_table_return() }
-    else
-      t={ f_table_name(name) }
-    end
-  elseif tname=="number" then
-    t={ f_table_entry(name) }
-  elseif tname=="boolean" then
-    if name then
-      t={ f_table_return() }
-    else
-      t={ f_table_direct() }
-    end
+  if level>0 then
+   n=n+1 t[n]=f_stop(depth-1)
+  end
+ end
+ local tname=type(name)
+ if tname=="string" then
+  if name=="return" then
+   t={ f_table_return() }
   else
-    t={ f_table_name("t") }
+   t={ f_table_name(name) }
   end
-  if root then
-    if getmetatable(root) then 
-      local dummy=root._w_h_a_t_e_v_e_r_ 
-      root._w_h_a_t_e_v_e_r_=nil
-    end
-    if next(root)~=nil then
-      local st=is_simple_table(root)
-      if st then
-        return t[1]..f_fin_seq(st) 
-      else
-        do_serialize(root,name,1,0)
-      end
-    end
+ elseif tname=="number" then
+  t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+  if name then
+   t={ f_table_return() }
+  else
+   t={ f_table_direct() }
   end
-  n=n+1
-  t[n]=f_table_finish()
-  return concat(t,"\n")
+ else
+  t={ f_table_name("t") }
+ end
+ if root then
+  if getmetatable(root) then 
+   local dummy=root._w_h_a_t_e_v_e_r_ 
+   root._w_h_a_t_e_v_e_r_=nil
+  end
+  if next(root)~=nil then
+   local st=is_simple_table(root)
+   if st then
+    return t[1]..f_fin_seq(st) 
+   else
+    do_serialize(root,name,1,0)
+   end
+  end
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
 end
 table.serialize=serialize
 if setinspector then
-  setinspector("table",function(v)
-    if type(v)=="table" then
-      print(serialize(v,"table",{ metacheck=false }))
-      return true
-    end
-  end)
+ setinspector("table",function(v)
+  if type(v)=="table" then
+   print(serialize(v,"table",{ metacheck=false }))
+   return true
+  end
+ end)
 end
+local mt={
+ __newindex=function(t,k,v)
+  local n=t.last+1
+  t.last=n
+  t.list[n]=k
+  t.hash[k]=v
+ end,
+ __index=function(t,k)
+  return t.hash[k]
+ end,
+ __len=function(t)
+  return t.last
+ end,
+}
+function table.orderedhash()
+ return setmetatable({ list={},hash={},last=0 },mt)
+end
+function table.ordered(t)
+ local n=t.last
+ if n>0 then
+  local l=t.list
+  local i=1
+  local h=t.hash
+  local f=function()
+   if i<=n then
+    local k=i
+    local v=h[l[k]]
+    i=i+1
+    return k,v
+   end
+  end
+  return f,1,h[l[1]]
+ else
+  return function() end
+ end
+end
 
 end -- closure
 
@@ -1797,11 +1791,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-sto']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
 utilities=utilities or {}
@@ -1808,154 +1802,154 @@
 utilities.storage=utilities.storage or {}
 local storage=utilities.storage
 function storage.mark(t)
-  if not t then
-    print("\nfatal error: storage cannot be marked\n")
-    os.exit()
-    return
-  end
-  local m=getmetatable(t)
-  if not m then
-    m={}
-    setmetatable(t,m)
-  end
-  m.__storage__=true
-  return t
+ if not t then
+  print("\nfatal error: storage cannot be marked\n")
+  os.exit()
+  return
+ end
+ local m=getmetatable(t)
+ if not m then
+  m={}
+  setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
 end
 function storage.allocate(t)
-  t=t or {}
-  local m=getmetatable(t)
-  if not m then
-    m={}
-    setmetatable(t,m)
-  end
-  m.__storage__=true
-  return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+  m={}
+  setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
 end
 function storage.marked(t)
-  local m=getmetatable(t)
-  return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
 end
 function storage.checked(t)
-  if not t then
-    report("\nfatal error: storage has not been allocated\n")
-    os.exit()
-    return
-  end
-  return t
+ if not t then
+  report("\nfatal error: storage has not been allocated\n")
+  os.exit()
+  return
+ end
+ return t
 end
 function storage.setinitializer(data,initialize)
-  local m=getmetatable(data) or {}
-  m.__index=function(data,k)
-    m.__index=nil 
-    initialize()
-    return data[k]
-  end
-  setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+  m.__index=nil 
+  initialize()
+  return data[k]
+ end
+ setmetatable(data,m)
 end
 local keyisvalue={ __index=function(t,k)
-  t[k]=k
-  return k
+ t[k]=k
+ return k
 end }
 function storage.sparse(t)
-  t=t or {}
-  setmetatable(t,keyisvalue)
-  return t
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
 end
-local function f_empty ()              return "" end 
-local function f_self (t,k) t[k]=k        return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0        return 0 end 
-local function f_ignore()                   end 
+local function f_empty ()         return "" end 
+local function f_self  (t,k) t[k]=k      return k  end
+local function f_table (t,k) local v={} t[k]=v return v  end
+local function f_number(t,k) t[k]=0      return 0  end 
+local function f_ignore()          end 
 local f_index={
-  ["empty"]=f_empty,
-  ["self"]=f_self,
-  ["table"]=f_table,
-  ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
 }
 function table.setmetatableindex(t,f)
-  if type(t)~="table" then
-    f,t=t,{}
-  end
-  local m=getmetatable(t)
-  local i=f_index[f] or f
-  if m then
-    m.__index=i
-  else
-    setmetatable(t,{ __index=i })
-  end
-  return t
+ if type(t)~="table" then
+  f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+  m.__index=i
+ else
+  setmetatable(t,{ __index=i })
+ end
+ return t
 end
 local f_index={
-  ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
 }
 function table.setmetatablenewindex(t,f)
-  if type(t)~="table" then
-    f,t=t,{}
-  end
-  local m=getmetatable(t)
-  local i=f_index[f] or f
-  if m then
-    m.__newindex=i
-  else
-    setmetatable(t,{ __newindex=i })
-  end
-  return t
+ if type(t)~="table" then
+  f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+  m.__newindex=i
+ else
+  setmetatable(t,{ __newindex=i })
+ end
+ return t
 end
 function table.setmetatablecall(t,f)
-  if type(t)~="table" then
-    f,t=t,{}
-  end
-  local m=getmetatable(t)
-  if m then
-    m.__call=f
-  else
-    setmetatable(t,{ __call=f })
-  end
-  return t
+ if type(t)~="table" then
+  f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+  m.__call=f
+ else
+  setmetatable(t,{ __call=f })
+ end
+ return t
 end
 function table.setmetatableindices(t,f,n,c)
-  if type(t)~="table" then
-    f,t=t,{}
-  end
-  local m=getmetatable(t)
-  local i=f_index[f] or f
-  if m then
-    m.__index=i
-    m.__newindex=n
-    m.__call=c
-  else
-    setmetatable(t,{
-      __index=i,
-      __newindex=n,
-      __call=c,
-    })
-  end
-  return t
+ if type(t)~="table" then
+  f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+  m.__index=i
+  m.__newindex=n
+  m.__call=c
+ else
+  setmetatable(t,{
+   __index=i,
+   __newindex=n,
+   __call=c,
+  })
+ end
+ return t
 end
 function table.setmetatablekey(t,key,value)
-  local m=getmetatable(t)
-  if not m then
-    m={}
-    setmetatable(t,m)
-  end
-  m[key]=value
-  return t
+ local m=getmetatable(t)
+ if not m then
+  m={}
+  setmetatable(t,m)
+ end
+ m[key]=value
+ return t
 end
 function table.getmetatablekey(t,key,value)
-  local m=getmetatable(t)
-  return m and m[key]
+ local m=getmetatable(t)
+ return m and m[key]
 end
 function table.makeweak(t)
-  if not t then
-    t={}
-  end
-  local m=getmetatable(t)
-  if m then
-    m.__mode="v"
-  else
-    setmetatable(t,{ __mode="v" })
-  end
-  return t
+ if not t then
+  t={}
+ end
+ local m=getmetatable(t)
+ if m then
+  m.__mode="v"
+ else
+  setmetatable(t,{ __mode="v" })
+ end
+ return t
 end
 
 end -- closure
@@ -1963,11 +1957,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-prs']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local lpeg,table,string=lpeg,table,string
 local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -2009,8 +2003,8 @@
 local nobracket=1-(lbracket+rbracket)
 local escape,left,right=P("\\"),P('{'),P('}')
 lpegpatterns.balanced=P {
-  [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
-  [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
 }
 local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
 local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -2018,9 +2012,9 @@
 local spaces=space^0
 local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
 local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces 
+lpegpatterns.nestedbraces=nestedbraces  
 lpegpatterns.nestedparents=nestedparents 
-lpegpatterns.nested=nestedbraces 
+lpegpatterns.nested=nestedbraces  
 lpegpatterns.argument=argument   
 lpegpatterns.content=content    
 local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
@@ -2032,7 +2026,7 @@
 local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
 local hash={}
 local function set(key,value)
-  hash[key]=value
+ hash[key]=value
 end
 local pattern_a_s=(pattern_a/set)^1
 local pattern_b_s=(pattern_b/set)^1
@@ -2043,78 +2037,78 @@
 patterns.settings_to_hash_c=pattern_c_s
 patterns.settings_to_hash_d=pattern_d_s
 function parsers.make_settings_to_hash_pattern(set,how)
-  if how=="strict" then
-    return (pattern_c/set)^1
-  elseif how=="tolerant" then
-    return (pattern_b/set)^1
-  else
-    return (pattern_a/set)^1
-  end
+ if how=="strict" then
+  return (pattern_c/set)^1
+ elseif how=="tolerant" then
+  return (pattern_b/set)^1
+ else
+  return (pattern_a/set)^1
+ end
 end
 function parsers.settings_to_hash(str,existing)
-  if not str or str=="" then
-    return {}
-  elseif type(str)=="table" then
-    if existing then
-      for k,v in next,str do
-        existing[k]=v
-      end
-      return exiting
-    else
-      return str
-    end
+ if not str or str=="" then
+  return {}
+ elseif type(str)=="table" then
+  if existing then
+   for k,v in next,str do
+    existing[k]=v
+   end
+   return exiting
   else
-    hash=existing or {}
-    lpegmatch(pattern_a_s,str)
-    return hash
+   return str
   end
+ else
+  hash=existing or {}
+  lpegmatch(pattern_a_s,str)
+  return hash
+ end
 end
 function parsers.settings_to_hash_colon_too(str)
-  if not str or str=="" then
-    return {}
-  elseif type(str)=="table" then
-    return str
-  else
-    hash={}
-    lpegmatch(pattern_d_s,str)
-    return hash
-  end
+ if not str or str=="" then
+  return {}
+ elseif type(str)=="table" then
+  return str
+ else
+  hash={}
+  lpegmatch(pattern_d_s,str)
+  return hash
+ end
 end
 function parsers.settings_to_hash_tolerant(str,existing)
-  if not str or str=="" then
-    return {}
-  elseif type(str)=="table" then
-    if existing then
-      for k,v in next,str do
-        existing[k]=v
-      end
-      return exiting
-    else
-      return str
-    end
+ if not str or str=="" then
+  return {}
+ elseif type(str)=="table" then
+  if existing then
+   for k,v in next,str do
+    existing[k]=v
+   end
+   return exiting
   else
-    hash=existing or {}
-    lpegmatch(pattern_b_s,str)
-    return hash
+   return str
   end
+ else
+  hash=existing or {}
+  lpegmatch(pattern_b_s,str)
+  return hash
+ end
 end
 function parsers.settings_to_hash_strict(str,existing)
-  if not str or str=="" then
-    return nil
-  elseif type(str)=="table" then
-    if existing then
-      for k,v in next,str do
-        existing[k]=v
-      end
-      return exiting
-    else
-      return str
-    end
-  elseif str and str~="" then
-    hash=existing or {}
-    lpegmatch(pattern_c_s,str)
-    return next(hash) and hash
+ if not str or str=="" then
+  return nil
+ elseif type(str)=="table" then
+  if existing then
+   for k,v in next,str do
+    existing[k]=v
+   end
+   return exiting
+  else
+   return str
   end
+ elseif str and str~="" then
+  hash=existing or {}
+  lpegmatch(pattern_c_s,str)
+  return next(hash) and hash
+ end
 end
 local separator=comma*space^0
 local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
@@ -2121,222 +2115,222 @@
 local pattern=spaces*Ct(value*(separator*value)^0)
 patterns.settings_to_array=pattern
 function parsers.settings_to_array(str,strict)
-  if not str or str=="" then
-    return {}
-  elseif type(str)=="table" then
-    return str
-  elseif strict then
-    if find(str,"{",1,true) then
-      return lpegmatch(pattern,str)
-    else
-      return { str }
-    end
-  elseif find(str,",",1,true) then
-    return lpegmatch(pattern,str)
+ if not str or str=="" then
+  return {}
+ elseif type(str)=="table" then
+  return str
+ elseif strict then
+  if find(str,"{",1,true) then
+   return lpegmatch(pattern,str)
   else
-    return { str }
+   return { str }
   end
+ elseif find(str,",",1,true) then
+  return lpegmatch(pattern,str)
+ else
+  return { str }
+ end
 end
 function parsers.settings_to_numbers(str)
-  if not str or str=="" then
-    return {}
-  end
-  if type(str)=="table" then
-  elseif find(str,",",1,true) then
-    str=lpegmatch(pattern,str)
-  else
-    return { tonumber(str) }
-  end
-  for i=1,#str do
-    str[i]=tonumber(str[i])
-  end
-  return str
+ if not str or str=="" then
+  return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+  str=lpegmatch(pattern,str)
+ else
+  return { tonumber(str) }
+ end
+ for i=1,#str do
+  str[i]=tonumber(str[i])
+ end
+ return str
 end
 local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
 local pattern=spaces*Ct(value*(separator*value)^0)
 function parsers.settings_to_array_obey_fences(str)
-  return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
 end
 local cache_a={}
 local cache_b={}
 function parsers.groupedsplitat(symbol,withaction)
-  if not symbol then
-    symbol=","
+ if not symbol then
+  symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+  local symbols=S(symbol)
+  local separator=space^0*symbols*space^0
+  local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+  if withaction then
+   local withvalue=Carg(1)*value/function(f,s) return f(s) end
+   pattern=spaces*withvalue*(separator*withvalue)^0
+   cache_b[symbol]=pattern
+  else
+   pattern=spaces*Ct(value*(separator*value)^0)
+   cache_a[symbol]=pattern
   end
-  local pattern=(withaction and cache_b or cache_a)[symbol]
-  if not pattern then
-    local symbols=S(symbol)
-    local separator=space^0*symbols*space^0
-    local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
-    if withaction then
-      local withvalue=Carg(1)*value/function(f,s) return f(s) end
-      pattern=spaces*withvalue*(separator*withvalue)^0
-      cache_b[symbol]=pattern
-    else
-      pattern=spaces*Ct(value*(separator*value)^0)
-      cache_a[symbol]=pattern
-    end
-  end
-  return pattern
+ end
+ return pattern
 end
 local pattern_a=parsers.groupedsplitat(",",false)
 local pattern_b=parsers.groupedsplitat(",",true)
 function parsers.stripped_settings_to_array(str)
-  if not str or str=="" then
-    return {}
-  else
-    return lpegmatch(pattern_a,str)
-  end
+ if not str or str=="" then
+  return {}
+ else
+  return lpegmatch(pattern_a,str)
+ end
 end
 function parsers.process_stripped_settings(str,action)
-  if not str or str=="" then
-    return {}
-  else
-    return lpegmatch(pattern_b,str,1,action)
-  end
+ if not str or str=="" then
+  return {}
+ else
+  return lpegmatch(pattern_b,str,1,action)
+ end
 end
 local function set(t,v)
-  t[#t+1]=v
+ t[#t+1]=v
 end
 local value=P(Carg(1)*value)/set
 local pattern=value*(separator*value)^0*Carg(1)
 function parsers.add_settings_to_array(t,str)
-  return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
 end
 function parsers.hash_to_string(h,separator,yes,no,strict,omit)
-  if h then
-    local t,tn,s={},0,sortedkeys(h)
-    omit=omit and tohash(omit)
-    for i=1,#s do
-      local key=s[i]
-      if not omit or not omit[key] then
-        local value=h[key]
-        if type(value)=="boolean" then
-          if yes and no then
-            if value then
-              tn=tn+1
-              t[tn]=key..'='..yes
-            elseif not strict then
-              tn=tn+1
-              t[tn]=key..'='..no
-            end
-          elseif value or not strict then
-            tn=tn+1
-            t[tn]=key..'='..tostring(value)
-          end
-        else
-          tn=tn+1
-          t[tn]=key..'='..value
-        end
+ if h then
+  local t,tn,s={},0,sortedkeys(h)
+  omit=omit and tohash(omit)
+  for i=1,#s do
+   local key=s[i]
+   if not omit or not omit[key] then
+    local value=h[key]
+    if type(value)=="boolean" then
+     if yes and no then
+      if value then
+       tn=tn+1
+       t[tn]=key..'='..yes
+      elseif not strict then
+       tn=tn+1
+       t[tn]=key..'='..no
       end
+     elseif value or not strict then
+      tn=tn+1
+      t[tn]=key..'='..tostring(value)
+     end
+    else
+     tn=tn+1
+     t[tn]=key..'='..value
     end
-    return concat(t,separator or ",")
-  else
-    return ""
+   end
   end
+  return concat(t,separator or ",")
+ else
+  return ""
+ end
 end
 function parsers.array_to_string(a,separator)
-  if a then
-    return concat(a,separator or ",")
-  else
-    return ""
-  end
+ if a then
+  return concat(a,separator or ",")
+ else
+  return ""
+ end
 end
 local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
 function utilities.parsers.settings_to_set(str)
-  return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
 end
 hashes.settings_to_set=table.setmetatableindex(function(t,k) 
-  local v=k and lpegmatch(pattern,k) or {}
-  t[k]=v
-  return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
 end)
 getmetatable(hashes.settings_to_set).__mode="kv" 
 function parsers.simple_hash_to_string(h,separator)
-  local t,tn={},0
-  for k,v in sortedhash(h) do
-    if v then
-      tn=tn+1
-      t[tn]=k
-    end
+ local t,tn={},0
+ for k,v in sortedhash(h) do
+  if v then
+   tn=tn+1
+   t[tn]=k
   end
-  return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
 end
 local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
 local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
 local splitter=setting^1
 function utilities.parsers.options_to_hash(str,target)
-  return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
 end
 local splitter=lpeg.tsplitat(" ")
 function utilities.parsers.options_to_array(str)
-  return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
 end
 local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
 local pattern_a=spaces*Ct(value*(separator*value)^0)
 local function repeater(n,str)
-  if not n then
-    return str
+ if not n then
+  return str
+ else
+  local s=lpegmatch(pattern_a,str)
+  if n==1 then
+   return unpack(s)
   else
-    local s=lpegmatch(pattern_a,str)
-    if n==1 then
-      return unpack(s)
-    else
-      local t,tn={},0
-      for i=1,n do
-        for j=1,#s do
-          tn=tn+1
-          t[tn]=s[j]
-        end
-      end
-      return unpack(t)
+   local t,tn={},0
+   for i=1,n do
+    for j=1,#s do
+     tn=tn+1
+     t[tn]=s[j]
     end
+   end
+   return unpack(t)
   end
+ end
 end
 local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
 local pattern_b=spaces*Ct(value*(separator*value)^0)
 function parsers.settings_to_array_with_repeat(str,expand) 
-  if expand then
-    return lpegmatch(pattern_b,str) or {}
-  else
-    return lpegmatch(pattern_a,str) or {}
-  end
+ if expand then
+  return lpegmatch(pattern_b,str) or {}
+ else
+  return lpegmatch(pattern_a,str) or {}
+ end
 end
 local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
 local pattern=Ct((space+value)^0)
 function parsers.arguments_to_table(str)
-  return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
 end
 function parsers.getparameters(self,class,parentclass,settings)
-  local sc=self[class]
-  if not sc then
-    sc={}
-    self[class]=sc
-    if parentclass then
-      local sp=self[parentclass]
-      if not sp then
-        sp={}
-        self[parentclass]=sp
-      end
-      setmetatableindex(sc,sp)
-    end
+ local sc=self[class]
+ if not sc then
+  sc={}
+  self[class]=sc
+  if parentclass then
+   local sp=self[parentclass]
+   if not sp then
+    sp={}
+    self[parentclass]=sp
+   end
+   setmetatableindex(sc,sp)
   end
-  parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
 end
 function parsers.listitem(str)
-  return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
 end
 local pattern=Cs { "start",
-  start=V("one")+V("two")+V("three"),
-  rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
-  thousand=digit*digit*digit,
-  one=digit*V("rest"),
-  two=digit*digit*V("rest"),
-  three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
 }
 lpegpatterns.splitthousands=pattern 
 function parsers.splitthousands(str)
-  return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
 end
 local optionalwhitespace=whitespace^0
 lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -2350,75 +2344,75 @@
 local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
 local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
 function parsers.keq_to_hash(str)
-  if str and str~="" then
-    return lpegmatch(pattern,str)
-  else
-    return {}
-  end
+ if str and str~="" then
+  return lpegmatch(pattern,str)
+ else
+  return {}
+ end
 end
 local defaultspecification={ separator=",",quote='"' }
 function parsers.csvsplitter(specification)
-  specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
-  local separator=specification.separator
-  local quotechar=specification.quote
-  local separator=S(separator~="" and separator or ",")
-  local whatever=C((1-separator-newline)^0)
-  if quotechar and quotechar~="" then
-    local quotedata=nil
-    for chr in gmatch(quotechar,".") do
-      local quotechar=P(chr)
-      local quoteword=quotechar*C((1-quotechar)^0)*quotechar
-      if quotedata then
-        quotedata=quotedata+quoteword
-      else
-        quotedata=quoteword
-      end
-    end
-    whatever=quotedata+whatever
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+  local quotedata=nil
+  for chr in gmatch(quotechar,".") do
+   local quotechar=P(chr)
+   local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+   if quotedata then
+    quotedata=quotedata+quoteword
+   else
+    quotedata=quoteword
+   end
   end
-  local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
-  return function(data)
-    return lpegmatch(parser,data)
-  end
+  whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+  return lpegmatch(parser,data)
+ end
 end
 function parsers.rfc4180splitter(specification)
-  specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
-  local separator=specification.separator 
-  local quotechar=P(specification.quote) 
-  local dquotechar=quotechar*quotechar  
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator 
+ local quotechar=P(specification.quote)  
+ local dquotechar=quotechar*quotechar   
 /specification.quote
-  local separator=S(separator~="" and separator or ",")
-  local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
-  local non_escaped=C((1-quotechar-newline-separator)^1)
-  local field=escaped+non_escaped+Cc("")
-  local record=Ct(field*(separator*field)^1)
-  local headerline=record*Cp()
-  local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
-  local headeryes=Ct(morerecords)
-  local headernop=Ct(record*morerecords)
-  return function(data,getheader)
-    if getheader then
-      local header,position=lpegmatch(headerline,data)
-      local data=lpegmatch(headeryes,data,position)
-      return data,header
-    else
-      return lpegmatch(headernop,data)
-    end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+  if getheader then
+   local header,position=lpegmatch(headerline,data)
+   local data=lpegmatch(headeryes,data,position)
+   return data,header
+  else
+   return lpegmatch(headernop,data)
   end
+ end
 end
 local function ranger(first,last,n,action)
-  if not first then
-  elseif last==true then
-    for i=first,n or first do
-      action(i)
-    end
-  elseif last then
-    for i=first,last do
-      action(i)
-    end
-  else
-    action(first)
+ if not first then
+ elseif last==true then
+  for i=first,n or first do
+   action(i)
   end
+ elseif last then
+  for i=first,last do
+   action(i)
+  end
+ else
+  action(first)
+ end
 end
 local cardinal=lpegpatterns.cardinal/tonumber
 local spacers=lpegpatterns.spacer^0
@@ -2426,89 +2420,89 @@
 local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
 local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring 
 function parsers.stepper(str,n,action)
-  if type(n)=="function" then
-    lpegmatch(stepper,str,1,false,n or print)
-  else
-    lpegmatch(stepper,str,1,n,action or print)
-  end
+ if type(n)=="function" then
+  lpegmatch(stepper,str,1,false,n or print)
+ else
+  lpegmatch(stepper,str,1,n,action or print)
+ end
 end
 local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
 local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
 patterns.unittotex=pattern
 function parsers.unittotex(str,textmode)
-  return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
 end
 local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
 function parsers.unittoxml(str)
-  return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
 end
 local cache={}
 local spaces=lpegpatterns.space^0
 local dummy=function() end
 setmetatableindex(cache,function(t,k)
-  local separator=P(k)
-  local value=(1-separator)^0
-  local pattern=spaces*C(value)*separator^0*Cp()
-  t[k]=pattern
-  return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
 end)
 local commalistiterator=cache[","]
 function utilities.parsers.iterator(str,separator)
-  local n=#str
-  if n==0 then
-    return dummy
-  else
-    local pattern=separator and cache[separator] or commalistiterator
-    local p=1
-    return function()
-      if p<=n then
-        local s,e=lpegmatch(pattern,str,p)
-        if e then
-          p=e
-          return s
-        end
-      end
+ local n=#str
+ if n==0 then
+  return dummy
+ else
+  local pattern=separator and cache[separator] or commalistiterator
+  local p=1
+  return function()
+   if p<=n then
+    local s,e=lpegmatch(pattern,str,p)
+    if e then
+     p=e
+     return s
     end
+   end
   end
+ end
 end
 local function initialize(t,name)
-  local source=t[name]
-  if source then
-    local result={}
-    for k,v in next,t[name] do
-      result[k]=v
-    end
-    return result
-  else
-    return {}
+ local source=t[name]
+ if source then
+  local result={}
+  for k,v in next,t[name] do
+   result[k]=v
   end
+  return result
+ else
+  return {}
+ end
 end
 local function fetch(t,name)
-  return t[name] or {}
+ return t[name] or {}
 end
 local function process(result,more)
-  for k,v in next,more do
-    result[k]=v
-  end
-  return result
+ for k,v in next,more do
+  result[k]=v
+ end
+ return result
 end
 local name=C((1-S(", "))^1)
 local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
 local merge=Cf(parser,process)
 function utilities.parsers.mergehashes(hash,list)
-  return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
 end
 function utilities.parsers.runtime(time)
-  if not time then
-    time=os.runtime()
-  end
-  local days=div(time,24*60*60)
-  time=mod(time,24*60*60)
-  local hours=div(time,60*60)
-  time=mod(time,60*60)
-  local minutes=div(time,60)
-  local seconds=mod(time,60)
-  return days,hours,minutes,seconds
+ if not time then
+  time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
 end
 local spacing=whitespace^0
 local apply=P("->")
@@ -2516,11 +2510,11 @@
 local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
 local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
 function utilities.parsers.splitmethod(str,default)
-  if str then
-    return lpegmatch(pattern,str,1,default or false)
-  else
-    return default or false,""
-  end
+ if str then
+  return lpegmatch(pattern,str,1,default or false)
+ else
+  return default or false,""
+ end
 end
 
 end -- closure
@@ -2528,11 +2522,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-dim']={
-  version=1.001,
-  comment="support for dimensions",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="support for dimensions",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local format,match,gsub,type,setmetatable=string.format,string.match,string.gsub,type,setmetatable
 local P,S,R,Cc,C,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.Cc,lpeg.C,lpeg.match
@@ -2546,34 +2540,34 @@
 number.tonumberf=function(n) return lpegmatch(p_stripzeros,format("%.20f",n)) end
 number.tonumberg=function(n) return format("%.20g",n) end
 local dimenfactors=allocate {
-  ["pt"]=1/65536,
-  ["in"]=(100/7227)/65536,
-  ["cm"]=(254/7227)/65536,
-  ["mm"]=(2540/7227)/65536,
-  ["sp"]=1,
-  ["bp"]=(7200/7227)/65536,
-  ["pc"]=(1/12)/65536,
-  ["dd"]=(1157/1238)/65536,
-  ["cc"]=(1157/14856)/65536,
-  ["nd"]=(20320/21681)/65536,
-  ["nc"]=(5080/65043)/65536
+ ["pt"]=1/65536,
+ ["in"]=(100/7227)/65536,
+ ["cm"]=(254/7227)/65536,
+ ["mm"]=(2540/7227)/65536,
+ ["sp"]=1,
+ ["bp"]=(7200/7227)/65536,
+ ["pc"]=(1/12)/65536,
+ ["dd"]=(1157/1238)/65536,
+ ["cc"]=(1157/14856)/65536,
+ ["nd"]=(20320/21681)/65536,
+ ["nc"]=(5080/65043)/65536
 }
 local f_none=formatters["%s%s"]
 local f_true=formatters["%0.5F%s"]
 local function numbertodimen(n,unit,fmt) 
-  if type(n)=='string' then
-    return n
+ if type(n)=='string' then
+  return n
+ else
+  unit=unit or 'pt'
+  n=n*dimenfactors[unit]
+  if not fmt then
+   fmt=f_none(n,unit)
+  elseif fmt==true then
+   fmt=f_true(n,unit)
   else
-    unit=unit or 'pt'
-    n=n*dimenfactors[unit]
-    if not fmt then
-      fmt=f_none(n,unit)
-    elseif fmt==true then
-      fmt=f_true(n,unit)
-    else
-      return formatters[fmt](n,unit)
-    end
+   return formatters[fmt](n,unit)
   end
+ end
 end
 number.maxdimen=1073741823
 number.todimen=numbertodimen
@@ -2583,13 +2577,13 @@
 function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
 function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end
 function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
-function number.toscaledpoints(n)   return      n.."sp"   end
-function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
+function number.toscaledpoints(n)  return   n.."sp"   end
+function number.tobasepoints  (n,fmt) return numbertodimen(n,"bp",fmt) end
 function number.topicas    (n,fmt) return numbertodimen(n "pc",fmt) end
 function number.todidots   (n,fmt) return numbertodimen(n,"dd",fmt) end
-function number.tociceros   (n,fmt) return numbertodimen(n,"cc",fmt) end
-function number.tonewdidots  (n,fmt) return numbertodimen(n,"nd",fmt) end
-function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
+function number.tociceros  (n,fmt) return numbertodimen(n,"cc",fmt) end
+function number.tonewdidots   (n,fmt) return numbertodimen(n,"nd",fmt) end
+function number.tonewciceros  (n,fmt) return numbertodimen(n,"nc",fmt) end
 local amount=(S("+-")^0*R("09")^0*P(".")^0*R("09")^0)+Cc("0")
 local unit=R("az")^1+P("%")
 local dimenpair=amount/tonumber*(unit^1/dimenfactors+Cc(1)) 
@@ -2596,10 +2590,10 @@
 lpeg.patterns.dimenpair=dimenpair
 local splitter=amount/tonumber*C(unit^1)
 function number.splitdimen(str)
-  return lpegmatch(splitter,str)
+ return lpegmatch(splitter,str)
 end
 setmetatableindex(dimenfactors,function(t,s)
-  return false
+ return false
 end)
 local stringtodimen 
 local amount=S("+-")^0*R("09")^0*S(".,")^0*R("09")^0
@@ -2608,106 +2602,106 @@
 lpeg.patterns.validdimen=validdimen
 local dimensions={}
 function dimensions.__add(a,b)
-  local ta,tb=type(a),type(b)
-  if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
-  if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
-  return setmetatable({ a+b },dimensions)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a+b },dimensions)
 end
 function dimensions.__sub(a,b)
-  local ta,tb=type(a),type(b)
-  if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
-  if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
-  return setmetatable({ a-b },dimensions)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a-b },dimensions)
 end
 function dimensions.__mul(a,b)
-  local ta,tb=type(a),type(b)
-  if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
-  if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
-  return setmetatable({ a*b },dimensions)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a*b },dimensions)
 end
 function dimensions.__div(a,b)
-  local ta,tb=type(a),type(b)
-  if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
-  if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
-  return setmetatable({ a/b },dimensions)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a/b },dimensions)
 end
 function dimensions.__unm(a)
-  local ta=type(a)
-  if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
-  return setmetatable({-a },dimensions)
+ local ta=type(a)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ return setmetatable({-a },dimensions)
 end
 function dimensions.__lt(a,b)
-  return a[1]<b[1]
+ return a[1]<b[1]
 end
 function dimensions.__eq(a,b)
-  return a[1]==b[1]
+ return a[1]==b[1]
 end
 function dimensions.__tostring(a)
-  return a[1]/65536 .."pt" 
+ return a[1]/65536 .."pt" 
 end
 function dimensions.__index(tab,key)
-  local d=dimenfactors[key]
-  if not d then
-    error("illegal property of dimen: "..key)
-    d=1
-  end
-  return 1/d
+ local d=dimenfactors[key]
+ if not d then
+  error("illegal property of dimen: "..key)
+  d=1
+ end
+ return 1/d
 end
-  dimenfactors["ex"]=4*1/65536 
-  dimenfactors["em"]=10*1/65536
+   dimenfactors["ex"]=4*1/65536 
+   dimenfactors["em"]=10*1/65536
 local known={} setmetatable(known,{ __mode="v" })
 function dimen(a)
-  if a then
-    local ta=type(a)
-    if ta=="string" then
-      local k=known[a]
-      if k then
-        a=k
-      else
-        local value,unit=lpegmatch(dimenpair,a)
-        if value and unit then
-          k=value/unit 
-        else
-          k=0
-        end
-        known[a]=k
-        a=k
-      end
-    elseif ta=="table" then
-      a=a[1]
+ if a then
+  local ta=type(a)
+  if ta=="string" then
+   local k=known[a]
+   if k then
+    a=k
+   else
+    local value,unit=lpegmatch(dimenpair,a)
+    if value and unit then
+     k=value/unit 
+    else
+     k=0
     end
-    return setmetatable({ a },dimensions)
-  else
-    return setmetatable({ 0 },dimensions)
+    known[a]=k
+    a=k
+   end
+  elseif ta=="table" then
+   a=a[1]
   end
+  return setmetatable({ a },dimensions)
+ else
+  return setmetatable({ 0 },dimensions)
+ end
 end
 function string.todimen(str) 
-  if type(str)=="number" then
-    return str
-  else
-    local k=known[str]
-    if not k then
-      local value,unit=lpegmatch(dimenpair,str)
-      if value and unit then
-        k=value/unit 
-      else
-        k=0
-      end
-      known[str]=k
-    end
-    return k
+ if type(str)=="number" then
+  return str
+ else
+  local k=known[str]
+  if not k then
+   local value,unit=lpegmatch(dimenpair,str)
+   if value and unit then
+    k=value/unit 
+   else
+    k=0
+   end
+   known[str]=k
   end
+  return k
+ end
 end
 stringtodimen=string.todimen 
 function number.toscaled(d)
-  return format("%0.5f",d/0x10000) 
+ return format("%0.5f",d/0x10000) 
 end
 function number.percent(n,d) 
-  d=d or texget("hsize")
-  if type(d)=="string" then
-    d=stringtodimen(d)
-  end
-  return (n/100)*d
+ d=d or texget("hsize")
+ if type(d)=="string" then
+  d=stringtodimen(d)
+ end
+ return (n/100)*d
 end
 number["%"]=number.percent
 
@@ -2716,15 +2710,15 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-jsn']={
-  version=1.001,
-  comment="companion to m-json.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to m-json.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local P,V,R,S,C,Cc,Cs,Ct,Cf,Cg=lpeg.P,lpeg.V,lpeg.R,lpeg.S,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Cf,lpeg.Cg
 local lpegmatch=lpeg.match
-local format=string.format
+local format,gsub=string.format,string.gsub
 local utfchar=utf.char
 local concat=table.concat
 local tonumber,tostring,rawset,type,next=tonumber,tostring,rawset,type,next
@@ -2740,13 +2734,15 @@
 local whitespace=lpeg.patterns.whitespace
 local optionalws=whitespace^0
 local escapes={
-  ["b"]="\010",
-  ["f"]="\014",
-  ["n"]="\n",
-  ["r"]="\r",
-  ["t"]="\t",
+ ["b"]="\010",
+ ["f"]="\014",
+ ["n"]="\n",
+ ["r"]="\r",
+ ["t"]="\t",
 }
-local escape_un=C(P("\\u")/"0x"*S("09","AF","af"))/function(s) return utfchar(tonumber(s)) end
+local escape_un=P("\\u")/""*(C(R("09","AF","af")^-4)/function(s)
+ return utfchar(tonumber(s,16))
+end)
 local escape_bs=P([[\]])/""*(P(1)/escapes) 
 local jstring=dquote*Cs((escape_un+escape_bs+(1-dquote))^0)*dquote
 local jtrue=P("true")*Cc(true)
@@ -2755,75 +2751,90 @@
 local jnumber=(1-whitespace-rparent-rbrace-comma)^1/tonumber
 local key=jstring
 local jsonconverter={ "value",
-  hash=lbrace*Cf(Ct("")*(V("pair")*(comma*V("pair"))^0+optionalws),rawset)*rbrace,
-  pair=Cg(optionalws*key*optionalws*colon*V("value")),
-  array=Ct(lparent*(V("value")*(comma*V("value"))^0+optionalws)*rparent),
-  value=optionalws*(jstring+V("hash")+V("array")+jtrue+jfalse+jnull+jnumber)*optionalws,
+ hash=lbrace*Cf(Ct("")*(V("pair")*(comma*V("pair"))^0+optionalws),rawset)*rbrace,
+ pair=Cg(optionalws*key*optionalws*colon*V("value")),
+ array=Ct(lparent*(V("value")*(comma*V("value"))^0+optionalws)*rparent),
+ value=optionalws*(jstring+V("hash")+V("array")+jtrue+jfalse+jnull+jnumber)*optionalws,
 }
 function json.tolua(str)
-  return lpegmatch(jsonconverter,str)
+ return lpegmatch(jsonconverter,str)
 end
-local function tojson(value,t) 
-  local kind=type(value)
-  if kind=="table" then
-    local done=false
-    local size=#value
-    if size==0 then
-      for k,v in next,value do
-        if done then
-          t[#t+1]=","
-        else
-          t[#t+1]="{"
-          done=true
-        end
-        t[#t+1]=format("%q:",k)
-        tojson(v,t)
-      end
-      if done then
-        t[#t+1]="}"
-      else
-        t[#t+1]="{}"
-      end
-    elseif size==1 then
-      t[#t+1]="["
-      tojson(value[1],t)
-      t[#t+1]="]"
+local escaper
+local function tojson(value,t,n) 
+ local kind=type(value)
+ if kind=="table" then
+  local done=false
+  local size=#value
+  if size==0 then
+   for k,v in next,value do
+    if done then
+     n=n+1;t[n]=","
     else
-      for i=1,size do
-        if done then
-          t[#t+1]=","
-        else
-          t[#t+1]="["
-          done=true
-        end
-        tojson(value[i],t)
-      end
-      t[#t+1]="]"
+     n=n+1;t[n]="{"
+     done=true
     end
-  elseif kind=="string" then
-    t[#t+1]=format("%q",value)
-  elseif kind=="number" then
-    t[#t+1]=value
-  elseif kind=="boolean" then
-    t[#t+1]=tostring(value)
+    n=n+1;t[n]=format("%q:",k)
+    t,n=tojson(v,t,n)
+   end
+   if done then
+    n=n+1;t[n]="}"
+   else
+    n=n+1;t[n]="{}"
+   end
+  elseif size==1 then
+   n=n+1;t[n]="["
+   t,n=tojson(value[1],t,n)
+   n=n+1;t[n]="]"
+  else
+   for i=1,size do
+    if done then
+     n=n+1;t[n]=","
+    else
+     n=n+1;t[n]="["
+     done=true
+    end
+    t,n=tojson(value[i],t,n)
+   end
+   n=n+1;t[n]="]"
   end
-  return t
+ elseif kind=="string"  then
+  n=n+1;t[n]='"'
+  n=n+1;t[n]=lpegmatch(escaper,value) or value
+  n=n+1;t[n]='"'
+ elseif kind=="number" then
+  n=n+1;t[n]=value
+ elseif kind=="boolean" then
+  n=n+1;t[n]=tostring(value)
+ end
+ return t,n
 end
 function json.tostring(value)
-  local kind=type(value)
-  if kind=="table" then
-    return concat(tojson(value,{}),"")
-  elseif kind=="string" or kind=="number" then
-    return value
-  else
-    return tostring(value)
+ local kind=type(value)
+ if kind=="table" then
+  if not escaper then
+   local escapes={
+    ["\\"]="\\u005C",
+    ["\""]="\\u0022",
+   }
+   for i=0,0x20 do
+    escapes[utfchar(i)]=format("\\u%04X",i)
+   end
+   escaper=Cs((
+    (R('\0\x20')+S('\"\\'))/escapes+P(1)
+   )^1 )
   end
+  return concat((tojson(value,{},0)))
+ elseif kind=="string" or kind=="number" then
+  return lpegmatch(escaper,value) or value
+ else
+  return tostring(value)
+ end
 end
 function json.load(filename)
-  local data=io.loaddata(filename)
-  if data then
-    return lpegmatch(jsonconverter,data)
-  end
+ local data=io.loaddata(filename)
+ if data then
+  return lpegmatch(jsonconverter,data)
+ end
 end
 return json
 
@@ -2832,11 +2843,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['trac-inf']={
-  version=1.001,
-  comment="companion to trac-inf.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local type,tonumber,select=type,tonumber,select
 local format,lower,find=string.format,string.lower,string.find
@@ -2851,86 +2862,86 @@
 statistics.threshold=0.01
 local statusinfo,n,registered,timers={},0,{},{}
 setmetatableindex(timers,function(t,k)
-  local v={ timing=0,loadtime=0 }
-  t[k]=v
-  return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
 end)
 local function hastiming(instance)
-  return instance and timers[instance]
+ return instance and timers[instance]
 end
 local function resettiming(instance)
-  timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
 local function starttiming(instance,reset)
-  local timer=timers[instance or "notimer"]
-  local it=timer.timing
-  if reset then
-    it=0
-    timer.loadtime=0
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if reset then
+  it=0
+  timer.loadtime=0
+ end
+ if it==0 then
+  timer.starttime=ticks()
+  if not timer.loadtime then
+   timer.loadtime=0
   end
-  if it==0 then
-    timer.starttime=ticks()
-    if not timer.loadtime then
-      timer.loadtime=0
-    end
-  end
-  timer.timing=it+1
+ end
+ timer.timing=it+1
 end
 local function stoptiming(instance)
-  local timer=timers[instance or "notimer"]
-  local it=timer.timing
-  if it>1 then
-    timer.timing=it-1
-  else
-    local starttime=timer.starttime
-    if starttime and starttime>0 then
-      local stoptime=ticks()
-      local loadtime=stoptime-starttime
-      timer.stoptime=stoptime
-      timer.loadtime=timer.loadtime+loadtime
-      timer.timing=0
-      timer.starttime=0
-      return loadtime
-    end
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+  timer.timing=it-1
+ else
+  local starttime=timer.starttime
+  if starttime and starttime>0 then
+   local stoptime=ticks()
+   local loadtime=stoptime-starttime
+   timer.stoptime=stoptime
+   timer.loadtime=timer.loadtime+loadtime
+   timer.timing=0
+   timer.starttime=0
+   return loadtime
   end
-  return 0
+ end
+ return 0
 end
 local function elapsed(instance)
-  if type(instance)=="number" then
-    return instance
-  else
-    local timer=timers[instance or "notimer"]
-    return timer and seconds(timer.loadtime) or 0
-  end
+ if type(instance)=="number" then
+  return instance
+ else
+  local timer=timers[instance or "notimer"]
+  return timer and seconds(timer.loadtime) or 0
+ end
 end
 local function currenttime(instance)
-  if type(instance)=="number" then
-    return instance
+ if type(instance)=="number" then
+  return instance
+ else
+  local timer=timers[instance or "notimer"]
+  local it=timer.timing
+  if it>1 then
   else
-    local timer=timers[instance or "notimer"]
-    local it=timer.timing
-    if it>1 then
-    else
-      local starttime=timer.starttime
-      if starttime and starttime>0 then
-        return seconds(timer.loadtime+ticks()-starttime)
-      end
-    end
-    return 0
+   local starttime=timer.starttime
+   if starttime and starttime>0 then
+    return seconds(timer.loadtime+ticks()-starttime)
+   end
   end
+  return 0
+ end
 end
 local function elapsedtime(instance)
-  return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
 end
 local function elapsedindeed(instance)
-  return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
 end
 local function elapsedseconds(instance,rest) 
-  if elapsedindeed(instance) then
-    return format("%0.3f seconds %s",elapsed(instance),rest or "")
-  end
+ if elapsedindeed(instance) then
+  return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
 end
 statistics.hastiming=hastiming
 statistics.resettiming=resettiming
@@ -2942,91 +2953,100 @@
 statistics.elapsedindeed=elapsedindeed
 statistics.elapsedseconds=elapsedseconds
 function statistics.register(tag,fnc)
-  if statistics.enable and type(fnc)=="function" then
-    local rt=registered[tag] or (#statusinfo+1)
-    statusinfo[rt]={ tag,fnc }
-    registered[tag]=rt
-    if #tag>n then n=#tag end
-  end
+ if statistics.enable and type(fnc)=="function" then
+  local rt=registered[tag] or (#statusinfo+1)
+  statusinfo[rt]={ tag,fnc }
+  registered[tag]=rt
+  if #tag>n then n=#tag end
+ end
 end
 local report=logs.reporter("mkiv lua stats")
 function statistics.show()
-  if statistics.enable then
-    local register=statistics.register
-    register("used platform",function()
-      return format("%s, type: %s, binary subtree: %s",
-        os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
-    end)
-    register("used engine",function()
-      return format("%s version %s with functionality level %s, banner: %s",
-        LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
-    end)
-    register("control sequences",function()
-      return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
-    end)
-    register("callbacks",statistics.callbacks)
-    if TEXENGINE=="luajittex" and JITSUPPORTED then
-      local jitstatus=jit.status
-      if jitstatus then
-        local jitstatus={ jitstatus() }
-        if jitstatus[1] then
-          register("luajit options",concat(jitstatus," ",2))
-        end
-      end
+ if statistics.enable then
+  local register=statistics.register
+  register("used platform",function()
+   return format("%s, type: %s, binary subtree: %s",
+    os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+  end)
+  register("used engine",function()
+   return format("%s version %s with functionality level %s, banner: %s",
+    LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+  end)
+  register("control sequences",function()
+   return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+  end)
+  register("callbacks",statistics.callbacks)
+  if TEXENGINE=="luajittex" and JITSUPPORTED then
+   local jitstatus=jit.status
+   if jitstatus then
+    local jitstatus={ jitstatus() }
+    if jitstatus[1] then
+     register("luajit options",concat(jitstatus," ",2))
     end
-    register("lua properties",function()
-      local hashchar=tonumber(status.luatex_hashchars)
-      local hashtype=status.luatex_hashtype
-      local mask=lua.mask or "ascii"
-      return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
-        jit and "luajit" or "lua",
-        LUAVERSION,
-        statistics.memused(),
-        hashtype or "default",
-        hashchar and 2^hashchar or "unknown",
-        mask,
-        mask=="utf" and "τεχ" or "tex")
-    end)
-    register("runtime",statistics.runtime)
-    logs.newline() 
-    for i=1,#statusinfo do
-      local s=statusinfo[i]
-      local r=s[2]()
-      if r then
-        report("%s: %s",s[1],r)
-      end
-    end
-    statistics.enable=false
+   end
   end
+  register("lua properties",function()
+   local hashchar=tonumber(status.luatex_hashchars)
+   local hashtype=status.luatex_hashtype
+   local mask=lua.mask or "ascii"
+   return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+    jit and "luajit" or "lua",
+    LUAVERSION,
+    statistics.memused(),
+    hashtype or "default",
+    hashchar and 2^hashchar or "unknown",
+    mask,
+    mask=="utf" and "τεχ" or "tex")
+  end)
+  register("runtime",statistics.runtime)
+  logs.newline() 
+  for i=1,#statusinfo do
+   local s=statusinfo[i]
+   local r=s[2]()
+   if r then
+    report("%s: %s",s[1],r)
+   end
+  end
+  statistics.enable=false
+ end
 end
 function statistics.memused() 
-  local round=math.round or math.floor
-  return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
 end
 starttiming(statistics)
 function statistics.formatruntime(runtime) 
-  return format("%s seconds",runtime)  
+ return format("%s seconds",runtime)   
 end
 function statistics.runtime()
-  stoptiming(statistics)
-  return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
 end
 local report=logs.reporter("system")
-function statistics.timed(action)
-  starttiming("run")
-  action()
-  stoptiming("run")
-  report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime=tonumber(elapsedtime("run"))
+ if all then
+  local alltime=tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
+  if alltime and alltime>0 then
+   report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+   return
+  end
+ end
+ report("total runtime: %0.3f seconds",runtime)
 end
 function statistics.tracefunction(base,tag,...)
-  for i=1,select("#",...) do
-    local name=select(i,...)
-    local stat={}
-    local func=base[name]
-    setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
-    base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
-    statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
-  end
+ for i=1,select("#",...) do
+  local name=select(i,...)
+  local stat={}
+  local func=base[name]
+  setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+  base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+  statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
 end
 
 end -- closure
@@ -3034,12 +3054,12 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-lua']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  comment="the strip code is written by Peter Cawley",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
 local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -3050,7 +3070,7 @@
 local report_mem=logs.reporter("system","lua memory")
 local tracestripping=false
 local tracememory=false
-luautilities.stripcode=true 
+luautilities.stripcode=true  
 luautilities.alwaysstripcode=false 
 luautilities.nofstrippedchunks=0
 luautilities.nofstrippedbytes=0
@@ -3057,143 +3077,144 @@
 local strippedchunks={} 
 luautilities.strippedchunks=strippedchunks
 luautilities.suffixes={
-  tma="tma",
-  tmc=jit and "tmb" or "tmc",
-  lua="lua",
-  luc=jit and "lub" or "luc",
-  lui="lui",
-  luv="luv",
-  luj="luj",
-  tua="tua",
-  tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
 }
 local function register(name) 
-  if tracestripping then
-    report_lua("stripped bytecode from %a",name or "unknown")
-  end
-  strippedchunks[#strippedchunks+1]=name
-  luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+  report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
 end
 local function stupidcompile(luafile,lucfile,strip)
-  local code=io.loaddata(luafile)
-  if code and code~="" then
-    code=load(code)
-    if code then
-      code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
-      if code and code~="" then
-        register(name)
-        io.savedata(lucfile,code)
-        return true,0
-      end
-    else
-      report_lua("fatal error %a in file %a",1,luafile)
-    end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+  code=load(code)
+  if code then
+   code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+   if code and code~="" then
+    register(name)
+    io.savedata(lucfile,code)
+    return true,0
+   end
   else
-    report_lua("fatal error %a in file %a",2,luafile)
+   report_lua("fatal error %a in file %a",1,luafile)
   end
-  return false,0
+ else
+  report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
 end
 function luautilities.loadedluacode(fullname,forcestrip,name,macros)
-  name=name or fullname
-  if macros then
-    macros=lua.macros
+ name=name or fullname
+ if macros then
+  macros=lua.macros
+ end
+ local code,message
+ if macros then
+  code,message=macros.loaded(fullname,true,false)
+ else
+  code,message=loadfile(fullname)
+ end
+ if code then
+  code()
+ else
+  report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+  code,message=loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+  if type(forcestrip)=="function" then
+   forcestrip=forcestrip(fullname)
   end
-  local code,message
-  if macros then
-    code,message=macros.loaded(fullname,true,false)
+  if forcestrip or luautilities.alwaysstripcode then
+   register(name)
+   return load(dump(code,true)),0
   else
-    code,message=loadfile(fullname)
+   return code,0
   end
-  if code then
-    code()
-  else
-    report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
-  end
-  if forcestrip and luautilities.stripcode then
-    if type(forcestrip)=="function" then
-      forcestrip=forcestrip(fullname)
-    end
-    if forcestrip or luautilities.alwaysstripcode then
-      register(name)
-      return load(dump(code,true)),0
-    else
-      return code,0
-    end
-  elseif luautilities.alwaysstripcode then
-    register(name)
-    return load(dump(code,true)),0
-  else
-    return code,0
-  end
+ elseif luautilities.alwaysstripcode then
+  register(name)
+  return load(dump(code,true)),0
+ else
+  return code,0
+ end
 end
 function luautilities.strippedloadstring(code,name,forcestrip) 
-  local code,message=load(code)
-  if not code then
-    report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
-  end
-  if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
-    register(name)
-    return load(dump(code,true)),0 
-  else
-    return code,0
-  end
+ local code,message=load(code)
+ if not code then
+  report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+  register(name)
+  return load(dump(code,true)),0 
+ else
+  return code,0
+ end
 end
 function luautilities.loadstring(code,name) 
-  local code,message=load(code)
-  if not code then
-    report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
-  end
-  return code,0
+ local code,message=load(code)
+ if not code then
+  report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
 end
 function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) 
-  report_lua("compiling %a into %a",luafile,lucfile)
-  os.remove(lucfile)
-  local done=stupidcompile(luafile,lucfile,strip~=false)
-  if done then
-    report_lua("dumping %a into %a stripped",luafile,lucfile)
-    if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
-      report_lua("removing %a",luafile)
-      os.remove(luafile)
-    end
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+  report_lua("dumping %a into %a stripped",luafile,lucfile)
+  if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+   report_lua("removing %a",luafile)
+   os.remove(luafile)
   end
-  return done
+ end
+ return done
 end
 function luautilities.loadstripped(...)
-  local l=load(...)
-  if l then
-    return load(dump(l,true))
-  end
+ local l=load(...)
+ if l then
+  return load(dump(l,true))
+ end
 end
 local finalizers={}
 setmetatable(finalizers,{
-  __gc=function(t)
-    for i=1,#t do
-      pcall(t[i]) 
-    end
+ __gc=function(t)
+  for i=1,#t do
+   pcall(t[i]) 
   end
+ end
 } )
 function luautilities.registerfinalizer(f)
-  finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
 end
 function luautilities.checkmemory(previous,threshold,trace) 
-  local current=collectgarbage("count")
-  if previous then
-    local checked=(threshold or 64)*1024
-    local delta=current-previous
-    if current-previous>checked then
-      collectgarbage("collect")
-      local afterwards=collectgarbage("count")
-      if trace or tracememory then
-        report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
-          previous/1024,current/1024,delta/1024,threshold,afterwards)
-      end
-      return afterwards
-    elseif trace or tracememory then
-      report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
-        previous/1024,current/1024,delta/1024,threshold)
-    end
+ local current=collectgarbage("count")
+ if previous then
+  local checked=(threshold or 64)*1024
+  local delta=current-previous
+  if current-previous>checked then
+   collectgarbage("collect")
+   local afterwards=collectgarbage("count")
+   if trace or tracememory then
+    report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+     previous/1024,current/1024,delta/1024,threshold,afterwards)
+   end
+   return afterwards
+  elseif trace or tracememory then
+   report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+    previous/1024,current/1024,delta/1024,threshold)
   end
-  return current
+ end
+ return current
 end
 
 end -- closure
@@ -3201,11 +3222,11 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-deb']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local type,next,tostring,tonumber=type,next,tostring,tonumber
 local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
@@ -3224,38 +3245,38 @@
 local initialize=false
 if not (FFISUPPORTED and ffi) then
 elseif os.type=="windows" then
-  initialize=function()
-    local kernel=ffilib("kernel32","system") 
-    if kernel then
-      local tonumber=ffi.number or tonumber
-      ffi.cdef[[
+ initialize=function()
+  local kernel=ffilib("kernel32","system") 
+  if kernel then
+   local tonumber=ffi.number or tonumber
+   ffi.cdef[[
                 int QueryPerformanceFrequency(int64_t *lpFrequency);
                 int QueryPerformanceCounter(int64_t *lpPerformanceCount);
             ]]
-      local target=ffi.new("__int64[1]")
-      ticks=function()
-        if kernel.QueryPerformanceCounter(target)==1 then
-          return tonumber(target[0])
-        else
-          return 0
-        end
-      end
-      local target=ffi.new("__int64[1]")
-      seconds=function(ticks)
-        if kernel.QueryPerformanceFrequency(target)==1 then
-          return ticks/tonumber(target[0])
-        else
-          return 0
-        end
-      end
+   local target=ffi.new("__int64[1]")
+   ticks=function()
+    if kernel.QueryPerformanceCounter(target)==1 then
+     return tonumber(target[0])
+    else
+     return 0
     end
-    initialize=false
+   end
+   local target=ffi.new("__int64[1]")
+   seconds=function(ticks)
+    if kernel.QueryPerformanceFrequency(target)==1 then
+     return ticks/tonumber(target[0])
+    else
+     return 0
+    end
+   end
   end
+  initialize=false
+ end
 elseif os.type=="unix" then
-  initialize=function()
-    local C=ffi.C
-    local tonumber=ffi.number or tonumber
-    ffi.cdef [[
+ initialize=function()
+  local C=ffi.C
+  local tonumber=ffi.number or tonumber
+  ffi.cdef [[
             /* what a mess */
             typedef int clk_id_t;
             typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
@@ -3262,228 +3283,228 @@
             typedef struct timespec { long sec; long nsec; } ctx_timespec;
             int clock_gettime(clk_id_t timerid, struct timespec *t);
         ]]
-    local target=ffi.new("ctx_timespec[?]",1)
-    local clock=C.CLOCK_PROCESS_CPUTIME_ID
-    ticks=function ()
-      C.clock_gettime(clock,target)
-      return tonumber(target[0].sec*1000000000+target[0].nsec)
-    end
-    seconds=function(ticks)
-      return ticks/1000000000
-    end
-    initialize=false
+  local target=ffi.new("ctx_timespec[?]",1)
+  local clock=C.CLOCK_PROCESS_CPUTIME_ID
+  ticks=function ()
+   C.clock_gettime(clock,target)
+   return tonumber(target[0].sec*1000000000+target[0].nsec)
   end
+  seconds=function(ticks)
+   return ticks/1000000000
+  end
+  initialize=false
+ end
 end
 setmetatableindex(names,function(t,name)
-  local v=setmetatableindex(function(t,source)
-    local v=setmetatableindex(function(t,line)
-      local v={ total=0,count=0,nesting=0 }
-      t[line]=v
-      return v
-    end)
-    t[source]=v
-    return v
+ local v=setmetatableindex(function(t,source)
+  local v=setmetatableindex(function(t,line)
+   local v={ total=0,count=0,nesting=0 }
+   t[line]=v
+   return v
   end)
-  t[name]=v
+  t[source]=v
   return v
+ end)
+ t[name]=v
+ return v
 end)
 local getinfo=nil
 local sethook=nil
 local function hook(where)
-  local f=getinfo(2,"nSl")
-  if f then
-    local source=f.short_src
-    if not source then
-      return
+ local f=getinfo(2,"nSl")
+ if f then
+  local source=f.short_src
+  if not source then
+   return
+  end
+  local line=f.linedefined or 0
+  local name=f.name
+  if not name then
+   local what=f.what
+   if what=="C" then
+    name="<anonymous>"
+   else
+    name=f.namewhat or what or "<unknown>"
+   end
+  end
+  local data=names[name][source][line]
+  if where=="call" then
+   local nesting=data.nesting
+   if nesting==0 then
+    data.count=data.count+1
+    insert(data,ticks())
+    data.nesting=1
+   else
+    data.nesting=nesting+1
+   end
+  elseif where=="return" then
+   local nesting=data.nesting
+   if nesting==1 then
+    local t=remove(data)
+    if t then
+     data.total=data.total+ticks()-t
     end
-    local line=f.linedefined or 0
-    local name=f.name
-    if not name then
-      local what=f.what
-      if what=="C" then
-        name="<anonymous>"
-      else
-        name=f.namewhat or what or "<unknown>"
-      end
-    end
-    local data=names[name][source][line]
-    if where=="call" then
-      local nesting=data.nesting
-      if nesting==0 then
-        data.count=data.count+1
-        insert(data,ticks())
-        data.nesting=1
-      else
-        data.nesting=nesting+1
-      end
-    elseif where=="return" then
-      local nesting=data.nesting
-      if nesting==1 then
-        local t=remove(data)
-        if t then
-          data.total=data.total+ticks()-t
-        end
-        data.nesting=0
-      else
-        data.nesting=nesting-1
-      end
-    end
+    data.nesting=0
+   else
+    data.nesting=nesting-1
+   end
   end
+ end
 end
 function debugger.showstats(printer,threshold)
-  local printer=printer or report
-  local calls=0
-  local functions=0
-  local dataset={}
-  local length=0
-  local realtime=0
-  local totaltime=0
-  local threshold=threshold or 0
-  for name,sources in next,names do
-    for source,lines in next,sources do
-      for line,data in next,lines do
-        local count=data.count
-        if count>threshold then
-          if #name>length then
-            length=#name
-          end
-          local total=data.total
-          local real=total
-          if real>0 then
-            real=total-(count*overhead/dummycalls)
-            if real<0 then
-              real=0
-            end
-            realtime=realtime+real
-          end
-          totaltime=totaltime+total
-          if line<0 then
-            line=0
-          end
-          dataset[#dataset+1]={ real,total,count,name,source,line }
-        end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+  for source,lines in next,sources do
+   for line,data in next,lines do
+    local count=data.count
+    if count>threshold then
+     if #name>length then
+      length=#name
+     end
+     local total=data.total
+     local real=total
+     if real>0 then
+      real=total-(count*overhead/dummycalls)
+      if real<0 then
+       real=0
       end
+      realtime=realtime+real
+     end
+     totaltime=totaltime+total
+     if line<0 then
+      line=0
+     end
+     dataset[#dataset+1]={ real,total,count,name,source,line }
     end
+   end
   end
-  sort(dataset,function(a,b)
-    if a[1]==b[1] then
-      if a[2]==b[2] then
-        if a[3]==b[3] then
-          if a[4]==b[4] then
-            if a[5]==b[5] then
-              return a[6]<b[6]
-            else
-              return a[5]<b[5]
-            end
-          else
-            return a[4]<b[4]
-          end
-        else
-          return b[3]<a[3]
-        end
+ end
+ sort(dataset,function(a,b)
+  if a[1]==b[1] then
+   if a[2]==b[2] then
+    if a[3]==b[3] then
+     if a[4]==b[4] then
+      if a[5]==b[5] then
+       return a[6]<b[6]
       else
-        return b[2]<a[2]
+       return a[5]<b[5]
       end
+     else
+      return a[4]<b[4]
+     end
     else
-      return b[1]<a[1]
+     return b[3]<a[3]
     end
-  end)
-  if length>50 then
-    length=50
+   else
+    return b[2]<a[2]
+   end
+  else
+   return b[1]<a[1]
   end
-  local fmt=string.formatters["%4.9k s  %3.3k %%  %4.9k s  %3.3k %%  %8i #  %-"..length.."s  %4i  %s"]
-  for i=1,#dataset do
-    local data=dataset[i]
-    local real=data[1]
-    local total=data[2]
-    local count=data[3]
-    local name=data[4]
-    local source=data[5]
-    local line=data[6]
-    calls=calls+count
-    functions=functions+1
-    name=gsub(name,"%s+"," ")
-    if #name>length then
-      name=sub(name,1,length)
-    end
-    printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end)
+ if length>50 then
+  length=50
+ end
+ local fmt=string.formatters["%4.9k s  %3.3k %%  %4.9k s  %3.3k %%  %8i #  %-"..length.."s  %4i  %s"]
+ for i=1,#dataset do
+  local data=dataset[i]
+  local real=data[1]
+  local total=data[2]
+  local count=data[3]
+  local name=data[4]
+  local source=data[5]
+  local line=data[6]
+  calls=calls+count
+  functions=functions+1
+  name=gsub(name,"%s+"," ")
+  if #name>length then
+   name=sub(name,1,length)
   end
-  printer("")
-  printer(format("functions : %i",functions))
-  printer(format("calls     : %i",calls))
-  printer(format("overhead  : %f",seconds(overhead/1000)))
+  printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls     : %i",calls))
+ printer(format("overhead  : %f",seconds(overhead/1000)))
 end
 local function getdebug()
-  if sethook and getinfo then
-    return
-  end
-  if not debug then
-    local okay
-    okay,debug=pcall(require,"debug")
-  end
-  if type(debug)~="table" then
-    return
-  end
-  getinfo=debug.getinfo
-  sethook=debug.sethook
-  if type(getinfo)~="function" then
-    getinfo=nil
-  end
-  if type(sethook)~="function" then
-    sethook=nil
-  end
+ if sethook and getinfo then
+  return
+ end
+ if not debug then
+  local okay
+  okay,debug=pcall(require,"debug")
+ end
+ if type(debug)~="table" then
+  return
+ end
+ getinfo=debug.getinfo
+ sethook=debug.sethook
+ if type(getinfo)~="function" then
+  getinfo=nil
+ end
+ if type(sethook)~="function" then
+  sethook=nil
+ end
 end
 function debugger.savestats(filename,threshold)
-  local f=io.open(filename,'w')
-  if f then
-    debugger.showstats(function(str) f:write(str,"\n") end,threshold)
-    f:close()
-  end
+ local f=io.open(filename,'w')
+ if f then
+  debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+  f:close()
+ end
 end
 function debugger.enable()
-  getdebug()
-  if sethook and getinfo and nesting==0 then
-    running=true
-    if initialize then
-      initialize()
-    end
-    sethook(hook,"cr")
-    local function dummy() end
-    local t=ticks()
-    for i=1,dummycalls do
-      dummy()
-    end
-    overhead=ticks()-t
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+  running=true
+  if initialize then
+   initialize()
   end
-  if nesting>0 then
-    nesting=nesting+1
+  sethook(hook,"cr")
+  local function dummy() end
+  local t=ticks()
+  for i=1,dummycalls do
+   dummy()
   end
+  overhead=ticks()-t
+ end
+ if nesting>0 then
+  nesting=nesting+1
+ end
 end
 function debugger.disable()
-  if nesting>0 then
-    nesting=nesting-1
-  end
-  if sethook and getinfo and nesting==0 then
-    sethook()
-  end
+ if nesting>0 then
+  nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+  sethook()
+ end
 end
 local function showtraceback(rep) 
-  getdebug()
-  if getinfo then
-    local level=2 
-    local reporter=rep or report
-    while true do
-      local info=getinfo(level,"Sl")
-      if not info then
-        break
-      elseif info.what=="C" then
-        reporter("%2i : %s",level-1,"C function")
-      else
-        reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
-      end
-      level=level+1
-    end
+ getdebug()
+ if getinfo then
+  local level=2 
+  local reporter=rep or report
+  while true do
+   local info=getinfo(level,"Sl")
+   if not info then
+    break
+   elseif info.what=="C" then
+    reporter("%2i : %s",level-1,"C function")
+   else
+    reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+   end
+   level=level+1
   end
+ end
 end
 debugger.showtraceback=showtraceback
 
@@ -3492,15 +3513,15 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-tpl']={
-  version=1.001,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 utilities.templates=utilities.templates or {}
 local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false  trackers.register("templates.trace",function(v) trace_template=v end)
 local report_template=logs.reporter("template")
 local tostring,next=tostring,next
 local format,sub,byte=string.format,string.sub,string.byte
@@ -3507,29 +3528,29 @@
 local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
 local replacer
 local function replacekey(k,t,how,recursive)
-  local v=t[k]
-  if not v then
-    if trace_template then
-      report_template("unknown key %a",k)
-    end
-    return ""
+ local v=t[k]
+ if not v then
+  if trace_template then
+   report_template("unknown key %a",k)
+  end
+  return ""
+ else
+  v=tostring(v)
+  if trace_template then
+   report_template("setting key %a to value %a",k,v)
+  end
+  if recursive then
+   return lpegmatch(replacer,v,1,t,how,recursive)
   else
-    v=tostring(v)
-    if trace_template then
-      report_template("setting key %a to value %a",k,v)
-    end
-    if recursive then
-      return lpegmatch(replacer,v,1,t,how,recursive)
-    else
-      return v
-    end
+   return v
   end
+ end
 end
 local sqlescape=lpeg.replacer {
-  { "'","''"  },
-  { "\\","\\\\" },
-  { "\r\n","\\n" },
-  { "\r","\\n" },
+ { "'","''"   },
+ { "\\","\\\\" },
+ { "\r\n","\\n"  },
+ { "\r","\\n"  },
 }
 local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
 lpegpatterns.sqlescape=sqlescape
@@ -3536,44 +3557,44 @@
 lpegpatterns.sqlquoted=sqlquoted
 local luaescape=lpegpatterns.luaescape
 local escapers={
-  lua=function(s)
-    return lpegmatch(luaescape,s)
-  end,
-  sql=function(s)
-    return lpegmatch(sqlescape,s)
-  end,
+ lua=function(s)
+  return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+  return lpegmatch(sqlescape,s)
+ end,
 }
 local quotedescapers={
-  lua=function(s)
-    return format("%q",s)
-  end,
-  sql=function(s)
-    return lpegmatch(sqlquoted,s)
-  end,
+ lua=function(s)
+  return format("%q",s)
+ end,
+ sql=function(s)
+  return lpegmatch(sqlquoted,s)
+ end,
 }
 local luaescaper=escapers.lua
 local quotedluaescaper=quotedescapers.lua
 local function replacekeyunquoted(s,t,how,recurse) 
-  if how==false then
-    return replacekey(s,t,how,recurse)
-  else
-    local escaper=how and escapers[how] or luaescaper
-    return escaper(replacekey(s,t,how,recurse))
-  end
+ if how==false then
+  return replacekey(s,t,how,recurse)
+ else
+  local escaper=how and escapers[how] or luaescaper
+  return escaper(replacekey(s,t,how,recurse))
+ end
 end
 local function replacekeyquoted(s,t,how,recurse) 
-  if how==false then
-    return replacekey(s,t,how,recurse)
-  else
-    local escaper=how and quotedescapers[how] or quotedluaescaper
-    return escaper(replacekey(s,t,how,recurse))
-  end
+ if how==false then
+  return replacekey(s,t,how,recurse)
+ else
+  local escaper=how and quotedescapers[how] or quotedluaescaper
+  return escaper(replacekey(s,t,how,recurse))
+ end
 end
 local function replaceoptional(l,m,r,t,how,recurse)
-  local v=t[l]
-  return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
 end
-local single=P("%") 
+local single=P("%")  
 local double=P("%%") 
 local lquoted=P("%[") 
 local rquoted=P("]%") 
@@ -3590,41 +3611,41 @@
 local noroptional=P("?%")/''
 local nomoptional=P(":")/''
 local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle  )^1)*args)/replacekey    )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle   )^1)*args)/replacekey  )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted  )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted  )^1)*args)/replacekeyunquoted)*norquoted
 local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
 local any=P(1)
    replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
 local function replace(str,mapping,how,recurse)
-  if mapping and str then
-    return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
-  else
-    return str
-  end
+ if mapping and str then
+  return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+  return str
+ end
 end
 templates.replace=replace
 function templates.replacer(str,how,recurse) 
-  return function(mapping)
-    return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
-  end
+ return function(mapping)
+  return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
 end
 function templates.load(filename,mapping,how,recurse)
-  local data=io.loaddata(filename) or ""
-  if mapping and next(mapping) then
-    return replace(data,mapping,how,recurse)
-  else
-    return data
-  end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+  return replace(data,mapping,how,recurse)
+ else
+  return data
+ end
 end
 function templates.resolve(t,mapping,how,recurse)
-  if not mapping then
-    mapping=t
-  end
-  for k,v in next,t do
-    t[k]=replace(v,mapping,how,recurse)
-  end
-  return t
+ if not mapping then
+  mapping=t
+ end
+ for k,v in next,t do
+  t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
 end
 
 end -- closure
@@ -3632,235 +3653,235 @@
 do -- begin closure to overcome local limits and interference
 
 if not modules then modules={} end modules ['util-sta']={
-  version=1.001,
-  comment="companion to util-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
+ version=1.001,
+ comment="companion to util-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
 }
 local insert,remove,fastcopy,concat=table.insert,table.remove,table.fastcopy,table.concat
 local format=string.format
 local select,tostring=select,tostring
-local trace_stacker=false trackers.register("stacker.resolve",function(v) trace_stacker=v end)
+local trace_stacker=false  trackers.register("stacker.resolve",function(v) trace_stacker=v end)
 local stacker=stacker or {}
 utilities.stacker=stacker
 local function start(s,t,first,last)
-  if s.mode=="switch" then
-    local n=tostring(t[last])
-    if trace_stacker then
-      s.report("start: %s",n)
-    end
-    return n
-  else
-    local r={}
-    for i=first,last do
-      r[#r+1]=tostring(t[i])
-    end
-    local n=concat(r," ")
-    if trace_stacker then
-      s.report("start: %s",n)
-    end
-    return n
+ if s.mode=="switch" then
+  local n=tostring(t[last])
+  if trace_stacker then
+   s.report("start: %s",n)
   end
+  return n
+ else
+  local r={}
+  for i=first,last do
+   r[#r+1]=tostring(t[i])
+  end
+  local n=concat(r," ")
+  if trace_stacker then
+   s.report("start: %s",n)
+  end
+  return n
+ end
 end
 local function stop(s,t,first,last)
-  if s.mode=="switch" then
-    local n=tostring(false)
-    if trace_stacker then
-      s.report("stop: %s",n)
-    end
-    return n
-  else
-    local r={}
-    for i=last,first,-1 do
-      r[#r+1]=tostring(false)
-    end
-    local n=concat(r," ")
-    if trace_stacker then
-      s.report("stop: %s",n)
-    end
-    return n
+ if s.mode=="switch" then
+  local n=tostring(false)
+  if trace_stacker then
+   s.report("stop: %s",n)
   end
+  return n
+ else
+  local r={}
+  for i=last,first,-1 do
+   r[#r+1]=tostring(false)
+  end
+  local n=concat(r," ")
+  if trace_stacker then
+   s.report("stop: %s",n)
+  end
+  return n
+ end
 end
 local function change(s,t1,first1,last1,t2,first2,last2)
-  if s.mode=="switch" then
-    local n=tostring(t2[last2])
-    if trace_stacker then
-      s.report("change: %s",n)
-    end
-    return n
-  else
-    local r={}
-    for i=last1,first1,-1 do
-      r[#r+1]=tostring(false)
-    end
-    local n=concat(r," ")
-    for i=first2,last2 do
-      r[#r+1]=tostring(t2[i])
-    end
-    if trace_stacker then
-      s.report("change: %s",n)
-    end
-    return n
+ if s.mode=="switch" then
+  local n=tostring(t2[last2])
+  if trace_stacker then
+   s.report("change: %s",n)
   end
+  return n
+ else
+  local r={}
+  for i=last1,first1,-1 do
+   r[#r+1]=tostring(false)
+  end
+  local n=concat(r," ")
+  for i=first2,last2 do
+   r[#r+1]=tostring(t2[i])
+  end
+  if trace_stacker then
+   s.report("change: %s",n)
+  end
+  return n
+ end
 end
 function stacker.new(name)
-  local report=logs.reporter("stacker",name or nil)
-  local s
-  local stack={}
-  local list={}
-  local ids={}
-  local hash={}
-  local hashing=true
-  local function push(...)
-    for i=1,select("#",...) do
-      insert(stack,(select(i,...))) 
-    end
-    if hashing then
-      local c=concat(stack,"|")
-      local n=hash[c]
-      if not n then
-        n=#list+1
-        hash[c]=n
-        list[n]=fastcopy(stack)
-      end
-      insert(ids,n)
-      return n
-    else
-      local n=#list+1
-      list[n]=fastcopy(stack)
-      insert(ids,n)
-      return n
-    end
+ local report=logs.reporter("stacker",name or nil)
+ local s
+ local stack={}
+ local list={}
+ local ids={}
+ local hash={}
+ local hashing=true
+ local function push(...)
+  for i=1,select("#",...) do
+   insert(stack,(select(i,...))) 
   end
-  local function pop()
-    remove(stack)
-    remove(ids)
-    return ids[#ids] or s.unset or -1
+  if hashing then
+   local c=concat(stack,"|")
+   local n=hash[c]
+   if not n then
+    n=#list+1
+    hash[c]=n
+    list[n]=fastcopy(stack)
+   end
+   insert(ids,n)
+   return n
+  else
+   local n=#list+1
+   list[n]=fastcopy(stack)
+   insert(ids,n)
+   return n
   end
-  local function clean()
-    if #stack==0 then
-      if trace_stacker then
-        s.report("%s list entries, %s stack entries",#list,#stack)
-      end
-    end
+ end
+ local function pop()
+  remove(stack)
+  remove(ids)
+  return ids[#ids] or s.unset or -1
+ end
+ local function clean()
+  if #stack==0 then
+   if trace_stacker then
+    s.report("%s list entries, %s stack entries",#list,#stack)
+   end
   end
-  local tops={}
-  local top=nil
-  local switch=nil
-  local function resolve_reset(mode)
-    if #tops>0 then
-      report("resetting %s left-over states of %a",#tops,name)
-    end
-    tops={}
-    top=nil
-    switch=nil
+ end
+ local tops={}
+ local top=nil
+ local switch=nil
+ local function resolve_reset(mode)
+  if #tops>0 then
+   report("resetting %s left-over states of %a",#tops,name)
   end
-  local function resolve_begin(mode)
-    if mode then
-      switch=mode=="switch"
-    else
-      switch=s.mode=="switch"
-    end
-    top={ switch=switch }
-    insert(tops,top)
+  tops={}
+  top=nil
+  switch=nil
+ end
+ local function resolve_begin(mode)
+  if mode then
+   switch=mode=="switch"
+  else
+   switch=s.mode=="switch"
   end
-  local function resolve_step(ti)
-    local result=nil
-    local noftop=top and #top or 0
-    if ti>0 then
-      local current=list[ti]
-      if current then
-        local noflist=#current
-        local nofsame=0
-        if noflist>noftop then
-          for i=1,noflist do
-            if current[i]==top[i] then
-              nofsame=i
-            else
-              break
-            end
-          end
-        else
-          for i=1,noflist do
-            if current[i]==top[i] then
-              nofsame=i
-            else
-              break
-            end
-          end
-        end
-        local plus=nofsame+1
-        if plus<=noftop then
-          if plus<=noflist then
-            if switch then
-              result=s.change(s,top,plus,noftop,current,nofsame,noflist)
-            else
-              result=s.change(s,top,plus,noftop,current,plus,noflist)
-            end
-          else
-            if switch then
-              result=s.change(s,top,plus,noftop,current,nofsame,noflist)
-            else
-              result=s.stop(s,top,plus,noftop)
-            end
-          end
-        elseif plus<=noflist then
-          if switch then
-            result=s.start(s,current,nofsame,noflist)
-          else
-            result=s.start(s,current,plus,noflist)
-          end
-        end
-        top=current
+  top={ switch=switch }
+  insert(tops,top)
+ end
+ local function resolve_step(ti)
+  local result=nil
+  local noftop=top and #top or 0
+  if ti>0 then
+   local current=list[ti]
+   if current then
+    local noflist=#current
+    local nofsame=0
+    if noflist>noftop then
+     for i=1,noflist do
+      if current[i]==top[i] then
+       nofsame=i
       else
-        if 1<=noftop then
-          result=s.stop(s,top,1,noftop)
-        end
-        top={}
+       break
       end
-      return result
+     end
     else
-      if 1<=noftop then
-        result=s.stop(s,top,1,noftop)
+     for i=1,noflist do
+      if current[i]==top[i] then
+       nofsame=i
+      else
+       break
       end
-      top={}
-      return result
+     end
     end
-  end
-  local function resolve_end()
-    if #tops>0 then 
-      local result=s.stop(s,top,1,#top)
-      remove(tops)
-      top=tops[#tops]
-      switch=top and top.switch
-      return result
+    local plus=nofsame+1
+    if plus<=noftop then
+     if plus<=noflist then
+      if switch then
+       result=s.change(s,top,plus,noftop,current,nofsame,noflist)
+      else
+       result=s.change(s,top,plus,noftop,current,plus,noflist)
+      end
+     else
+      if switch then
+       result=s.change(s,top,plus,noftop,current,nofsame,noflist)
+      else
+       result=s.stop(s,top,plus,noftop)
+      end
+     end
+    elseif plus<=noflist then
+     if switch then
+      result=s.start(s,current,nofsame,noflist)
+     else
+      result=s.start(s,current,plus,noflist)
+     end
     end
-  end
-  local function resolve(t)
-    resolve_begin()
-    for i=1,#t do
-      resolve_step(t[i])
+    top=current
+   else
+    if 1<=noftop then
+     result=s.stop(s,top,1,noftop)
     end
-    resolve_end()
+    top={}
+   end
+   return result
+  else
+   if 1<=noftop then
+    result=s.stop(s,top,1,noftop)
+   end
+   top={}
+   return result
   end
-  s={
-    name=name or "unknown",
-    unset=-1,
-    report=report,
-    start=start,
-    stop=stop,
-    change=change,
-    push=push,
-    pop=pop,
-    clean=clean,
-    resolve=resolve,
-    resolve_begin=resolve_begin,
-    resolve_step=resolve_step,
-    resolve_end=resolve_end,
-    resolve_reset=resolve_reset,
-  }
-  return s 
+ end
+ local function resolve_end()
+  if #tops>0 then 
+   local result=s.stop(s,top,1,#top)
+   remove(tops)
+   top=tops[#tops]
+   switch=top and top.switch
+   return result
+  end
+ end
+ local function resolve(t)
+  resolve_begin()
+  for i=1,#t do
+   resolve_step(t[i])
+  end
+  resolve_end()
+ end
+ s={
+  name=name or "unknown",
+  unset=-1,
+  report=report,
+  start=start,
+  stop=stop,
+  change=change,
+  push=push,
+  pop=pop,
+  clean=clean,
+  resolve=resolve,
+  resolve_begin=resolve_begin,
+  resolve_step=resolve_step,
+  resolve_end=resolve_end,
+  resolve_reset=resolve_reset,
+ }
+ return s 
 end
 
 end -- closure

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -30,8 +30,8 @@
 
 local lualibs_extended_module = {
   name          = "lualibs-extended",
-  version       = 2.62,
-  date          = "2018-12-19",
+  version       = 2.63,
+  date          = "2019-01-28",
   description   = "ConTeXt Lua libraries -- extended collection.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-lua.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-lua.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-lua.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -35,8 +35,6 @@
     LUAVERSION   = 5.2
 end
 
-_LUAVERSION = LUAVERSION -- for old times sake, will go away
-
 -- lpeg
 
 if not lpeg then

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -253,16 +253,25 @@
 function statistics.runtime()
     stoptiming(statistics)
  -- stoptiming(statistics) -- somehow we can start the timer twice, but where
-    return statistics.formatruntime(elapsedtime(statistics))
+    local runtime = lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+    return statistics.formatruntime(runtime)
 end
 
 local report = logs.reporter("system")
 
-function statistics.timed(action)
+function statistics.timed(action,all)
     starttiming("run")
     action()
     stoptiming("run")
-    report("total runtime: %s seconds",elapsedtime("run"))
+    local runtime = tonumber(elapsedtime("run"))
+    if all then
+        local alltime = tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
+        if alltime and alltime > 0 then
+            report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+            return
+        end
+    end
+    report("total runtime: %0.3f seconds",runtime)
 end
 
 -- goodie

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -14,10 +14,12 @@
 --
 -- Reminder for me: check usage in framework and extend when needed. Also document
 -- it in the cld lib documentation.
+--
+-- Upgraded for handling the somewhat more fax server templates.
 
 local P, V, R, S, C, Cc, Cs, Ct, Cf, Cg = lpeg.P, lpeg.V, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cf, lpeg.Cg
 local lpegmatch = lpeg.match
-local format = string.format
+local format, gsub = string.format, string.gsub
 local utfchar = utf.char
 local concat = table.concat
 
@@ -26,9 +28,6 @@
 local json      = utilities.json or { }
 utilities.json  = json
 
--- moduledata      = moduledata or { }
--- moduledata.json = json
-
 -- \\ \/ \b \f \n \r \t \uHHHH
 
 local lbrace     = P("{")
@@ -43,16 +42,19 @@
 local optionalws = whitespace^0
 
 local escapes    = {
- -- ["\\"] = "\\",  -- lua will escape these
- -- ["/"]  = "/",   -- no need to escape this one
-    ["b"]  = "\010",
-    ["f"]  = "\014",
-    ["n"]  = "\n",
-    ["r"]  = "\r",
-    ["t"]  = "\t",
+    ["b"] = "\010",
+    ["f"] = "\014",
+    ["n"] = "\n",
+    ["r"] = "\r",
+    ["t"] = "\t",
 }
 
-local escape_un  = C(P("\\u") / "0x" * S("09","AF","af")) / function(s) return utfchar(tonumber(s)) end
+-- todo: also handle larger utf16
+
+local escape_un  = P("\\u")/"" * (C(R("09","AF","af")^-4) / function(s)
+    return utfchar(tonumber(s,16))
+end)
+
 local escape_bs  = P([[\]]) / "" * (P(1) / escapes) -- if not found then P(1) is returned i.e. the to be escaped char
 
 local jstring    = dquote * Cs((escape_un + escape_bs + (1-dquote))^0) * dquote
@@ -85,7 +87,9 @@
     return lpegmatch(jsonconverter,str)
 end
 
-local function tojson(value,t) -- we could optimize #t
+local escaper
+
+local function tojson(value,t,n) -- we could optimize #t
     local kind = type(value)
     if kind == "table" then
         local done = false
@@ -93,44 +97,46 @@
         if size == 0 then
             for k, v in next, value do
                 if done then
-                    t[#t+1] = ","
+                    n = n + 1 ; t[n] = ","
                 else
-                    t[#t+1] = "{"
+                    n = n + 1 ; t[n] = "{"
                     done = true
                 end
-                t[#t+1] = format("%q:",k)
-                tojson(v,t)
+                n = n + 1 ; t[n] = format("%q:",k)
+                t, n = tojson(v,t,n)
             end
             if done then
-                t[#t+1] = "}"
+                n = n + 1 ; t[n] = "}"
             else
-                t[#t+1] = "{}"
+                n = n + 1 ; t[n] = "{}"
             end
         elseif size == 1 then
             -- we can optimize for non tables
-            t[#t+1] = "["
-            tojson(value[1],t)
-            t[#t+1] = "]"
+            n = n + 1 ; t[n] = "["
+            t, n = tojson(value[1],t,n)
+            n = n + 1 ; t[n] = "]"
         else
             for i=1,size do
                 if done then
-                    t[#t+1] = ","
+                    n = n + 1 ; t[n] = ","
                 else
-                    t[#t+1] = "["
+                    n = n + 1 ; t[n] = "["
                     done = true
                 end
-                tojson(value[i],t)
+                t, n = tojson(value[i],t,n)
             end
-            t[#t+1] = "]"
+            n = n + 1 ; t[n] = "]"
         end
     elseif kind == "string"  then
-        t[#t+1] = format("%q",value)
+        n = n + 1 ; t[n] = '"'
+        n = n + 1 ; t[n] = lpegmatch(escaper,value) or value
+        n = n + 1 ; t[n] = '"'
     elseif kind == "number" then
-        t[#t+1] = value
+        n = n + 1 ; t[n] = value
     elseif kind == "boolean" then
-        t[#t+1] = tostring(value)
+        n = n + 1 ; t[n] = tostring(value)
     end
-    return t
+    return t, n
 end
 
 function json.tostring(value)
@@ -137,16 +143,29 @@
     -- todo optimize for non table
     local kind = type(value)
     if kind == "table" then
-        return concat(tojson(value,{}),"")
+        if not escaper then
+            local escapes = {
+                ["\\"] = "\\u005C",
+                ["\""] = "\\u0022",
+            }
+            for i=0,0x20 do
+                escapes[utfchar(i)] = format("\\u%04X",i)
+            end
+            escaper = Cs( (
+                (R('\0\x20') + S('\"\\')) / escapes
+              + P(1)
+            )^1 )
+
+        end
+        return concat((tojson(value,{},0)))
     elseif kind == "string" or kind == "number" then
-        return value
+        return lpegmatch(escaper,value) or value
     else
         return tostring(value)
     end
 end
 
--- local tmp = [[ { "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
-
+-- local tmp = [[ { "t" : "foobar", "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
 -- tmp = json.tolua(tmp)
 -- inspect(tmp)
 -- tmp = json.tostring(tmp)
@@ -155,7 +174,6 @@
 -- inspect(tmp)
 -- tmp = json.tostring(tmp)
 -- inspect(tmp)
-
 -- inspect(json.tostring(true))
 
 function json.load(filename)
@@ -165,4 +183,11 @@
     end
 end
 
+-- local s = [[\foo"bar"]]
+-- local j = json.tostring { s = s }
+-- local l = json.tolua(j)
+-- inspect(j)
+-- inspect(l)
+-- print(s==l.s)
+
 return json

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -88,6 +88,7 @@
         code()
     else
         report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+        code, message = loadfile(fullname)
     end
     if forcestrip and luautilities.stripcode then
         if type(forcestrip) == "function" then

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -22,25 +22,12 @@
 ----- loadstripped = utilities.lua.loadstripped
 ----- setmetatableindex = table.setmetatableindex
 
-local loadstripped = nil
-local oldfashioned = LUAVERSION < 5.2
-
-if oldfashioned then
-
-    loadstripped = function(str,shortcuts)
-        return load(str)
+local loadstripped = function(str,shortcuts)
+    if shortcuts then
+        return load(dump(load(str),true),nil,nil,shortcuts)
+    else
+        return load(dump(load(str),true))
     end
-
-else
-
-    loadstripped = function(str,shortcuts)
-        if shortcuts then
-            return load(dump(load(str),true),nil,nil,shortcuts)
-        else
-            return load(dump(load(str),true))
-        end
-    end
-
 end
 
 -- todo: make a special namespace for the formatter
@@ -598,67 +585,35 @@
 return function(%s) return %s end
 ]]
 
-local preamble, environment = "", { }
+local preamble = ""
 
-if oldfashioned then
+local environment = {
+    global          = global or _G,
+    lpeg            = lpeg,
+    type            = type,
+    tostring        = tostring,
+    tonumber        = tonumber,
+    format          = string.format,
+    concat          = table.concat,
+    signed          = number.signed,
+    points          = number.points,
+    basepoints      = number.basepoints,
+    utfchar         = utf.char,
+    utfbyte         = utf.byte,
+    lpegmatch       = lpeg.match,
+    nspaces         = string.nspaces,
+    utfpadding      = string.utfpadding,
+    tracedchar      = string.tracedchar,
+    autosingle      = string.autosingle,
+    autodouble      = string.autodouble,
+    sequenced       = table.sequenced,
+    formattednumber = number.formatted,
+    sparseexponent  = number.sparseexponent,
+    formattedfloat  = number.formattedfloat,
+    stripzero       = lpeg.patterns.stripzero,
+    stripzeros      = lpeg.patterns.stripzeros,
+}
 
-    preamble = [[
-local lpeg=lpeg
-local type=type
-local tostring=tostring
-local tonumber=tonumber
-local format=string.format
-local concat=table.concat
-local signed=number.signed
-local points=number.points
-local basepoints= number.basepoints
-local utfchar=utf.char
-local utfbyte=utf.byte
-local lpegmatch=lpeg.match
-local nspaces=string.nspaces
-local utfpadding=string.utfpadding
-local tracedchar=string.tracedchar
-local autosingle=string.autosingle
-local autodouble=string.autodouble
-local sequenced=table.sequenced
-local formattednumber=number.formatted
-local sparseexponent=number.sparseexponent
-local formattedfloat=number.formattedfloat
-local stripzero=lpeg.patterns.stripzero
-local stripzeros=lpeg.patterns.stripzeros
-    ]]
-
-else
-
-    environment = {
-        global          = global or _G,
-        lpeg            = lpeg,
-        type            = type,
-        tostring        = tostring,
-        tonumber        = tonumber,
-        format          = string.format,
-        concat          = table.concat,
-        signed          = number.signed,
-        points          = number.points,
-        basepoints      = number.basepoints,
-        utfchar         = utf.char,
-        utfbyte         = utf.byte,
-        lpegmatch       = lpeg.match,
-        nspaces         = string.nspaces,
-        utfpadding      = string.utfpadding,
-        tracedchar      = string.tracedchar,
-        autosingle      = string.autosingle,
-        autodouble      = string.autodouble,
-        sequenced       = table.sequenced,
-        formattednumber = number.formatted,
-        sparseexponent  = number.sparseexponent,
-        formattedfloat  = number.formattedfloat,
-        stripzero       = lpeg.patterns.stripzero,
-        stripzeros      = lpeg.patterns.stripzeros,
-    }
-
-end
-
 -- -- --
 
 local arguments = { "a1" } -- faster than previously used (select(n,...))
@@ -1036,44 +991,86 @@
 --     strip = true
 -- end
 
+-- add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp")
 --
+-- add(formatters,"foo:bar",[[foo(...)]], { foo = function(...) print(...) return "!" end })
+-- print(string.formatters["foo %3!foo:bar! bar"](1,2,3))
 
+
 local format_rest = function(s)
     return format("%q",s) -- catches " and \n and such
 end
 
+-- local format_extension = function(extensions,f,name)
+--     local extension = extensions[name] or "tostring(%s)"
+--     local f = tonumber(f) or 1
+--     local w = find(extension,"%.%.%.")
+--     if f == 0 then
+--         if w then
+--             extension = gsub(extension,"%.%.%.","")
+--         end
+--         return extension
+--     elseif f == 1 then
+--         if w then
+--             extension = gsub(extension,"%.%.%.","%%s")
+--         end
+--         n = n + 1
+--         local a = "a" .. n
+--         return format(extension,a,a) -- maybe more times?
+--     elseif f < 0 then
+--         local a = "a" .. (n + f + 1)
+--         return format(extension,a,a)
+--     else
+--         if w then
+--             extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+--         end
+--         -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+--         -- cache we don't save much and there are hardly any extensions anyway
+--         local t = { }
+--         for i=1,f do
+--             n = n + 1
+--          -- t[#t+1] = "a" .. n
+--             t[i] = "a" .. n
+--         end
+--         return format(extension,unpack(t))
+--     end
+-- end
+
 local format_extension = function(extensions,f,name)
     local extension = extensions[name] or "tostring(%s)"
     local f = tonumber(f) or 1
     local w = find(extension,"%.%.%.")
-    if f == 0 then
-        if w then
+    if w then
+        -- we have a wildcard
+        if f == 0 then
             extension = gsub(extension,"%.%.%.","")
-        end
-        return extension
-    elseif f == 1 then
-        if w then
+            return extension
+        elseif f == 1 then
             extension = gsub(extension,"%.%.%.","%%s")
+            n = n + 1
+            local a = "a" .. n
+            return format(extension,a,a) -- maybe more times?
+        elseif f < 0 then
+            local a = "a" .. (n + f + 1)
+            return format(extension,a,a)
+        else
+            extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+            -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+            -- cache we don't save much and there are hardly any extensions anyway
+            local t = { }
+            for i=1,f do
+                n = n + 1
+             -- t[#t+1] = "a" .. n
+                t[i] = "a" .. n
+            end
+            return format(extension,unpack(t))
         end
-        n = n + 1
-        local a = "a" .. n
-        return format(extension,a,a) -- maybe more times?
-    elseif f < 0 then
-        local a = "a" .. (n + f + 1)
-        return format(extension,a,a)
     else
-        if w then
-            extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
-        end
-        -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
-        -- cache we don't save much and there are hardly any extensions anyway
-        local t = { }
-        for i=1,f do
+        extension = gsub(extension,"%%s",function()
             n = n + 1
-         -- t[#t+1] = "a" .. n
-            t[i] = "a" .. n
-        end
-        return format(extension,unpack(t))
+            return "a" .. n
+        end)
+        return extension
     end
 end
 
@@ -1273,36 +1270,22 @@
 
 -- _connector_ is an experiment
 
-if oldfashioned then
-
-    function strings.formatters.new(noconcat)
-        local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = preamble, _environment_ = { } }
-        setmetatable(t, { __index = make, __call = use })
-        return t
+function strings.formatters.new(noconcat)
+    local e = { } -- better make a copy as we can overload
+    for k, v in next, environment do
+        e[k] = v
     end
-
-else
-
-    function strings.formatters.new(noconcat)
-        local e = { } -- better make a copy as we can overload
-        for k, v in next, environment do
-            e[k] = v
-        end
-        local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = "", _environment_ = e }
-        setmetatable(t, { __index = make, __call = use })
-        return t
-    end
-
+    local t = {
+        _type_        = "formatter",
+        _connector_   = noconcat and "," or "..",
+        _extensions_  = { },
+        _preamble_    = "",
+        _environment_ = e,
+    }
+    setmetatable(t, { __index = make, __call = use })
+    return t
 end
 
--- function strings.formatters.new()
---     local t = { _extensions_ = { }, _preamble_ = "", _type_ = "formatter", _n_ = 0 }
---     local m = { _t_ = t }
---     setmetatable(t, { __index = m, __call = use })
---     setmetatable(m, { __index = make })
---     return t
--- end
-
 local formatters   = strings.formatters.new() -- the default instance
 
 string.formatters  = formatters -- in the main string namespace
@@ -1333,20 +1316,10 @@
 -- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but
 -- faster again when other q-escapables are found (the ones we don't need to escape)
 
-if oldfashioned then
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape })
 
-    add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
-    add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
-    add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
-
-else
-
-    add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape })
-    add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape })
-    add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape })
-
-end
-
 -- -- yes or no:
 --
 -- local function make(t,str)

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -820,3 +820,53 @@
     end)
 end
 
+-- ordered hashes (for now here but in the table namespace):
+
+-- local t = table.orderedhash()
+--
+-- t["1"]  = { "a", "b" }
+-- t["2"]  = { }
+-- t["2a"] = { "a", "c", "d" }
+--
+-- for k, v in table.ordered(t) do
+--     ...
+-- end
+
+local mt = {
+    __newindex = function(t,k,v)
+        local n = t.last + 1
+        t.last    = n
+        t.list[n] = k
+        t.hash[k] = v
+    end,
+    __index = function(t,k)
+        return t.hash[k]
+    end,
+    __len = function(t)
+        return t.last
+    end,
+}
+
+function table.orderedhash()
+    return setmetatable({ list = { }, hash = { }, last = 0 }, mt)
+end
+
+function table.ordered(t)
+    local n = t.last
+    if n > 0 then
+        local l = t.list
+        local i = 1
+        local h = t.hash
+        local f = function()
+            if i <= n then
+                local k = i
+                local v = h[l[k]]
+                i = i + 1
+                return k, v
+            end
+        end
+        return f, 1, h[l[1]]
+    else
+        return function() end
+    end
+end

Modified: trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua	2019-02-08 23:00:59 UTC (rev 49981)
+++ trunk/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua	2019-02-08 23:01:17 UTC (rev 49982)
@@ -25,8 +25,8 @@
 
 lualibs.module_info = {
   name          = "lualibs",
-  version       = 2.62,
-  date          = "2018-12-19",
+  version       = 2.63,
+  date          = "2019-01-28",
   description   = "ConTeXt Lua standard libraries.",
   author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
   copyright     = "PRAGMA ADE / ConTeXt Development Team",



More information about the tex-live-commits mailing list