summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/anch-pos.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/anch-pos.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/anch-pos.lua368
1 files changed, 294 insertions, 74 deletions
diff --git a/Master/texmf-dist/tex/context/base/anch-pos.lua b/Master/texmf-dist/tex/context/base/anch-pos.lua
index 8066af4ceba..789e1aefe71 100644
--- a/Master/texmf-dist/tex/context/base/anch-pos.lua
+++ b/Master/texmf-dist/tex/context/base/anch-pos.lua
@@ -12,155 +12,375 @@ 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
-local texprint, ctxcatcodes = tex.print, tex.ctxcatcodes
+-- 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
-jobpositions = jobpositions or { }
-jobpositions.collected = jobpositions.collected or { }
-jobpositions.tobesaved = jobpositions.tobesaved or { }
+local collected = allocate()
+local tobesaved = allocate()
--- these are global since they are used often at the tex end
+local jobpositions = {
+ collected = collected,
+ tobesaved = tobesaved,
+}
--- \the\dimexpr #2\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax
--- \the\dimexpr #3\ifnum\positionanchormode=\plusone-\MPy\pageanchor\fi\relax
+job.positions = jobpositions
-ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -- global
+_ptbs_, _pcol_ = tobesaved, collected -- global
-local dx, dy = "0pt", "0pt"
+local dx, dy, nx, ny = "0pt", "0pt", 0, 0
local function initializer()
- ptbs, pcol = jobpositions.tobesaved, jobpositions.collected
- local p = pcol["page:0"] -- page:1
- if p then
--- to be checked !
---~ dx, dy = p[2] or "0pt", p[3] or "0pt"
- end
+ tobesaved = jobpositions.tobesaved
+ collected = jobpositions.collected
+ _ptbs_ = tobesaved -- global
+ _pcol_ = collected -- global
+ -- local p = collected["page:0"] -- page:1
+ -- if p then
+ -- dx, nx = p[2] or "0pt", 0
+ -- dy, ny = p[3] or "0pt", 0
+ -- end
end
-job.register('jobpositions.collected', jobpositions.tobesaved, initializer)
+job.register('job.positions.collected', tobesaved, initializer)
function jobpositions.copy(target,source)
- jobpositions.collected[target] = jobpositions.collected[source] or ptbs[source]
+ collected[target] = collected[source] or tobesaved[source]
end
function jobpositions.replace(name,...)
- jobpositions.collected[name] = {...}
+ collected[name] = {...}
+end
+
+function jobpositions.page(id)
+ local jpi = collected[id] or tobesaved[id]
+ 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.doifelse(name)
- commands.testcase(jobpositions.collected[name] or ptbs[name])
+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.MPp(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[1]) or '0' ) end
-function jobpositions.MPx(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[2]) or '0pt') end
-function jobpositions.MPy(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[3]) or '0pt') end
-function jobpositions.MPw(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[4]) or '0pt') end
-function jobpositions.MPh(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[5]) or '0pt') end
-function jobpositions.MPd(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[6]) or '0pt') end
+function jobpositions.width(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[4])
+ else
+ return 0
+ end
+end
+function jobpositions.height(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[5])
+ else
+ return 0
+ end
+end
-function jobpositions.MPx(id)
- local jpi = pcol[id] or ptbs[id]
+function jobpositions.depth(id)
+ local jpi = collected[id] or tobesaved[id]
+ if jpi then
+ return texsp(jpi[6])
+ else
+ return 0
+ end
+end
+
+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
- texprint(ctxcatcodes,format('\\the\\dimexpr%s-%s\\relax',x,dx)) -- no space after dimexpr !
+ if nx == 0 then
+ context(x)
+ else
+ context('\\the\\dimexpr%s-%s\\relax',x,dx)
+ end
else
- texprint(ctxcatcodes,'0pt')
+ context('0pt')
end
end
-function jobpositions.MPy(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPy(id)
+ local jpi = collected[id] or tobesaved[id]
local y = jpi and jpi[3]
if y then
- texprint(ctxcatcodes,format('\\the\\dimexpr%s-%s\\relax',y,dy)) -- no space after dimexpr !
+ if ny == 0 then
+ context(y)
+ else
+ context('\\the\\dimexpr%s-%s\\relax',y,dy)
+ end
else
- texprint(ctxcatcodes,'0pt')
+ 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 commands.MPd(id)
+ local jpi = collected[id] or tobesaved[id]
+ context(jpi and jpi[6] or '0pt')
+end
-function jobpositions.MPxy(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPxy(id)
+ local jpi = collected[id] or tobesaved[id]
if jpi then
- texprint(ctxcatcodes,format('(%s-%s,%s-%s)',jpi[2],dx,jpi[3],dy))
---~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'-',dy,')')
+ context('(%s-%s,%s-%s)',jpi[2],dx,jpi[3],dy)
else
- texprint(ctxcatcodes,'(0,0)')
+ context('(0,0)')
end
end
-function jobpositions.MPll(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPll(id)
+ local jpi = collected[id] or tobesaved[id]
if jpi then
- texprint(ctxcatcodes,format('(%s-%s,%s-%s-%s)',jpi[2],dx,jpi[3],jpi[6],dy))
---~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'-',jpi[6],'-',dy,')')
+ context('(%s-%s,%s-%s-%s)',jpi[2],dx,jpi[3],jpi[6],dy)
else
- texprint(ctxcatcodes,'(0,0)')
+ context('(0,0)')
end
end
-function jobpositions.MPlr(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPlr(id)
+ local jpi = collected[id] or tobesaved[id]
if jpi then
- texprint(ctxcatcodes,format('(%s+%s-%s,%s-%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[6],dy))
---~ texprint(ctxcatcodes,'(',jpi[2],'+',jpi[4],'-',dx,',',jpi[3],'-',jpi[6],'-',dy,')')
+ context('(%s+%s-%s,%s-%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[6],dy)
else
- texprint(ctxcatcodes,'(0,0)')
+ context('(0,0)')
end
end
-function jobpositions.MPur(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPur(id)
+ local jpi = collected[id] or tobesaved[id]
if jpi then
- texprint(ctxcatcodes,format('(%s+%s-%s,%s+%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[5],dy))
---~ texprint(ctxcatcodes,'(',jpi[2],'+',jpi[4],'-',dx,',',jpi[3],'+',jpi[5],'-',dy,')')
+ context('(%s+%s-%s,%s+%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[5],dy)
else
- texprint(ctxcatcodes,'(0,0)')
+ context('(0,0)')
end
end
-function jobpositions.MPul(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPul(id)
+ local jpi = collected[id] or tobesaved[id]
if jpi then
- texprint(ctxcatcodes,format('(%s-%s,%s+%s-%s)',jpi[2],dx,jpi[3],jpi[5],dy))
---~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'+',jpi[5],'-',dy,')')
+ context('(%s-%s,%s+%s-%s)',jpi[2],dx,jpi[3],jpi[5],dy)
else
- texprint(ctxcatcodes,'(0,0)')
+ context('(0,0)')
end
end
-function jobpositions.MPpos(id)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPpos(id)
+ local jpi = collected[id] or tobesaved[id]
if jpi then
- texprint(ctxcatcodes,concat(jpi,',',1,6))
+ context(concat(jpi,',',1,6))
else
- texprint(ctxcatcodes,'0,0,0,0,0,0')
+ context('0,0,0,0,0,0')
end
end
local splitter = lpeg.Ct(lpeg.splitat(","))
-function jobpositions.MPplus(id,n,default)
- local jpi = pcol[id] or ptbs[id]
+function commands.MPplus(id,n,default)
+ local jpi = collected[id] or tobesaved[id]
if not jpi then
- texprint(ctxcatcodes,default)
+ context(default)
else
local split = jpi[0]
if not split then
split = lpegmatch(splitter,jpi[7])
jpi[0] = split
end
- texprint(ctxcatcodes,split[n] or default)
+ context(split[n] or default)
end
end
-function jobpositions.MPrest(id,default)
- local jpi = pcol[id] or ptbs[id]
- -- texprint(ctxcatcodes,(jpi and jpi[7] and concat(jpi,",",7,#jpi)) or default)
- texprint(ctxcatcodes,(jpi and jpi[7]) or default)
+function commands.MPrest(id,default)
+ local jpi = collected[id] or tobesaved[id]
+ context(jpi and jpi[7] or default)
+end
+
+-- 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