summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/strc-mar.lmt
blob: 61972009c9583ff66bf0b943548cc9995a92b5c0 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
if not modules then modules = { } end modules ['strc-mar'] = {
    version   = 1.001,
    comment   = "companion to strc-mar.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

local lpegmatch = lpeg.match
local setmetatableindex = table.setmetatableindex

local context        = context

local implement      = interfaces.implement
local variables      = interfaces.variables

local v_first        = variables.first
local v_last         = variables.last
local v_previous     = variables.previous
local v_next         = variables.next
local v_column       = variables.column

local nuts           = nodes.nuts
local nextmark       = nuts.traversers.mark
local getbox         = nuts.getbox
local getid          = nuts.getid
local getlist        = nuts.getlist
local getindex       = nuts.getindex
local getdata        = nuts.getdata
----- setmark_code   = nodes.markcodes.set
local flushmark_code = nodes.markcodes.flush
local hlist_code     = nodes.nodecodes.hlist
local vlist_code     = nodes.nodecodes.vlist

local marks      = { }
structures.marks = marks

local markdata = setmetatableindex("table")
local pattern  = lpeg.splitat(":")

implement {
    name      = "synchronizemarking",
    arguments =  { "string", "integer", "integer" },
    actions   = function(category,index,boxnumber)
        local new = setmetatableindex("table")
        local box = getbox(boxnumber)
        while box and getid(box) == hlist_code do
            box = getlist(box)
        end
        if box and getid(box) == vlist_code then
            local list = getlist(box)
            if list then
                for n, subtype in nextmark, list do
                    local class = getindex(n)
                    local entry = new[class]
                    if subtype == flushmark_code then
                        entry.first = false
                        entry.last  = false
                    else
                        if not entry.first then
                            entry.first = n
                        end
                        entry.last = n
                    end
                end
                for class, entry in next, new do
                    local first = entry.first
                    local last  = entry.last
                    if last and first ~= last then
                        entry.last = getdata(last,true)
                    end
                    if first then
                        entry.first = getdata(first,true)
                    end
                end
            else
                -- wipe empty columns
            end
        else
            -- wipe empty columns
        end
        local m = markdata[category]
        if m then
            local entry = m[index]
            if entry then
                local prev = index == 1 and m[#m] or m[index-1]
                for class, data in next, entry do
                    local pcls = prev[class]
                    local last = pcls and pcls.last
                    if last then
                        local ncls = new[class]
                        ncls.previous = last
                        if not ncls.first then
                            ncls.first = last
                        end
                        if not ncls.last then
                            ncls.last = ncls.first
                        end
                    end
                end
            end
            m[index] = new
        else
            new.previous = ""
            markdata[category] = { [index] = new }
        end
     -- inspect(data)
    end,
}

implement {
    name      = "getsynchronizemarking",
    arguments = { "integer", "string", "string" },
    actions   = function(class,category,what)
        local category, n = lpegmatch(pattern,category)
        local useddata = markdata[category]
        if useddata then
            local index = tonumber(n) or 1
            local data  = useddata[index]
            if data then
                local entry = data[class]
                if entry then
                    if what == v_first then
                        context(entry.first or "")
                    elseif what == v_last then
                        context(entry.last or "")
                    elseif what == v_previous then
                        context(entry.previous or "")
                    elseif what == v_next then
                     -- context(entry.next or "") -- will be done when i need it, unreliable anyway
                    end
                end
            end
        end
    end
}

implement {
    name      = "resetsynchronizemarking",
    arguments = "argument",
    actions   = function(category)
        local category, n = lpegmatch(pattern,category)
        markdata[category] = nil
    end
}

local pattern = lpeg.afterprefix("li::")

function marks.title(tag,n)
    local listindex = lpegmatch(pattern,n)
    if listindex then
        commands.savedlisttitle(tag,listindex,"marking")
    else
        context(n)
    end
end

function marks.number(tag,n) -- no spec
    local listindex = lpegmatch(pattern,n)
    if listindex then
        commands.savedlistnumber(tag,listindex)
    else
        -- no prefix (as it is the prefix)
        context(n)
    end
end

-- interface

implement { name = "markingtitle",  actions = marks.title, arguments = "2 strings" }
implement { name = "markingnumber", actions = marks.number,arguments = "2 strings" }