pack-rul.lua /size: 8758 b    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
pack-rul
'
]
=
{
2
version
=
1
.
001
,
3
optimize
=
true
,
4
comment
=
"
companion to pack-rul.mkiv
"
,
5
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
6
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
7
license
=
"
see context related readme files
"
8
}
9 10
--[[ldx-- 11<p>An explanation is given in the history document <t>mk</t>.</p> 12--ldx]]
--
13 14
-- we need to be careful with display math as it uses shifts
15 16
-- \framed[align={lohi,middle}]{$x$}
17
-- \framed[align={lohi,middle}]{$ $}
18
-- \framed[align={lohi,middle}]{\hbox{ }}
19
-- \framed[align={lohi,middle}]{\hbox{}}
20
-- \framed[align={lohi,middle}]{$\hskip2pt$}
21 22
local
type
=
type
23 24
local
context
=
context
25 26
local
nodecodes
=
nodes
.
nodecodes
27
local
listcodes
=
nodes
.
listcodes
28 29
local
hlist_code
=
nodecodes
.
hlist
30
local
vlist_code
=
nodecodes
.
vlist
31 32
local
boxlist_code
=
listcodes
.
box
33
local
linelist_code
=
listcodes
.
line
34
local
equationlist_code
=
listcodes
.
equation
35 36
local
texsetdimen
=
tex
.
setdimen
37
local
texsetcount
=
tex
.
setcount
38 39
local
implement
=
interfaces
.
implement
40 41
local
nuts
=
nodes
.
nuts
42 43
local
getnext
=
nuts
.
getnext
44
local
getprev
=
nuts
.
getprev
45
local
getlist
=
nuts
.
getlist
46
local
setlist
=
nuts
.
setlist
47
local
getwhd
=
nuts
.
getwhd
48
local
getid
=
nuts
.
getid
49
local
getsubtype
=
nuts
.
getsubtype
50
local
getbox
=
nuts
.
getbox
51
local
getdirection
=
nuts
.
getdirection
52
local
setshift
=
nuts
.
setshift
53
local
setwidth
=
nuts
.
setwidth
54
local
getwidth
=
nuts
.
getwidth
55
local
setboxglue
=
nuts
.
setboxglue
56
local
getboxglue
=
nuts
.
getboxglue
57 58
local
hpack
=
nuts
.
hpack
59
local
getdimensions
=
nuts
.
dimensions
60
local
flushnode
=
nuts
.
flush
61 62
local
traversers
=
nuts
.
traversers
63
local
nexthlist
=
traversers
.
hlist
64
local
nextvlist
=
traversers
.
vlist
65
local
nextlist
=
traversers
.
list
66 67
local
checkformath
=
false
68 69
directives
.
register
(
"
framed.checkmath
"
,
function
(
v
)
checkformath
=
v
end
)
-- experiment
70 71
-- beware: dir nodes and pseudostruts can end up on lines of their own
72 73
local
function
doreshapeframedbox
(
n
)
74
local
box
=
getbox
(
n
)
75
local
noflines
=
0
76
local
nofnonzero
=
0
77
local
firstheight
=
nil
78
local
lastdepth
=
nil
79
local
lastlinelength
=
0
80
local
minwidth
=
0
81
local
maxwidth
=
0
82
local
totalwidth
=
0
83
local
averagewidth
=
0
84
local
boxwidth
=
getwidth
(
box
)
85
if
boxwidth
~
=
0
then
-- and h.subtype == vlist_code
86
local
list
=
getlist
(
box
)
87
if
list
then
88
local
hdone
=
false
89
for
n
,
id
,
subtype
,
list
in
nextlist
,
list
do
-- no dir etc needed
90
local
width
,
height
,
depth
=
getwhd
(
n
)
91
if
not
firstheight
then
92
firstheight
=
height
93
end
94
lastdepth
=
depth
95
noflines
=
noflines
+
1
96
if
list
then
97
if
id
=
=
hlist_code
then
98
if
subtype
=
=
boxlist_code
or
subtype
=
=
linelist_code
then
99
lastlinelength
=
getdimensions
(
list
)
100
else
101
lastlinelength
=
width
102
end
103
hdone
=
true
104
else
105
lastlinelength
=
width
106
-- vdone = true
107
end
108
if
lastlinelength
>
maxwidth
then
109
maxwidth
=
lastlinelength
110
end
111
if
lastlinelength
<
minwidth
or
minwidth
=
=
0
then
112
minwidth
=
lastlinelength
113
end
114
if
lastlinelength
>
0
then
115
nofnonzero
=
nofnonzero
+
1
116
end
117
totalwidth
=
totalwidth
+
lastlinelength
118
end
119
end
120
if
not
firstheight
then
121
-- done)
122
elseif
maxwidth
~
=
0
then
123
if
hdone
then
124
for
h
,
id
,
subtype
,
list
in
nextlist
,
list
do
125
if
list
and
id
=
=
hlist_code
then
126
-- called a lot so maybe a simple case is needed
127
if
subtype
=
=
boxlist_code
or
subtype
=
=
linelist_code
then
128
-- getdirection is irrelevant here so it will go
129
-- somehow a parfillskip also can get influenced
130
local
p
=
hpack
(
list
,
maxwidth
,
'
exactly
'
,
getdirection
(
h
)
)
-- multiple return value
131
local
set
,
order
,
sign
=
getboxglue
(
p
)
132
setboxglue
(
h
,
set
,
order
,
sign
)
133
setlist
(
p
)
134
flushnode
(
p
)
135
elseif
checkformath
and
subtype
=
=
equationlist_code
then
136
-- display formulas use a shift
137
if
nofnonzero
=
=
1
then
138
setshift
(
h
,
0
)
139
end
140
end
141
setwidth
(
h
,
maxwidth
)
142
end
143
end
144
end
145
-- if vdone then
146
-- for v in nextvlist, list do
147
-- local width = getwidth(n)
148
-- if width > maxwidth then
149
-- setwidth(v,maxwidth)
150
-- end
151
-- end
152
-- end
153
setwidth
(
box
,
maxwidth
)
154
averagewidth
=
noflines
>
0
and
totalwidth
/
noflines
or
0
155
else
-- e.g. empty math {$ $} or \hbox{} or ...
156
setwidth
(
box
,
0
)
157
end
158
end
159
end
160
texsetcount
(
"
global
"
,
"
framednoflines
"
,
noflines
)
161
texsetdimen
(
"
global
"
,
"
framedfirstheight
"
,
firstheight
or
0
)
-- also signal
162
texsetdimen
(
"
global
"
,
"
framedlastdepth
"
,
lastdepth
or
0
)
163
texsetdimen
(
"
global
"
,
"
framedminwidth
"
,
minwidth
)
164
texsetdimen
(
"
global
"
,
"
framedmaxwidth
"
,
maxwidth
)
165
texsetdimen
(
"
global
"
,
"
framedaveragewidth
"
,
averagewidth
)
166
end
167 168
local
function
doanalyzeframedbox
(
n
)
169
local
box
=
getbox
(
n
)
170
local
noflines
=
0
171
local
firstheight
=
nil
172
local
lastdepth
=
nil
173
if
getwidth
(
box
)
~
=
0
then
174
local
list
=
getlist
(
box
)
175
if
list
then
176
for
n
in
nexthlist
,
list
do
177
local
width
,
height
,
depth
=
getwhd
(
n
)
178
if
not
firstheight
then
179
firstheight
=
height
180
end
181
lastdepth
=
depth
182
noflines
=
noflines
+
1
183
end
184
for
n
in
nextvlist
,
list
do
185
local
width
,
height
,
depth
=
getwhd
(
n
)
186
if
not
firstheight
then
187
firstheight
=
height
188
end
189
lastdepth
=
depth
190
noflines
=
noflines
+
1
191
end
192
end
193
end
194
texsetcount
(
"
global
"
,
"
framednoflines
"
,
noflines
)
195
texsetdimen
(
"
global
"
,
"
framedfirstheight
"
,
firstheight
or
0
)
196
texsetdimen
(
"
global
"
,
"
framedlastdepth
"
,
lastdepth
or
0
)
197
end
198 199
implement
{
name
=
"
doreshapeframedbox
"
,
actions
=
doreshapeframedbox
,
arguments
=
"
integer
"
}
200
implement
{
name
=
"
doanalyzeframedbox
"
,
actions
=
doanalyzeframedbox
,
arguments
=
"
integer
"
}
201 202
local
function
maxboxwidth
(
box
)
203
local
boxwidth
=
getwidth
(
box
)
204
if
boxwidth
=
=
0
then
205
return
0
206
end
207
local
list
=
getlist
(
box
)
208
if
not
list
then
209
return
0
210
end
211
if
getid
(
box
)
=
=
hlist_code
then
212
return
boxwidth
213
end
214
local
lastlinelength
=
0
215
local
maxwidth
=
0
216
for
n
,
subtype
in
nexthlist
,
list
do
-- no dir etc needed
217
local
l
=
getlist
(
n
)
218
if
l
then
219
if
subtype
=
=
boxlist_code
or
subtype
=
=
linelist_code
then
220
lastlinelength
=
getdimensions
(
l
)
221
else
222
lastlinelength
=
getwidth
(
n
)
223
end
224
if
lastlinelength
>
maxwidth
then
225
maxwidth
=
lastlinelength
226
end
227
end
228
end
229
for
n
,
subtype
in
nextvlist
,
list
do
-- no dir etc needed
230
local
l
=
getlist
(
n
)
231
if
l
then
232
lastlinelength
=
getwidth
(
n
)
233
if
lastlinelength
>
maxwidth
then
234
maxwidth
=
lastlinelength
235
end
236
end
237
end
238
return
maxwidth
239
end
240 241
nodes
.
maxboxwidth
=
maxboxwidth
242 243
implement
{
244
name
=
"
themaxboxwidth
"
,
245
actions
=
function
(
n
)
context
(
"
%rsp
"
,
maxboxwidth
(
getbox
(
n
)
)
)
end
,
-- r = rounded
246
arguments
=
"
integer
"
247
}
248