if not modules then modules = { } end modules ['luat-cbk'] = { 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 insert, remove, find = table.insert, table.remove, string.find local collectgarbage, type, next = collectgarbage, type, next local round = math.round local trace_checking = false trackers.register("memory.checking", function(v) trace_checking = v end) --[[ldx--
Callbacks are the real asset of
When you (temporarily) want to install a callback function, and after a while wants to revert to the original one, you can use the following two functions.
--ldx]]-- local trace_callbacks = false trackers.register("system.callbacks", function(v) trace_callbacks = v end) local register_callback, find_callback = callback.register, callback.find local frozen, stack = { }, { } callback.original_register_callback = register_callback local function frozen_message(what,name) logs.report("callbacks","not %s frozen '%s' (%s)",what,name,frozen[name]) end local function frozen_callback(name) return nil, format("callback '%s' is frozen (%s)",name,frozen[name]) end local function state(name) local f = find_callback(name) if f == false then return "disabled" elseif f then return "enabled" else return "undefined" end end function callbacks.report() local list = callback.list() for name, func in table.sortedhash(list) do local str = frozen[name] if str then logs.report("callbacks","%s: %s -> %s",state(name),name,str) else logs.report("callbacks","%s: %s",state(name),name) end end end function callbacks.table() local NC, NR, verbatim = context.NC, context.NR, context.type context.starttabulate { "|l|l|p|" } for name, func in table.sortedhash(callback.list()) do NC() verbatim(name) NC() verbatim(state(name)) NC() context(frozen[name] or "") NC() NR() end context.stoptabulate() end function callbacks.freeze(name,freeze) freeze = type(freeze) == "string" and freeze --~ print(name) if find(name,"%*") then local pattern = name -- string.simpleesc(name) local list = callback.list() for name, func in next, list do if find(name,pattern) then frozen[name] = freeze or frozen[name] or "frozen" end end else frozen[name] = freeze or frozen[name] or "frozen" end end function callbacks.register(name,func,freeze) if frozen[name] then if trace_callbacks then frozen_message("registering",name) end return frozen_callback(name) elseif freeze then frozen[name] = (type(freeze) == "string" and freeze) or "registered" end return register_callback(name,func) end function callback.register(name,func) -- original if not frozen[name] then return register_callback(name,func) elseif trace_callbacks then frozen_message("registering",name) end return frozen_callback(name) end function callbacks.push(name, func) if not frozen[name] then local sn = stack[name] if not sn then sn = { } stack[name] = sn end insert(sn,find_callback(name)) register_callback(name, func) elseif trace_callbacks then frozen_message("pushing",name) end end function callbacks.pop(name) if not frozen[name] then local sn = stack[name] if not sn or #sn == 0 then -- some error register_callback(name, nil) -- ! really needed else -- this fails: register_callback(name, remove(stack[name])) local func = remove(sn) register_callback(name, func) end end end --~ -- somehow crashes later on --~ --~ callbacks.freeze("find_.*_file","finding file") --~ callbacks.freeze("read_.*_file","reading file") --~ callbacks.freeze("open_.*_file","opening file") --[[ldx--The simple case is to remove the callback:
callbacks.push('linebreak_filter')
... some actions ...
callbacks.pop('linebreak_filter')
Often, in such case, another callback or a macro call will pop the original.
In practice one will install a new handler, like in:
callbacks.push('linebreak_filter', function(...)
return something_done(...)
end)
Even more interesting is:
callbacks.push('linebreak_filter', function(...)
callbacks.pop('linebreak_filter')
return something_done(...)
end)
This does a one-shot.
--ldx]]-- --[[ldx--Callbacks may result in
At some point in the development we did some tests with counting nodes (in this case 121049).
setstepmul | seconds | megabytes |
200 | 24.0 | 80.5 |
175 | 21.0 | 78.2 |
150 | 22.0 | 74.6 |
160 | 22.0 | 74.6 |
165 | 21.0 | 77.6 |
125 | 21.5 | 89.2 |
100 | 21.5 | 88.4 |
The following code is kind of experimental. In the documents
that describe the development of