typo-swp.lmt /size: 3521 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['typo-stc'] = {
2    version   = 1.001,
3    comment   = "companion to typo-stc.mkxl",
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 nodes, node = nodes, node
10
11local nuts       = nodes.nuts
12local tonut      = nuts.tonut
13local getattr    = nuts.getattr
14----- getwhd     = nuts.getwhd
15local getboth    = nuts.getboth
16local setlink    = nuts.setlink
17local nextlist   = nuts.traversers.list
18
19local a_swapping <const> = attributes.private("swapping")
20
21local swapping       = typesetters.swapping or { }
22typesetters.swapping = swapping
23
24local enabled = false
25local stack   = { }
26
27local report  = logs.reporter("swapping")
28
29interfaces.implement {
30    name      = "enableswapping",
31    actions   = function()
32        if not enabled then
33            nodes.tasks.enableaction("shipouts", "typesetters.swapping.handler")
34            enabled = true
35        end
36    end,
37}
38
39-- check if wd/ht/dp match
40
41local function process(head, parent)
42    for current, id, subtype, list in nextlist, head do
43        if list then
44            local a = getattr(current,a_swapping)
45            if a then
46                if not stack then
47                    stack = { }
48                end
49                local s = stack[a]
50                if not s then
51                    s = { }
52                    stack[a] = s
53                end
54             -- s[#s+1] = { parent, current }
55                s[#s+1] = current
56            end
57            process(list,current)
58        end
59    end
60    return head
61end
62
63swapping.handler = function(head)
64    if enabled then
65        stack = { }
66        head  = process(head)
67        if stack then
68            for k, v in next, stack do
69                local parent  = v[1]
70                local box     = v[2]
71                local columns = k & 0xFFFF
72                local w = lua.newindex(#v)
73                local rows = #v//columns
74                local vn = 1
75                local wr = 0
76                local wc = 1
77                for r=1,rows do
78                    for c=1,columns do
79                        wr = wr + 1
80                        if wr > rows then
81                            wc = wc + 1
82                            wr = 1
83                        end
84                        local wn = (wr-1)*columns+wc
85                     -- local old = v[vn]
86                     -- local new = v[wn]
87                     -- local vi  = old[2]
88                     -- local prv, nxt = getboth(new[2])
89                        --
90                     -- local oldwd, oldht, olddp = getwhd(old[1])
91                     -- local newwd, newht, newdp = getwhd(new[1])
92                     -- if oldht ~= newht or olddp ~= newdp then
93                     --     report("difference old (%p,%p), new (%p,%p)",oldht,olddp,newht,newdp)
94                     -- end
95                        local vi  = v[vn]
96                        local prv, nxt = getboth(v[wn])
97                        --
98                        w[wn] = { vi, prv, nxt }
99                        vn = vn + 1
100                    end
101                end
102                for i=1,#w do
103                    local wi = w[i]
104                    local vi = wi[1]
105                    if vi and wi and vi ~= wi then
106                        setlink(wi[2],vi,wi[3])
107                    end
108                end
109            end
110        end
111        stack = false
112    end
113    return head
114end
115
116