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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
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 allocate, mark = utilities.storage.allocate, utilities.storage.mark
local trace_pages = false trackers.register("structures.pages", function(v) trace_pages = v end)
local report_pages = logs.reporter("structure","pages")
local structures = structures
local helpers = structures.helpers
local sections = structures.sections
local pages = structures.pages
local processors = structures.processors
local sets = structures.sets
local counters = structures.counters
local counterdata = counters.data
local variables = interfaces.variables
local context = context
-- storage
local collected, tobesaved = allocate(), allocate()
pages.collected = collected
pages.tobesaved = tobesaved
local function initializer()
collected = pages.collected
tobesaved = pages.tobesaved
end
job.register('structures.pages.collected', 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
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
report_pages("not saving page %s.%s",realpage,userpage)
end
end
function 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
report_pages("forcing pagenumber of realpage %s to %s",r,t.number)
end
end
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
context.convertnumber(conversion,userpage)
else
if conversionset == "" then conversionset = "default" end
local theconversion = sets.get("structure:conversions",block,conversionset,1,"numbers") -- to be checked: 1
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.analyze(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, sections.collected[references.section], "okay"
end
function helpers.page(data,pagespec)
if data then
local pagedata = pages.analyze(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.analyze(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.analyze(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
local sectiondata = sections.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.analyze(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
-- move to strc-pag.lua
function counters.analyze(name,counterspecification)
local cd = counterdata[name]
-- safeguard
if not cd then
return false, false, "no counter data"
end
-- section data
local sectiondata = sections.current()
if not sectiondata then
return cd, false, "not in section"
end
local references = sectiondata.references
if not references then
return cd, false, "no references"
end
local section = references.section
if not section then
return cd, false, "no section"
end
sectiondata = sections.collected[references.section]
if not sectiondata then
return cd, false, "no section data"
end
-- local preferences
local no = variables.no
if counterspecification and counterspecification.prefix == no then
return cd, false, "current spec blocks prefix"
end
-- stored preferences (not used)
if cd.prefix == no then
return cd, false, "entry blocks prefix"
end
-- sectioning
-- if sectiondata.prefix == no then
-- return false, false, "sectiondata blocks prefix"
-- end
-- final verdict
return cd, sectiondata, "okay"
end
function counters.prefixedconverted(name,prefixspec,numberspec)
local cd, prefixdata, result = counters.analyze(name,prefixspec)
if cd then
if prefixdata then
sections.typesetnumber(prefixdata,"prefix",prefixspec or false,cd or false)
end
counters.converted(name,numberspec)
end
end
|