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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
if not modules then modules = { } end modules ['strc-pag'] = {
version = 1.001,
comment = "companion to strc-pag.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local texcount, format = tex.count, string.format
local ctxcatcodes = tex.ctxcatcodes
local texsprint, texwrite = tex.sprint, tex.write
local trace_pages = false trackers.register("structure.pages", function(v) trace_pages = v end)
structure.pages = structure.pages or { }
local helpers = structure.helpers or { }
local sections = structure.sections or { }
local pages = structure.pages or { }
local processors = structure.processors or { }
local sets = structure.sets or { }
local variables = interfaces.variables
-- storage
jobpages = jobpages or { }
jobpages.collected = jobpages.collected or { }
jobpages.tobesaved = jobpages.tobesaved or { }
local collected, tobesaved = jobpages.collected, jobpages.tobesaved
local function initializer()
collected, tobesaved = jobpages.collected, jobpages.tobesaved
end
job.register('jobpages.collected', jobpages.tobesaved, initializer)
local specification = { } -- to be checked
function pages.save(prefixdata,numberdata)
local realpage, userpage = texcount.realpageno, texcount.userpageno
if realpage > 0 then
if trace_pages then
logs.report("pages","saving page %s.%s",realpage,userpage)
end
local data = {
number = userpage,
block = sections.currentblock(),
prefixdata = prefixdata and helpers.simplify(prefixdata),
numberdata = numberdata and helpers.simplify(numberdata),
}
tobesaved[realpage] = data
if not collected[realpage] then
collected[realpage] = data
end
elseif trace_pages then
logs.report("pages","not saving page %s.%s",realpage,userpage)
end
end
function structure.counters.specials.userpage()
local r = texcount.realpageno
if r > 0 then
local t = tobesaved[r]
if t then
t.number = texcount.userpageno
if trace_pages then
logs.report("pages","forcing pagenumber of realpage %s to %s",r,t.number)
end
end
end
end
--~ function pages.pagenumber(localspec)
--~ local deltaspec
--~ if localspec then
--~ for k,v in next, localspec do
--~ if v ~= "" and v ~= specification[k] then
--~ if not deltaspec then deltaspec = { } end
--~ deltaspec[k] = v
--~ end
--~ end
--~ end
--~ if deltaspec then
--~ return { realpage = texcount.realpageno, specification = deltaspec }
--~ else
--~ return { realpage = texcount.realpageno }
--~ end
--~ end
local function convertnumber(str,n)
return format("\\convertnumber{%s}{%s}",str or "numbers",n)
end
function pages.number(realdata,pagespec)
local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock()
local numberspec = realdata.numberdata
local conversionset = (pagespec and pagespec.conversionset ~= "" and pagespec.conversionset) or (numberspec and numberspec.conversionset ~= "" and numberspec.conversionset) or ""
local conversion = (pagespec and pagespec.conversion ~= "" and pagespec.conversion ) or (numberspec and numberspec.conversion ~= "" and numberspec.conversion ) or ""
local starter = (pagespec and pagespec.starter ~= "" and pagespec.starter ) or (numberspec and numberspec.starter ~= "" and numberspec.starter ) or ""
local stopper = (pagespec and pagespec.stopper ~= "" and pagespec.stopper ) or (numberspec and numberspec.stopper ~= "" and numberspec.stopper ) or ""
if starter ~= "" then
processors.sprint(ctxcatcodes,starter)
end
if conversion ~= "" then
texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,userpage))
else
if conversionset == "" then conversionset = "default" end
local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
processors.sprint(ctxcatcodes,theconversion,convertnumber,userpage)
end
if stopper ~= "" then
processors.sprint(ctxcatcodes,stopper)
end
end
-- (pagespec.prefix == yes|unset) and (pages.prefix == yes) => prefix
function pages.analyse(entry,pagespecification)
-- safeguard
if not entry then
return false, false, "no entry"
end
local references = entry.references
if not references then
return false, false, "no references"
end
local realpage = references.realpage
if not realpage then
return false, false, "no realpage"
end
local pagedata = collected[realpage]
if not pagedata then
return false, false, "no pagedata"
end
local section = references.section
if not section then
return pagedata, false, "no section"
end
local no = variables.no
-- local preferences
if pagespecification and pagespecification.prefix == no then
return pagedata, false, "current spec blocks prefix"
end
-- stored preferences
--~ if entry.prefix == no then
--~ return pagedata, false, "entry blocks prefix"
--~ end
-- stored page state
pagespecification = pagedata.prefixdata
if pagespecification and pagespecification.prefix == no then
return pagedata, false, "pagedata blocks prefix"
end
-- final verdict
return pagedata, jobsections.collected[references.section], "okay"
end
function helpers.page(data,pagespec)
if data then
local pagedata = pages.analyse(data,pagespec)
if pagedata then
pages.number(pagedata,pagespec)
end
end
end
function helpers.prefixpage(data,prefixspec,pagespec)
if data then
local pagedata, prefixdata, e = pages.analyse(data,pagespec)
if pagedata then
if prefixdata then
sections.typesetnumber(prefixdata,"prefix",prefixspec or false,prefixdata or false,pagedata.prefixdata or false)
end
pages.number(pagedata,pagespec)
end
end
end
function helpers.prefixlastpage(data,prefixspec,pagespec)
if data then
local r = data.references
local ls, lr = r.section, r.realpage
r.section, r.realpage = r.lastsection or r.section, r.lastrealpage or r.realpage
helpers.prefixpage(data,prefixspec,pagespec)
r.section, r.realpage = ls, lr
end
end
--
function helpers.analyse(entry,specification)
-- safeguard
if not entry then
return false, false, "no entry"
end
local yes, no = variables.yes, variables.no
-- section data
local references = entry.references
if not references then
return entry, false, "no references"
end
local section = references.section
if not section then
return entry, false, "no section"
end
sectiondata = jobsections.collected[references.section]
if not sectiondata then
return entry, false, "no section data"
end
-- local preferences
if specification and specification.prefix == no then
return entry, false, "current spec blocks prefix"
end
-- stored preferences (not used)
local prefixdata = entry.prefixdata
if prefixdata and prefixdata.prefix == no then
return entry, false, "entry blocks prefix"
end
-- final verdict
return entry, sectiondata, "okay"
end
function helpers.prefix(data,prefixspec)
if data then
local _, prefixdata, status = helpers.analyse(data,prefixspec)
if prefixdata then
sections.typesetnumber(prefixdata,"prefix",prefixspec or false,data.prefixdata or false,prefixdata or false)
end
end
end
function pages.is_odd(n)
n = n or texcount.realpageno
if texcount.pagenoshift % 2 == 0 then
return n % 2 == 0
else
return n % 2 ~= 0
end
end
|