diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/l-table.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/l-table.lua | 135 |
1 files changed, 101 insertions, 34 deletions
diff --git a/Master/texmf-dist/tex/context/base/l-table.lua b/Master/texmf-dist/tex/context/base/l-table.lua index d231830eddc..97e0441eb09 100644 --- a/Master/texmf-dist/tex/context/base/l-table.lua +++ b/Master/texmf-dist/tex/context/base/l-table.lua @@ -49,12 +49,22 @@ function table.keys(t) end end +-- local function compare(a,b) +-- local ta, tb = type(a), type(b) -- needed, else 11 < 2 +-- if ta == tb then +-- return a < b +-- else +-- return tostring(a) < tostring(b) -- not that efficient +-- end +-- end + local function compare(a,b) - local ta, tb = type(a), type(b) -- needed, else 11 < 2 - if ta == tb then + local ta = type(a) -- needed, else 11 < 2 + local tb = type(b) -- needed, else 11 < 2 + if ta == tb and ta == "number" then return a < b else - return tostring(a) < tostring(b) + return tostring(a) < tostring(b) -- not that efficient end end @@ -164,14 +174,14 @@ local function sortedhash(t,cmp) end local n = 0 local m = #s - local function kv(s) + local function kv() -- (s) if n < m then n = n + 1 local k = s[n] return k, t[k] end end - return kv, s + return kv -- , s else return nothing end @@ -400,7 +410,7 @@ local function simple_table(t) if tv == "number" then nt = nt + 1 if hexify then - tt[nt] = format("0x%04X",v) + tt[nt] = format("0x%X",v) else tt[nt] = tostring(v) -- tostring not needed end @@ -451,7 +461,7 @@ local function do_serialize(root,name,depth,level,indexed) local tn = type(name) if tn == "number" then if hexify then - handle(format("%s[0x%04X]={",depth,name)) + handle(format("%s[0x%X]={",depth,name)) else handle(format("%s[%s]={",depth,name)) end @@ -469,7 +479,7 @@ local function do_serialize(root,name,depth,level,indexed) end end -- we could check for k (index) being number (cardinal) - if root and next(root) then + if root and next(root) ~= nil then -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone) -- if compact then -- -- NOT: for k=1,#root do (we need to quit at nil) @@ -502,7 +512,7 @@ local function do_serialize(root,name,depth,level,indexed) 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%04X,",depth,v)) + handle(format("%s 0x%X,",depth,v)) else handle(format("%s %s,",depth,v)) -- %.99g end @@ -513,7 +523,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s %q,",depth,v)) end elseif tv == "table" then - if not next(v) then + if next(v) == nil then handle(format("%s {},",depth)) elseif inline then -- and #t > 0 local st = simple_table(v) @@ -543,25 +553,25 @@ local function do_serialize(root,name,depth,level,indexed) elseif tv == "number" then if tk == "number" then if hexify then - handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) + handle(format("%s [0x%X]=0x%X,",depth,k,v)) else handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g end elseif tk == "boolean" then if hexify then - handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v)) + 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)) -- %.99g end elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then - handle(format("%s %s=0x%04X,",depth,k,v)) + handle(format("%s %s=0x%X,",depth,k,v)) else handle(format("%s %s=%s,",depth,k,v)) -- %.99g end else if hexify then - handle(format("%s [%q]=0x%04X,",depth,k,v)) + handle(format("%s [%q]=0x%X,",depth,k,v)) else handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g end @@ -570,7 +580,7 @@ local function do_serialize(root,name,depth,level,indexed) if reduce and tonumber(v) then if tk == "number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v)) + handle(format("%s [0x%X]=%s,",depth,k,v)) else handle(format("%s [%s]=%s,",depth,k,v)) end @@ -584,7 +594,7 @@ local function do_serialize(root,name,depth,level,indexed) else if tk == "number" then if hexify then - handle(format("%s [0x%04X]=%q,",depth,k,v)) + handle(format("%s [0x%X]=%q,",depth,k,v)) else handle(format("%s [%s]=%q,",depth,k,v)) end @@ -597,10 +607,10 @@ local function do_serialize(root,name,depth,level,indexed) end end elseif tv == "table" then - if not next(v) then + if next(v) == nil then if tk == "number" then if hexify then - handle(format("%s [0x%04X]={},",depth,k)) + handle(format("%s [0x%X]={},",depth,k)) else handle(format("%s [%s]={},",depth,k)) end @@ -616,7 +626,7 @@ local function do_serialize(root,name,depth,level,indexed) if st then if tk == "number" then if hexify then - handle(format("%s [0x%04X]={ %s },",depth,k,concat(st,", "))) + handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", "))) else handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) end @@ -636,7 +646,7 @@ local function do_serialize(root,name,depth,level,indexed) elseif tv == "boolean" then if tk == "number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false")) + 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 @@ -653,7 +663,7 @@ local function do_serialize(root,name,depth,level,indexed) -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip if tk == "number" then if hexify then - handle(format("%s [0x%04X]=load(%q),",depth,k,f)) + handle(format("%s [0x%X]=load(%q),",depth,k,f)) else handle(format("%s [%s]=load(%q),",depth,k,f)) end @@ -668,7 +678,7 @@ local function do_serialize(root,name,depth,level,indexed) else if tk == "number" then if hexify then - handle(format("%s [0x%04X]=%q,",depth,k,tostring(v))) + handle(format("%s [0x%X]=%q,",depth,k,tostring(v))) else handle(format("%s [%s]=%q,",depth,k,tostring(v))) end @@ -683,7 +693,7 @@ local function do_serialize(root,name,depth,level,indexed) --~ end end end - if level > 0 then + if level > 0 then handle(format("%s},",depth)) end end @@ -727,7 +737,7 @@ local function serialize(_handle,root,name,specification) -- handle wins end elseif tname == "number" then if hexify then - handle(format("[0x%04X]={",name)) + handle(format("[0x%X]={",name)) else handle("[" .. name .. "]={") end @@ -748,7 +758,7 @@ local function serialize(_handle,root,name,specification) -- handle wins root._w_h_a_t_e_v_e_r_ = nil end -- Let's forget about empty tables. - if next(root) then + if next(root) ~= nil then do_serialize(root,name,"",0) end end @@ -922,16 +932,27 @@ end table.identical = identical table.are_equal = are_equal --- maybe also make a combined one - -function table.compact(t) -- remove empty tables, assumes subtables - if t then - for k, v in next, t do - if not next(v) then -- no type checking - t[k] = nil +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 end end + return new +end + +table.sparse = sparse + +function table.compact(t) + return sparse(t,true,true) end function table.contains(t, v) @@ -1055,11 +1076,11 @@ end -- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice) function table.is_empty(t) - return not t or not next(t) + return not t or next(t) == nil end function table.has_one_entry(t) - return t and not next(t,next(t)) + return t and next(t,next(t)) == nil end -- new @@ -1114,3 +1135,49 @@ function table.values(t,s) -- optional sort flag return { } end end + +-- maybe this will move to util-tab.lua + +-- for k, v in table.filtered(t,pattern) do ... end +-- for k, v in table.filtered(t,pattern,true) do ... end +-- for k, v in table.filtered(t,pattern,true,cmp) do ... end + +function table.filtered(t,pattern,sort,cmp) + if t and type(pattern) == "string" then + if sort then + local s + if cmp then + -- it would be nice if the sort function would accept a third argument (or nicer, an optional first) + s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end) + else + s = sortedkeys(t) -- the robust one + 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 + end + else + return nothing + end +end |