summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-ref.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/strc-ref.lua')
-rw-r--r--tex/context/base/strc-ref.lua110
1 files changed, 85 insertions, 25 deletions
diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua
index 6811c4da3..12b4b2558 100644
--- a/tex/context/base/strc-ref.lua
+++ b/tex/context/base/strc-ref.lua
@@ -10,6 +10,7 @@ local format, find, gmatch, match, concat = string.format, string.find, string.g
local lpegmatch, lpegP, lpegCs = lpeg.match, lpeg.P, lpeg.Cs
local texsprint, texwrite, texcount, texsetcount = tex.sprint, tex.write, tex.count, tex.setcount
local allocate, mark = utilities.storage.allocate, utilities.storage.mark
+local setmetatable, rawget = setmetatable, rawget
local allocate = utilities.storage.allocate
@@ -53,18 +54,22 @@ local executers = allocate()
local handlers = allocate()
local tobesaved = allocate()
local collected = allocate()
-
-references.derived = derived
-references.specials = specials
-references.runners = runners
-references.internals = internals
-references.exporters = exporters
-references.imported = imported
-references.filters = filters
-references.executers = executers
-references.handlers = handlers
-references.tobesaved = tobesaved
-references.collected = collected
+local tobereferred = allocate()
+local referred = allocate()
+
+references.derived = derived
+references.specials = specials
+references.runners = runners
+references.internals = internals
+references.exporters = exporters
+references.imported = imported
+references.filters = filters
+references.executers = executers
+references.handlers = handlers
+references.tobesaved = tobesaved
+references.collected = collected
+references.tobereferred = tobereferred
+references.referred = referred
storage.register("structures/references/defined", references.defined, "structures.references.defined")
@@ -87,6 +92,7 @@ local function initializer() -- can we use a tobesaved as metatable for collecte
initializers[i](tobesaved,collected)
end
end
+
local function finalizer()
-- tobesaved = mark(references.tobesaved)
for i=1,#finalizers do
@@ -94,10 +100,68 @@ local function finalizer()
end
end
-if job then
- job.register('structures.references.collected', tobesaved, initializer, finalizer)
+job.register('structures.references.collected', tobesaved, initializer, finalizer)
+
+local maxreferred = 1
+
+local function initializer() -- can we use a tobesaved as metatable for collected?
+ tobereferred = mark(references.tobereferred)
+ referred = mark(references.referred)
+
+ function get(t,n) -- catch sparse, a bit slow but who cares
+ for i=n,1,-1 do -- we could make a tree ... too much work
+ local p = rawget(t,i)
+ if p then
+ return p
+ end
+ end
+ end
+ setmetatable(referred, { __index = get })
+end
+
+local function finalizer() -- make sparse
+ local last
+ for i=1,maxreferred do
+ local r = tobereferred[i]
+ if not last then
+ last = r
+ elseif r == last then
+ tobereferred[i] = nil
+ else
+ last = r
+ end
+ end
+end
+
+function references.referredpage(n)
+ return referred[n] or referred[n] or texcount.realpageno
end
+function references.checkedpage(n,page)
+ local r, p = referred[n] or texcount.realpageno, tonumber(page)
+ if not p then
+ -- sorry
+ elseif p > r then
+ texcount.referencepagestate = 3
+ elseif p < r then
+ texcount.referencepagestate = 2
+ else
+ texcount.referencepagestate = 1
+ end
+ return p
+end
+
+function references.registerpage(n)
+ if not tobereferred[n] then
+ if n > maxreferred then
+ maxreferred = n
+ end
+ tobereferred[n] = texcount.realpageno
+ end
+end
+
+job.register('structures.references.referred', tobereferred, initializer, finalizer)
+
-- todo: delay split till later as in destinations we split anyway
local orders, lastorder = { }, 0
@@ -763,12 +827,15 @@ end
local prefixsplitter = lpegCs(lpegP((1-lpegP(":"))^1 * lpegP(":"))) * lpegCs(lpegP(1)^1)
-
-- todo: add lots of tracing here
+local n = 0
+
local function identify(prefix,reference)
local set = resolve(prefix,reference)
local bug = false
+n = n + 1
+set.n = n
for i=1,#set do
local var = set[i]
local special, inner, outer, arguments, operation = var.special, var.inner, var.outer, var.arguments, var.operation
@@ -1131,10 +1198,12 @@ function references.getcurrentmetadata(tag)
texsprint(ctxcatcodes,data)
end
end
+
local function currentmetadata(tag)
local data = currentreference and currentreference.i
return data and data.metadata and data.metadata[tag]
end
+
references.currentmetadata = currentmetadata
function references.getcurrentprefixspec(default) -- todo: message
@@ -1328,16 +1397,7 @@ function references.analyze(actions)
what = what(a,actions)
end
end
- local realpage, p = texcount.realpageno, tonumber(actions.realpage)
- if not p then
- -- sorry
- elseif p > realpage then
- texcount.referencepagestate = 3
- elseif p < realpage then
- texcount.referencepagestate = 2
- else
- texcount.referencepagestate = 1
- end
+ references.checkedpage(actions.n,actions.realpage)
end
end
return actions