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