summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/page-inj.lua
blob: d3548b4fb91723de9fd49e594311d30adb894896 (plain)
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
116
117
118
119
120
121
122
123
124
if not modules then modules = { } end modules ["page-inj"] = {
    version   = 1.000,
    comment   = "Page injections",
    author    = "Wolfgang Schuster & Hans Hagen",
    copyright = "Wolfgang Schuster & Hans Hagen",
    license   = "see context related readme files",
}

-- Adapted a bit by HH: numbered states, tracking, delayed, order, etc.

local type, tonumber = type, tonumber

local injections        = pagebuilders.injections or { }
pagebuilders.injections = injections

local report            = logs.reporter("pagebuilder","injections")
local trace             = false  trackers.register("pagebuilder.injections",function(v) trace = v end)

local context           = context
local implement         = interfaces.implement
local variables         = interfaces.variables

local texsetcount       = tex.setcount

local v_previous        = variables.previous
local v_next            = variables.next

local order             = 0
local cache             = { }

function injections.save(specification) -- maybe not public, just commands.*
    order = order + 1
    cache[#cache+1] = {
        order      = order,
        name       = specification.name,
        state      = tonumber(specification.state) or specification.state,
        parameters = specification.userdata,
    }
    texsetcount("global","c_page_boxes_flush_n",#cache)
end

function injections.flushbefore() -- maybe not public, just commands.*
    if #cache > 0 then
        local delayed = { }
        context.unprotect()
        for i=1,#cache do
            local c = cache[i]
            local oldstate = c.state
            if oldstate == v_previous then
                if trace then
                    report("entry %a, order %a, flushing due to state %a",i,c.order,oldstate)
                end
                context.page_injections_flush_saved(c.name,c.parameters)
            elseif type(oldstate) == "number" and oldstate < 0 then
                local newstate = oldstate + 1
                if newstate >= 0 then
                    newstate = v_previous
                end
                if trace then
                    report("entry %a, order %a, changing state from %a to %a",i,c.order,oldstate,newstate)
                end
                c.state = newstate
                delayed[#delayed+1] = c
            else
                delayed[#delayed+1] = c
            end
        end
        context.unprotect()
        cache = delayed
        texsetcount("global","c_page_boxes_flush_n",#cache)
    end
end

function injections.flushafter() -- maybe not public, just commands.*
    if #cache > 0 then
        local delayed = { }
        context.unprotect()
        for i=1,#cache do
            local c = cache[i]
            local oldstate = c.state
            if oldstate == v_next then
                if trace then
                    report("entry %a, order %a, flushing due to state %a",i,c.order,oldstate)
                end
                context.page_injections_flush_saved(c.name,c.parameters)
            elseif type(oldstate) == "number" and oldstate> 0 then
                local newstate = oldstate- 1
                if newstate <= 0 then
                    newstate = v_next
                end
                if trace then
                    report("entry %a, order %a, changing state from %a to %a",i,c.order,oldstate,newstate)
                end
                c.state = newstate
                delayed[#delayed+1] = c
            end
        end
        context.protect()
        cache = delayed
        texsetcount("global","c_page_boxes_flush_n",#cache)
    end
end

implement {
    name      = "savepageinjections",
    actions   = injections.save,
    arguments = {
        {
            { "name" },
            { "state" },
            { "userdata" }
        }
    }
}

implement {
    name    = "flushpageinjectionsbefore",
    actions = injections.flushbefore
}

implement {
    name    = "flushpageinjectionsafter",
    actions = injections.flushafter
}