1if not modules then modules = { } end modules [ ' spac-ali ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to spac-ali.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
9local div = math . div
10local format = string . format
11
12local tasks = nodes . tasks
13local enableaction = tasks . enableaction
14
15local nuts = nodes . nuts
16local nodepool = nuts . pool
17
18local tonode = nuts . tonode
19local tonut = nuts . tonut
20
21local getnext = nuts . getnext
22local getprev = nuts . getprev
23local getid = nuts . getid
24local getlist = nuts . getlist
25local setlist = nuts . setlist
26local setlink = nuts . setlink
27local getdirection = nuts . getdirection
28local takeattr = nuts . takeattr
29local getsubtype = nuts . getsubtype
30local getwidth = nuts . getwidth
31local findtail = nuts . tail
32
33local righttoleft_code = nodes . dirvalues . righttoleft
34
35local hpack_nodes = nuts . hpack
36
37local unsetvalue = attributes . unsetvalue
38
39local nodecodes = nodes . nodecodes
40local listcodes = nodes . listcodes
41
42local hlist_code = nodecodes . hlist
43local vlist_code = nodecodes . vlist
44
45local linelist_code = listcodes . line
46
47local new_stretch = nodepool . stretch
48
49local a_realign = attributes . private ( " realign " )
50
51local texsetattribute = tex . setattribute
52local texgetcount = tex . getcount
53
54local isleftpage = layouts . status . isleftpage
55
56typesetters = typesetters or { }
57local alignments = { }
58typesetters . alignments = alignments
59
60local report_realign = logs . reporter ( " typesetters " , " margindata " )
61local trace_realign = trackers . register ( " typesetters.margindata " , function ( v ) trace_margindata = v end )
62
63local nofrealigned = 0
64
65
66
67
68
69
70local function handler ( head , leftpage , realpageno )
71 local current = head
72 while current do
73 local id = getid ( current )
74 if id = = hlist_code then
75 if getsubtype ( current ) = = linelist_code then
76 local a = takeattr ( current , a_realign )
77 if not a or a = = 0 then
78
79 else
80 local align = a % 10
81 local pageno = div ( a , 10 )
82 if pageno = = realpageno then
83
84 else
85 local action = 0
86 if align = = 1 then
87 action = leftpage and 1 or 2
88 elseif align = = 2 then
89 action = leftpage and 2 or 1
90 end
91
92 local direction = getdirection ( current )
93
94 if direction = = righttoleft_code then
95 if action = = 1 then
96 action = 2
97 elseif action = = 2 then
98 action = 1
99 end
100 end
101
102 if action = = 1 then
103 local head = getlist ( current )
104 setlink ( findtail ( head ) , new_stretch ( 3 ) )
105 setlist ( current , hpack_nodes ( head , getwidth ( current ) , " exactly " , direction ) )
106 if trace_realign then
107 report_realign ( " flushing left, align %a, page %a, realpage %a " , align , pageno , realpageno )
108 end
109 elseif action = = 2 then
110 local list = getlist ( current )
111 local head = setlink ( new_stretch ( 3 ) , list )
112 setlist ( current , hpack_nodes ( head , getwidth ( current ) , " exactly " , direction ) )
113 if trace_realign then
114 report_realign ( " flushing right. align %a, page %a, realpage %a " , align , pageno , realpageno )
115 end
116 elseif trace_realign then
117 report_realign ( " invalid flushing, align %a, page %a, realpage %a " , align , pageno , realpageno )
118 end
119 nofrealigned = nofrealigned + 1
120 end
121 end
122 end
123 handler ( getlist ( current ) , leftpage , realpageno )
124 elseif id = = vlist_code then
125 handler ( getlist ( current ) , leftpage , realpageno )
126 end
127 current = getnext ( current )
128 end
129 return head
130end
131
132function alignments . handler ( head )
133 return handler ( head , isleftpage ( ) , texgetcount ( " realpageno " ) )
134end
135
136local enabled = false
137
138function alignments . set ( n )
139 if not enabled then
140 enableaction ( " shipouts " , " typesetters.alignments.handler " )
141 enabled = true
142 if trace_realign then
143 report_realign ( " enabled " )
144 end
145 end
146 texsetattribute ( a_realign , texgetcount ( " realpageno " ) * 10 + n )
147end
148
149interfaces . implement {
150 name = " setrealign " ,
151 actions = alignments . set ,
152 arguments = " integer " ,
153}
154
155statistics . register ( " realigning " , function ( )
156 if nofrealigned > 0 then
157 return format ( " %s processed " , nofrealigned )
158 else
159 return nil
160 end
161end )
162 |