node-bck.lua /size: 9713 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
node-bck
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to node-bck.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- beware, this one takes quite some runtime, so we need a status flag
10
-- maybe some page related state
11 12
-- todo: done (or just get rid of done altogether) ... saves no purpose
13
-- any longer
14 15
local
attributes
,
nodes
,
node
=
attributes
,
nodes
,
node
16 17
local
enableaction
=
nodes
.
tasks
.
enableaction
18 19
local
nodecodes
=
nodes
.
nodecodes
20
local
listcodes
=
nodes
.
listcodes
21 22
local
hlist_code
=
nodecodes
.
hlist
23
local
vlist_code
=
nodecodes
.
vlist
24 25
local
alignmentlist_code
=
listcodes
.
alignment
26
local
celllist_code
=
listcodes
.
cell
27 28
local
nuts
=
nodes
.
nuts
29
local
nodepool
=
nuts
.
pool
30 31
local
getnext
=
nuts
.
getnext
32
local
getprev
=
nuts
.
getprev
33
local
getid
=
nuts
.
getid
34
local
getlist
=
nuts
.
getlist
35
local
getattr
=
nuts
.
getattr
36
local
getsubtype
=
nuts
.
getsubtype
37
local
getwhd
=
nuts
.
getwhd
38
local
getwidth
=
nuts
.
getwidth
39
local
getprop
=
nuts
.
getprop
40 41
local
setattr
=
nuts
.
setattr
42
local
setlink
=
nuts
.
setlink
43
local
setlist
=
nuts
.
setlist
44
local
setattributelist
=
nuts
.
setattributelist
45
local
setprop
=
nuts
.
setprop
46 47
local
takebox
=
nuts
.
takebox
48
local
findtail
=
nuts
.
tail
49 50
local
nextnode
=
nuts
.
traversers
.
node
51
local
nexthlist
=
nuts
.
traversers
.
hlist
52
local
nextlist
=
nuts
.
traversers
.
list
53 54
local
flush_node_list
=
nuts
.
flush_list
55 56
local
new_rule
=
nodepool
.
rule
57
local
new_kern
=
nodepool
.
kern
58
local
new_hlist
=
nodepool
.
hlist
59 60
local
privateattributes
=
attributes
.
private
61
local
unsetvalue
=
attributes
.
unsetvalue
62 63
local
linefillers
=
nodes
.
linefillers
64 65
local
a_color
=
privateattributes
(
"
color
"
)
66
local
a_transparency
=
privateattributes
(
"
transparency
"
)
67
local
a_colormodel
=
privateattributes
(
"
colormodel
"
)
68
local
a_background
=
privateattributes
(
"
background
"
)
69
local
a_alignbackground
=
privateattributes
(
"
alignbackground
"
)
70
local
a_linefiller
=
privateattributes
(
"
linefiller
"
)
71
local
a_ruled
=
privateattributes
(
"
ruled
"
)
72 73
local
trace_alignment
=
false
74
local
report_alignment
=
logs
.
reporter
(
"
backgrounds
"
,
"
alignment
"
)
75 76
trackers
.
register
(
"
backgrounds.alignments
"
,
function
(
v
)
trace_alignment
=
v
end
)
77 78
-- We can't use listbuilders with where=alignment because at that stage we have
79
-- unset boxes. Also, post_linebreak is unsuitable for nested processing as we
80
-- get the same stuff many times (wrapped again and again).
81
--
82
-- After many experiments with different callbacks the shipout is still the best
83
-- place but then we need to store some settings longer or save them with the node.
84
-- For color only we can get away with it with an extra attribute flagging a row
85
-- but for more complex stuff we can better do as we do here now.
86 87
local
overshoot
=
math
.
floor
(
65781
/
5
)
-- could be an option per table (just also store it)
88 89
local
function
colored_a
(
current
,
list
,
template
,
id
)
90
local
width
,
height
,
depth
=
getwhd
(
current
)
91
local
total
=
height
+
depth
92
if
width
>
0
and
total
>
0
then
93
local
rule
=
nil
94
--
95
local
a
=
getattr
(
template
,
a_linefiller
)
96
if
a
then
97
local
d
=
linefillers
.
data
[
a
%
1000
]
98
if
d
then
99
rule
=
linefillers
.
filler
(
template
,
d
,
width
,
height
,
depth
)
100
end
101
end
102
--
103
if
not
rule
then
104
rule
=
new_rule
(
width
,
height
,
depth
)
105
end
106
setattributelist
(
rule
,
template
)
107
local
back
=
new_kern
(
-
(
(
id
=
=
vlist_code
and
total
)
or
width
)
)
108
return
setlink
(
rule
,
back
,
list
)
109
end
110
end
111 112
local
function
colored_b
(
current
,
list
,
template
,
id
,
indent
)
113
local
width
,
height
,
depth
=
getwhd
(
current
)
114
local
total
=
height
+
depth
115
if
width
>
0
and
total
>
0
then
116
local
fore
=
(
indent
~
=
0
)
and
new_kern
(
indent
)
117
local
rule
=
nil
118
--
119
local
a
=
getattr
(
template
,
a_linefiller
)
120
if
a
then
121
local
d
=
linefillers
.
data
[
a
%
1000
]
122
if
d
then
123
rule
=
linefillers
.
filler
(
template
,
d
,
width
-
indent
,
height
,
depth
)
124
end
125
end
126
--
127
if
not
rule
then
128
rule
=
new_rule
(
width
-
indent
,
height
+
overshoot
,
depth
+
overshoot
)
129
setattributelist
(
rule
,
template
)
130
end
131
if
overshoot
=
=
0
then
132
local
back
=
new_kern
(
-
(
(
id
=
=
vlist_code
and
total
)
or
width
)
)
133
return
setlink
(
fore
,
rule
,
back
,
list
)
134
else
135
rule
=
new_hlist
(
rule
)
136
return
setlink
(
fore
,
rule
,
list
)
137
end
138
end
139
end
140 141
local
templates
=
{
}
142
local
currentrow
=
0
143
local
enabled
=
false
144
local
alignments
=
false
145 146
local
function
add_alignbackgrounds
(
head
,
list
)
147
for
current
,
id
,
subtype
,
list
in
nextlist
,
list
do
148
if
list
and
id
=
=
hlist_code
and
subtype
=
=
celllist_code
then
149
for
template
in
nexthlist
,
list
do
150
local
background
=
getattr
(
template
,
a_alignbackground
)
151
if
background
then
152
local
list
=
colored_a
(
current
,
list
,
template
)
153
if
list
then
154
setlist
(
current
,
list
)
155
end
156
setattr
(
template
,
a_alignbackground
,
unsetvalue
)
-- or property
157
end
158
break
159
end
160
end
161
end
162
local
template
=
getprop
(
head
,
"
alignmentchecked
"
)
163
if
template
then
164
list
=
colored_b
(
head
,
list
,
template
[
1
]
,
hlist_code
,
template
[
2
]
)
165
flush_node_list
(
template
)
166
templates
[
currentrow
]
=
false
167
return
list
168
end
169
end
170 171
local
function
add_backgrounds
(
head
,
id
,
list
)
172
if
list
then
173
for
current
,
id
,
subtype
,
list
in
nextlist
,
list
do
174
if
list
then
175
if
alignments
and
subtype
=
=
alignmentlist_code
then
176
local
l
=
add_alignbackgrounds
(
current
,
list
)
177
if
l
then
178
list
=
l
179
setlist
(
current
,
list
)
180
end
181
end
182
local
l
=
add_backgrounds
(
current
,
id
,
list
)
183
if
l
then
184
list
=
l
185
setlist
(
current
,
l
)
186
end
187
end
188
end
189
end
190
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
191
local
background
=
getattr
(
head
,
a_background
)
192
if
background
then
193
list
=
colored_a
(
head
,
list
,
head
,
id
)
194
-- not needed
195
setattr
(
head
,
a_background
,
unsetvalue
)
-- or property
196
return
list
197
end
198
end
199
end
200 201
function
nodes
.
handlers
.
backgrounds
(
head
)
202
add_backgrounds
(
head
,
getid
(
head
)
,
getlist
(
head
)
)
203
return
head
204
end
205 206
function
nodes
.
handlers
.
backgroundspage
(
head
,
where
)
207
if
head
and
where
=
=
"
alignment
"
then
208
for
n
in
nexthlist
,
head
do
209
local
p
=
getprop
(
n
,
"
alignmentchecked
"
)
210
if
not
p
and
getsubtype
(
n
)
=
=
alignmentlist_code
then
211
currentrow
=
currentrow
+
1
212
local
template
=
templates
[
currentrow
]
213
if
trace_alignment
then
214
report_alignment
(
"
%03i %s %s
"
,
currentrow
,
"
page
"
,
template
and
"
+
"
or
"
-
"
)
215
end
216
setprop
(
n
,
"
alignmentchecked
"
,
template
)
217
end
218
end
219
end
220
return
head
221
end
222 223
function
nodes
.
handlers
.
backgroundsvbox
(
head
,
where
)
224
if
head
and
where
=
=
"
vbox
"
then
225
local
list
=
getlist
(
head
)
226
if
list
then
227
for
n
in
nexthlist
,
list
do
228
local
p
=
getprop
(
n
,
"
alignmentchecked
"
)
229
if
not
p
and
getsubtype
(
n
)
=
=
alignmentlist_code
then
230
currentrow
=
currentrow
+
1
231
local
template
=
templates
[
currentrow
]
232
if
trace_alignment
then
233
report_alignment
(
"
%03i %s %s
"
,
currentrow
,
"
vbox
"
,
template
and
"
+
"
or
"
-
"
)
234
end
235
setprop
(
n
,
"
alignmentchecked
"
,
template
)
236
end
237
end
238
end
239
end
240
return
head
241
end
242 243
-- interfaces.implement {
244
-- name = "enablebackgroundboxes",
245
-- onlyonce = true,
246
-- actions = enableaction,
247
-- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
248
-- }
249
--
250
-- doing it in the shipout works as well but this is nicer
251 252
local
function
enable
(
alignmentstoo
)
253
if
not
enabled
then
254
enabled
=
true
255
enableaction
(
"
shipouts
"
,
"
nodes.handlers.backgrounds
"
)
256
end
257
if
not
alignments
and
alignmentstoo
then
258
alignments
=
true
259
enableaction
(
"
vboxbuilders
"
,
"
nodes.handlers.backgroundsvbox
"
)
260
enableaction
(
"
mvlbuilders
"
,
"
nodes.handlers.backgroundspage
"
)
261
end
262
end
263 264
interfaces
.
implement
{
265
name
=
"
enablebackgroundboxes
"
,
266
onlyonce
=
true
,
267
actions
=
enable
,
268
}
269 270
interfaces
.
implement
{
271
name
=
"
enablebackgroundalign
"
,
272
onlyonce
=
true
,
273
actions
=
function
(
)
274
enable
(
true
)
275
end
,
276
}
277 278
interfaces
.
implement
{
279
name
=
"
setbackgroundrowdata
"
,
280
arguments
=
{
"
integer
"
,
"
integer
"
,
"
dimension
"
}
,
281
actions
=
function
(
row
,
box
,
indent
)
282
row
=
row
-1
-- better here than in tex
283
if
box
=
=
0
then
284
templates
[
row
]
=
false
285
else
286
templates
[
row
]
=
{
takebox
(
box
)
,
indent
}
287
end
288
end
,
289
}
290 291
interfaces
.
implement
{
292
name
=
"
resetbackgroundrowdata
"
,
293
actions
=
function
(
)
294
currentrow
=
0
295
end
,
296
}
297