1if not modules then modules = { } end modules ['typo-lin'] = {
2 version = 1.001,
3 comment = "companion to typo-lin.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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53local type = type
54
55local trace_anchors = false trackers.register("paragraphs.anchors", function(v) trace_anchors = v end)
56
57local report = logs.reporter("anchors")
58
59local nuts = nodes.nuts
60local nodecodes = nodes.nodecodes
61local listcodes = nodes.listcodes
62
63local hlist_code <const> = nodecodes.hlist
64local kern_code <const> = nodecodes.kern
65local linelist_code <const> = listcodes.line
66
67local tonut = nodes.tonut
68local tonode = nodes.tonode
69
70local nexthlist = nuts.traversers.hlist
71local insertbefore = nuts.insertbefore
72local insertafter = nuts.insertafter
73
74local getlist = nuts.getlist
75local setlist = nuts.setlist
76local getid = nuts.getid
77local getboth = nuts.getboth
78local setlink = nuts.setlink
79local setkern = nuts.setkern
80local getkern = nuts.getkern
81local getdirection = nuts.getdirection
82local getshift = nuts.getshift
83local setshift = nuts.setshift
84local getwidth = nuts.getwidth
85local setwidth = nuts.setwidth
86
87local getnormalizedline = nuts.getnormalizedline
88
89local setprop = nuts.setprop
90local getprop = nuts.rawprop
91
92local effectiveglue = nuts.effectiveglue
93
94local nodepool = nuts.pool
95local new_kern = nodepool.kern
96local new_hlist = nodepool.hlist
97local new_rule = nodepool.rule
98local new_glue = nodepool.glue
99
100local righttoleft_code <const> = tex.directioncodes.righttoleft
101
102local setmetatableindex = table.setmetatableindex
103
104local jobpositions = job.positions
105local getposition = jobpositions.get
106local getreserved = jobpositions.getreserved
107
108local paragraphs = { }
109typesetters.paragraphs = paragraphs
110
111local noflines = 0
112
113local function finalize(prop,key)
114 local line = prop.line
115 local hsize = prop.hsize
116 local width = prop.width
117 local shift = getshift(line)
118 local reverse = getdirection(line) == righttoleft_code or false
119 local pack = new_hlist()
120 local head = getlist(line)
121 local delta = 0
122 if reverse then
123 delta = - shift + (hsize - width)
124 else
125 delta = shift
126 end
127 local kern1 = new_kern(delta)
128 local kern2 = new_kern(-delta)
129 head = insertbefore(head,head,kern1)
130 head = insertbefore(head,head,pack)
131 head = insertbefore(head,head,kern2)
132 setlist(line,head)
133 local where = {
134 pack = pack,
135 head = nil,
136 tail = nil,
137 }
138 prop.where = where
139 prop.reverse = reverse
140
141 setmetatableindex(prop,nil)
142 return prop[key]
143end
144
145local function normalize(line,islocal)
146 local prop = getnormalizedline(line)
147 local width = getwidth(line)
148 local hsize = islocal and width or tex.hsize
149 noflines = noflines + 1
150 if prop then
151 prop.width = width
152 prop.hsize = hsize
153 prop.line = line
154 prop.number = noflines
155 else
156
157 prop = {
158 width = width,
159 hsize = hsize,
160 leftskip = 0,
161 rightskip = 0,
162 lefthangskip = 0,
163 righthangskip = 0,
164 parfillleftskip = 0,
165 parfillrightskip = 0,
166 line = line,
167 number = noflines,
168 }
169 end
170 setprop(line,"line",prop)
171 setmetatableindex(prop,finalize)
172 return prop
173end
174
175function paragraphs.checkline(n)
176 return getprop(n,"line") or normalize(n,true)
177end
178
179
180
181
182
183
184
185
186local function addtoline(n,list,option)
187 local line = getprop(n,"line")
188 if not line then
189 line = normalize(n,true)
190 end
191 if line then
192 if trace_anchors and not line.traced then
193 line.traced = true
194 local rule = new_rule(2*65536,2*65536,1*65536)
195 local list = insertbefore(rule,rule,new_kern(-1*65536))
196 addtoline(n,list)
197 local rule = new_rule(2*65536,6*65536,-3*65536)
198 local list = insertbefore(rule,rule,new_kern(-1*65536))
199 addtoline(n,list,"internal")
200 else
201 line.traced = true
202 end
203 local list = tonut(list)
204 local where = line.where
205 local head = where.head
206 local tail = where.tail
207 local blob = new_hlist(list)
208 local delta = 0
209 if option == "internal" then
210 if line.reverse then
211 delta = line.lefthangskip - line.leftskip - (line.hsize - line.width)
212 else
213 delta = line.lefthangskip + line.leftskip
214 end
215 end
216
217
218
219 local xoffset = nuts.getoffsets(n)
220 delta = delta - xoffset
221
222
223
224
225 local kern = new_kern(delta)
226 if tail then
227 head, tail = insertafter(head,tail,kern)
228 else
229 head, tail = kern, kern
230 setlist(where.pack,head)
231 end
232 head, tail = insertafter(head,tail,blob)
233 local kern = new_kern(-delta)
234 head, tail = insertafter(head,tail,kern)
235
236 where.head = head
237 where.tail = tail
238 return line, blob
239 else
240
241 end
242end
243
244local function addanchortoline(n,anchor)
245 local line = type(n) ~= "table" and getprop(n,"line") or n
246 if not line then
247 line = normalize(n,true)
248 end
249 if line then
250 local anchor = tonut(anchor)
251 local where = line.where
252 if trace_anchors then
253 anchor = new_hlist(setlink(
254 anchor,
255 new_kern(-65536/4),
256 new_rule(65536/2,4*65536,4*65536),
257 new_kern(-65536/4-4*65536),
258 new_rule(8*65536,65536/4,65536/4)
259 ))
260 setwidth(anchor,0)
261 end
262 if where.tail then
263 local head = where.head
264 insertbefore(head,head,anchor)
265 else
266 where.tail = anchor
267 end
268 setlist(where.pack,anchor)
269 where.head = anchor
270 return line
271 end
272end
273
274paragraphs.addtoline = addtoline
275paragraphs.addanchortoline = addanchortoline
276
277function paragraphs.moveinline(n,blob,dx,dy)
278 if not blob then
279 return
280 end
281 if not dx then
282 dx = 0
283 end
284 if not dy then
285 dy = 0
286 end
287 if dx ~= 0 or dy ~= 0 then
288 local line = type(n) ~= "table" and getprop(n,"line") or n
289 if line then
290 if dx ~= 0 then
291 local prev, next = getboth(blob)
292 if prev and getid(prev) == kern_code then
293 setkern(prev,getkern(prev) + dx)
294 end
295 if next and getid(next) == kern_code then
296 setkern(next,getkern(next) - dx)
297 end
298 end
299 if dy ~= 0 then
300 if getid(blob) == hlist_code then
301 setshift(blob,getshift(blob) + dy)
302 end
303 end
304 else
305
306 end
307 end
308end
309
310local latelua = nodepool.latelua
311local setposition = jobpositions.setspec
312
313local function setanchor(h_anchor)
314 return latelua {
315 action = setposition,
316 name = "md:h",
317 index = h_anchor,
318 value = { x = true, c = true },
319 }
320end
321
322
323
324function paragraphs.calculatedelta(n,width,delta,atleft,islocal,followshape,area)
325 local line = type(n) ~= "table" and getprop(n,"line") or n
326 if not line then
327 line = normalize(n,true)
328 end
329 local hmove = 0
330 if line then
331 local reverse = line.reverse
332
333 if atleft then
334 if reverse then
335
336 else
337 delta = - delta - width
338 end
339 else
340 if reverse then
341 delta = - delta - width - line.hsize
342 else
343 delta = delta + line.hsize
344 end
345 end
346 if islocal then
347
348 if atleft then
349 if reverse then
350 delta = delta - line.leftskip
351 else
352 delta = delta + line.leftskip
353 end
354 else
355 if reverse then
356 delta = delta + line.rightskip
357 else
358 delta = delta - line.rightskip
359 end
360 end
361 if followshape then
362
363 if atleft then
364 if reverse then
365 delta = delta + line.lefthangskip - line.hsize + line.width
366 else
367 delta = delta + line.lefthangskip
368 end
369 else
370 if reverse then
371 delta = delta + line.lefthangskip + line.parfillrightskip
372 else
373 delta = delta + line.lefthangskip - line.hsize + line.width - line.parfillrightskip
374 end
375 end
376 end
377 end
378 if area then
379 local number = line.number
380 if not line.hanchor then
381 addanchortoline(line,setanchor(number))
382 line.hanchor = true
383 end
384 local blob = getposition("md:h",number)
385 if blob then
386 local reference = getreserved(area,blob.c)
387 if reference then
388 hmove = (reference.x or 0) - (blob.x or 0)
389 if atleft then
390 if reverse then
391 hmove = hmove + (reference.w or 0)
392 else
393
394 end
395 else
396 if reverse then
397 hmove = hmove + line.hsize
398 else
399 hmove = hmove + (reference.w or 0) - line.hsize
400 end
401 end
402 end
403 end
404 end
405 end
406 return delta, hmove
407end
408 |