summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/anch-pos.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-01-27 16:14:16 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-01-27 16:14:16 +0100
commit95a1799032dc61dbca4a11e495be34b4397c8fec (patch)
tree4b24bf117a90ba704dedf19ab1b1a734d78f4e45 /tex/context/base/mkiv/anch-pos.lua
parent0cfeab235554eeee0dddd6c3f44d3939ab490ff1 (diff)
downloadcontext-95a1799032dc61dbca4a11e495be34b4397c8fec.tar.gz
2017-01-27 14:46:00
Diffstat (limited to 'tex/context/base/mkiv/anch-pos.lua')
-rw-r--r--tex/context/base/mkiv/anch-pos.lua261
1 files changed, 135 insertions, 126 deletions
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua
index b415fac3a..72d76301c 100644
--- a/tex/context/base/mkiv/anch-pos.lua
+++ b/tex/context/base/mkiv/anch-pos.lua
@@ -20,7 +20,7 @@ more efficient.</p>
-- this is one of the first modules using scanners and we need to replace
-- it by implement and friends
-local tostring, next, rawget, setmetatable, tonumber = tostring, next, rawget, setmetatable, tonumber
+local tostring, next, rawget, rawset, setmetatable, tonumber = tostring, next, rawget, rawset, setmetatable, tonumber
local sort, sortedhash, sortedkeys = table.sort, table.sortedhash, table.sortedkeys
local format, gmatch, match, find = string.format, string.gmatch, string.match, string.find
local rawget = rawget
@@ -51,7 +51,8 @@ local texsp = tex.sp
local pdf = pdf -- h and v are variables
-local setmetatableindex = table.setmetatableindex
+local setmetatableindex = table.setmetatableindex
+local setmetatablenewindex = table.setmetatablenewindex
local nuts = nodes.nuts
@@ -61,9 +62,10 @@ local setlink = nuts.setlink
local getlist = nuts.getlist
local setlist = nuts.setlist
local getbox = nuts.getbox
-local getskip = nuts.getskip
local getid = nuts.getid
-local getdimensions = nuts.dimensions
+local getwhd = nuts.getwhd
+
+local n_flush_node = nodes.flush
local hlist_code = nodes.listcodes.hlist
@@ -122,134 +124,31 @@ local f_region = formatters["region:%s"]
local f_tag_three = formatters["%s:%s:%s"]
local f_tag_two = formatters["%s:%s"]
-local function sorter(a,b)
- return a.y > b.y
-end
-
-local nofusedregions = 0
-local nofmissingregions = 0
-local nofregular = 0
-
-jobpositions.used = false
-
--- todo: register subsets and count them indepently
--- todo: categories, like par, page, ... saves find and also ordered tags then
-
--- local function initializer()
--- tobesaved = jobpositions.tobesaved
--- collected = jobpositions.collected
--- -- add sparse regions
--- local pages = structures.pages.collected
--- if pages then
--- local last = nil
--- for p=1,#pages do
--- local region = "page:" .. p
--- local data = collected[region]
--- if data then
--- last = data
--- last.p = nil -- no need for a page
--- elseif last and not collected[region] then
--- collected[region] = last
--- end
--- end
--- end
--- -- enhance regions with paragraphs -- could be a list of tags instead -- there can be too many
--- local regions = { }
--- -- for tag, data in sortedhash(collected) do --saves a sort later on but can be huge
--- for tag, data in next, collected do
--- if find(tag,"^p:") then
--- local region = data.r
--- if region then
--- local paragraphs = regions[region]
--- if paragraphs then
--- local par = match(tag,"%d+")
--- data.par = tonumber(par)
--- paragraphs[#paragraphs+1] = data
--- nofusedregions = nofusedregions + 1
--- elseif r == false then
--- nofmissingregions = nofmissingregions + 1
--- else
--- local r = collected[region]
--- if r then
--- local par = match(tag,"%d+")
--- data.par = tonumber(par)
--- paragraphs = { data }
--- regions[region] = paragraphs
--- nofusedregions = nofusedregions + 1
--- r.paragraphs = paragraphs
--- else
--- nofmissingregions = nofmissingregions + 1
--- regions[region] = false
--- end
--- end
--- else
--- nofregular = nofregular + 1
--- end
--- end
--- setmetatable(data,default)
--- end
--- -- sort this data
--- for tag, paragraphs in next, regions do
--- if paragraphs then
--- sort(paragraphs,function(a,b) return a.par < b.par end)
--- end
--- end
--- jobpositions.used = next(collected)
--- end
+jobpositions.used = false
-local splitter = lpeg.splitat(":")
+local nofregular = 0
+local nofspecial = 0
+local splitter = lpeg.splitat(":",true)
local function initializer()
tobesaved = jobpositions.tobesaved
collected = jobpositions.collected
- -- add sparse regions
- -- enhance regions with paragraphs -- could be a list of tags instead -- there can be too many
- local regiondata = { }
- local pagedata = { }
- local freedata = setmetatableindex("table")
- -- for tag, data in sortedhash(collected) do --saves a sort later on but can be huge
+ local pagedata = { }
+ local freedata = setmetatableindex("table")
for tag, data in next, collected do
local prefix, rest = lpegmatch(splitter,tag)
if prefix == "p" then
- local region = data.r
- if region then
- local paragraphs = regiondata[region]
- if paragraphs then
- data.par = tonumber(rest) or 0
- paragraphs[#paragraphs+1] = data
- nofusedregions = nofusedregions + 1
- elseif r == false then
- nofmissingregions = nofmissingregions + 1
- else
- local r = collected[region]
- if r then
- data.par = tonumber(rest) or 0
- paragraphs = { data }
- regiondata[region] = paragraphs
- nofusedregions = nofusedregions + 1
- r.paragraphs = paragraphs
- else
- nofmissingregions = nofmissingregions + 1
- regiondata[region] = false
- end
- end
- else
- nofregular = nofregular + 1
- end
+ nofregular = nofregular + 1
elseif prefix == "page" then
+ nofregular = nofregular + 1
pagedata[tonumber(rest) or 0] = data
elseif prefix == "free" then
+ nofspecial = nofspecial + 1
local t = freedata[data.p or 0]
t[#t+1] = data
end
setmetatable(data,default)
end
- -- sort this data
- for tag, paragraphs in next, regiondata do
- if paragraphs then
- sort(paragraphs,function(a,b) return a.par < b.par end)
- end
- end
--
local pages = structures.pages.collected
if pages then
@@ -280,6 +179,98 @@ local function initializer()
jobpositions.used = next(collected)
end
+-- -- we can gain a little when we group positions but then we still have to
+-- -- deal with regions and cells so we either end up with lots of extra small
+-- -- tables pointing to them and/or assembling/disassembling so in the end
+-- -- it makes no sense to do it (now) and still have such a mix
+--
+-- local splitter = lpeg.splitat(":",true)
+--
+-- local function setpos(t,k,v)
+-- local class, tag = lpegmatch(splitter,k)
+-- if tag then
+-- local c = rawget(t,class)
+-- if c then
+-- c[tonumber(tag) or tag] = v
+-- else
+-- rawset(t,class,{ [tonumber(tag) or tag] = v })
+-- end
+-- else
+-- t.default[tonumber(k) or k] = v
+-- end
+-- end
+--
+-- local function getpos(t,k)
+-- local class, tag = lpegmatch(splitter,k)
+-- if tag then
+-- local c = rawget(t,class)
+-- if c then
+-- return c[tonumber(tag) or tag]
+-- end
+-- else
+-- return c.default[tonumber(k) or k]
+-- end
+-- end
+--
+-- tobesaved.default = tobesaved.default or { }
+-- setmetatablenewindex(tobesaved,setpos)
+-- setmetatableindex (tobesaved,getpos)
+--
+-- local function initializer()
+-- tobesaved = jobpositions.tobesaved
+-- collected = jobpositions.collected
+--
+-- tobesaved.default = tobesaved.default or { }
+-- collected.default = collected.default or { }
+--
+-- setmetatablenewindex(tobesaved,setpos)
+-- setmetatableindex (collected,getpos)
+-- setmetatableindex (tobesaved,getpos)
+--
+-- for class, list in next, collected do
+-- for tag, data in next, list do
+-- setmetatable(data,default)
+-- nofregular = nofregular + 1
+-- end
+-- end
+--
+-- local pagedata = collected.page or { }
+-- local freedata = setmetatableindex("table")
+--
+-- for tag, data in next, collected.free or { } do
+-- local t = freedata[data.p or 0]
+-- t[#t+1] = data
+-- end
+--
+-- --
+-- local pages = structures.pages.collected
+-- if pages then
+-- local last = nil
+-- for p=1,#pages do
+-- local data = pagedata[p]
+-- local free = freedata[p]
+-- if free then
+-- sort(free,function(a,b) return b.y < a.y end) -- order matters !
+-- end
+-- if data then
+-- last = data
+-- last.free = free
+-- elseif last then
+-- local t = setmetatableindex({ free = free, p = p },last)
+-- if not pagedata[p] then
+-- pagedata[p] = t
+-- end
+-- end
+-- end
+-- end
+-- jobpositions.page = pagedata
+-- jobpositions.free = freedata
+-- jobpositions.used = next(collected)
+-- end
+--
+-- function jobpositions.getcollected(class,tag) if tag then return collected[class..tag] else return collected[class] end end
+-- function jobpositions.gettobesaved(class,tag) if tag then return tobesaved[class..tag] else return tobesaved[class] end end
+
job.register('job.positions.collected', tobesaved, initializer)
local regions = { }
@@ -494,7 +485,7 @@ local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind
tag = f_region(nofregions)
end
local box = getbox(n)
- local w, h, d = getdimensions(box)
+ local w, h, d = getwhd(box)
local x, y = getpos() -- hm, makes no sense here
tobesaved[tag] = {
-- p = texgetcount("realpageno"), -- we copy them
@@ -556,7 +547,7 @@ scanners.parpos = function() -- todo: relate to localpar (so this is an intermed
nofparagraphs = nofparagraphs + 1
texsetcount("global","c_anch_positions_paragraph",nofparagraphs)
local box = getbox("strutbox")
- local w, h, d = getdimensions(box)
+ local w, h, d = getwhd(box)
local t = {
p = true,
c = true,
@@ -567,8 +558,8 @@ scanners.parpos = function() -- todo: relate to localpar (so this is an intermed
d = d,
hs = texget("hsize"), -- never 0
}
- local leftskip = getfield(getskip("leftskip"),"width")
- local rightskip = getfield(getskip("rightskip"),"width")
+ local leftskip = texget("leftskip",false)
+ local rightskip = texget("rightskip",false)
local hangindent = texget("hangindent")
local hangafter = texget("hangafter")
local parindent = texget("parindent")
@@ -633,7 +624,7 @@ end
scanners.dosetpositionbox = function() -- name box
local name = scanstring()
local box = getbox(scaninteger())
- local w, h, d = getdimensions(box)
+ local w, h, d = getwhd(box)
tobesaved[name] = {
p = true,
c = column,
@@ -673,7 +664,7 @@ end
scanners.dosetpositionstrut = function() -- name
local name = scanstring()
local box = getbox("strutbox")
- local w, h, d = getdimensions(box)
+ local w, h, d = getwhd(box)
tobesaved[name] = {
p = true,
c = column,
@@ -692,7 +683,7 @@ scanners.dosetpositionstrutkind = function() -- name
local name = scanstring()
local kind = scaninteger()
local box = getbox("strutbox")
- local w, h, d = getdimensions(box)
+ local w, h, d = getwhd(box)
tobesaved[name] = {
k = kind,
p = true,
@@ -876,6 +867,8 @@ function jobpositions.position(id)
end
end
+local splitter = lpeg.splitat(",")
+
function jobpositions.extra(id,n,default) -- assume numbers
local jpi = collected[id]
if jpi then
@@ -1282,6 +1275,13 @@ scanners.doifposition = function() -- name
doif(collected[scanstring()])
end
+-- local ctx_iftrue = context.protected.cs.iftrue
+-- local ctx_iffalse = context.protected.cs.iffalse
+--
+-- scanners.ifknownposition = function() -- name
+-- (collected[scanstring()] and ctx_iftrue or ctx_iffalse)()
+-- end
+
scanners.doifelsepositiononpage = function() -- name page -- probably always realpageno
local c = collected[scanstring()]
local p = scaninteger()
@@ -1331,11 +1331,20 @@ end
-- statistics (at least for the moment, when testing)
+-- statistics.register("positions", function()
+-- local total = nofregular + nofusedregions + nofmissingregions
+-- if total > 0 then
+-- return format("%s collected, %s regulars, %s regions, %s unresolved regions",
+-- total, nofregular, nofusedregions, nofmissingregions)
+-- else
+-- return nil
+-- end
+-- end)
+
statistics.register("positions", function()
- local total = nofregular + nofusedregions + nofmissingregions
+ local total = nofregular + nofspecial
if total > 0 then
- return format("%s collected, %s regulars, %s regions, %s unresolved regions",
- total, nofregular, nofusedregions, nofmissingregions)
+ return format("%s collected, %s regular, %s special",total,nofregular,nofspecial)
else
return nil
end