1
2
3
4
5
6
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
if not modules then modules = { } end modules ['spac-ali'] = {
version = 1.001,
comment = "companion to spac-ali.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local div = math.div
local format = string.format
local tasks = nodes.tasks
local enableaction = tasks.enableaction
local nuts = nodes.nuts
local nodepool = nuts.pool
local tonode = nuts.tonode
local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
local getlist = nuts.getlist
local setlist = nuts.setlist
local setlink = nuts.setlink
local takeattr = nuts.takeattr
local getsubtype = nuts.getsubtype
local getwidth = nuts.getwidth
local findtail = nuts.tail
local hpack_nodes = nuts.hpack
local unsetvalue = attributes.unsetvalue
local nodecodes = nodes.nodecodes
local listcodes = nodes.listcodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local line_code = listcodes.line
local new_stretch = nodepool.stretch
local a_realign = attributes.private("realign")
local texsetattribute = tex.setattribute
local texgetcount = tex.getcount
local isleftpage = layouts.status.isleftpage
typesetters = typesetters or { }
local alignments = { }
typesetters.alignments = alignments
local report_realign = logs.reporter("typesetters","margindata")
local trace_realign = trackers.register("typesetters.margindata", function(v) trace_margindata = v end)
local nofrealigned = 0
-- leftskip rightskip parfillskip
-- raggedleft 0 + 0 -
-- raggedright 0 0 fil
-- raggedcenter 0 + 0 + -
local function handler(head,leftpage,realpageno)
local current = head
local done = false
while current do
local id = getid(current)
if id == hlist_code then
if getsubtype(current) == line_code then
local a = takeattr(current,a_realign)
if not a or a == 0 then
-- skip
else
local align = a % 10
local pageno = div(a,10)
if pageno == realpageno then
-- already ok
else
local action = 0
if align == 1 then -- flushright
action = leftpage and 1 or 2
elseif align == 2 then -- flushleft
action = leftpage and 2 or 1
end
if action == 1 then
local head = getlist(current)
setlink(findtail(head),new_stretch(3)) -- append
setlist(current,hpack_nodes(head,getwidth(current),"exactly"))
if trace_realign then
report_realign("flushing left, align %a, page %a, realpage %a",align,pageno,realpageno)
end
elseif action == 2 then
local list = getlist(current)
local head = setlink(new_stretch(3),list) -- prepend
setlist(current,hpack_nodes(head,getwidth(current),"exactly"))
if trace_realign then
report_realign("flushing right. align %a, page %a, realpage %a",align,pageno,realpageno)
end
elseif trace_realign then
report_realign("invalid flushing, align %a, page %a, realpage %a",align,pageno,realpageno)
end
done = true
nofrealigned = nofrealigned + 1
end
end
end
handler(getlist(current),leftpage,realpageno)
elseif id == vlist_code then
handler(getlist(current),leftpage,realpageno)
end
current = getnext(current)
end
return head, done
end
function alignments.handler(head)
local leftpage = isleftpage()
local realpageno = texgetcount("realpageno")
local head, done = handler(tonut(head),leftpage,realpageno)
return tonode(head), done
end
local enabled = false
function alignments.set(n)
if not enabled then
enableaction("shipouts","typesetters.alignments.handler")
enabled = true
if trace_realign then
report_realign("enabled")
end
end
texsetattribute(a_realign,texgetcount("realpageno") * 10 + n)
end
interfaces.implement {
name = "setrealign",
actions = alignments.set,
arguments = "integer",
}
statistics.register("realigning", function()
if nofrealigned > 0 then
return format("%s processed",nofrealigned)
else
return nil
end
end)
|