summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/strc-mar.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/strc-mar.lmt')
-rw-r--r--tex/context/base/mkxl/strc-mar.lmt822
1 files changed, 117 insertions, 705 deletions
diff --git a/tex/context/base/mkxl/strc-mar.lmt b/tex/context/base/mkxl/strc-mar.lmt
index eb94f9fc3..e5266daf0 100644
--- a/tex/context/base/mkxl/strc-mar.lmt
+++ b/tex/context/base/mkxl/strc-mar.lmt
@@ -6,719 +6,143 @@ if not modules then modules = { } end modules ['strc-mar'] = {
license = "see context related readme files"
}
--- todo: cleanup stack (structures.marks.reset(v_all) also does the job)
--- todo: only commands.* print to tex, native marks return values
-
-local insert, concat = table.insert, table.concat
-local tostring, next, rawget, type = tostring, next, rawget, type
local lpegmatch = lpeg.match
-
-local context = context
-local commands = commands
-
-local implement = interfaces.implement
-
-local allocate = utilities.storage.allocate
-local setmetatableindex = table.setmetatableindex
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getattr = nuts.getattr
-local getbox = nuts.getbox
-
-local nextnode = nuts.traversers.node
-
-local nodecodes = nodes.nodecodes
-local whatsitcodes = nodes.whatsitcodes
-
-local glyph_code = nodecodes.glyph
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local whatsit_code = nodecodes.whatsit
-
-local lateluawhatsit_code = whatsitcodes.latelua
-
-local texsetattribute = tex.setattribute
-
-local a_marks = attributes.private("marks")
-
-local trace_set = false trackers.register("marks.set", function(v) trace_set = v end)
-local trace_get = false trackers.register("marks.get", function(v) trace_get = v end)
-local trace_details = false trackers.register("marks.details", function(v) trace_details = v end)
-
-local report_marks = logs.reporter("structure","marks")
-
-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_top = variables.top
-local v_bottom = variables.bottom
-local v_current = variables.current
-local v_default = variables.default
-local v_page = variables.page
-local v_all = variables.all
-local v_keep = variables.keep
-
-local v_nocheck_suffix = ":" .. variables.nocheck
-
-local v_first_nocheck = variables.first .. v_nocheck_suffix
-local v_last_nocheck = variables.last .. v_nocheck_suffix
-local v_previous_nocheck = variables.previous .. v_nocheck_suffix
-local v_next_nocheck = variables.next .. v_nocheck_suffix
-local v_top_nocheck = variables.top .. v_nocheck_suffix
-local v_bottom_nocheck = variables.bottom .. v_nocheck_suffix
-
-local structures = structures
-local marks = structures.marks
-
-local settings_to_array = utilities.parsers.settings_to_array
-
-local boxes_too = false -- at some point we can also tag boxes or use a zero char
-
-directives.register("marks.boxestoo", function(v) boxes_too = v end)
-
-local data = marks.data or allocate()
-marks.data = data
-
-storage.register("structures/marks/data", marks.data, "structures.marks.data")
-
-local stack, topofstack = { }, 0
-
-local ranges = {
- [v_page] = {
- first = 0,
- last = 0,
- },
-}
-
-local function resolve(t,k)
- if k then
- if trace_set or trace_get then
- report_marks("undefined mark, name %a",k)
- end
- local crap = { autodefined = true } -- maybe set = 0 and reset = 0
- t[k] = crap
- return crap
- else
- -- weird: k is nil
- end
-end
-
-setmetatableindex(data, resolve)
-
-function marks.exists(name)
- return rawget(data,name) ~= nil
-end
-
--- identify range
-
-local function sweep(head,first,last)
- for n, id, subtype in nextnode, head do
- -- we need to handle empty heads so we test for latelua
- if id == glyph_code or (id == whatsit_code and subtype == lateluawhatsit_code) then -- brrr
- local a = getattr(n,a_marks)
- if not a then
- -- next
- elseif first == 0 then
- first, last = a, a
- elseif a > last then
- last = a
- end
- elseif id == hlist_code or id == vlist_code then
- if boxes_too then
- local a = getattr(n,a_marks)
- if not a then
- -- next
- elseif first == 0 then
- first, last = a, a
- elseif a > last then
- last = a
- end
- end
- local list = getlist(n)
+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
- first, last = sweep(list,first,last)
- end
- end
- end
- return first, last
-end
-
-local classes = { }
-
-setmetatableindex(classes, function(t,k) local s = settings_to_array(k) t[k] = s return s end)
-
-local lasts = { }
-
-function marks.synchronize(class,n,option)
- local box = getbox(n)
- if box then
- local first, last = sweep(getlist(box),0,0)
- if option == v_keep and first == 0 and last == 0 then
- if trace_get or trace_set then
- report_marks("action %a, class %a, box %a","retain at synchronize",class,n)
- end
- -- todo: check if still valid first/last in range
- first = lasts[class] or 0
- last = first
- else
- lasts[class] = last
- local classlist = classes[class]
- for i=1,#classlist do
- local class = classlist[i]
- local range = ranges[class]
- if range then
- range.first = first
- range.last = last
- else
- range = {
- first = first,
- last = last,
- }
- ranges[class] = range
- end
- if trace_get or trace_set then
- report_marks("action %a, class %a, first %a, last %a","synchronize",class,range.first,range.last)
- end
- end
- end
- elseif trace_get or trace_set then
- report_marks("action %s, class %a, box %a","synchronize without content",class,n)
- end
-end
-
--- define etc
-
-local function resolve(t,k)
- if k == "fullchain" then
- local fullchain = { }
- local chain = t.chain
- while chain and chain ~= "" do
- insert(fullchain,1,chain)
- chain = data[chain].chain
- end
- t[k] = fullchain
- return fullchain
- elseif k == "chain" then
- t[k] = ""
- return ""
- elseif k == "reset" or k == "set" then
- t[k] = 0
- return 0
- elseif k == "parent" then
- t[k] = false
- return false
- end
-end
-
-function marks.define(name,settings)
- if not settings then
- settings = { }
- elseif type(settings) == "string" then
- settings = { parent = settings }
- end
- data[name] = settings
- local parent = settings.parent
- if parent == nil or parent == "" or parent == name then
- settings.parent = false
- else
- local dp = data[parent]
- if not dp then
- settings.parent = false
- elseif dp.parent then
- settings.parent = dp.parent
- end
- end
- setmetatableindex(settings, resolve)
-end
-
-for k, v in next, data do
- setmetatableindex(v,resolve) -- runtime loaded table
-end
-
-local function parentname(name)
- local dn = data[name]
- return dn and dn.parent or name
-end
-
-function marks.relate(name,chain)
- local dn = data[name]
- if dn and not dn.parent then
- if chain and chain ~= "" then
- dn.chain = chain
- local dc = data[chain]
- if dc then
- local children = dc.children
- if not children then
- children = { }
- dc.children = children
- end
- children[#children+1] = name
- end
- elseif trace_set then
- report_marks("error: invalid relation, name %a, chain %a",name,chain)
- end
- end
-end
-
-local function resetchildren(new,name)
- local dn = data[name]
- if dn and not dn.parent then
- local children = dn.children
- if children then
- for i=1,#children do
- local ci = children[i]
- new[ci] = false
- if trace_set then
- report_marks("action %a, parent %a, child %a","reset",name,ci)
- end
- resetchildren(new,ci)
- end
- end
- end
-end
-
-function marks.set(name,value)
- local dn = data[name]
- if dn then
- local child = name
- local parent = dn.parent
- if parent then
- name = parent
- dn = data[name]
- end
- dn.set = topofstack
- if not dn.reset then
- dn.reset = 0 -- in case of selfdefined
- end
- local top = stack[topofstack]
- local new = { }
- if top then
- for k, v in next, top do
- local d = data[k]
- local r = d.reset or 0
- local s = d.set or 0
- if r <= topofstack and s < r then
- new[k] = false
- else
- new[k] = v
- end
- end
- end
- resetchildren(new,name)
- new[name] = value
- topofstack = topofstack + 1
- stack[topofstack] = new
- if trace_set then
- if name == child then
- report_marks("action %a, name %a, index %a, value %a","set",name,topofstack,value)
- else
- report_marks("action %a, parent %a, child %a, index %a, value %a","set",parent,child,topofstack,value)
- end
- end
- texsetattribute("global",a_marks,topofstack)
- end
-end
-
-local function reset(name)
- if v_all then
- if trace_set then
- report_marks("action %a","reset all")
- end
- stack = { }
- for name, dn in next, data do
- local parent = dn.parent
- if parent then
- dn.reset = 0
- dn.set = 0
- end
- end
- else
- local dn = data[name]
- if dn then
- local parent = dn.parent
- if parent then
- name = parent
- dn = data[name]
- end
- if trace_set then
- report_marks("action %a, name %a, index %a","reset",name,topofstack)
- end
- dn.reset = topofstack
- local children = dn.children
- if children then
- for i=1,#children do
- local ci = children[i]
- reset(ci)
- end
- end
- end
- end
-end
-
-marks.reset = reset
-
-function marks.get(n,name,value)
- local dn = data[name]
- if dn then
- name = dn.parent or name
- local top = stack[n]
- if top then
- context(top[name])
- end
- end
-end
-
-function marks.show(first,last)
- if first and last then
- for k=first,last do
- local v = stack[k]
- if v then
- report_marks("% 4i: %s",k,table.sequenced(v))
- end
- end
- else
- for k, v in table.sortedpairs(stack) do
- report_marks("% 4i: %s",k,table.sequenced(v))
- end
- end
-end
-
-local function resolve(name,first,last,strict,quitonfalse,notrace)
- local dn = data[name]
- if dn then
- local child = name
- local parent = dn.parent
- name = parent or child
- dn = data[name]
- local step, method
- if first > last then
- step, method = -1, "bottom-up"
- else
- step, method = 1, "top-down"
- end
- if trace_get and not notrace then
- report_marks("action %a, strategy %a, name %a, parent %a, strict %a","request",method,child,parent,strict or false)
- end
- if trace_details and not notrace then
- marks.show(first,last)
- end
- local r = dn.reset
- local s = dn.set
- if first <= last and first <= r then
- if trace_get and not notrace then
- report_marks("action %a, name %a, first %a, last %a, reset %a, index %a","reset first",name,first,last,r,first)
- end
- elseif first >= last and last <= r then
- if trace_get and not notrace then
- report_marks("action %a, name %a, first %a, last %a, reset %a, index %a","reset last",name,first,last,r,last)
- end
- elseif not stack[first] or not stack[last] then
- if trace_get and not notrace then
- -- a previous or next method can give an out of range, which is valid
- report_marks("error: out of range, name %a, reset %a, index %a",name,r,first)
- end
- elseif strict then
- local top = stack[first]
- local fullchain = dn.fullchain
- if not fullchain or #fullchain == 0 then
- if trace_get and not notrace then
- report_marks("warning: no full chain, trying again, name %a, first %a, last %a",name,first,last)
- end
- return resolve(name,first,last)
- else
- if trace_get and not notrace then
- report_marks("found chain [ % => T ]",fullchain)
- end
- local chaindata = { }
- local chainlength = #fullchain
- for i=1,chainlength do
- local cname = fullchain[i]
- if data[cname].set > 0 then
- local value = resolve(cname,first,last,false,false,true)
- if value == "" then
- if trace_get and not notrace then
- report_marks("quitting chain, name %a, reset %a, start %a",name,r,first)
- end
- return ""
- else
- chaindata[i] = value
+ 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
- if trace_get and not notrace then
- report_marks("using chain [ % => T ]",chaindata)
- end
- local value, index, found = resolve(name,first,last,false,false,true)
- if value ~= "" then
- if trace_get and not notrace then
- report_marks("following chain [ % => T ]",chaindata)
- end
- for i=1,chainlength do
- local cname = fullchain[i]
- if data[cname].set > 0 and chaindata[i] ~= found[cname] then
- if trace_get and not notrace then
- report_marks("quiting chain, name %a, reset %a, index %a",name,r,first)
- end
- return ""
- 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 trace_get and not notrace then
- report_marks("found in chain, name %a, reset %a, start %a, index %a, value %a",name,r,first,index,value)
+ if first then
+ entry.first = getdata(first,true)
end
- return value, index, found
- elseif trace_get and not notrace then
- report_marks("not found, name %a, reset %a",name,r)
end
+ else
+ -- wipe empty columns
end
else
- for i=first,last,step do
- local current = stack[i]
- local value = current and current[name]
- if value == nil then
- -- search on
- elseif value == false then
- if quitonfalse then
- return ""
- end
- elseif value == true then
- if trace_get and not notrace then
- report_marks("quitting steps, name %a, reset %a, start %a, index %a",name,r,first,i)
- end
- return ""
- elseif value ~= "" then
- if trace_get and not notrace then
- report_marks("found in steps, name %a, reset %a, start %a, index %a, value %a",name,r,first,i,value)
- end
- return value, i, current
- end
- end
- if trace_get and not notrace then
- report_marks("not found in steps, name %a, reset %a",name,r)
- end
- end
- end
- return ""
-end
-
--- todo: column:first column:last
-
-local methods = { }
-
-local function doresolve(name,rangename,swap,df,dl,strict)
- local range = ranges[rangename] or ranges[v_page]
- local first = range.first
- local last = range.last
- if trace_get then
- report_marks("action %a, name %a, range %a, swap %a, first %a, last %a, df %a, dl %a, strict %a",
- "resolving",name,rangename,swap or false,first,last,df,dl,strict or false)
- end
- if swap then
- first, last = last + df, first + dl
- else
- first, last = first + df, last + dl
- end
- local value, index, found = resolve(name,first,last,strict)
- -- maybe something more
- return value, index, found
-end
-
--- previous : last before sync
--- next : first after sync
-
--- top : first in sync
--- bottom : last in sync
-
--- first : first not top in sync
--- last : last not bottom in sync
-
-methods[v_previous] = function(name,range) return doresolve(name,range,false,-1,0,true ) end -- strict
-methods[v_top] = function(name,range) return doresolve(name,range,false, 0,0,true ) end -- strict
-methods[v_bottom] = function(name,range) return doresolve(name,range,true , 0,0,true ) end -- strict
-methods[v_next] = function(name,range) return doresolve(name,range,true , 0,1,true ) end -- strict
-
-methods[v_previous_nocheck] = function(name,range) return doresolve(name,range,false,-1,0,false) end
-methods[v_top_nocheck] = function(name,range) return doresolve(name,range,false, 0,0,false) end
-methods[v_bottom_nocheck] = function(name,range) return doresolve(name,range,true , 0,0,false) end
-methods[v_next_nocheck] = function(name,range) return doresolve(name,range,true , 0,1,false) end
-
-local function do_first(name,range,check)
- if trace_get then
- report_marks("action %a, name %a, range %a","resolving first",name,range)
- end
- local f_value, f_index, f_found = doresolve(name,range,false,0,0,check)
- if f_found then
- if trace_get then
- report_marks("action %a, name %a, range %a","resolving last",name,range)
- end
- local l_value, l_index, l_found = doresolve(name,range,true ,0,0,check)
- if l_found and l_index > f_index then
- local name = parentname(name)
- for i=f_index,l_index,1 do
- local si = stack[i]
- local sn = si[name]
- if sn and sn ~= false and sn ~= true and sn ~= "" and sn ~= f_value then
- if trace_get then
- report_marks("action %a, name %a, range %a, index %a, value %a","resolving",name,range,i,sn)
+ -- 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
- return sn, i, si
end
end
+ m[index] = new
+ else
+ new.previous = ""
+ markdata[category] = { [index] = new }
end
- end
- if trace_get then
- report_marks("resolved, name %a, range %a, using first",name,range)
- end
- return f_value, f_index, f_found
-end
+ -- inspect(data)
+ end,
+}
-local function do_last(name,range,check)
- if trace_get then
- report_marks("action %a, name %a, range %a","resolving last",name,range)
- end
- local l_value, l_index, l_found = doresolve(name,range,true ,0,0,check)
- if l_found then
- if trace_get then
- report_marks("action %a, name %a, range %a","resolving first",name,range)
- end
- local f_value, f_index, f_found = doresolve(name,range,false,0,0,check)
- if f_found and l_index > f_index then
- local name = parentname(name)
- for i=l_index,f_index,-1 do
- local si = stack[i]
- local sn = si[name]
- if sn and sn ~= false and sn ~= true and sn ~= "" and sn ~= l_value then
- if trace_get then
- report_marks("action %a, name %a, range %a, index %a, value %a","resolving",name,range,i,sn)
+implement {
+ name = "getsynchronizedmarking",
+ 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
- return sn, i, si
end
end
end
end
- if trace_get then
- report_marks("resolved, name %a, range %a, using first",name,range)
- end
- return l_value, l_index, l_found
-end
-
-methods[v_first ] = function(name,range) return do_first(name,range,true ) end
-methods[v_last ] = function(name,range) return do_last (name,range,true ) end
-methods[v_first_nocheck] = function(name,range) return do_first(name,range,false) end
-methods[v_last_nocheck ] = function(name,range) return do_last (name,range,false) end
-
-methods[v_current] = function(name,range) -- range is ignored here
- local top = stack[topofstack]
- return top and top[parentname(name)] or ""
-end
-
-local function fetched(name,range,method)
- local value = (methods[method] or methods[v_first])(name,range) or ""
- if not trace_get then
- -- no report
- elseif value == "" then
- report_marks("nothing fetched, name %a, range %a, method %a",name,range,method)
- else
- report_marks("marking fetched, name %a, range %a, method %a, value %a",name,range,method,value)
- end
- return value or ""
-end
-
--- can be used at the lua end:
-
-marks.fetched = fetched
-
--- this will move to a separate runtime modules
-
-marks.tracers = marks.tracers or { }
-
-function marks.tracers.showtable()
- context.starttabulate { "|l|l|l|lp|lp|" }
- context.tabulaterowbold("name","parent","chain","children","fullchain")
- context.ML()
- for k, v in table.sortedpairs(data) do
- local parent = v.parent or ""
- local chain = v.chain or ""
- local children = v.children or { }
- local fullchain = v.fullchain or { }
- table.sort(children) -- in-place but harmless
- context.tabulaterowtyp(k,parent,chain,concat(children," "),concat(fullchain," "))
- end
- context.stoptabulate()
-end
-
--- pushing to context:
-
--- local separator = context.nested.markingseparator
--- local command = context.nested.markingcommand
--- local ctxconcat = context.concat
-
--- local function fetchonemark(name,range,method)
--- context(command(name,fetched(name,range,method)))
--- end
-
--- local function fetchtwomarks(name,range)
--- ctxconcat( {
--- command(name,fetched(name,range,v_first)),
--- command(name,fetched(name,range,v_last)),
--- }, separator(name))
--- end
-
--- local function fetchallmarks(name,range)
--- ctxconcat( {
--- command(name,fetched(name,range,v_previous)),
--- command(name,fetched(name,range,v_first)),
--- command(name,fetched(name,range,v_last)),
--- }, separator(name))
--- end
-
- local ctx_separator = context.markingseparator
- local ctx_command = context.markingcommand
-
- local function fetchonemark(name,range,method)
- ctx_command(name,fetched(name,range,method))
- end
-
- local function fetchtwomarks(name,range)
- ctx_command(name,fetched(name,range,v_first))
- ctx_separator(name)
- ctx_command(name,fetched(name,range,v_last))
- end
-
- local function fetchallmarks(name,range)
- ctx_command(name,fetched(name,range,v_previous))
- ctx_separator(name)
- ctx_command(name,fetched(name,range,v_first))
- ctx_separator(name)
- ctx_command(name,fetched(name,range,v_last))
- end
+}
-function marks.fetch(name,range,method) -- chapter page first | chapter column:1 first
- if trace_get then
- report_marks("marking requested, name %a, range %a, method %a",name,range,method)
- end
- if method == "" or method == v_default then
- fetchonemark(name,range,v_first)
- elseif method == v_both then
- fetchtwomarks(name,range)
- elseif method == v_all then
- fetchallmarks(name,range)
- else
- fetchonemark(name,range,method)
+implement {
+ name = "resetsynchronizedmarking",
+ arguments = "argument",
+ actions = function(category)
+ local category, n = lpegmatch(pattern,category)
+ markdata[category] = nil
end
-end
-
-function marks.fetchonemark (name,range,method) fetchonemark (name,range,method) end
-function marks.fetchtwomarks(name,range) fetchtwomarks(name,range ) end
-function marks.fetchallmarks(name,range) fetchallmarks(name,range ) end
-
--- here we have a few helpers .. will become commands.*
+}
local pattern = lpeg.afterprefix("li::")
@@ -743,17 +167,5 @@ end
-- interface
-implement { name = "markingtitle", actions = marks.title, arguments = "2 strings" }
-implement { name = "markingnumber", actions = marks.number, arguments = "2 strings" }
-
-implement { name = "definemarking", actions = marks.define, arguments = "2 strings" }
-implement { name = "relatemarking", actions = marks.relate, arguments = "2 strings" }
-implement { name = "setmarking", actions = marks.set, arguments = "2 strings" }
-implement { name = "resetmarking", actions = marks.reset, arguments = "string" }
-implement { name = "synchronizemarking", actions = marks.synchronize, arguments = { "string", "integer", "string" } }
-implement { name = "getmarking", actions = marks.fetch, arguments = "3 strings" }
-implement { name = "fetchonemark", actions = marks.fetchonemark, arguments = "3 strings" }
-implement { name = "fetchtwomarks", actions = marks.fetchtwomarks, arguments = "2 strings" }
-implement { name = "fetchallmarks", actions = marks.fetchallmarks, arguments = "2 strings" }
-
-implement { name = "doifelsemarking", actions = { marks.exists, commands.doifelse }, arguments = "string" }
+implement { name = "markingtitle", actions = marks.title, arguments = "2 strings" }
+implement { name = "markingnumber", actions = marks.number,arguments = "2 strings" }