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