summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/node-dir.lua
blob: ef26286e51bf2e3fea4e2d55ed4a4461b4c29f6b (plain)
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
if not modules then modules = { } end modules ['node-dir'] = {
    version   = 1.001,
    comment   = "companion to node-ini.mkiv",
    author    = "Hans Hagen",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

local nodes             = nodes
local nuts              = nodes.nuts

local normaldir_code    = nodes.dircodes.normal
local line_code         = nodes.listcodes.line
local lefttoright_code  = nodes.dirvalues.lefttoright

local getnext           = nuts.getnext
local getlist           = nuts.getlist
local getwhd            = nuts.getwhd
local getdirection      = nuts.getdirection

local setlist           = nuts.setlist

local nextdir           = nuts.traversers.dir
local nexthlist         = nuts.traversers.hlist

local rangedimensions   = nuts.rangedimensions
local insert_before     = nuts.insert_before

local new_rule          = nuts.pool.rule
local new_kern          = nuts.pool.kern

local setcolor          = nodes.tracers.colors.set
local settransparency   = nodes.tracers.transparencies.set

local function dirdimensions(parent,begindir) -- can be a helper
    local level  = 1
    local enddir = begindir
    local width  = 0
    for current, subtype in nextdir, getnext(begindir) do
        if subtype == normaldir_code then -- todo
            level = level + 1
        else
            level = level - 1
        end
        if level == 0 then -- does the type matter
            enddir = current
            width  = rangedimensions(parent,begindir,enddir)
        end
    end
    if enddir == begindir then
        width = rangedimensions(parent,begindir)
    end
    return width, enddir
end

nuts.dirdimensions = dirdimensions

local function colorit(list,current,dir,w,h,d)
    local rule  = new_rule(w,h,d)
    local kern  = new_kern(-w)
    local color = dir == lefttoright_code and "trace:s" or "trace:o"
    setcolor(rule,color)
    settransparency(rule,color)
    list, current = insert_before(list,current,kern)
    list, current = insert_before(list,current,rule)
    return list, current
end

function nodes.tracers.directions(head)
    for hlist, subtype in nexthlist, head do
        if subtype == line_code then
            local list = getlist(hlist)
            local w, h, d = getwhd(hlist)
            list = colorit(list,list,getdirection(hlist),w,h,d)
            for current in nextdir, list do
                local dir, cancel = getdirection(current)
                if not cancel then
                    local width = dirdimensions(hlist,current)
                    list = colorit(list,current,dir,width,h,d)
                end
            end
            setlist(hlist,list)
        end
    end
    return head
end

local enabled = false

trackers.register("nodes.directions", function(v)
    if not enabled then
        enabled = true
        nodes.tasks.appendaction("finalizers","after","nodes.tracers.directions",nil,"nut","enabled")
    end
    nodes.tasks.setaction(v)
end)