diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/anch-snc.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/anch-snc.lua | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/anch-snc.lua b/Master/texmf-dist/tex/context/base/mkiv/anch-snc.lua new file mode 100644 index 00000000000..8006f3bd674 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/anch-snc.lua @@ -0,0 +1,271 @@ +if not modules then modules = { } end modules ['anch-snc'] = { + version = 1.001, + comment = "companion to anch-snc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + + +function mp.xxOverlayRegion() + local r = tokens.getters.macro("m_overlay_region") + mp.quoted('"'.. r .. '"') +-- mp.print('"'.. r .. '"') +end + +-- use factors as in mlib-int.lua + +local tonumber, next, setmetatable = tonumber, next, setmetatable +local concat, sort, remove, copy = table.concat, table.sort, table.remove, table.copy +local match, find = string.match, string.find +local lpegmatch = lpeg.match + +local setmetatableindex = table.setmetatableindex + +local factor = number.dimenfactors.bp +local mpprint = mp.print +local mpnumeric = mp.numeric +local mppoints = mp.points +local texgetdimen = tex.getdimen + +local p_number = lpeg.patterns.cardinal/tonumber +local p_space = lpeg.patterns.whitespace^0 +local p_tag = lpeg.P("syncpos:") * p_number * lpeg.P(":") * p_number +local p_option = p_number -- for now + * ((lpeg.P(",") * p_space * lpeg.P("reset") * lpeg.Cc(true)) + lpeg.Cc(false)) + +local list = { } +local colors = setmetatableindex("table") + +local kinds = { + above = 1, + continue = 2, + nothing = 3, + normal = 4, + below = 5, +} + +local allentries = setmetatableindex(function(t,category) + setmetatable(t,nil) + for tag, pos in next, job.positions.collected do + local c, n = lpegmatch(p_tag,tag) + if c then + local tc = t[c] + if tc then + tc[n] = pos + else + t[c] = { [n] = pos } + end + end + end + for k, list in next, t do + sort(list,function(a,b) + local ap = a.p + local bp = b.p + if ap == bp then + return b.y < a.y + else + return ap < bp + end + end) + list.start = 1 + end + setmetatableindex(t,"table") + return t[category] +end) + +local lastdone = { } + +function mp.sync_collect(category,realpage,useregion) + local all = allentries[category] + local m = 0 + local n = #all + list = { } + if useregion then + -- successive can be optimized when we sort by region + local start = 1 + local done = false + local last, rtop, rbot + for i=start,n do + local pos = all[i] + local p = pos.p + local r = pos.r + if r == useregion then + if not done then + local region = job.positions.collected[r] + list.region = region + list.page = region + rtop = (region.y or 0) + (region.h or 0) + rbot = (region.y or 0) - (region.d or 0) + last = { kind = "nothing", top = rtop, bottom = 0, task = 0 } + m = m + 1 ; list[m] = last + done = true + end + local top = pos.y + pos.h + last.bottom = top + local task, reset = lpegmatch(p_option,pos.e) + last = { kind = "normal", top = top, bottom = 0, task = task } + m = m + 1 ; list[m] = last + end + end + if done then + last.bottom = rbot + end + else + local start = all.start or 1 + local done = false + local last, rtop, rbot, ptop, pbot + for i=start,n do + local pos = all[i] + local p = pos.p + if p == realpage then + if not done then + local region = job.positions.collected[pos.r] + local page = job.positions.collected["page:"..realpage] or region + list.region = region + list.page = page + rtop = (region.y or 0) + (region.h or 0) + rbot = (region.y or 0) - (region.d or 0) + ptop = (page .y or 0) + (page .h or 0) + pbot = (page .y or 0) - (page .d or 0) + last = { kind = "above", top = ptop, bottom = rtop, task = 0 } + m = m + 1 ; list[m] = last + if i > 1 then + local task, reset = lpegmatch(p_option,all[i-1].e) + last = { kind = "continue", top = rtop, bottom = 0, task = task } + m = m + 1 ; list[m] = last + else + last = { kind = "nothing", top = rtop, bottom = 0, task = 0 } + m = m + 1 ; list[m] = last + end + done = true + end + local top = pos.y + pos.h + last.bottom = top + local task, reset = lpegmatch(p_option,pos.e) + if reset then + local l = list[2] + l.kind = "nothing" + l.task = 0 + end + last = { kind = "normal", top = top, bottom = 0, task = task } + m = m + 1 ; list[m] = last + elseif p > realpage then + all.start = i -- tricky, only for page + break + end + end + if done then + last.bottom = rbot + last = { kind = "below", top = rbot, bottom = pbot, task = 0 } + m = m + 1 ; list[m] = last + lastdone[category] = { + { kind = "above", top = ptop, bottom = rtop, task = 0 }, + { kind = "continue", top = rtop, bottom = rbot, task = list[#list-1].task }, -- lasttask + { kind = "below", top = rbot, bottom = pbot, task = 0 }, + region = list.region, + page = list.page, + } + else + local l = lastdone[category] + if l then + list = copy(l) -- inefficient, mayb emetatable for region/page + m = 3 + end + end + end + mpnumeric(m) +end + +function mp.sync_extend() + local n = #list + if n > 0 then + for i=1,n do + local l = list[i] + local k = l.kind + if k == "nothing" then + local ll = list[i+1] + if ll and ll.kind == "normal" then + ll.top = l.top + remove(list,i) + n = #list + break + end + end + end + end + mpnumeric(n) +end + +function mp.sync_prune() + local n = #list + if n > 0 then + if list[1].kind == "above" then + remove(list,1) + end + if list[1].kind == "nothing" then + remove(list,1) + end + if list[#list].kind == "below" then + remove(list,#list) + end + n = #list + end + mpnumeric(n) +end + +function mp.sync_collapse() + local n = #list + if n > 0 then + local m = 0 + local p = nil + for i=1,n do + local l = list[i] + local t = l.task + if p == t then + list[m].bottom = l.bottom + else + m = m + 1 + list[m] = l + end + p = t + end + for i=n,m+1,-1 do + list[i] = nil + end + n = m + end + mpnumeric(n) +end + +function mp.sync_set_color(category,n,v) + colors[category][n] = v +end + +function mp.sync_get_color(category,n) + mpprint(colors[category][n]) +end + +-- function mp.sync_get_size () mpnumeric(#list) end +-- function mp.sync_get_top (n) mppoints (list[n].top) end +-- function mp.sync_get_bottom(n) mppoints (list[n].bottom) end +-- function mp.sync_get_kind (n) mpnumeric(kinds[list[n].kind]) end +-- function mp.sync_get_task (n) mpnumeric(list[n].task) end + +-- function mp.sync_get_x() mppoints(list.page.x or 0) end +-- function mp.sync_get_y() mppoints(list.page.y or 0) end +-- function mp.sync_get_w() mppoints(list.page.w or 0) end +-- function mp.sync_get_h() mppoints(list.page.h or 0) end +-- function mp.sync_get_d() mppoints(list.page.d or 0) end + +function mp.sync_get_size () mpnumeric(#list) end +function mp.sync_get_top (n) mpnumeric(list[n].top * factor) end +function mp.sync_get_bottom(n) mpnumeric(list[n].bottom * factor) end +function mp.sync_get_kind (n) mpnumeric(kinds[list[n].kind]) end +function mp.sync_get_task (n) mpnumeric(list[n].task) end + +function mp.sync_get_x() mpnumeric((list.page.x or 0)*factor) end +function mp.sync_get_y() mpnumeric((list.page.y or 0)*factor) end +function mp.sync_get_w() mpnumeric((list.page.w or 0)*factor) end +function mp.sync_get_h() mpnumeric((list.page.h or 0)*factor) end +function mp.sync_get_d() mpnumeric((list.page.d or 0)*factor) end |