From 7b107268d43038815d72037d28dbb3a3e4331d64 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Fri, 19 Apr 2013 16:29:00 +0200
Subject: beta 2013.04.19 16:29

---
 tex/context/base/cont-new.mkiv                     |   2 +-
 tex/context/base/context-version.pdf               | Bin 4134 -> 4130 bytes
 tex/context/base/context-version.png               | Bin 40526 -> 40489 bytes
 tex/context/base/context.mkiv                      |   2 +-
 tex/context/base/data-lua.lua                      |  58 ++----
 tex/context/base/font-ctx.lua                      |  18 +-
 tex/context/base/font-def.lua                      |  22 +--
 tex/context/base/font-otp.lua                      |   4 +-
 tex/context/base/l-dir.lua                         |  23 ++-
 tex/context/base/l-os.lua                          |  16 +-
 tex/context/base/l-package.lua                     | 201 ++++++++++-----------
 tex/context/base/l-table.lua                       |   9 +-
 tex/context/base/lpdf-ano.lua                      |   3 -
 tex/context/base/lpdf-ini.lua                      |  40 ++--
 tex/context/base/math-act.lua                      |  19 +-
 tex/context/base/math-vfu.lua                      |   1 -
 tex/context/base/mult-def.mkiv                     |   2 +
 tex/context/base/page-mix.mkiv                     |   2 -
 tex/context/base/scrn-fld.mkvi                     |  10 +-
 tex/context/base/spac-chr.mkiv                     |  39 ++--
 tex/context/base/status-files.pdf                  | Bin 24748 -> 24755 bytes
 tex/context/base/status-lua.pdf                    | Bin 211484 -> 211441 bytes
 tex/context/base/util-env.lua                      |  29 +++
 tex/context/base/util-pck.lua                      |  10 +-
 tex/generic/context/luatex/luatex-fonts-merged.lua |  30 +--
 25 files changed, 283 insertions(+), 257 deletions(-)

(limited to 'tex')

diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 52c58c99c..e8571ea21 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2013.04.17 18:36}
+\newcontextversion{2013.04.19 16:29}
 
 %D This file is loaded at runtime, thereby providing an excellent place for
 %D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 9c62d6945..a7f052cf0 100644
Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ
diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png
index 7e9beb60a..16b951ff1 100644
Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 7b0ad79d7..45b0bc69d 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -25,7 +25,7 @@
 %D up and the dependencies are more consistent.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2013.04.17 18:36}
+\edef\contextversion{2013.04.19 16:29}
 \edef\contextkind   {beta}
 
 %D For those who want to use this:
diff --git a/tex/context/base/data-lua.lua b/tex/context/base/data-lua.lua
index 14aebf959..0e7c81181 100644
--- a/tex/context/base/data-lua.lua
+++ b/tex/context/base/data-lua.lua
@@ -48,7 +48,6 @@ function helpers.cleanpath(path) -- hm, don't we have a helper for this?
 end
 
 local loadedaslib      = helpers.loadedaslib
-local loadedbypath     = helpers.loadedbypath
 local getextraluapaths = package.extraluapaths
 local getextralibpaths = package.extralibpaths
 local registerpath     = helpers.registerpath
@@ -77,30 +76,23 @@ local function getlibformatpaths()
     return libformatpaths
 end
 
-local function loadedbyformat(name,rawname,suffixes,islib)
+local function loadedbyformat(name,rawname,suffixes,islib,what)
     local trace  = helpers.trace
     local report = helpers.report
-    if trace then
-        report("locating %a as %a using formats %a",rawname,name,suffixes)
-    end
     for i=1,#suffixes do -- so we use findfile and not a lookup loop
         local format = suffixes[i]
         local resolved = resolvers.findfile(name,format) or ""
         if trace then
-            report("checking %a using format %a",name,format)
+            report("%s format, identifying %a using format %a",what,name,format)
         end
         if resolved ~= "" then
             if trace then
-                report("lib %a located on %a",name,resolved)
+                report("%s format, %a found on %a",what,name,resolved)
             end
-            local result = nil
             if islib then
-                result = loadedaslib(resolved,rawname)
+                return loadedaslib(resolved,rawname)
             else
-                result = loadfile(resolved)
-            end
-            if result then
-                return true, result()
+                return loadfile(resolved)
             end
         end
     end
@@ -120,46 +112,20 @@ helpers.loadedbyformat = loadedbyformat
 -- we could build a list of relevant paths but for tracing it's better to have the
 -- whole lot (ok, we could skip the duplicates)
 
-local shown = false
-
 methods["lua variable format"] = function(name)
-    if not shown and helpers.trace then
-        local luapaths = getluaformatpaths() -- triggers building
-        if #luapaths > 0 then
-            helpers.report("using %s lua format paths",#luapaths)
-        else
-            helpers.report("no lua format paths defined")
-        end
-        shown = true
-    end
-    local thename = lualibfile(name)
-    local luaname = addsuffix(thename,"lua")
-    local done, result = loadedbyformat(luaname,name,luasuffixes,false)
-    if done then
-        return true, result
+    if helpers.trace then
+        helpers.report("%s format, checking %s paths","lua",#getluaformatpaths()) -- call triggers building
     end
+    return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
 end
 
-local shown = false
-
 methods["lib variable format"] = function(name)
-    if not shown and helpers.trace then
-        local libpaths = getlibformatpaths() -- triggers building
-        if #libpaths > 0 then
-            helpers.report("using %s lib format paths",#libpaths)
-        else
-            helpers.report("no lib format paths defined")
-        end
-        shown = true
-    end
-    local thename = lualibfile(name)
-    local libname = addsuffix(thename,os.libsuffix)
-    local done, result = loadedbyformat(libname,name,libsuffixes,true)
-    if done then
-        return true, result
+    if helpers.trace then
+        helpers.report("%s format, checking %s paths","lib",#getlibformatpaths()) -- call triggers building
     end
+    return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
 end
 
 -- package.extraclibpath(environment.ownpath)
 
-resolvers.loadlualib = require
+resolvers.loadlualib = require -- hm
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index cb640b892..c894660d5 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -959,7 +959,7 @@ function commands.definefont_two(global,cs,str,size,inheritancemode,classfeature
         csnames[tfmdata] = specification.cs
         tex.definefont(global,cs,tfmdata)
         -- resolved (when designsize is used):
-        setsomefontsize(fontdata[tfmdata].parameters.size .. "sp")
+        setsomefontsize((fontdata[tfmdata].parameters.size or 0) .. "sp")
         lastfontid = tfmdata
     else
         -- setting the extra characters will move elsewhere
@@ -1533,6 +1533,22 @@ end)
 to scale virtual characters.</p>
 --ldx]]--
 
+function constructors.checkvirtualids(tfmdata)
+    -- begin of experiment: we can use { "slot", 0, number } in virtual fonts
+    local fonts = tfmdata.fonts
+    local selfid = font.nextid()
+    if fonts and #fonts > 0 then
+        for i=1,#fonts do
+            if fonts[i][2] == 0 then
+                fonts[i][2] = selfid
+            end
+        end
+    else
+     -- tfmdata.fonts = { "id", selfid } -- conflicts with other next id's (vf math), too late anyway
+    end
+    -- end of experiment
+end
+
 -- function constructors.getvirtualid(tfmdata)
 --     --  since we don't know the id yet, we use 0 as signal
 --     local tf = tfmdata.fonts
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index 5074e49ed..da31beac9 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -328,20 +328,8 @@ function definers.loadfont(specification)
     return tfmdata
 end
 
-local function checkvirtual(tfmdata)
-    -- begin of experiment: we can use { "slot", 0, number } in virtual fonts
-    local fonts = tfmdata.fonts
-    local selfid = font.nextid()
-    if fonts and #fonts > 0 then
-        for i=1,#fonts do
-            if fonts[i][2] == 0 then
-                fonts[i][2] = selfid
-            end
-        end
-    else
-        tfmdata.fonts = { "id", selfid }
-    end
-    -- end of experiment
+function constructors.checkvirtualids()
+    -- dummy in plain version
 end
 
 function constructors.readanddefine(name,size) -- no id -- maybe a dummy first
@@ -356,7 +344,7 @@ function constructors.readanddefine(name,size) -- no id -- maybe a dummy first
     if not id then
         local tfmdata = definers.loadfont(specification)
         if tfmdata then
-            checkvirtual(tfmdata) -- experiment, will become obsolete when slots can selfreference
+            constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference
             id = font.define(tfmdata)
             definers.register(tfmdata,id)
         else
@@ -393,7 +381,9 @@ end
 function definers.register(tfmdata,id)
     if tfmdata and id then
         local hash = tfmdata.properties.hash
-        if not internalized[hash] then
+        if not hash then
+            report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
+        elseif not internalized[hash] then
             internalized[hash] = id
             if trace_defining then
                 report_defining("registering font, id %s, hash %a",id,hash)
diff --git a/tex/context/base/font-otp.lua b/tex/context/base/font-otp.lua
index 8a37c5cdf..c07d9ad4e 100644
--- a/tex/context/base/font-otp.lua
+++ b/tex/context/base/font-otp.lua
@@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['font-otp'] = {
 }
 
 -- todo: pack math (but not that much to share)
+--
 -- pitfall 5.2: hashed tables can suddenly become indexed with nil slots
 
 local next, type = next, type
@@ -203,7 +204,6 @@ local function packdata(data)
         end
         local function pack_mixed(v)
             local tag = tabstr_mixed(v)
--- print(">>>",tag)
             local ht = h[tag]
             if ht then
                 c[ht] = c[ht] + 1
@@ -344,13 +344,11 @@ local function packdata(data)
                         if what == "baselig" then
                             for _, a in next, anchor do
                                 for k=1,#a do
---                                     a[k] = pack_normal(a[k])
                                     a[k] = pack_indexed(a[k])
                                 end
                             end
                         else
                             for k, v in next, anchor do
---                                 anchor[k] = pack_normal(v)
                                 anchor[k] = pack_indexed(v)
                             end
                         end
diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua
index 00cda3899..3d0576eeb 100644
--- a/tex/context/base/l-dir.lua
+++ b/tex/context/base/l-dir.lua
@@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['l-dir'] = {
 
 local type, select = type, select
 local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub
-local concat, insert, remove = table.concat, table.insert, table.remove
+local concat, insert, remove, unpack = table.concat, table.insert, table.remove, table.unpack
 local lpegmatch = lpeg.match
 
 local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
@@ -447,3 +447,24 @@ function dir.pop()
     end
     return d
 end
+
+local function found(...) -- can have nil entries
+    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
+            -- here we asume no holes, i.e. an indexed table
+            local path = found(unpack(path))
+            if path then
+                return path
+            end
+        end
+    end
+ -- return nil -- if we want print("crappath") to show something
+end
+
+dir.found = found
diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua
index 42f3e4862..05ca0acdc 100644
--- a/tex/context/base/l-os.lua
+++ b/tex/context/base/l-os.lua
@@ -452,8 +452,20 @@ function os.now()
     return date("!%Y-%m-%d %H:%M:%S") -- 2011-12-04 14:59:12
 end
 
-if not os.sleep and socket then
-    os.sleep = socket.sleep
+-- if not os.sleep and socket then
+--     os.sleep = socket.sleep
+-- end
+
+if not os.sleep then
+    local socket = socket
+    function os.sleep(n)
+        if not socket then
+            -- so we delay ... if os.sleep is really needed then one should also
+            -- be sure that socket can be found
+            socket = require("socket")
+        end
+        socket.sleep(n)
+    end
 end
 
 -- print(os.which("inkscape.exe"))
diff --git a/tex/context/base/l-package.lua b/tex/context/base/l-package.lua
index 7b82fa541..303e727d8 100644
--- a/tex/context/base/l-package.lua
+++ b/tex/context/base/l-package.lua
@@ -30,8 +30,6 @@ local filejoin   = file and file.join        or function(path,name)   return pat
 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 separator, concatinator, placeholder, pathofexecutable, ignorebefore = string.match(package.config,"(.-)\n(.-)\n(.-)\n(.-)\n(.-)\n")
 --
 -- local config = {
@@ -42,8 +40,6 @@ local addsuffix  = file and file.addsuffix   or function(name,suffix) return nam
 --     ignorebefore     = ignorebefore,        -- - remove all before this when making lua_open
 -- }
 
---
-
 local function cleanpath(path) -- hm, don't we have a helper for this?
     return path
 end
@@ -84,28 +80,69 @@ package.helpers  = helpers
 local methods = helpers.methods
 local builtin = helpers.builtin
 
--- extra tds/ctx paths
+-- extra tds/ctx paths ... a bit of overhead for efficient tracing
 
 local extraluapaths = { }
 local extralibpaths = { }
 local luapaths      = nil -- delayed
 local libpaths      = nil -- delayed
+local oldluapath    = nil
+local oldlibpath    = nil
+
+local nofextralua   = -1
+local nofextralib   = -1
+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)
+    end
+    return nofpaths
+end
 
 local function getextraluapaths()
+    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
 end
 
 local function getluapaths()
-    luapaths = luapaths or file.splitpath(package.path, ";")
+    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()
-    libpaths = libpaths or file.splitpath(package.cpath, ";")
+    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
 
@@ -167,8 +204,10 @@ end
 -- lib loader (used elsewhere)
 
 local function loadedaslib(resolved,rawname) -- todo: strip all before first -
- -- local init = "luaopen_" .. string.match(rawname,".-([^%.]+)$")
-    local init = "luaopen_"..gsub(rawname,"%.","_")
+    local base = gsub(rawname,"%.","_")
+ -- so, we can do a require("foo/bar") and initialize bar
+ -- local base = gsub(file.basename(rawname),"%.","_")
+    local init = "luaopen_" .. gsub(base,"%.","_")
     if helpers.trace then
         helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
     end
@@ -180,159 +219,115 @@ helpers.loadedaslib = loadedaslib
 -- wrapped and new loaders
 
 local function loadedbypath(name,rawname,paths,islib,what)
-    local trace  = helpers.trace
-    local report = helpers.report
-    if trace then
-        report("locating '%s' as '%s' on '%s' paths",rawname,name,what)
-    end
+    local trace = helpers.trace
     for p=1,#paths do
-        local path = paths[p]
+        local path     = paths[p]
         local resolved = filejoin(path,name)
-        if trace then -- mode detail
-            report("checking '%s' using '%s' path '%s'",name,what,path)
+        if trace then
+            helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
         end
         if isreadable(resolved) then
             if trace then
-                report("'%s' located on '%s'",name,resolved)
+                helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
             end
-            local result = nil
             if islib then
-                result = loadedaslib(resolved,rawname)
+                return loadedaslib(resolved,rawname)
             else
-                result = loadfile(resolved)
-            end
-            if result then
-                result()
+                return loadfile(resolved)
             end
-            return true, result
         end
     end
 end
 
 helpers.loadedbypath = loadedbypath
 
--- alternatively we could set the package.searchers
-
 methods["already loaded"] = function(name)
-    local result = package.loaded[name]
-    if result then
-        return true, result
-    end
+    return package.loaded[name]
 end
 
 methods["preload table"] = function(name)
-    local result = builtin["preload table"](name)
-    if type(result) == "function" then
-        return true, result
-    end
+    return builtin["preload table"](name)
 end
 
 methods["lua extra list"] = function(name)
-    local thename  = lualibfile(name)
-    local luaname  = addsuffix(thename,"lua")
-    local luapaths = getextraluapaths()
-    local done, result = loadedbypath(luaname,name,luapaths,false,"lua")
-    if done then
-        return true, result
-    end
+    return loadedbypath(addsuffix(lualibfile(name),"lua"       ),name,getextraluapaths(),false,"lua")
 end
 
 methods["lib extra list"] = function(name)
-    local thename  = lualibfile(name)
-    local libname  = addsuffix(thename,os.libsuffix)
-    local libpaths = getextralibpaths()
-    local done, result = loadedbypath(libname,name,libpaths,true,"lib")
-    if done then
-        return true, result
-    end
+    return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true, "lib")
 end
 
-local shown = false
-
 methods["path specification"] = function(name)
-    if not shown and helpers.trace then
-        local luapaths = getluapaths() -- triggers list building
-        if #luapaths > 0 then
-            helpers.report("using %s built in lua paths",#luapaths)
-        else
-            helpers.report("no built in lua paths defined")
-        end
-        shown = true
-    end
-    local result = builtin["path specification"](name)
-    if type(result) == "function" then
-        return true, result()
-    end
+    getluapaths() -- triggers list building and tracing
+    return builtin["path specification"](name)
 end
 
-local shown = false
-
 methods["cpath specification"] = function(name)
-    if not shown and helpers.trace then
-        local libpaths = getlibpaths() -- triggers list building
-        if #libpaths > 0 then
-            helpers.report("using %s built in lib paths",#libpaths)
-        else
-            helpers.report("no built in lib paths defined")
-        end
-        shown = true
-    end
-    local result = builtin["cpath specification"](name)
-    if type(result) == "function" then
-        return true, result()
-    end
+    getlibpaths() -- triggers list building and tracing
+    return builtin["cpath specification"](name)
 end
 
 methods["all in one fallback"] = function(name)
-    local result = builtin["all in one fallback"](name)
-    if type(result) == "function" then
-        return true, result()
-    end
+    return builtin["all in one fallback"](name)
 end
 
+local nomore = function() return nil, "no more loaders" end
+
 methods["not loaded"] = function(name)
     if helpers.trace then
         helpers.report("unable to locate '%s'",name)
     end
+    return nomore
 end
 
+local level = 0
+local dummy = function() return nil end
+
 function helpers.loaded(name)
+ -- if searchers[1] ~= helpers.loaded then
+ --     -- just in case another loader is pushed in front ... in principle we could
+ --     -- shuffle that one but let's forget about it for now
+ --     if helpers.trace then
+ --         helpers.report("disabled")
+ --     end
+ --     return dummy
+ -- end
     local sequence = helpers.sequence
+    level = level + 1
     for i=1,#sequence do
-        local step = sequence[i]
+        local method = sequence[i]
         if helpers.trace then
-            helpers.report("locating '%s' using method '%s'",name,step)
+            helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
         end
-        local done, result = methods[step](name)
-        if done then
+        local result, rest = methods[method](name)
+        if type(result) == "function" then
             if helpers.trace then
-                helpers.report("'%s' located via method '%s' returns '%s'",name,step,type(result))
+                helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
             end
-            if result then
-                package.loaded[name] = result
-            end
-            return result
+            level = level - 1
+            return result, rest
         end
     end
-    return nil -- we must return a value
+    if helpers.trace then
+        helpers.report("%s, level '%s', method '%s', name '%s'","not found",level,method,name)
+    end
+    -- safeguard, we never come here
+    level = level - 1
+    return nomore
 end
 
 function helpers.unload(name)
     if helpers.trace then
         if package.loaded[name] then
-            helpers.report("unloading '%s', %s",name,"done")
+            helpers.report("unloading, name '%s', %s",name,"done")
         else
-            helpers.report("unloading '%s', %s",name,"not loaded")
+            helpers.report("unloading, name '%s', %s",name,"not loaded")
         end
     end
-    package.loaded[name] = nil -- does that work? is readable only, maybe we need our own hash
+    package.loaded[name] = nil
 end
 
-searchers[1] = nil
-searchers[2] = nil
-searchers[3] = nil
-searchers[4] = nil
-
-helpers.savedrequire = helpers.savedrequire or require
+-- overloading require does not work out well so we need to push it in
+-- front ..
 
-require = helpers.loaded
+table.insert(searchers,1,helpers.loaded)
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 640bbbb28..e57abe854 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -1094,7 +1094,7 @@ function table.tofile(filename,root,name,specification)
     end
 end
 
-local function flattened(t,f,depth)
+local function flattened(t,f,depth) -- also handles { nil, 1, nil, 2 }
     if f == nil then
         f = { }
         depth = 0xFFFF
@@ -1110,19 +1110,16 @@ local function flattened(t,f,depth)
             if depth > 0 and type(v) == "table" then
                 flattened(v,f,depth-1)
             else
-                f[k] = v
+                f[#f+1] = v
             end
         end
     end
-    local n = #f
     for k=1,#t do
         local v = t[k]
         if depth > 0 and type(v) == "table" then
             flattened(v,f,depth-1)
-            n = #f
         else
-            n = n + 1
-            f[n] = v
+            f[#f+1] = v
         end
     end
     return f
diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua
index e722446ee..adfea3812 100644
--- a/tex/context/base/lpdf-ano.lua
+++ b/tex/context/base/lpdf-ano.lua
@@ -288,7 +288,6 @@ local function use_shared_annotations()
 
     statistics.register("pdf annotations", function()
         if nofused > 0 then
-         -- table.print(hashed,"hashed_annotations")
             return format("%s embedded, %s unique",nofused,nofunique)
         else
             return nil
@@ -414,8 +413,6 @@ runners["special operation with arguments"] = runners["special"]
 function specials.internal(var,actions) -- better resolve in strc-ref
     local i = tonumber(var.operation)
     local v = i and references.internals[i]
---~ print(">>>>>>>",i)
---~ inspect(v)
     if not v then
         -- error
         report_reference("no internal reference %a",i)
diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua
index 0b1473d2f..cd601f21f 100644
--- a/tex/context/base/lpdf-ini.lua
+++ b/tex/context/base/lpdf-ini.lua
@@ -451,28 +451,36 @@ end
 local shareobjectcache, shareobjectreferencecache = { }, { }
 
 function lpdf.shareobject(content)
-    content = tostring(content)
-    local o = shareobjectcache[content]
-    if not o then
-        o = pdfimmediateobject(content)
-        shareobjectcache[content] = o
-    end
-    return o
-end
-
-function lpdf.shareobjectreference(content)
-    content = tostring(content)
-    local r = shareobjectreferencecache[content]
-    if not r then
+    if content == nil then
+        -- invalid object not created
+    else
+        content = tostring(content)
         local o = shareobjectcache[content]
         if not o then
             o = pdfimmediateobject(content)
             shareobjectcache[content] = o
         end
-        r = pdfreference(o)
-        shareobjectreferencecache[content] = r
+        return o
+    end
+end
+
+function lpdf.shareobjectreference(content)
+    if content == nil then
+        -- invalid object not created
+    else
+        content = tostring(content)
+        local r = shareobjectreferencecache[content]
+        if not r then
+            local o = shareobjectcache[content]
+            if not o then
+                o = pdfimmediateobject(content)
+                shareobjectcache[content] = o
+            end
+            r = pdfreference(o)
+            shareobjectreferencecache[content] = r
+        end
+        return r
     end
-    return r
 end
 
 --~ local d = lpdf.dictionary()
diff --git a/tex/context/base/math-act.lua b/tex/context/base/math-act.lua
index 8aeb0a97f..4f9b3b7e8 100644
--- a/tex/context/base/math-act.lua
+++ b/tex/context/base/math-act.lua
@@ -92,16 +92,23 @@ function mathematics.checkaccentbaseheight(target,original)
     end
 end
 
-sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight")
+sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead
 
 function mathematics.checkprivateparameters(target,original)
     local mathparameters = target.mathparameters
     if mathparameters then
-        if not mathparameters.FractionDelimiterSize then
-            mathparameters.FractionDelimiterSize = 1.01 * target.parameters.size
-        end
-        if not mathparameters.FractionDelimiterDisplayStyleSize then
-            mathparameters.FractionDelimiterDisplayStyleSize = 2.40 * target.parameters.size
+        local parameters = target.parameters
+        if parameters then
+            if not mathparameters.FractionDelimiterSize then
+                mathparameters.FractionDelimiterSize = 1.01 * parameters.size
+            end
+            if not mathparameters.FractionDelimiterDisplayStyleSize then
+                mathparameters.FractionDelimiterDisplayStyleSize = 2.40 * parameters.size
+            end
+        elseif target.properties then
+            report_math("no parameters in font %a",target.properties.fullname or "?")
+        else
+            report_math("no parameters and properties in font")
         end
     end
 end
diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua
index b169ec5e5..2f7c0507b 100644
--- a/tex/context/base/math-vfu.lua
+++ b/tex/context/base/math-vfu.lua
@@ -908,7 +908,6 @@ function vfmath.define(specification,set,goodies)
         size = size,
     }
     --
-    --
     main.mathparameters = mathparameters -- still traditional ones
     vfmath.addmissing(main,#fontlist,size)
     mathematics.addfallbacks(main)
diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv
index 66d4f4748..ec33171da 100644
--- a/tex/context/base/mult-def.mkiv
+++ b/tex/context/base/mult-def.mkiv
@@ -80,6 +80,8 @@
 \def\s!insert           {insert} % maybe insertclass
 \def\s!marker           {marker}
 
+\def\s!mixedcolumn      {mixedcolumn}
+
 \def\s!double           {double}
 \def\s!decimal          {decimal}
 
diff --git a/tex/context/base/page-mix.mkiv b/tex/context/base/page-mix.mkiv
index a5c343fc7..a4a9bab09 100644
--- a/tex/context/base/page-mix.mkiv
+++ b/tex/context/base/page-mix.mkiv
@@ -50,8 +50,6 @@
 
 \installcorenamespace{mixedcolumns}
 
-\def\s!mixedcolumn{mixedcolumn}
-
 \installframedcommandhandler \??mixedcolumns {mixedcolumns} \??mixedcolumns
 
 \setupmixedcolumns
diff --git a/tex/context/base/scrn-fld.mkvi b/tex/context/base/scrn-fld.mkvi
index cc84b9c71..049ac92c3 100644
--- a/tex/context/base/scrn-fld.mkvi
+++ b/tex/context/base/scrn-fld.mkvi
@@ -367,7 +367,7 @@
      \begingroup
        \edef\currentdefaultfieldvalue{\ctxcommand{getdefaultfieldvalue("#tag")}}%
        \setbox\b_scrn_field_fit_symbol\hbox{\symbol[\currentdefaultfieldvalue]}%
-       \fitfieldframed[#tag]
+       \fitfieldframed
          {\fieldbody[#tag]
             [\c!width=\wd\b_scrn_field_fit_symbol,
              \c!height=\ht\b_scrn_field_fit_symbol,
@@ -952,14 +952,14 @@
 
 \def\scrn_rollbutton_symbol_m
   {\scrn_rollbutton_symbol_indeed
-     \getinteractionmenuparameter
+     \interactionmenuparameter
      \inheritedinteractionmenuframed
      \setinteractionmenuparameter
      \useinteractionmenustyleandcolor}
 
 \def\scrn_rollbutton_symbol_b
   {\scrn_rollbutton_symbol_indeed
-     \getbuttonparameter
+     \buttonparameter
      \inheritedbuttonframed
      \setbuttonparameter
      \usebuttonstyleandcolor}
@@ -967,8 +967,8 @@
 \def\scrn_rollbutton[#tag][#settings]#text[#reference]%
   {\dontleavehmode
    \bgroup
-   \doglobal\advance\c_scrn_rollbutton_n_button
-   \doglobal\advance\c_scrn_rollbutton_n_symbol
+   \advance\c_scrn_rollbutton_n_button\plusone
+   \advance\c_scrn_rollbutton_n_symbol\plusone
    \iffirstargument
      \ifsecondargument
        \edef\currentinteractionmenu{#tag}%
diff --git a/tex/context/base/spac-chr.mkiv b/tex/context/base/spac-chr.mkiv
index 6b7c8742f..0b6ebe0a9 100644
--- a/tex/context/base/spac-chr.mkiv
+++ b/tex/context/base/spac-chr.mkiv
@@ -55,26 +55,25 @@
 % catcode vector.
 
 %    \nobreakspace            {\begingroup\setalignstateattribute\normalUchar"00A0\endgroup} % 1 = left
-
-\edef\nobreakspace            {\normalUchar"00A0}
-\edef\ideographicspace        {\normalUchar"2000}
-\edef\ideographichalffillspace{\normalUchar"2001}
-\edef\twoperemspace           {\normalUchar"2002}
-\edef\threeperemspace         {\normalUchar"2004}
-\edef\fourperemspace          {\normalUchar"2005}
-\edef\sixperemspace           {\normalUchar"2006}
-\edef\figurespace             {\normalUchar"2007}
-\edef\punctuationspace        {\normalUchar"2008}
-\edef\breakablethinspace      {\normalUchar"2009}
-\edef\hairspace               {\normalUchar"200A}
-\edef\zerowidthspace          {\normalUchar"200B}
-\edef\zwnj                    {\normalUchar"200C}
-\edef\zwj                     {\normalUchar"200D}
-\edef\narrownobreakspace      {\normalUchar"202F}
-
-%edef\zerowidthnobreakspace   {\normalUchar"FEFF}
-
-\unexpanded\def\zerowidthnobreakspace{\penalty\plustenthousand\kern\zeropoint}
+\edef\nobreakspace            {\normalUchar"00A0} % space
+\edef\ideographicspace        {\normalUchar"2000} % quad/2
+\edef\ideographichalffillspace{\normalUchar"2001} % quad
+\edef\twoperemspace           {\normalUchar"2002} % quad/2
+%                             %            "2003  % quad == \quad == \hskip\emwidth
+\edef\threeperemspace         {\normalUchar"2004} % quad/3
+\edef\fourperemspace          {\normalUchar"2005} % quad/4
+\edef\sixperemspace           {\normalUchar"2006} % quad/6
+\edef\figurespace             {\normalUchar"2007} % width of zero
+\edef\punctuationspace        {\normalUchar"2008} % width of period
+\edef\breakablethinspace      {\normalUchar"2009} % quad/8
+\edef\hairspace               {\normalUchar"200A} % quad/8
+\edef\zerowidthspace          {\normalUchar"200B} % 0
+\edef\zwnj                    {\normalUchar"200C} % 0
+\edef\zwj                     {\normalUchar"200D} % 0
+\edef\narrownobreakspace      {\normalUchar"202F} % quad/8
+%                             %            "205F  % space/8 (math)
+%    \zerowidthnobreakspace   {\normalUchar"FEFF}
+\udef\zerowidthnobreakspace   {\penalty\plustenthousand\kern\zeropoint}
 
 % Shortcuts:
 
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index b61a21221..740de0373 100644
Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 51f1cf8c5..9cb8402ad 100644
Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ
diff --git a/tex/context/base/util-env.lua b/tex/context/base/util-env.lua
index 283b91c0a..f4f3ef69f 100644
--- a/tex/context/base/util-env.lua
+++ b/tex/context/base/util-env.lua
@@ -206,6 +206,35 @@ function environment.reconstructcommandline(arg,noquote)
     end
 end
 
+-- handy in e.g. package.addluapath(environment.relativepath("scripts"))
+
+function environment.relativepath(path,root)
+    if not path then
+        path = ""
+    end
+    if not file.is_rootbased_path(path) then
+        if not root then
+            root = file.pathpart(environment.ownscript or environment.ownname or ".")
+        end
+        if root == "" then
+            root = "."
+        end
+        path = root .. "/" .. path
+    end
+    return file.collapsepath(path,true)
+end
+
+-- -- when script lives on e:/tmp we get this:
+--
+-- print(environment.relativepath("x/y/z","c:/w")) -- c:/w/x/y/z
+-- print(environment.relativepath("x"))            -- e:/tmp/x
+-- print(environment.relativepath("../x"))         -- e:/x
+-- print(environment.relativepath("./x"))          -- e:/tmp/x
+-- print(environment.relativepath("/x"))           -- /x
+-- print(environment.relativepath("c:/x"))         -- c:/x
+-- print(environment.relativepath("//x"))          -- //x
+-- print(environment.relativepath())               -- e:/tmp
+
 -- -- to be tested:
 --
 -- function environment.reconstructcommandline(arg,noquote)
diff --git a/tex/context/base/util-pck.lua b/tex/context/base/util-pck.lua
index cf1445b40..7be5e8f42 100644
--- a/tex/context/base/util-pck.lua
+++ b/tex/context/base/util-pck.lua
@@ -108,11 +108,12 @@ function packers.pack(t,p,shared)
         if #p.index > 0 then
             t.packer = {
                 version = p.version or packers.version,
-                keys = p.keys,
-                index = p.index,
+                keys    = p.keys,
+                index   = p.index,
             }
         end
-        p.hash, p.index = { }, { }
+        p.hash  = { }
+        p.index = { }
     end
 end
 
@@ -138,3 +139,6 @@ end
 function packers.strip(p)
     p.hash = nil
 end
+
+-- We could have a packer.serialize where we first flush the shared table
+-- and then use inline a reference . This saves an unpack.
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 44f42edee..e8eb49c9c 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
 -- merged file : luatex-fonts-merged.lua
 -- parent file : luatex-fonts.lua
--- merge date  : 04/17/13 18:36:10
+-- merge date  : 04/19/13 16:29:24
 
 do -- begin closure to overcome local limits and interference
 
@@ -1401,7 +1401,7 @@ function table.tofile(filename,root,name,specification)
     io.flush()
   end
 end
-local function flattened(t,f,depth)
+local function flattened(t,f,depth) 
   if f==nil then
     f={}
     depth=0xFFFF
@@ -1416,19 +1416,16 @@ local function flattened(t,f,depth)
       if depth>0 and type(v)=="table" then
         flattened(v,f,depth-1)
       else
-        f[k]=v
+        f[#f+1]=v
       end
     end
   end
-  local n=#f
   for k=1,#t do
     local v=t[k]
     if depth>0 and type(v)=="table" then
       flattened(v,f,depth-1)
-      n=#f
     else
-      n=n+1
-      f[n]=v
+      f[#f+1]=v
     end
   end
   return f
@@ -10579,18 +10576,7 @@ function definers.loadfont(specification)
   end
   return tfmdata
 end
-local function checkvirtual(tfmdata)
-  local fonts=tfmdata.fonts
-  local selfid=font.nextid()
-  if fonts and #fonts>0 then
-    for i=1,#fonts do
-      if fonts[i][2]==0 then
-        fonts[i][2]=selfid
-      end
-    end
-  else
-    tfmdata.fonts={ "id",selfid }
-  end
+function constructors.checkvirtualids()
 end
 function constructors.readanddefine(name,size) 
   local specification=definers.analyze(name,size)
@@ -10604,7 +10590,7 @@ function constructors.readanddefine(name,size)
   if not id then
     local tfmdata=definers.loadfont(specification)
     if tfmdata then
-      checkvirtual(tfmdata) 
+      constructors.checkvirtualids(tfmdata) 
       id=font.define(tfmdata)
       definers.register(tfmdata,id)
     else
@@ -10625,7 +10611,9 @@ end
 function definers.register(tfmdata,id)
   if tfmdata and id then
     local hash=tfmdata.properties.hash
-    if not internalized[hash] then
+    if not hash then
+      report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
+    elseif not internalized[hash] then
       internalized[hash]=id
       if trace_defining then
         report_defining("registering font, id %s, hash %a",id,hash)
-- 
cgit v1.2.3