summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/core-pag.lmt
blob: 219171d424e38b2c8d925e3153e8e7fffb7e514f (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
if not modules then modules = { } end modules ['core-dat'] = {
    version   = 1.001,
    comment   = "companion to core-dat.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- This module provides a (multipass) container for arbitrary data. It replaces the
-- twopass data mechanism.

local tonumber = tonumber

local context           = context
local ctx_latelua       = context.latelua

local trace_pagestates  = false  trackers.register("job.pagestates", function(v) trace_pagestates = v end)

local report_pagestate  = logs.reporter("pagestate")

local allocate          = utilities.storage.allocate

local texgetcount       = tex.getcount
local texsetcount       = tex.setcount

local new_latelua       = nodes.pool.latelua

local implement         = interfaces.implement
local getnamespace      = interfaces.getnamespace

local c_realpageno      = tex.iscount("realpageno")
local c_realpagestateno = tex.iscount("realpagestateno")

local collected = allocate()
local tobesaved = allocate()

local pagestates = {
    collected = collected,
    tobesaved = tobesaved,
}

job.pagestates = pagestates

local function initializer()
    collected = pagestates.collected
    tobesaved = pagestates.tobesaved
end

job.register("job.pagestates.collected", tobesaved, initializer, nil)

table.setmetatableindex(tobesaved, "table")

local function setstate(settings)
    local name = settings.name
    local tag  = settings.tag
    local list = tobesaved[name]
    if not tag then
        tag = #list + 1
    else
        tag = tonumber(tag) or tag -- autonumber saves keys
    end
    local realpage = texgetcount(c_realpageno)
    local data = realpage
    list[tag] = data
    if trace_pagestates then
        report_pagestate("action %a, name %a, tag %a, preset %a","set",name,tag,realpage)
    end
    return name, tag, data
end

local function extend(name,tag)
    local realpage = texgetcount(c_realpageno)
    if trace_pagestates then
        report_pagestate("action %a, name %a, tag %a, preset %a","synchronize",name,tag,realpage)
    end
    tobesaved[name][tag] = realpage
end

local function realpage(name,tag,default)
    local t = collected[name]
    if t then
        t = t[tag] or t[tonumber(tag)]
        if t then
            return tonumber(t or default)
        elseif trace_pagestates then
            report_pagestate("error: unknown dataset, name %a, tag %a",name,tag)
        end
    elseif trace_pagestates then
        report_pagestate("error: unknown dataset, name %a, tag %a",name) -- nil
    end
    return default
end

local function realpageorder(name,tag)
    local t = collected[name]
    if t then
        local p = t[tag]
        if p then
            local n = 1
            for i=tag-1,1,-1 do
                if t[i] == p then
                    n = n  +1
                end
            end
            return n
        end
    end
    return 0
end

pagestates.setstate      = setstate
pagestates.extend        = extend
pagestates.realpage      = realpage
pagestates.realpageorder = realpageorder

function pagestates.countervalue(name)
    return name and texgetcount(getnamespace("pagestatecounter") .. name) or 0
end

local function setpagestate(settings)
    local name, tag = setstate(settings)
 -- context(new_latelua(function() extend(name,tag) end))
    ctx_latelua(function() extend(name,tag) end)
end

local function setpagestaterealpageno(name,tag)
    local t = collected[name]
    t = t and (t[tag] or t[tonumber(tag)])
    texsetcount("realpagestateno",t or texgetcount(c_realpageno))
end

implement {
    name      = "setpagestate",
    actions   = setpagestate,
    arguments = {
        {
            { "name" },
            { "tag" },
            { "delay" },
        }
    }
}

implement {
    name      = "pagestaterealpage",
    actions   = { realpage, context },
    arguments = "2 strings",
}

implement {
    name      = "setpagestaterealpageno",
    actions   = setpagestaterealpageno,
    arguments = "2 strings",
}

implement {
    name      = "pagestaterealpageorder",
    actions   = { realpageorder, context },
    arguments = { "string", "integer" }
}