diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua | 173 |
1 files changed, 51 insertions, 122 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua index 5ebfca87d14..485e742b64a 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua @@ -26,12 +26,14 @@ local getid = nuts.getid local getnext = nuts.getnext local getprev = nuts.getprev local getsubtype = nuts.getsubtype -local getfield = nuts.getfield local getlist = nuts.getlist local setlist = nuts.setlist +local getprop = nuts.getprop + local removenode = nuts.remove -local traverse = nuts.traverse -local traverse_id = nuts.traverse_id + +local nextnode = nuts.traversers.node +local nextwhatsit = nuts.traversers.whatsit local nodecodes = nodes.nodecodes local whatsitcodes = nodes.whatsitcodes @@ -39,18 +41,17 @@ local whatsitcodes = nodes.whatsitcodes local whatsit_code = nodecodes.whatsit local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local userdefined_code = whatsitcodes.userdefined + +local userdefinedwhatsit_code = whatsitcodes.userdefined local nodepool = nodes.pool -local new_usernumber = nodepool.usernumber +local new_usernode = nodepool.usernode local variables = interfaces.variables local v_before = variables.before local v_after = variables.after local v_here = variables.here -local cache = { } -local nofslots = 0 local property_id = nodepool.userids["property"] local properties = nodes.properties @@ -71,15 +72,8 @@ local function register(where,data,...) where = v_after end if data then - local data = { where, data, ... } nofslots = nofslots + 1 - if nofslots > 1 then - cache[nofslots] = data - else - -- report("restarting attacher") - cache = { data } -- also forces collection - end - return new_usernumber(property_id,nofslots) + return new_usernode(property_id,{ where, data, ... }) end end @@ -108,17 +102,9 @@ local f_delayed = formatters["return function(target,head,where,propdata,paren local f_immediate = formatters["return function(target,head,where,propdata) %s end"] local nofdelayed = 0 -- better is to keep track of it per page ... we can have deleted nodes with properties +local nofslots = 0 function actions.delayed(target,head,where,propdata,code,...) -- this one is used at the tex end --- local kind = type(code) --- if kind == "string" then --- code, err = load(f_delayed(code)) --- if code then --- code = code() --- end --- elseif kind ~= "function" then --- code = nil --- end if code then local delayed = propdata.delayed if delayed then @@ -131,15 +117,6 @@ function actions.delayed(target,head,where,propdata,code,...) -- this one is use end function actions.fdelayed(target,head,where,propdata,code,...) -- this one is used at the tex end --- local kind = type(code) --- if kind == "string" then --- code, err = load(f_delayed(code)) --- if code then --- code = code() --- end --- elseif kind ~= "function" then --- code = nil --- end if code then local delayed = propdata.delayed if delayed then @@ -170,81 +147,41 @@ function actions.immediate(target,head,where,propdata,code,...) -- this one is u end end --- another experiment (a table or function closure are equally efficient); a function --- is easier when we want to experiment with different (compatible) implementations - --- local nutpool = nuts.pool --- local nut_usernumber = nutpool.usernumber - --- function nodes.nuts.pool.deferredfunction(...) --- nofdelayed = nofdelayed + 1 --- local n = nut_usernumber(property_id,0) --- propertydata[n] = { deferred = { ... } } --- return n --- end - --- function nodes.nuts.pool.deferredfunction(f) --- nofdelayed = nofdelayed + 1 --- local n = nut_usernumber(property_id,0) --- propertydata[n] = { deferred = f } --- return n --- end - --- maybe actions will get parent too - local function delayed(head,parent) -- direct based - for target in traverse(head) do + for target, id in nextnode, head do local p = propertydata[target] if p then - -- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v) - -- if deferred then - -- -- if #deferred > 0 then - -- -- deferred[1](unpack(deferred,2)) - -- -- else - -- -- deferred[1]() - -- -- end - -- deferred() - -- p.deferred = false - -- if nofdelayed == 1 then - -- nofdelayed = 0 - -- return head - -- else - -- nofdelayed = nofdelayed - 1 - -- end - -- else - local delayed = p.delayed - if delayed then - for i=1,#delayed do - local d = delayed[i] - local code = d[2] - local kind = type(code) - if kind == "string" then - code, err = load(f_delayed(code)) - if code then - code = code() - end - end - local where = d[1] - if where then - local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent - if h and h ~= head then - head = h - end - else - code(unpack(d,3)) + local delayed = p.delayed + if delayed then + for i=1,#delayed do + local d = delayed[i] + local code = d[2] + local kind = type(code) + if kind == "string" then + code, err = load(f_delayed(code)) + if code then + code = code() end end - p.delayed = nil - if nofdelayed == 1 then - nofdelayed = 0 - return head + local where = d[1] + if where then + local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent + if h and h ~= head then + head = h + end else - nofdelayed = nofdelayed - 1 + code(unpack(d,3)) end end - -- end + p.delayed = nil + if nofdelayed == 1 then + nofdelayed = 0 + return head + else + nofdelayed = nofdelayed - 1 + end + end end - local id = getid(target) if id == hlist_code or id == vlist_code then local list = getlist(target) if list then @@ -268,14 +205,13 @@ function properties.delayed(head) -- if nofdelayed > 0 then -- if next(propertydata) then starttiming(properties) - head = delayed(tonut(head)) + head = delayed(head) stoptiming(properties) - return tonode(head), true -- done in shipout anyway -- else -- delayed = 0 - -- end + -- end end - return head, false + return head end -- more explicit ones too @@ -284,7 +220,7 @@ local anchored = { [v_before] = function(n) while n do n = getprev(n) - if getid(n) == whatsit_code and getsubtype(n) == user_code and getfield(n,"user_id") == property_id then + if getid(n) == whatsit_code and getsubtype(n) == user_code and getprop(n,"id") == property_id then -- continue else return n @@ -296,7 +232,7 @@ local anchored = { n = getnext(n) if getid(n) == whatsit_code then local subtype = getsubtype(n) - if (subtype == userdefined_code and getfield(n,"user_id") == property_id) then + if (subtype == userdefinedwhatsit_code and getprop(n,"id") == property_id) then -- continue else return n @@ -320,26 +256,22 @@ end) function properties.attach(head) if nofslots <= 0 then - return head, false + return head end - local done = false local last = nil - local head = tonut(head) starttiming(properties) - for source in traverse_id(whatsit_code,head) do - if getsubtype(source) == userdefined_code then + for source, subtype in nextwhatsit, head do + if subtype == userdefinedwhatsit_code then if last then removenode(head,last,true) last = nil end - if getfield(source,"user_id") == property_id then - local slot = getfield(source,"value") - local data = cache[slot] + if getprop(source,"id") == property_id then + local data = getprop(source,"data") if data then - cache[slot] = nil local where = data[1] local target = anchored[where](source) if target then @@ -393,7 +325,7 @@ function properties.attach(head) target,nodecodes[getid(target)],serialize(propertydata[target],false)) end end - if nofslots == 1 then + if nofslots == 1 then nofslots = 0 last = source break @@ -412,25 +344,22 @@ function properties.attach(head) stoptiming(properties) - return head, done + return head end -local tasks = nodes.tasks - -- maybe better hard coded in-place --- tasks.prependaction("processors","before","nodes.properties.attach") --- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed") - statistics.register("properties processing time", function() return statistics.elapsedseconds(properties) end) -- only for development +-- local tasks = nodes.tasks +-- -- local function show(head,level,report) --- for target in traverse(head) do +-- for target in nextnode, head do -- local p = propertydata[target] -- if p then -- report("level %i, node %i, id %s, data %s", |