summaryrefslogtreecommitdiff
path: root/tex/context/base/anch-pos.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/anch-pos.lua')
-rw-r--r--tex/context/base/anch-pos.lua271
1 files changed, 231 insertions, 40 deletions
diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua
index 1e40bbc7b..132ad32c7 100644
--- a/tex/context/base/anch-pos.lua
+++ b/tex/context/base/anch-pos.lua
@@ -12,9 +12,15 @@ can we store much more information in <l n='lua'/> but it's also
more efficient.</p>
--ldx]]--
-local concat, format = table.concat, string.format
+-- to be considered: store as numbers instead of string
+-- maybe replace texsp by our own converter (stay at the lua end)
+
+local tostring = tostring
+local concat, format, gmatch = table.concat, string.format, string.gmatch
local lpegmatch = lpeg.match
local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local texsp = tex.sp
+----- texsp = string.todimen -- because we cache this is much faster but no rounding
local collected, tobesaved = allocate(), allocate()
@@ -27,7 +33,7 @@ job.positions = jobpositions
_ptbs_, _pcol_ = tobesaved, collected -- global
-local dx, dy = "0pt", "0pt"
+local dx, dy, nx, ny = "0pt", "0pt", 0, 0
local function initializer()
tobesaved = mark(jobpositions.tobesaved)
@@ -35,8 +41,8 @@ local function initializer()
_ptbs_, _pcol_ = tobesaved, collected -- global
local p = collected["page:0"] -- page:1
if p then
--- to be checked !
---~ dx, dy = p[2] or "0pt", p[3] or "0pt"
+ -- dx, nx = p[2] or "0pt", 0
+ -- dy, ny = p[3] or "0pt", 0
end
end
@@ -52,49 +58,239 @@ end
function jobpositions.page(id)
local jpi = collected[id] or tobesaved[id]
- context(jpi and jpi[1] or '0')
+ if jpi then
+ return texsp(jpi[1])
+ else
+ return 0
+ end
+end
+
+function jobpositions.x(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[2]) - nx
+ else
+ return 0
+ end
+end
+
+function jobpositions.y(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[3]) - ny
+ else
+ return 0
+ end
end
function jobpositions.width(id)
local jpi = collected[id] or tobesaved[id]
- context(jpi and jpi[4] or '0pt')
+ if jpi then
+ return texsp(jpi[4])
+ else
+ return 0
+ end
end
function jobpositions.height(id)
local jpi = collected[id] or tobesaved[id]
- context(jpi and jpi[5] or '0pt')
+ if jpi then
+ return texsp(jpi[5])
+ else
+ return 0
+ end
end
function jobpositions.depth(id)
local jpi = collected[id] or tobesaved[id]
- context(jpi and jpi[6] or '0pt')
+ if jpi then
+ return texsp(jpi[6])
+ else
+ return 0
+ end
end
-function jobpositions.x(id)
+function jobpositions.xy(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[2]) - nx, texsp(jpi[3]) - ny
+ else
+ return 0, 0
+ end
+end
+
+function jobpositions.lowerleft(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[2]) - nx, texsp(jpi[3]) - texsp(jpi[6]) - ny
+ else
+ return 0, 0
+ end
+end
+
+function jobpositions.lowerright(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[2]) + texsp(jpi[4]) - nx, texsp(jpi[3]) - texsp(jpi[6]) - ny
+ else
+ return 0, 0
+ end
+end
+
+function jobpositions.upperright(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[2]) + texsp(jpi[4]) - nx, texsp(jpi[3]) + texsp(jpi[5]) - ny
+ else
+ return 0, 0
+ end
+end
+
+function jobpositions.upperleft(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[2]) - nx, texsp(jpi[3]) + texsp(jpi[5]) - ny
+ else
+ return 0, 0
+ end
+end
+
+function jobpositions.position(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[1]), texsp(jpi[2]), texsp(jpi[3]), texsp(jpi[4]), texsp(jpi[5]), texsp(jpi[6])
+ else
+ return 0, 0, 0, 0, 0, 0
+ end
+end
+
+function jobpositions.extra(id,n,default) -- assume numbers
+ local jpi = collected[id] or tobesaved[id]
+ if not jpi then
+ return default
+ else
+ local split = jpi[0]
+ if not split then
+ split = lpegmatch(splitter,jpi[7])
+ jpi[0] = split
+ end
+ return texsp(split[n]) or default
+ end
+end
+
+local function overlapping(one,two,overlappingmargin)
+ one = collected[one] or tobesaved[one]
+ two = collected[two] or tobesaved[two]
+ if one and two and one[1] == two[1] then
+ if not overlappingmargin then
+ overlappingmargin = 2
+ end
+ local x_one = one[2]
+ local x_two = two[2]
+ local w_two = two[4]
+ 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[4]
+ 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[3]
+ local y_two = two[3]
+ local d_one = one[6]
+ local h_two = two[5]
+ 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[5]
+ local d_two = two[6]
+ 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] or tobesaved[id]
+ if jpi then
+ local p = jpi[1]
+ if not page then
+ page = p
+ elseif page ~= p then
+ return false
+ end
+ end
+ end
+ return page
+end
+
+jobpositions.overlapping = overlapping
+jobpositions.onsamepage = onsamepage
+
+-- interface
+
+commands.replacepospxywhd = jobpositions.replace
+commands.copyposition = jobpositions.copy
+
+function commands.MPp(id)
+ local jpi = collected[id] or tobesaved[id]
+ context(jpi and jpi[1] or '0')
+end
+
+function commands.MPx(id)
local jpi = collected[id] or tobesaved[id]
local x = jpi and jpi[2]
if x then
- context('\\the\\dimexpr%s-%s\\relax',x,dx)
+ if nx == 0 then
+ context(x)
+ else
+ context('\\the\\dimexpr%s-%s\\relax',x,dx)
+ end
else
context('0pt')
end
end
-function jobpositions.y(id)
+function commands.MPy(id)
local jpi = collected[id] or tobesaved[id]
local y = jpi and jpi[3]
if y then
- context('\\the\\dimexpr%s-%s\\relax',y,dy)
+ if ny == 0 then
+ context(y)
+ else
+ context('\\the\\dimexpr%s-%s\\relax',y,dy)
+ end
else
context('0pt')
end
end
--- the following are only for MP so there we can leave out the pt
+function commands.MPw(id)
+ local jpi = collected[id] or tobesaved[id]
+ context(jpi and jpi[4] or '0pt')
+end
--- can be writes and no format needed any more
+function commands.MPh(id)
+ local jpi = collected[id] or tobesaved[id]
+ context(jpi and jpi[5] or '0pt')
+end
-function jobpositions.xy(id)
+function commands.MPd(id)
+ local jpi = collected[id] or tobesaved[id]
+ context(jpi and jpi[6] or '0pt')
+end
+
+function commands.MPxy(id)
local jpi = collected[id] or tobesaved[id]
if jpi then
context('(%s-%s,%s-%s)',jpi[2],dx,jpi[3],dy)
@@ -103,7 +299,7 @@ function jobpositions.xy(id)
end
end
-function jobpositions.lowerleft(id)
+function commands.MPll(id)
local jpi = collected[id] or tobesaved[id]
if jpi then
context('(%s-%s,%s-%s-%s)',jpi[2],dx,jpi[3],jpi[6],dy)
@@ -112,7 +308,7 @@ function jobpositions.lowerleft(id)
end
end
-function jobpositions.lowerright(id)
+function commands.MPlr(id)
local jpi = collected[id] or tobesaved[id]
if jpi then
context('(%s+%s-%s,%s-%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[6],dy)
@@ -121,7 +317,7 @@ function jobpositions.lowerright(id)
end
end
-function jobpositions.upperright(id)
+function commands.MPur(id)
local jpi = collected[id] or tobesaved[id]
if jpi then
context('(%s+%s-%s,%s+%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[5],dy)
@@ -130,7 +326,7 @@ function jobpositions.upperright(id)
end
end
-function jobpositions.upperleft(id)
+function commands.MPul(id)
local jpi = collected[id] or tobesaved[id]
if jpi then
context('(%s-%s,%s+%s-%s)',jpi[2],dx,jpi[3],jpi[5],dy)
@@ -139,7 +335,7 @@ function jobpositions.upperleft(id)
end
end
-function jobpositions.position(id)
+function commands.MPpos(id)
local jpi = collected[id] or tobesaved[id]
if jpi then
context(concat(jpi,',',1,6))
@@ -150,7 +346,7 @@ end
local splitter = lpeg.Ct(lpeg.splitat(","))
-function jobpositions.pardata(id,n,default)
+function commands.MPplus(id,n,default)
local jpi = collected[id] or tobesaved[id]
if not jpi then
context(default)
@@ -164,30 +360,25 @@ function jobpositions.pardata(id,n,default)
end
end
-function jobpositions.extradata(id,default)
+function commands.MPrest(id,default)
local jpi = collected[id] or tobesaved[id]
context(jpi and jpi[7] or default)
end
--- interface
-
-commands.replacepospxywhd = jobpositions.replace
-commands.copyposition = jobpositions.copy
-commands.MPp = jobpositions.page
-commands.MPx = jobpositions.x
-commands.MPy = jobpositions.y
-commands.MPw = jobpositions.width
-commands.MPh = jobpositions.height
-commands.MPd = jobpositions.depth
-commands.MPxy = jobpositions.xy
-commands.MPll = jobpositions.lowerleft
-commands.MPlr = jobpositions.lowerright
-commands.MPur = jobpositions.upperright
-commands.MPul = jobpositions.upperleft
-commands.MPpos = jobpositions.position
-commands.MPplus = jobpositions.pardata
-commands.MPrest = jobpositions.extradata
+-- is testcase already defined? if so, then local
function commands.doifpositionelse(name)
commands.testcase(collected[name] or tobesaved[name])
end
+
+function commands.doifoverlappingelse(one,two,overlappingmargin)
+ commands.testcase(overlapping(one,two,overlappingmargin))
+end
+
+function commands.doifpositionsonsamepageelse(list,page)
+ commands.testcase(onsamepage(list))
+end
+
+function commands.doifpositionsonthispageelse(list)
+ commands.testcase(onsamepage(list,tostring(tex.count.realpageno)))
+end