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
11
12
13
14
15
16
17
18local type = type
19
20local context = context
21
22local nodecodes = nodes.nodecodes
23local listcodes = nodes.listcodes
24
25local hlist_code = nodecodes.hlist
26local vlist_code = nodecodes.vlist
27
28local boxlist_code = listcodes.box
29local linelist_code = listcodes.line
30local equationlist_code = listcodes.equation
31
32local texsetdimen = tex.setdimen
33local texsetcount = tex.setcount
34
35local implement = interfaces.implement
36
37local nuts = nodes.nuts
38
39local getnext = nuts.getnext
40local getprev = nuts.getprev
41local getlist = nuts.getlist
42local setlist = nuts.setlist
43local getwhd = nuts.getwhd
44local getid = nuts.getid
45local getsubtype = nuts.getsubtype
46local getbox = nuts.getbox
47local getdirection = nuts.getdirection
48local setshift = nuts.setshift
49local setwidth = nuts.setwidth
50local getwidth = nuts.getwidth
51local setboxglue = nuts.setboxglue
52local getboxglue = nuts.getboxglue
53
54local hpack = nuts.hpack
55local getdimensions = nuts.dimensions
56local flushnode = nuts.flush
57
58local traversers = nuts.traversers
59local nexthlist = traversers.hlist
60local nextvlist = traversers.vlist
61local nextlist = traversers.list
62
63local checkformath = false
64
65directives.register("framed.checkmath",function(v) checkformath = v end)
66
67
68
69local function doreshapeframedbox(n)
70 local box = getbox(n)
71 local noflines = 0
72 local nofnonzero = 0
73 local firstheight = nil
74 local lastdepth = nil
75 local lastlinelength = 0
76 local minwidth = 0
77 local maxwidth = 0
78 local totalwidth = 0
79 local averagewidth = 0
80 local boxwidth = getwidth(box)
81 if boxwidth ~= 0 then
82 local list = getlist(box)
83 if list then
84 local hdone = false
85 for n, id, subtype, list in nextlist, list do
86 local width, height, depth = getwhd(n)
87 if not firstheight then
88 firstheight = height
89 end
90 lastdepth = depth
91 noflines = noflines + 1
92 if list then
93 if id == hlist_code then
94 if subtype == boxlist_code or subtype == linelist_code then
95 lastlinelength = getdimensions(list)
96 else
97 lastlinelength = width
98 end
99 hdone = true
100 else
101 lastlinelength = width
102
103 end
104 if lastlinelength > maxwidth then
105 maxwidth = lastlinelength
106 end
107 if lastlinelength < minwidth or minwidth == 0 then
108 minwidth = lastlinelength
109 end
110 if lastlinelength > 0 then
111 nofnonzero = nofnonzero + 1
112 end
113 totalwidth = totalwidth + lastlinelength
114 end
115 end
116 if not firstheight then
117
118 elseif maxwidth ~= 0 then
119 if hdone then
120 for h, id, subtype, list in nextlist, list do
121 if list and id == hlist_code then
122
123 if subtype == boxlist_code or subtype == linelist_code then
124
125
126 local p = hpack(list,maxwidth,'exactly',getdirection(h))
127 local set, order, sign = getboxglue(p)
128 setboxglue(h,set,order,sign)
129 setlist(p)
130 flushnode(p)
131 elseif checkformath and subtype == equationlist_code then
132
133 if nofnonzero == 1 then
134 setshift(h,0)
135 end
136 end
137 setwidth(h,maxwidth)
138 end
139 end
140 end
141
142
143
144
145
146
147
148
149 setwidth(box,maxwidth)
150 averagewidth = noflines > 0 and totalwidth/noflines or 0
151 else
152 setwidth(box,0)
153 end
154 end
155 end
156 texsetcount("global","framednoflines",noflines)
157 texsetdimen("global","framedfirstheight",firstheight or 0)
158 texsetdimen("global","framedlastdepth",lastdepth or 0)
159 texsetdimen("global","framedminwidth",minwidth)
160 texsetdimen("global","framedmaxwidth",maxwidth)
161 texsetdimen("global","framedaveragewidth",averagewidth)
162end
163
164local function doanalyzeframedbox(n)
165 local box = getbox(n)
166 local noflines = 0
167 local firstheight = nil
168 local lastdepth = nil
169 if getwidth(box) ~= 0 then
170 local list = getlist(box)
171 if list then
172 for n in nexthlist, list do
173 local width, height, depth = getwhd(n)
174 if not firstheight then
175 firstheight = height
176 end
177 lastdepth = depth
178 noflines = noflines + 1
179 end
180 for n in nextvlist, list do
181 local width, height, depth = getwhd(n)
182 if not firstheight then
183 firstheight = height
184 end
185 lastdepth = depth
186 noflines = noflines + 1
187 end
188 end
189 end
190 texsetcount("global","framednoflines",noflines)
191 texsetdimen("global","framedfirstheight",firstheight or 0)
192 texsetdimen("global","framedlastdepth",lastdepth or 0)
193end
194
195implement { name = "doreshapeframedbox", actions = doreshapeframedbox, arguments = "integer" }
196implement { name = "doanalyzeframedbox", actions = doanalyzeframedbox, arguments = "integer" }
197
198local function maxboxwidth(box)
199 local boxwidth = getwidth(box)
200 if boxwidth == 0 then
201 return 0
202 end
203 local list = getlist(box)
204 if not list then
205 return 0
206 end
207 if getid(box) == hlist_code then
208 return boxwidth
209 end
210 local lastlinelength = 0
211 local maxwidth = 0
212 for n, subtype in nexthlist, list do
213 local l = getlist(n)
214 if l then
215 if subtype == boxlist_code or subtype == linelist_code then
216 lastlinelength = getdimensions(l)
217 else
218 lastlinelength = getwidth(n)
219 end
220 if lastlinelength > maxwidth then
221 maxwidth = lastlinelength
222 end
223 end
224 end
225 for n, subtype in nextvlist, list do
226 local l = getlist(n)
227 if l then
228 lastlinelength = getwidth(n)
229 if lastlinelength > maxwidth then
230 maxwidth = lastlinelength
231 end
232 end
233 end
234 return maxwidth
235end
236
237nodes.maxboxwidth = maxboxwidth
238
239implement {
240 name = "themaxboxwidth",
241 actions = function(n) context("%rsp",maxboxwidth(getbox(n))) end,
242 arguments = "integer"
243}
244 |