trac-jus.lmt /size: 4429 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['trac-jus'] = {
2    version   = 1.001,
3    comment   = "companion to trac-jus.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 checkers        = typesetters.checkers or { }
10typesetters.checkers  = checkers
11
12----- report_justification = logs.reporter("visualize","justification")
13
14local a_alignstate    <const> = attributes.private("alignstate")
15local a_justification <const> = attributes.private("justification")
16
17local nuts            = nodes.nuts
18
19local getfield        = nuts.getfield
20local getlist         = nuts.getlist
21local getattr         = nuts.getattr
22local setattr         = nuts.setattr
23local setlist         = nuts.setlist
24local setlink         = nuts.setlink
25local getwidth        = nuts.getwidth
26local findtail        = nuts.tail
27
28local nexthlist       = nuts.traversers.hlist
29
30local getdimensions   = nuts.dimensions
31local copylist        = nuts.copylist
32
33local tracedrule      = nodes.tracers.pool.nuts.rule
34
35local nodepool        = nuts.pool
36
37local new_hlist       = nodepool.hlist
38local new_kern        = nodepool.kern
39
40local hlist_code      <const> = nodes.nodecodes.hlist
41
42local texsetattribute = tex.setattribute
43
44local unsetvalue      <const> = attributes.unsetvalue
45
46local enableaction    = nodes.tasks.enableaction
47
48local min_threshold   = 0
49local max_threshold   = 0
50
51local function set(n)
52    enableaction("mvlbuilders", "typesetters.checkers.handler")
53    enableaction("vboxbuilders","typesetters.checkers.handler")
54    texsetattribute(a_justification,n or 1)
55    function typesetters.checkers.set(n)
56        texsetattribute(a_justification,n or 1)
57    end
58end
59
60local function reset()
61    texsetattribute(a_justification,unsetvalue)
62end
63
64checkers.set   = set
65checkers.reset = reset
66
67interfaces.implement {
68    name    = "showjustification",
69    actions = set
70}
71
72trackers.register("visualizers.justification", function(v)
73    if v then
74        set(1)
75    else
76        reset()
77    end
78end)
79
80function checkers.handler(head)
81    for current in nexthlist, head do
82        if getattr(current,a_justification) == 1 then
83            setattr(current,a_justification,0) -- kind of reset
84            local width = getwidth(current)
85            if width > 0 then
86                local list = getlist(current)
87                if list then
88                    local naturalwidth, naturalheight, naturaldepth = getdimensions(list)
89                    local delta = naturalwidth - width
90                    if naturalwidth == 0 or delta == 0 then
91                        -- special box
92                    elseif delta >= max_threshold then
93                        local rule = new_hlist(tracedrule(delta,naturalheight,naturaldepth,getfield(list,"glueset") == 1 and "trace:dr" or "trace:db"))
94                        setlink(findtail(list),rule)
95                        setlist(current,list)
96                    elseif delta <= min_threshold then
97                        local alignstate = getattr(list,a_alignstate)
98                        if alignstate == 1 then
99                            local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dc"))
100                            setlink(rule,list)
101                            setlist(current,rule)
102                        elseif alignstate == 2 then
103                            local lrule = new_hlist(tracedrule(-delta/2,naturalheight,naturaldepth,"trace:dy"))
104                            local rrule = copylist(lrule)
105                            setlink(lrule,list)
106                            setlink(findtail(list),new_kern(delta/2),rrule)
107                            setlist(current,lrule)
108                        elseif alignstate == 3 then
109                            local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dm"))
110                            setlink(findtail(list),new_kern(delta),rule)
111                            setlist(current,list)
112                        else
113                            local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dg"))
114                            setlink(findtail(list),new_kern(delta),rule)
115                            setlist(current,list)
116                        end
117                    end
118                end
119            end
120        end
121    end
122    return head
123end
124