diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/anch-pos.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/anch-pos.lua | 368 |
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 |