1if 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
13
14
15
16
17
18
19
20
21
22local type = type
23
24local context = context
25
26local nodecodes = nodes . nodecodes
27local listcodes = nodes . listcodes
28
29local hlist_code = nodecodes . hlist
30local vlist_code = nodecodes . vlist
31
32local boxlist_code = listcodes . box
33local linelist_code = listcodes . line
34local equationlist_code = listcodes . equation
35
36local texsetdimen = tex . setdimen
37local texsetcount = tex . setcount
38
39local implement = interfaces . implement
40
41local nuts = nodes . nuts
42
43local getnext = nuts . getnext
44local getprev = nuts . getprev
45local getlist = nuts . getlist
46local setlist = nuts . setlist
47local getwhd = nuts . getwhd
48local getid = nuts . getid
49local getsubtype = nuts . getsubtype
50local getbox = nuts . getbox
51local getdirection = nuts . getdirection
52local setshift = nuts . setshift
53local setwidth = nuts . setwidth
54local getwidth = nuts . getwidth
55local setboxglue = nuts . setboxglue
56local getboxglue = nuts . getboxglue
57
58local hpack = nuts . hpack
59local getdimensions = nuts . dimensions
60local flushnode = nuts . flush
61
62local traversers = nuts . traversers
63local nexthlist = traversers . hlist
64local nextvlist = traversers . vlist
65local nextlist = traversers . list
66
67local checkformath = false
68
69directives . register ( " framed.checkmath " , function ( v ) checkformath = v end )
70
71
72
73local 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
86 local list = getlist ( box )
87 if list then
88 local hdone = false
89 for n , id , subtype , list in nextlist , list do
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
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
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
127 if subtype = = boxlist_code or subtype = = linelist_code then
128
129
130 local p = hpack ( list , maxwidth , ' exactly ' , getdirection ( h ) )
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
137 if nofnonzero = = 1 then
138 setshift ( h , 0 )
139 end
140 end
141 setwidth ( h , maxwidth )
142 end
143 end
144 end
145
146
147
148
149
150
151
152
153 setwidth ( box , maxwidth )
154 averagewidth = noflines > 0 and totalwidth / noflines or 0
155 else
156 setwidth ( box , 0 )
157 end
158 end
159 end
160 texsetcount ( " global " , " framednoflines " , noflines )
161 texsetdimen ( " global " , " framedfirstheight " , firstheight or 0 )
162 texsetdimen ( " global " , " framedlastdepth " , lastdepth or 0 )
163 texsetdimen ( " global " , " framedminwidth " , minwidth )
164 texsetdimen ( " global " , " framedmaxwidth " , maxwidth )
165 texsetdimen ( " global " , " framedaveragewidth " , averagewidth )
166end
167
168local 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 )
197end
198
199implement { name = " doreshapeframedbox " , actions = doreshapeframedbox , arguments = " integer " }
200implement { name = " doanalyzeframedbox " , actions = doanalyzeframedbox , arguments = " integer " }
201
202local 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
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
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
239end
240
241nodes . maxboxwidth = maxboxwidth
242
243implement {
244 name = " themaxboxwidth " ,
245 actions = function ( n ) context ( " %rsp " , maxboxwidth ( getbox ( n ) ) ) end ,
246 arguments = " integer "
247}
248 |