summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua217
1 files changed, 95 insertions, 122 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua b/Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua
index a0d2eee2c8e..2788c9d1a55 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/anch-pos.lua
@@ -24,10 +24,9 @@ more efficient.</p>
-- we need virtual table accessors as well as have tag/id accessors ... we don't
-- save much here (at least not now)
-local tostring, next, rawget, rawset, setmetatable, tonumber = tostring, next, rawget, rawset, setmetatable, tonumber
+local tostring, next, setmetatable, tonumber = tostring, next, setmetatable, tonumber
local sort = table.sort
local format, gmatch = string.format, string.gmatch
-local rawget = rawget
local lpegmatch = lpeg.match
local insert, remove = table.insert, table.remove
local allocate = utilities.storage.allocate
@@ -54,8 +53,6 @@ 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 setmetatablenewindex = table.setmetatablenewindex
@@ -71,7 +68,7 @@ local getwhd = nuts.getwhd
local hlist_code = nodes.nodecodes.hlist
local find_tail = nuts.tail
-local hpack = nuts.hpack
+----- hpack = nuts.hpack
local new_latelua = nuts.pool.latelua
@@ -123,17 +120,17 @@ local f_region = formatters["region:%s"]
local f_tag_three = formatters["%s:%s:%s"]
local f_tag_two = formatters["%s:%s"]
-jobpositions.used = false
-
local nofregular = 0
local nofspecial = 0
local splitter = lpeg.splitat(":",true)
+local pagedata = { }
+local columndata = setmetatableindex("table") -- per page
+local freedata = setmetatableindex("table") -- per page
+
local function initializer()
tobesaved = jobpositions.tobesaved
collected = jobpositions.collected
- local pagedata = { }
- local freedata = setmetatableindex("table")
for tag, data in next, collected do
local prefix, rest = lpegmatch(splitter,tag)
if prefix == "p" then
@@ -145,6 +142,8 @@ local function initializer()
nofspecial = nofspecial + 1
local t = freedata[data.p or 0]
t[#t+1] = data
+ elseif prefix == "columnarea" then
+ columndata[data.p or 0][data.c or 0] = data
end
setmetatable(data,default)
end
@@ -173,101 +172,23 @@ local function initializer()
end
end
end
- jobpositions.page = pagedata
- jobpositions.free = freedata
- jobpositions.used = next(collected)
+ jobpositions.pagedata = pagedata
end
--- -- we can gain a little when we group positions but then we still have to
--- -- deal with regions and cells so we either end up with lots of extra small
--- -- tables pointing to them and/or assembling/disassembling so in the end
--- -- it makes no sense to do it (now) and still have such a mix
---
--- local splitter = lpeg.splitat(":",true)
---
--- local function setpos(t,k,v)
--- local class, tag = lpegmatch(splitter,k)
--- if tag then
--- local c = rawget(t,class)
--- if c then
--- c[tonumber(tag) or tag] = v
--- else
--- rawset(t,class,{ [tonumber(tag) or tag] = v })
--- end
--- else
--- t.default[tonumber(k) or k] = v
--- end
--- end
---
--- local function getpos(t,k)
--- local class, tag = lpegmatch(splitter,k)
--- if tag then
--- local c = rawget(t,class)
--- if c then
--- return c[tonumber(tag) or tag]
--- end
--- else
--- return c.default[tonumber(k) or k]
--- end
--- end
---
--- tobesaved.default = tobesaved.default or { }
--- setmetatablenewindex(tobesaved,setpos)
--- setmetatableindex (tobesaved,getpos)
---
--- local function initializer()
--- tobesaved = jobpositions.tobesaved
--- collected = jobpositions.collected
---
--- tobesaved.default = tobesaved.default or { }
--- collected.default = collected.default or { }
---
--- setmetatablenewindex(tobesaved,setpos)
--- setmetatableindex (collected,getpos)
--- setmetatableindex (tobesaved,getpos)
---
--- for class, list in next, collected do
--- for tag, data in next, list do
--- setmetatable(data,default)
--- nofregular = nofregular + 1
--- end
--- end
---
--- local pagedata = collected.page or { }
--- local freedata = setmetatableindex("table")
---
--- for tag, data in next, collected.free or { } do
--- local t = freedata[data.p or 0]
--- t[#t+1] = data
--- end
---
--- local pages = structures.pages.collected
--- if pages then
--- local last = nil
--- for p=1,#pages do
--- local data = pagedata[p]
--- local free = freedata[p]
--- if free then
--- sort(free,function(a,b) return b.y < a.y end) -- order matters !
--- end
--- if data then
--- last = data
--- last.free = free
--- elseif last then
--- local t = setmetatableindex({ free = free, p = p },last)
--- if not pagedata[p] then
--- pagedata[p] = t
--- end
--- end
--- end
--- end
--- jobpositions.page = pagedata
--- jobpositions.free = freedata
--- jobpositions.used = next(collected)
--- end
+function jobpositions.used()
+ return next(collected) -- we can safe it
+end
+
+function jobpositions.getfree(page)
+ return freedata[page]
+end
+
+-- we can gain a little when we group positions but then we still have to
+-- deal with regions and cells so we either end up with lots of extra small
+-- tables pointing to them and/or assembling/disassembling so in the end
+-- it makes no sense to do it (now) and still have such a mix
--
--- function jobpositions.getcollected(class,tag) if tag then return collected[class..tag] else return collected[class] end end
--- function jobpositions.gettobesaved(class,tag) if tag then return tobesaved[class..tag] else return tobesaved[class] end end
+-- proof of concept code removed ... see archive
local function finalizer()
-- We make the (possible extensive) shape lists sparse working
@@ -334,14 +255,18 @@ local getpos, gethpos, getvpos
function jobpositions.registerhandlers(t)
getpos = t and t.getpos or function() return 0, 0 end
- gethpos = t and t.gethpos or function() return 0 end
- getvpos = t and t.getvpos or function() return 0 end
+ getrpos = t and t.getrpos or function() return 0, 0, 0 end
+ gethpos = t and t.gethpos or function() return 0 end
+ getvpos = t and t.getvpos or function() return 0 end
end
function jobpositions.getpos () return getpos () end
+function jobpositions.getrpos() return getrpos() end
function jobpositions.gethpos() return gethpos() end
function jobpositions.getvpos() return getvpos() end
+-------- jobpositions.getcolumn() return column end
+
jobpositions.registerhandlers()
local function setall(name,p,x,y,w,h,d,extra)
@@ -401,7 +326,8 @@ end
-- use that one instead of a table (so, a 3rd / 4th argument: key, e.g. "x")
local function set(name,index,value) -- ,key
- local data = enhance(tobesaved[value or index])
+ -- officially there should have been a settobesaved
+ local data = enhance(value or {})
if value then
container = tobesaved[name]
if not container then
@@ -420,7 +346,7 @@ local function setspec(specification)
local name = specification.name
local index = specification.index
local value = specification.value
- local data = enhance(tobesaved[value or index])
+ local data = enhance(value or {})
if value then
container = tobesaved[name]
if not container then
@@ -553,7 +479,7 @@ jobpositions.e_region = e_region
local lastregion
-local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind
+local function setregionbox(n,tag,k,lo,ro,to,bo,column) -- kind
if not tag or tag == "" then
nofregions = nofregions + 1
tag = f_region(nofregions)
@@ -572,6 +498,7 @@ local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind
ro = ro ~= 0 and ro or nil,
to = to ~= 0 and to or nil,
bo = bo ~= 0 and bo or nil,
+ c = column or nil,
}
lastregion = tag
return tag, box
@@ -615,6 +542,13 @@ function jobpositions.gettobesaved(name,tag)
end
end
+function jobpositions.settobesaved(name,tag,data)
+ local t = tobesaved[name]
+ if t and tag and data then
+ t[tag] = data
+ end
+end
+
local nofparagraphs = 0
scanners.parpos = function()
@@ -803,12 +737,22 @@ 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 function getpage(id)
local jpi = collected[id]
return jpi and jpi.p
end
-function jobpositions.region(id)
+local function getcolumn(id)
+ local jpi = collected[id]
+ return jpi and jpi.c or false
+end
+
+local function getparagraph(id)
+ local jpi = collected[id]
+ return jpi and jpi.n
+end
+
+local function getregion(id)
local jpi = collected[id]
if jpi then
local r = jpi.r
@@ -823,20 +767,15 @@ function jobpositions.region(id)
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.page = getpage
+jobpositions.column = getcolumn
+jobpositions.paragraph = getparagraph
+jobpositions.region = getregion
-jobpositions.p = jobpositions.page
-jobpositions.r = jobpositions.region
-jobpositions.c = jobpositions.column
-jobpositions.n = jobpositions.paragraph
+jobpositions.p = getpage -- not used, kind of obsolete
+jobpositions.c = getcolumn -- idem
+jobpositions.n = getparagraph -- idem
+jobpositions.r = getregion -- idem
function jobpositions.x(id)
local jpi = collected[id]
@@ -1030,8 +969,24 @@ local function onsamepage(list,page)
return page
end
+local function columnofpos(realpage,xposition)
+ local p = columndata[realpage]
+ if p then
+ for i=1,#p do
+ local c = p[i]
+ local x = c.x or 0
+ local w = c.w or 0
+ if xposition >= x and xposition <= (x + w) then
+ return i
+ end
+ end
+ end
+ return 1
+end
+
jobpositions.overlapping = overlapping
jobpositions.onsamepage = onsamepage
+jobpositions.columnofpos = columnofpos
-- interface
@@ -1287,7 +1242,7 @@ scanners.MPposset = function() -- name (special helper, used in backgrounds)
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))
+ local p = f_p_tag(getparagraph(b))
MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p)
end
@@ -1387,6 +1342,10 @@ scanners.doifelsepositionsonthispage = function() -- list
doifelse(onsamepage(scanstring(),tostring(texgetcount("realpageno"))))
end
+-- scanners.columnofpos = function()
+-- context(columnofpos(scaninteger(),scandimen())
+-- end
+
scanners.doifelsepositionsused = function()
doifelse(next(collected))
end
@@ -1403,6 +1362,11 @@ scanners.markregionboxtagged = function() -- box tag
markregionbox(scaninteger(),scanstring())
end
+scanners.markregionboxtaggedn = function() -- box tag n
+ markregionbox(scaninteger(),scanstring(),nil,
+ nil,nil,nil,nil,nil,scaninteger())
+end
+
scanners.setregionboxtagged = function() -- box tag
setregionbox(scaninteger(),scanstring())
end
@@ -1441,3 +1405,12 @@ statistics.register("positions", function()
return nil
end
end)
+
+-- We support the low level positional commands too:
+
+local newsavepos = nodes.pool.savepos
+local implement = interfaces.implement
+
+implement { name = "savepos", actions = function() context(newsavepos()) end }
+implement { name = "lastxpos", actions = function() context(gethpos()) end }
+implement { name = "lastypos", actions = function() context(getvpos()) end }