page-inj.lua /size: 3992 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ["page-inj"] = {
2    version   = 1.000,
3    comment   = "Page injections",
4    author    = "Wolfgang Schuster & Hans Hagen",
5    copyright = "Wolfgang Schuster & Hans Hagen",
6    license   = "see context related readme files",
7}
8
9-- Adapted a bit by HH: numbered states, tracking, delayed, order, etc.
10
11local type, tonumber = type, tonumber
12
13local injections        = pagebuilders.injections or { }
14pagebuilders.injections = injections
15
16local report            = logs.reporter("pagebuilder","injections")
17local trace             = false  trackers.register("pagebuilder.injections",function(v) trace = v end)
18
19local context           = context
20local implement         = interfaces.implement
21local variables         = interfaces.variables
22
23local texsetcount       = tex.setcount
24
25local v_previous        = variables.previous
26local v_next            = variables.next
27
28local order             = 0
29local cache             = { }
30
31function injections.save(specification) -- maybe not public, just commands.*
32    order = order + 1
33    cache[#cache+1] = {
34        order      = order,
35        name       = specification.name,
36        state      = tonumber(specification.state) or specification.state,
37        parameters = specification.userdata,
38    }
39    texsetcount("global","c_page_boxes_flush_n",#cache)
40end
41
42function injections.flushbefore() -- maybe not public, just commands.*
43    if #cache > 0 then
44        local delayed = { }
45        context.unprotect()
46        for i=1,#cache do
47            local c = cache[i]
48            local oldstate = c.state
49            if oldstate == v_previous then
50                if trace then
51                    report("entry %a, order %a, flushing due to state %a",i,c.order,oldstate)
52                end
53                context.page_injections_flush_saved(c.name,c.parameters)
54            elseif type(oldstate) == "number" and oldstate < 0 then
55                local newstate = oldstate + 1
56                if newstate >= 0 then
57                    newstate = v_previous
58                end
59                if trace then
60                    report("entry %a, order %a, changing state from %a to %a",i,c.order,oldstate,newstate)
61                end
62                c.state = newstate
63                delayed[#delayed+1] = c
64            else
65                delayed[#delayed+1] = c
66            end
67        end
68        context.unprotect()
69        cache = delayed
70        texsetcount("global","c_page_boxes_flush_n",#cache)
71    end
72end
73
74function injections.flushafter() -- maybe not public, just commands.*
75    if #cache > 0 then
76        local delayed = { }
77        context.unprotect()
78        for i=1,#cache do
79            local c = cache[i]
80            local oldstate = c.state
81            if oldstate == v_next then
82                if trace then
83                    report("entry %a, order %a, flushing due to state %a",i,c.order,oldstate)
84                end
85                context.page_injections_flush_saved(c.name,c.parameters)
86            elseif type(oldstate) == "number" and oldstate> 0 then
87                local newstate = oldstate- 1
88                if newstate <= 0 then
89                    newstate = v_next
90                end
91                if trace then
92                    report("entry %a, order %a, changing state from %a to %a",i,c.order,oldstate,newstate)
93                end
94                c.state = newstate
95                delayed[#delayed+1] = c
96            end
97        end
98        context.protect()
99        cache = delayed
100        texsetcount("global","c_page_boxes_flush_n",#cache)
101    end
102end
103
104implement {
105    name      = "savepageinjections",
106    actions   = injections.save,
107    arguments = {
108        {
109            { "name" },
110            { "state" },
111            { "userdata" }
112        }
113    }
114}
115
116implement {
117    name    = "flushpageinjectionsbefore",
118    actions = injections.flushbefore
119}
120
121implement {
122    name    = "flushpageinjectionsafter",
123    actions = injections.flushafter
124}
125