strc-mar.lmt /size: 6032 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['strc-mar'] = {
2    version   = 1.001,
3    comment   = "companion to strc-mar.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 lpegmatch = lpeg.match
10local setmetatableindex = table.setmetatableindex
11
12local context        = context
13local commands       = commands
14
15local implement      = interfaces.implement
16local variables      = interfaces.variables
17
18local v_first        <const> = variables.first
19local v_last         <const> = variables.last
20local v_previous     <const> = variables.previous
21local v_next         <const> = variables.next
22local v_column       <const> = variables.column
23
24local nuts           = nodes.nuts
25local nextmark       = nuts.traversers.mark
26local getbox         = nuts.getbox
27local getid          = nuts.getid
28local getlist        = nuts.getlist
29local getindex       = nuts.getindex
30local getdata        = nuts.getdata
31----- setmark_code   = nodes.markcodes.set
32local flushmark_code <const> = nodes.markcodes.flush
33local hlist_code     <const> = nodes.nodecodes.hlist
34local vlist_code     <const> = nodes.nodecodes.vlist
35
36local marks      = { }
37structures.marks = marks
38
39local markdata = setmetatableindex("table")
40local pattern  = lpeg.splitat(":")
41
42implement {
43    name      = "synchronizemarking",
44    arguments =  { "string", "integer", "integer" },
45    actions   = function(category,index,boxnumber)
46        local new = setmetatableindex("table")
47        local box = getbox(boxnumber)
48        while box and getid(box) == hlist_code do
49            box = getlist(box)
50        end
51        if box and getid(box) == vlist_code then
52            local list = getlist(box)
53            if list then
54                for n, subtype in nextmark, list do
55                    local class = getindex(n)
56                    local entry = new[class]
57                    if subtype == flushmark_code then
58                        entry.first = false
59                        entry.last  = false
60                    else
61                        if not entry.first then
62                            entry.first = n
63                        end
64                        entry.last = n
65                    end
66                end
67                for class, entry in next, new do
68                    local first = entry.first
69                    local last  = entry.last
70                    if last and first ~= last then
71                        entry.last = getdata(last,true)
72                    end
73                    if first then
74                        entry.first = getdata(first,true)
75                    end
76                end
77            else
78                -- wipe empty columns
79            end
80        else
81            -- wipe empty columns
82        end
83        local m = markdata[category]
84        if m then
85            local entry = m[index]
86            if entry then
87                local prev = index == 1 and m[#m] or m[index-1]
88                for class, data in next, entry do
89                    local pcls = prev[class]
90                    local last = pcls and pcls.last
91                    if last then
92                        local ncls = new[class]
93                        ncls.previous = last
94                        if not ncls.first then
95                            ncls.first = last
96                        end
97                        if not ncls.last then
98                            ncls.last = ncls.first
99                        end
100                    end
101                end
102            end
103            m[index] = new
104        else
105            new.previous = ""
106            markdata[category] = { [index] = new }
107        end
108     -- inspect(data)
109    end,
110}
111
112implement {
113    name      = "getsynchronizemarking",
114    arguments = { "integer", "string", "string" },
115    actions   = function(class,category,what)
116        local category, n = lpegmatch(pattern,category)
117        local useddata = markdata[category]
118        if useddata then
119            local index = tonumber(n) or 1
120            local data  = useddata[index]
121            if data then
122                local entry = data[class]
123                if entry then
124                    if what == v_first then
125                        context(entry.first or "")
126                    elseif what == v_last then
127                        context(entry.last or "")
128                    elseif what == v_previous then
129                        context(entry.previous or "")
130                    elseif what == v_next then
131                     -- context(entry.next or "") -- will be done when i need it, unreliable anyway
132                    end
133                end
134            end
135        end
136    end
137}
138
139implement {
140    name      = "resetsynchronizemarking",
141    arguments = "argument",
142    actions   = function(category)
143        local category, n = lpegmatch(pattern,category)
144        markdata[category] = nil
145    end
146}
147
148local pattern = lpeg.afterprefix("li::")
149
150function marks.title(tag,n)
151    local listindex = lpegmatch(pattern,n)
152    if listindex then
153        commands.savedlisttitle(tag,tonumber(listindex),"marking")
154    else
155        context(n)
156    end
157end
158
159function marks.number(tag,n) -- no spec
160    local listindex = lpegmatch(pattern,n)
161    if listindex then
162        commands.savedlistnumber(tag,tonumber(listindex))
163    else
164        -- no prefix (as it is the prefix)
165        context(n)
166    end
167end
168
169-- function marks.prefixednumber(tag,n) -- no spec
170--     local listindex = lpegmatch(pattern,n)
171--     if listindex then
172--         commands.savedlistprefixednumber(tag,tonumber(listindex))
173--     else
174--         context(n)
175--     end
176-- end
177
178-- interface
179
180implement { name = "markingtitle",          actions = marks.title,          arguments = "2 strings" }
181implement { name = "markingnumber",         actions = marks.number,         arguments = "2 strings" }
182--------- { name = "markingprefixednumber", actions = marks.prefixednumber, arguments = "2 strings" }
183