1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
if not modules then modules = { } end modules ['node-shp'] = {
version = 1.001,
optimize = true,
comment = "companion to node-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local next, type = next, type
local format = string.format
local setmetatableindex = table.setmetatableindex
local nodes = nodes
local tasks = nodes.tasks
local handlers = nodes.handlers
local nodecodes = nodes.nodecodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local nuts = nodes.nuts
local tonut = nuts.tonut
local nextnode = nuts.traversers.node
local getlist = nuts.getlist
local getbox = nuts.getbox
local implement = interfaces.implement
local actions = tasks.actions("shipouts")
function handlers.finalizebox(box)
actions(getbox(box)) -- nut
end
handlers.cleanuppage = nuts.flatten_discretionaries
-- interface
implement {
name = "finalizebox",
arguments = "integer",
actions = handlers.finalizebox,
}
-- just in case we want to optimize lookups:
local frequencies = { }
nodes.tracers.frequencies = frequencies
local data = { }
local done = false
setmetatableindex(data,function(t,k)
local v = { }
setmetatableindex(v,function(t,k)
local v = { }
t[k] = v
setmetatableindex(v,function(t,k)
t[k] = 0
return 0
end)
return v
end)
t[k] = v
return v
end)
local function count(head,data,subcategory)
-- no components, pre, post, replace .. can maybe an option .. but
-- we use this for optimization so it makes sense to look the the
-- main node only
for n, id in nextnode, tonut(head) do
local dn = data[nodecodes[id]] -- we could use id and then later convert to nodecodes
dn[subcategory] = dn[subcategory] + 1
if id == hlist_code or id == vlist_code then
count(getlist(n),data,subcategory)
end
end
end
local function register(category,subcategory)
return function(head)
done = true
count(head,data[category],subcategory)
return head, false
end
end
frequencies.register = register
frequencies.filename = nil
trackers.register("nodes.frequencies",function(v)
if type(v) == "string" then
frequencies.filename = v
end
handlers.frequencies_shipouts_before = register("shipouts", "begin")
handlers.frequencies_shipouts_after = register("shipouts", "end")
handlers.frequencies_processors_before = register("processors", "begin")
handlers.frequencies_processors_after = register("processors", "end")
tasks.prependaction("shipouts", "before", "nodes.handlers.frequencies_shipouts_before")
tasks.appendaction ("shipouts", "after", "nodes.handlers.frequencies_shipouts_after")
tasks.prependaction("processors", "before", "nodes.handlers.frequencies_processors_before")
tasks.appendaction ("processors", "after", "nodes.handlers.frequencies_processors_after")
end)
statistics.register("node frequencies", function()
if done then
local filename = frequencies.filename or (tex.jobname .. "-frequencies.lua")
io.savedata(filename,table.serialize(data,true))
return format("saved in %q",filename)
end
end)
|