node-dir.lua /size: 3625 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['node-dir'] = {
2    version   = 1.001,
3    comment   = "companion to node-ini.mkiv",
4    author    = "Hans Hagen",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local nodes             = nodes
10local nuts              = nodes.nuts
11
12local normaldir_code    = nodes.dircodes.normal
13local line_code         = nodes.listcodes.line
14local lefttoright_code  = nodes.dirvalues.lefttoright
15
16local getnext           = nuts.getnext
17local getlist           = nuts.getlist
18local getwhd            = nuts.getwhd
19local getdirection      = nuts.getdirection
20
21local setlist           = nuts.setlist
22
23local nextdir           = nuts.traversers.dir
24local nexthlist         = nuts.traversers.hlist
25
26local rangedimensions   = nuts.rangedimensions
27local insert_before     = nuts.insert_before
28
29local new_rule          = nuts.pool.rule
30local new_kern          = nuts.pool.kern
31
32local setcolor          = nodes.tracers.colors.set
33local settransparency   = nodes.tracers.transparencies.set
34
35-- local function dirdimensions(parent,begindir) -- can be a helper
36--     local level   = 1
37--     local enddir  = begindir
38--     local width   = 0
39--     for current, subtype in nextdir, getnext(begindir) do
40--         if subtype == normaldir_code then -- todo
41--             level = level + 1
42--         else
43--             level = level - 1
44--         end
45--         if level == 0 then -- does the type matter
46--             enddir = current
47--             width  = rangedimensions(parent,begindir,enddir)
48--             return width, enddir
49--         end
50--     end
51--     if enddir == begindir then
52--         width = rangedimensions(parent,begindir)
53--     end
54--     return width, enddir
55-- end
56
57local function dirdimensions(parent,begindir) -- can be a helper
58    local level   = 1
59    local lastdir = nil
60    local width   = 0
61    for current, subtype in nextdir, getnext(begindir) do
62        if subtype == normaldir_code then -- todo
63            level = level + 1
64        else
65            level = level - 1
66        end
67        if level == 0 then -- does the type matter
68            return (rangedimensions(parent,begindir,current)), current
69        end
70    end
71    return (rangedimensions(parent,begindir)), begindir
72end
73
74nuts.dirdimensions = dirdimensions
75
76local function colorit(list,current,dir,w,h,d)
77    local rule  = new_rule(w,h,d)
78    local kern  = new_kern(-w)
79    local color = dir == lefttoright_code and "trace:s" or "trace:o"
80    setcolor(rule,color)
81    settransparency(rule,color)
82    list, current = insert_before(list,current,kern)
83    list, current = insert_before(list,current,rule)
84    return list, current
85end
86
87function nodes.tracers.directions(head)
88    for hlist, subtype in nexthlist, head do
89        if subtype == line_code then
90            local list = getlist(hlist)
91            local w, h, d = getwhd(hlist)
92            list = colorit(list,list,getdirection(hlist),w,h,d)
93            for current in nextdir, list do
94                local dir, cancel = getdirection(current)
95                if not cancel then
96                    local width = dirdimensions(hlist,current)
97                    list = colorit(list,current,dir,width,h,d)
98                end
99            end
100            setlist(hlist,list)
101        end
102    end
103    return head
104end
105
106local enabled = false
107
108trackers.register("nodes.directions", function(v)
109    if not enabled then
110        enabled = true
111        nodes.tasks.appendaction("finalizers","after","nodes.tracers.directions",nil,"nut","enabled")
112    end
113    nodes.tasks.setaction(v)
114end)
115