1if not modules then modules = { } end modules ['typo-adj'] = {
2 version = 1.001,
3 optimize = true,
4 comment = "companion to typo-adj.mkxl",
5 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
6 copyright = "PRAGMA ADE / ConTeXt Development Team",
7 license = "see context related readme files"
8}
9
10local setdimen = tex.setdimen
11local isdimen = tex.isdimen
12local setmacro = tokens.setters.macro
13local expandmacro = token.expandmacro
14
15local nuts = nodes.nuts
16local tonut = nodes.tonut
17local getattr = nuts.getattr
18local getdepth = nuts.getdepth
19local getlistdimensions = nuts.getlistdimensions
20local getexcept = nuts.getexcept
21local getheight = nuts.getheight
22local getid = nuts.getid
23local getleader = nuts.getleader
24local getlist = nuts.getlist
25local getnext = nuts.getnext
26local getprop = nuts.getprop
27local gettail = nuts.tail
28local getwhd = nuts.getwhd
29local getwidth = nuts.getwidth
30local setattr = nuts.setattr
31local setdepth = nuts.setdepth
32local setexcept = nuts.setexcept
33local setheight = nuts.setheight
34local setlink = nuts.setlink
35local setlist = nuts.setlist
36local setoffsets = nuts.setoffsets
37local setprop = nuts.setprop
38local setstate = nuts.setstate
39
40local hpacknodes = nuts.hpack
41
42local hlist_code <const> = nodes.nodecodes.hlist
43local vlist_code <const> = nodes.nodecodes.vlist
44
45local getbox = nuts.getbox
46local takebox = nuts.takebox
47
48local new_kern = nuts.pool.kern
49local new_vlist = nuts.pool.vlist
50
51local flattenleaders = nuts.flattenleaders
52local traverselist = nuts.traverselist
53local traverseleader = nuts.traverseleader
54
55local a_adaptive <const> = attributes.private("adaptive")
56
57local registervalue = attributes.registervalue
58local getvalue = attributes.getvalue
59local hasvalues = attributes.hasvalues
60local texsetattribute = tex.setattribute
61
62local v_right <const> = interfaces.variables.right
63
64local adaptive = nodes.adaptive or { }
65nodes.adaptive = adaptive
66local enabled = false
67
68
69
70local d_adaptive_width <const> = isdimen("d_adaptive_width")
71local d_adaptive_height <const> = isdimen("d_adaptive_height")
72local d_adaptive_depth <const> = isdimen("d_adaptive_depth")
73local d_adaptive_line <const> = isdimen("d_adaptive_line")
74
75local function setadaptive(w,h,d,l,c,a)
76 setdimen(d_adaptive_width,w)
77 setdimen(d_adaptive_height,h)
78 setdimen(d_adaptive_depth,d)
79 setdimen(d_adaptive_line,l)
80 setmacro("m_adaptive_color",c)
81 setmacro("m_adaptive_alternative",a)
82end
83
84local methods = {
85
86 [1] = function(settings,parent,box)
87 local setups = settings.setups
88 if setups and setups ~= "" then
89 local w, h, d, s, list = getlistdimensions(parent)
90 setadaptive(w,h,d,settings.rulethickness,settings.color,settings.alternative)
91 expandmacro("setup",true,setups)
92 local l = takebox("b_adaptive_box")
93 if l then
94 setlist(parent,setlink(l,new_kern(-getwidth(l)),list))
95 end
96 end
97 end
98}
99
100adaptive.methods = methods
101
102
103local function handleuleader(n,grp,index,box,location)
104 local m = tonut(n)
105 local a = getattr(m,a_adaptive) or index
106 if a then
107 local settings = getvalue(a_adaptive,a)
108 if settings then
109 setstate(m,0)
110 local action = methods[settings.method or 1]
111 if action then
112 action(settings,m,tonut(box))
113 end
114 end
115 end
116 return n
117end
118
119
120
121function adaptive.set(settings)
122 if not enabled then
123
124
125 callback.register("handle_uleader", handleuleader)
126 enabled = true
127 end
128 texsetattribute(a_adaptive,registervalue(a_adaptive,settings))
129end
130
131interfaces.implement {
132 name = "setadaptive",
133 actions = adaptive.set,
134 arguments = {
135 {
136 { "setups", "string" },
137 { "method", "integer" },
138 { "mp", "string" },
139 { "location", "string" },
140 { "color", "string" },
141 { "rulethickness", "dimension" },
142 { "alternative", "string" },
143 }
144 }
145}
146
147
148
149
150
151
152
153local function handlehorizontal(n)
154 if hasvalues(a_adaptive) then
155 for _, t, _, l in traverselist(n) do
156 if t == hlist_code then
157 for m, _, _, ll in traverseleader(l) do
158 local a = getattr(m,a_adaptive)
159 if a then
160 local settings = getvalue(a_adaptive,a)
161 if settings then
162 setstate(m,0)
163 local action = methods[settings.method or 1]
164 if action then
165 action(settings,m,ll)
166 end
167 end
168 end
169 end
170 end
171 end
172 end
173 return n
174end
175
176local function handlevertical(n)
177 if hasvalues(a_adaptive) then
178
179 for _, t, _, l in traverselist(n) do
180 if t == vlist_code then
181 for m, _, _, ll in traverseleader(l) do
182 local a = getattr(m,a_adaptive)
183 if a then
184 local settings = getvalue(a_adaptive,a)
185 if settings then
186 setstate(m,0)
187 local action = methods[settings.method or 1]
188 if action then
189 action(settings,m,ll)
190 end
191 end
192 end
193 end
194 end
195 end
196 end
197 return n
198end
199
200adaptive.handlehorizontal = handlehorizontal
201adaptive.handlevertical = handlevertical
202
203interfaces.implement {
204 name = "adaptivecheckbox",
205 arguments = "integer",
206 public = true,
207 protected = true,
208 actions = function(n)
209 local b = getbox(n)
210 if b and flattenleaders(b) > 0 then
211 if getid(b) == hlist_code then
212 handlehorizontal(b)
213 else
214 handlevertical(b)
215 end
216 end
217 end,
218}
219
220
221
222
223
224
225
226
227
228nodes.adaptive.methods[2] = function(settings,parent,box)
229 local list = getlist(parent)
230 if list then
231 local except,
232 amount = getexcept(box)
233 local left = nil
234 local right = nil
235 local current = except
236 while current do
237 local location = getprop(current,"exceptlocation")
238 if location == "left" then
239 left = current
240 elseif location == "right" then
241 right = current
242 end
243 current = getnext(current)
244 end
245 if not left then
246 left = new_vlist()
247 right = new_vlist()
248 setprop(left, "exceptlocation","left")
249 setprop(right,"exceptlocation","right")
250 setlink(left,except,right)
251 setexcept(box,left)
252 except = left
253 end
254
255 local target = settings.location == v_right and right or left
256
257 local n = getlist(list)
258 local nw, nh, nd = getwhd(n)
259 local h = hpacknodes(n)
260 if getprop(target,"except") then
261 nd = getdepth(target) + nh + nd
262 setlink(gettail(getlist(target)),h)
263 else
264 setheight(target,nh)
265 setlist(target,h)
266 setprop(target,"except",true)
267 end
268 setdepth(target,nd)
269 setexcept(box,except,nd > amount and nd or amount)
270 setoffsets(n,target == right and getwidth(box) or -nw)
271 setlist(list)
272 setlist(real)
273 end
274end
275
276 |