if not modules then modules = { } end modules ['anch-pos'] = {
version = 1.001,
comment = "companion to anch-pos.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
--[[ldx--
We save positional information in the main utility table. Not only
can we store much more information in but it's also
more efficient.
--ldx]]--
-- plus (extra) is obsolete but we will keep it for a while
-- context(new_latelua_node(f_enhance(tag)))
-- =>
-- context.lateluafunction(function() f_enhance(tag) end)
-- maybe replace texsp by our own converter (stay at the lua end)
-- eventually mp will have large numbers so we can use sp there too
local tostring, next, rawget, setmetatable = tostring, next, rawget, setmetatable
local sort = table.sort
local format, gmatch, match = string.format, string.gmatch, string.match
local rawget = rawget
local lpegmatch = lpeg.match
local insert, remove = table.insert, table.remove
local allocate, mark = utilities.storage.allocate, utilities.storage.mark
local scanners = tokens.scanners
local scanstring = scanners.string
local scaninteger = scanners.integer
local scandimen = scanners.dimen
local compilescanner = tokens.compile
local scanners = interfaces.scanners
local commands = commands
local context = context
local tex = tex
local texgetcount = tex.getcount
local texsetcount = tex.setcount
local texget = tex.get
local texsp = tex.sp
----- texsp = string.todimen -- because we cache this is much faster but no rounding
local pdf = pdf -- h and v are variables
local setmetatableindex = table.setmetatableindex
local nuts = nodes.nuts
local getfield = nuts.getfield
local setfield = nuts.setfield
local getlist = nuts.getlist
local getbox = nuts.getbox
local getskip = nuts.getskip
local find_tail = nuts.tail
local new_latelua = nuts.pool.latelua
local new_latelua_node = nodes.pool.latelua
local variables = interfaces.variables
local v_text = variables.text
local v_column = variables.column
local pt = number.dimenfactors.pt
local pts = number.pts
local formatters = string.formatters
local collected = allocate()
local tobesaved = allocate()
local jobpositions = {
collected = collected,
tobesaved = tobesaved,
}
job.positions = jobpositions
_plib_ = jobpositions -- might go
local default = { -- not r and paragraphs etc
__index = {
x = 0, -- x position baseline
y = 0, -- y position baseline
w = 0, -- width
h = 0, -- height
d = 0, -- depth
p = 0, -- page
n = 0, -- paragraph
ls = 0, -- leftskip
rs = 0, -- rightskip
hi = 0, -- hangindent
ha = 0, -- hangafter
hs = 0, -- hsize
pi = 0, -- parindent
ps = false, -- parshape
}
}
local f_b_tag = formatters["b:%s"]
local f_e_tag = formatters["e:%s"]
local f_p_tag = formatters["p:%s"]
local f_w_tag = formatters["w:%s"]
local f_b_column = formatters["_plib_.b_col(%q)"]
local f_e_column = formatters["_plib_.e_col()"]
local f_enhance = formatters["_plib_.enhance(%q)"]
local f_region = formatters["region:%s"]
local f_b_region = formatters["_plib_.b_region(%q)"]
local f_e_region = formatters["_plib_.e_region(%s)"]
local f_tag_three = formatters["%s:%s:%s"]
local f_tag_two = formatters["%s:%s"]
local function sorter(a,b)
return a.y > b.y
end
local nofusedregions = 0
local nofmissingregions = 0
local nofregular = 0
jobpositions.used = false
-- todo: register subsets and count them indepently
local function initializer()
tobesaved = jobpositions.tobesaved
collected = jobpositions.collected
-- add sparse regions
local pages = structures.pages.collected
if pages then
local last = nil
for p=1,#pages do
local region = "page:" .. p
local data = collected[region]
if data then
last = data
last.p = nil -- no need for a page
elseif last then
collected[region] = last
end
end
end
-- enhance regions with paragraphs
for tag, data in next, collected do
local region = data.r
if region then
local r = collected[region]
if r then
local paragraphs = r.paragraphs
if not paragraphs then
r.paragraphs = { data }
else
paragraphs[#paragraphs+1] = data
end
nofusedregions = nofusedregions + 1
else
nofmissingregions = nofmissingregions + 1
end
else
nofregular = nofregular + 1
end
setmetatable(data,default)
end
-- add metatable
-- for tag, data in next, collected do
-- setmetatable(data,default)
-- end
-- sort this data
for tag, data in next, collected do
local region = data.r
if region then
local r = collected[region]
if r then
local paragraphs = r.paragraphs
if paragraphs and #paragraphs > 1 then
sort(paragraphs,sorter)
end
end
end
-- so, we can be sparse and don't need 'or 0' code
end
jobpositions.used = next(collected)
end
job.register('job.positions.collected', tobesaved, initializer)
local regions = { }
local nofregions = 0
local region = nil
local columns = { }
local nofcolumns = 0
local column = nil
local nofpages = nil
-- beware ... we're not sparse here as lua will reserve slots for the nilled
local getpos = function() getpos = backends.codeinjections.getpos return getpos () end
local gethpos = function() gethpos = backends.codeinjections.gethpos return gethpos() end
local getvpos = function() getvpos = backends.codeinjections.getvpos return getvpos() end
local function setdim(name,w,h,d,extra) -- will be used when we move to sp allover
local x, y = getpos()
if x == 0 then x = nil end
if y == 0 then y = nil end
if w == 0 then w = nil end
if h == 0 then h = nil end
if d == 0 then d = nil end
if extra == "" then extra = nil end
-- todo: sparse
tobesaved[name] = {
p = texgetcount("realpageno"),
x = x,
y = y,
w = w,
h = h,
d = d,
e = extra,
r = region,
c = column,
}
end
local function setall(name,p,x,y,w,h,d,extra)
if x == 0 then x = nil end
if y == 0 then y = nil end
if w == 0 then w = nil end
if h == 0 then h = nil end
if d == 0 then d = nil end
if extra == "" then extra = nil end
-- todo: sparse
tobesaved[name] = {
p = p,
x = x,
y = y,
w = w,
h = h,
d = d,
e = extra,
r = region,
c = column,
}
end
local function enhance(data)
if not data then
return nil
end
if data.r == true then -- or ""
data.r = region
end
if data.x == true then
if data.y == true then
data.x, data.y = getpos()
else
data.x = gethpos()
end
elseif data.y == true then
data.y = getvpos()
end
if data.p == true then
data.p = texgetcount("realpageno")
end
if data.c == true then
data.c = column
end
if data.w == 0 then
data.w = nil
end
if data.h == 0 then
data.h = nil
end
if data.d == 0 then
data.d = nil
end
return data
end
-- analyze some files (with lots if margindata) and then when one key optionally
-- use that one instead of a table (so, a 3rd / 4th argument: key, e.g. "x")
local function set(name,index,val) -- ,key
local data = enhance(val or index)
if val then
-- if data[key] and not next(next(data)) then
-- data = data[key]
-- end
container = tobesaved[name]
if not container then
tobesaved[name] = {
[index] = data
}
else
container[index] = data
end
else
tobesaved[name] = data
end
end
local function get(id,index)
if index then
local container = collected[id]
return container and container[index]
else
return collected[id]
end
end
jobpositions.setdim = setdim
jobpositions.setall = setall
jobpositions.set = set
jobpositions.get = get
-- scanners.setpos = setall
-- trackers.enable("tokens.compi*")
-- something weird: the compiler fails us here
scanners.dosaveposition = compilescanner {
actions = setall, -- name p x y
arguments = { "string", "integer", "dimen", "dimen" }
}
scanners.dosavepositionwhd = compilescanner { -- somehow fails
actions = setall, -- name p x y w h d
arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen" }
}
scanners.dosavepositionplus = compilescanner {
actions = setall, -- name p x y w h d extra
arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen", "string" }
}
-- will become private table (could also become attribute driven but too nasty
-- as attributes can bleed e.g. in margin stuff)
-- not much gain in keeping stack (inc/dec instead of insert/remove)
function jobpositions.b_col(tag)
tobesaved[tag] = {
r = true,
x = gethpos(),
w = 0,
}
insert(columns,tag)
column = tag
end
function jobpositions.e_col(tag)
local t = tobesaved[column]
if not t then
-- something's wrong
else
t.w = gethpos() - t.x
t.r = region
end
remove(columns)
column = columns[#columns]
end
scanners.bposcolumn = function() -- tag
local tag = scanstring()
insert(columns,tag)
column = tag
end
scanners.bposcolumnregistered = function() -- tag
local tag = scanstring()
insert(columns,tag)
column = tag
context(new_latelua_node(f_b_column(tag)))
end
scanners.eposcolumn = function()
remove(columns)
column = columns[#columns]
end
scanners.eposcolumnregistered = function()
context(new_latelua_node(f_e_column()))
remove(columns)
column = columns[#columns]
end
-- regions
function jobpositions.b_region(tag)
local last = tobesaved[tag]
last.x, last.y = getpos()
last.p = texgetcount("realpageno")
insert(regions,tag)
region = tag
end
function jobpositions.e_region(correct)
local last = tobesaved[region]
local v = getvpos()
if correct then
last.h = last.y - v
end
last.y = v
remove(regions)
region = regions[#regions]
end
local function setregionbox(n,tag)
if not tag or tag == "" then
nofregions = nofregions + 1
tag = f_region(nofregions)
end
local box = getbox(n)
local w = getfield(box,"width")
local h = getfield(box,"height")
local d = getfield(box,"depth")
tobesaved[tag] = {
p = true,
x = true,
y = getvpos(), -- true,
w = w ~= 0 and w or nil,
h = h ~= 0 and h or nil,
d = d ~= 0 and d or nil,
}
return tag, box
end
local function markregionbox(n,tag,correct)
local tag, box = setregionbox(n,tag)
local push = new_latelua(f_b_region(tag))
local pop = new_latelua(f_e_region(tostring(correct))) -- todo: check if tostring is needed with formatter
-- maybe we should construct a hbox first (needs experimenting) so that we can avoid some at the tex end
local head = getlist(box)
if head then
local tail = find_tail(head)
setfield(head,"prev",push)
setfield(push,"next",head)
setfield(pop,"prev",tail)
setfield(tail,"next",pop)
else -- we can have a simple push/pop
setfield(push,"next",pop)
setfield(pop,"prev",push)
end
setfield(box,"list",push)
end
jobpositions.markregionbox = markregionbox
jobpositions.setregionbox = setregionbox
function jobpositions.enhance(name)
enhance(tobesaved[name])
end
-- scanners.pos = function(name,t) -- name t
-- local name = scanstring()
-- tobesaved[name] = scanstring()
-- context(new_latelua_node(f_enhance(name)))
-- end
local nofparagraphs = 0
scanners.parpos = function() -- todo: relate to localpar (so this is an intermediate variant)
nofparagraphs = nofparagraphs + 1
texsetcount("global","c_anch_positions_paragraph",nofparagraphs)
local strutbox = getbox("strutbox")
local t = {
p = true,
c = true,
r = true,
x = true,
y = true,
h = getfield(strutbox,"height"),
d = getfield(strutbox,"depth"),
hs = texget("hsize"),
}
local leftskip = getfield(getskip("leftskip"),"width")
local rightskip = getfield(getskip("rightskip"),"width")
local hangindent = texget("hangindent")
local hangafter = texget("hangafter")
local parindent = texget("parindent")
local parshape = texget("parshape")
if leftskip ~= 0 then
t.ls = leftskip
end
if rightskip ~= 0 then
t.rs = rightskip
end
if hangindent ~= 0 then
t.hi = hangindent
end
if hangafter ~= 1 and hangafter ~= 0 then -- can not be zero .. so it needs to be 1 if zero
t.ha = hangafter
end
if parindent ~= 0 then
t.pi = parindent
end
if parshape and #parshape > 0 then
t.ps = parshape
end
local tag = f_p_tag(nofparagraphs)
tobesaved[tag] = t
context(new_latelua_node(f_enhance(tag)))
end
scanners.dosetposition = function() -- name
local name = scanstring()
tobesaved[name] = {
p = true,
c = column,
r = true,
x = true,
y = true,
n = nofparagraphs > 0 and nofparagraphs or nil,
}
context(new_latelua_node(f_enhance(name)))
end
scanners.dosetpositionwhd = function() -- name w h d extra
local name = scanstring()
tobesaved[name] = {
p = true,
c = column,
r = true,
x = true,
y = true,
w = scandimen(),
h = scandimen(),
d = scandimen(),
n = nofparagraphs > 0 and nofparagraphs or nil,
}
context(new_latelua_node(f_enhance(name)))
end
scanners.dosetpositionbox = function() -- name box
local name = scanstring()
local box = getbox(scaninteger())
tobesaved[name] = {
p = true,
c = column,
r = true,
x = true,
y = true,
w = getfield(box,"width"),
h = getfield(box,"height"),
d = getfield(box,"depth"),
n = nofparagraphs > 0 and nofparagraphs or nil,
}
context(new_latelua_node(f_enhance(name)))
end
scanners.dosetpositionplus = function() -- name w h d extra
local name = scanstring()
tobesaved[name] = {
p = true,
c = column,
r = true,
x = true,
y = true,
w = scandimen(),
h = scandimen(),
d = scandimen(),
n = nofparagraphs > 0 and nofparagraphs or nil,
e = scanstring(),
}
context(new_latelua_node(f_enhance(name)))
end
scanners.dosetpositionstrut = function() -- name
local name = scanstring()
local strutbox = getbox("strutbox")
tobesaved[name] = {
p = true,
c = column,
r = true,
x = true,
y = true,
h = getfield(strutbox,"height"),
d = getfield(strutbox,"depth"),
n = nofparagraphs > 0 and nofparagraphs or nil,
}
context(new_latelua_node(f_enhance(name)))
end
function jobpositions.getreserved(tag,n)
if tag == v_column then
local fulltag = f_tag_three(tag,texgetcount("realpageno"),n or 1)
local data = collected[fulltag]
if data then
return data, fulltag
end
tag = v_text
end
if tag == v_text then
local fulltag = f_tag_two(tag,texgetcount("realpageno"))
return collected[fulltag] or false, fulltag
end
return collected[tag] or false, tag
end
function jobpositions.copy(target,source)
collected[target] = collected[source]
end
function jobpositions.replace(id,p,x,y,w,h,d)
collected[id] = { p = p, x = x, y = y, w = w, h = h, d = d } -- c g
end
function jobpositions.page(id)
local jpi = collected[id]
return jpi and jpi.p
end
function jobpositions.region(id)
local jpi = collected[id]
if jpi then
local r = jpi.r
if r then
return r
end
local p = jpi.p
if p then
return "page:" .. p
end
end
return false
end
function jobpositions.column(id)
local jpi = collected[id]
return jpi and jpi.c or false
end
function jobpositions.paragraph(id)
local jpi = collected[id]
return jpi and jpi.n
end
jobpositions.p = jobpositions.page
jobpositions.r = jobpositions.region
jobpositions.c = jobpositions.column
jobpositions.n = jobpositions.paragraph
function jobpositions.x(id)
local jpi = collected[id]
return jpi and jpi.x
end
function jobpositions.y(id)
local jpi = collected[id]
return jpi and jpi.y
end
function jobpositions.width(id)
local jpi = collected[id]
return jpi and jpi.w
end
function jobpositions.height(id)
local jpi = collected[id]
return jpi and jpi.h
end
function jobpositions.depth(id)
local jpi = collected[id]
return jpi and jpi.d
end
function jobpositions.leftskip(id)
local jpi = collected[id]
return jpi and jpi.ls
end
function jobpositions.rightskip(id)
local jpi = collected[id]
return jpi and jpi.rs
end
function jobpositions.hsize(id)
local jpi = collected[id]
return jpi and jpi.hs
end
function jobpositions.parindent(id)
local jpi = collected[id]
return jpi and jpi.pi
end
function jobpositions.hangindent(id)
local jpi = collected[id]
return jpi and jpi.hi
end
function jobpositions.hangafter(id)
local jpi = collected[id]
return jpi and jpi.ha or 1
end
function jobpositions.xy(id)
local jpi = collected[id]
if jpi then
return jpi.x, jpi.y
else
return 0, 0
end
end
function jobpositions.lowerleft(id)
local jpi = collected[id]
if jpi then
return jpi.x, jpi.y - jpi.d
else
return 0, 0
end
end
function jobpositions.lowerright(id)
local jpi = collected[id]
if jpi then
return jpi.x + jpi.w, jpi.y - jpi.d
else
return 0, 0
end
end
function jobpositions.upperright(id)
local jpi = collected[id]
if jpi then
return jpi.x + jpi.w, jpi.y + jpi.h
else
return 0, 0
end
end
function jobpositions.upperleft(id)
local jpi = collected[id]
if jpi then
return jpi.x, jpi.y + jpi.h
else
return 0, 0
end
end
function jobpositions.position(id)
local jpi = collected[id]
if jpi then
return jpi.p, jpi.x, jpi.y, jpi.w, jpi.h, jpi.d
else
return 0, 0, 0, 0, 0, 0
end
end
function jobpositions.extra(id,n,default) -- assume numbers
local jpi = collected[id]
if jpi then
local e = jpi.e
if e then
local split = jpi.split
if not split then
split = lpegmatch(splitter,jpi.e)
jpi.split = split
end
return texsp(split[n]) or default -- watch the texsp here
end
end
return default
end
local function overlapping(one,two,overlappingmargin) -- hm, strings so this is wrong .. texsp
one = collected[one]
two = collected[two]
if one and two and one.p == two.p then
if not overlappingmargin then
overlappingmargin = 2
end
local x_one = one.x
local x_two = two.x
local w_two = two.w
local llx_one = x_one - overlappingmargin
local urx_two = x_two + w_two + overlappingmargin
if llx_one > urx_two then
return false
end
local w_one = one.w
local urx_one = x_one + w_one + overlappingmargin
local llx_two = x_two - overlappingmargin
if urx_one < llx_two then
return false
end
local y_one = one.y
local y_two = two.y
local d_one = one.d
local h_two = two.h
local lly_one = y_one - d_one - overlappingmargin
local ury_two = y_two + h_two + overlappingmargin
if lly_one > ury_two then
return false
end
local h_one = one.h
local d_two = two.d
local ury_one = y_one + h_one + overlappingmargin
local lly_two = y_two - d_two - overlappingmargin
if ury_one < lly_two then
return false
end
return true
end
end
local function onsamepage(list,page)
for id in gmatch(list,"(, )") do
local jpi = collected[id]
if jpi then
local p = jpi.p
if not p then
return false
elseif not page then
page = p
elseif page ~= p then
return false
end
end
end
return page
end
jobpositions.overlapping = overlapping
jobpositions.onsamepage = onsamepage
-- interface
scanners.replacepospxywhd = function() -- name page x y w h d
collected[scanstring()] = {
p = scaninteger(),
x = scandimen(),
y = scandimen(),
w = scandimen(),
h = scandimen(),
d = scandimen(),
}
end
scanners.copyposition = function() -- target source
collected[scanstring()] = collected[scanstring()]
end
scanners.MPp = function() -- name
local jpi = collected[scanstring()]
if jpi then
local p = jpi.p
if p and p ~= true then
context(p)
return
end
end
context('0')
end
scanners.MPx = function() -- name
local jpi = collected[scanstring()]
if jpi then
local x = jpi.x
if x and x ~= true and x ~= 0 then
context("%.5Fpt",x*pt)
return
end
end
context('0pt')
end
scanners.MPy = function() -- name
local jpi = collected[scanstring()]
if jpi then
local y = jpi.y
if y and y ~= true and y ~= 0 then
context("%.5Fpt",y*pt)
return
end
end
context('0pt')
end
scanners.MPw = function() -- name
local jpi = collected[scanstring()]
if jpi then
local w = jpi.w
if w and w ~= 0 then
context("%.5Fpt",w*pt)
return
end
end
context('0pt')
end
scanners.MPh = function() -- name
local jpi = collected[scanstring()]
if jpi then
local h = jpi.h
if h and h ~= 0 then
context("%.5Fpt",h*pt)
return
end
end
context('0pt')
end
scanners.MPd = function() -- name
local jpi = collected[scanstring()]
if jpi then
local d = jpi.d
if d and d ~= 0 then
context("%.5Fpt",d*pt)
return
end
end
context('0pt')
end
scanners.MPxy = function() -- name
local jpi = collected[scanstring()]
if jpi then
context('(%.5Fpt,%.5Fpt)',
jpi.x*pt,
jpi.y*pt
)
else
context('(0,0)')
end
end
scanners.MPll = function() -- name
local jpi = collected[scanstring()]
if jpi then
context('(%.5Fpt,%.5Fpt)',
jpi.x *pt,
(jpi.y-jpi.d)*pt
)
else
context('(0,0)') -- for mp only
end
end
scanners.MPlr = function() -- name
local jpi = collected[scanstring()]
if jpi then
context('(%.5Fpt,%.5Fpt)',
(jpi.x + jpi.w)*pt,
(jpi.y - jpi.d)*pt
)
else
context('(0,0)') -- for mp only
end
end
scanners.MPur = function() -- name
local jpi = collected[scanstring()]
if jpi then
context('(%.5Fpt,%.5Fpt)',
(jpi.x + jpi.w)*pt,
(jpi.y + jpi.h)*pt
)
else
context('(0,0)') -- for mp only
end
end
scanners.MPul = function() -- name
local jpi = collected[scanstring()]
if jpi then
context('(%.5Fpt,%.5Fpt)',
jpi.x *pt,
(jpi.y + jpi.h)*pt
)
else
context('(0,0)') -- for mp only
end
end
local function MPpos(id)
local jpi = collected[id]
if jpi then
local p = jpi.p
if p then
context("%s,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt",
p,
jpi.x*pt,
jpi.y*pt,
jpi.w*pt,
jpi.h*pt,
jpi.d*pt
)
return
end
end
context('0,0,0,0,0,0') -- for mp only
end
scanners.MPpos = function() -- name
MPpos(scanstring())
end
scanners.MPn = function() -- name
local jpi = collected[scanstring()]
if jpi then
local n = jpi.n
if n then
context(n)
return
end
end
context(0)
end
scanners.MPc = function() -- name
local jpi = collected[scanstring()]
if jpi then
local c = jpi.c
if c and c ~= true then
context(c)
return
end
end
context('0') -- okay ?
end
scanners.MPr = function() -- name
local jpi = collected[scanstring()]
if jpi then
local r = jpi.r
if r and r ~= true then
context(r)
end
local p = jpi.p
if p then
context("page:" .. p)
end
end
end
local function MPpardata(n)
local t = collected[n]
if not t then
local tag = f_p_tag(n)
t = collected[tag]
end
if t then
context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%s,%.5Fpt",
t.hs*pt,
t.ls*pt,
t.rs*pt,
t.hi*pt,
t.ha,
t.pi*pt
)
else
context("0,0,0,0,0,0") -- for mp only
end
end
scanners.MPpardata = function() -- name
MPpardata(scanstring())
end
scanners.MPposset = function() -- name (special helper, used in backgrounds)
local name = scanstring()
local b = f_b_tag(name)
local e = f_e_tag(name)
local w = f_w_tag(name)
local p = f_p_tag(jobpositions.n(b))
MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p)
end
scanners.MPls = function() -- name
local jpi = collected[scanstring()]
if jpi then
context("%.5Fpt",jpi.ls*pt)
else
context("0pt")
end
end
scanners.MPrs = function() -- name
local jpi = collected[scanstring()]
if jpi then
context("%.5Fpt",jpi.rs*pt)
else
context("0pt")
end
end
local splitter = lpeg.tsplitat(",")
scanners.MPplus = function() -- name n default
local jpi = collected[scanstring()]
local n = scaninteger()
local default = scanstring()
if jpi then
local e = jpi.e
if e then
local split = jpi.split
if not split then
split = lpegmatch(splitter,jpi.e)
jpi.split = split
end
context(split[n] or default)
return
end
end
context(default)
end
scanners.MPrest = function() -- name default
local jpi = collected[scanstring()]
local default = scanstring()
context(jpi and jpi.e or default)
end
scanners.MPxywhd = function() -- name
local jpi = collected[scanstring()]
if jpi then
context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt",
jpi.x*pt,
jpi.y*pt,
jpi.w*pt,
jpi.h*pt,
jpi.d*pt
)
else
context("0,0,0,0,0") -- for mp only
end
end
local doif = commands.doif
local doifelse = commands.doifelse
scanners.doifelseposition = function() -- name
doifelse(collected[scanstring()])
end
scanners.doifposition = function() -- name
doif(collected[scanstring()])
end
scanners.doifelsepositiononpage = function() -- name page -- probably always realpageno
local c = collected[scanstring()]
local p = scaninteger()
doifelse(c and c.p == p)
end
scanners.doifelseoverlapping = function() -- one two
doifelse(overlapping(scanstring(),scanstring()))
end
scanners.doifelsepositionsonsamepage = function() -- list
doifelse(onsamepage(scanstring()))
end
scanners.doifelsepositionsonthispage = function() -- list
doifelse(onsamepage(scanstring(),tostring(texgetcount("realpageno"))))
end
scanners.doifelsepositionsused = function()
doifelse(next(collected))
end
scanners.markregionbox = function() -- box
markregionbox(scaninteger())
end
scanners.setregionbox = function() -- box
setregionbox(scaninteger())
end
scanners.markregionboxtagged = function() -- box tag
markregionbox(scaninteger(),scanstring())
end
scanners.setregionboxtagged = function() -- box tag
setregionbox(scaninteger(),scanstring())
end
scanners.markregionboxcorrected = function() -- box tag
markregionbox(scaninteger(),scanstring(),true)
end
-- statistics (at least for the moment, when testing)
statistics.register("positions", function()
local total = nofregular + nofusedregions + nofmissingregions
if total > 0 then
return format("%s collected, %s regulars, %s regions, %s unresolved regions",
total, nofregular, nofusedregions, nofmissingregions)
else
return nil
end
end)