summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-num.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/strc-num.lua')
-rw-r--r--tex/context/base/strc-num.lua207
1 files changed, 64 insertions, 143 deletions
diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua
index b82132a00..0715a9e49 100644
--- a/tex/context/base/strc-num.lua
+++ b/tex/context/base/strc-num.lua
@@ -6,13 +6,12 @@ if not modules then modules = { } end modules ['strc-num'] = {
license = "see context related readme files"
}
+-- this will be reimplemented and some more will move to the commands namespace
+
local format = string.format
local next, type = next, type
local min, max = math.min, math.max
-local texcount, texsetcount = tex.count, tex.setcount
-
--- Counters are managed here. They can have multiple levels which makes it easier to synchronize
--- them. Synchronization is sort of special anyway, as it relates to document structuring.
+local texcount = tex.count
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
@@ -27,23 +26,8 @@ local counters = structures.counters
local documents = structures.documents
local variables = interfaces.variables
-local v_start = variables.start
-local v_page = variables.page
-local v_reverse = variables.reverse
-local v_first = variables.first
-local v_next = variables.next
-local v_previous = variables.previous
-local v_prev = variables.prev
-local v_last = variables.last
------ v_no = variables.no
-local v_backward = variables.backward
-local v_forward = variables.forward
------ v_subs = variables.subs or "subs"
-
--- states: start stop none reset
-
--- specials are used for counters that are set and incremented in special ways, like
--- pagecounters that get this treatment in the page builder
+
+-- state: start stop none reset
counters.specials = counters.specials or { }
local counterspecials = counters.specials
@@ -82,83 +66,54 @@ end
job.register('structures.counters.collected', tobesaved, initializer, finalizer)
-local constructor = { -- maybe some day we will provide an installer for more variants
-
- last = function(t,name,i)
+local function constructor(t,s,name,i) -- variables ?
+ if s == "last" then
local cc = collected[name]
- local stop = (cc and cc[i] and cc[i][t.range]) or 0 -- stop is available for diagnostics purposes only
- t.stop = stop
+ t.stop = (cc and cc[i] and cc[i][t.range]) or 0 -- stop is available for diagnostics purposes only
if t.offset then
- return stop - t.step
+ return t.stop - t.step
else
- return stop
+ return t.stop
end
- end,
-
- first = function(t,name,i)
- local start = t.start
- if start > 0 then
- return start -- brrr
+ elseif s == "first" then
+ if t.start > 0 then
+ return t.start -- brrr
elseif t.offset then
- return start + t.step + 1
+ return t.start + t.step + 1
else
- return start + 1
+ return t.start + 1
end
- end,
-
- prev = function(t,name,i)
+ elseif s == "prev" or s == "previous" then
return max(t.first,t.number-1) -- todo: step
- end,
-
- previous = function(t,name,i)
- return max(t.first,t.number-1) -- todo: step
- end,
-
- next = function(t,name,i)
+ elseif s == "next" then
return min(t.last,t.number+1) -- todo: step
- end,
-
- backward =function(t,name,i)
+ elseif s == "backward" then
if t.number - 1 < t.first then
return t.last
else
return t.previous
end
- end,
-
- forward = function(t,name,i)
+ elseif s == "forward" then
if t.number + 1 > t.last then
return t.first
else
return t.next
end
- end,
-
- subs = function(t,name,i)
+ elseif s == "subs" then
local cc = collected[name]
t.subs = (cc and cc[i+1] and cc[i+1][t.range]) or 0
return t.subs
- end,
-
-}
-
-local function dummyconstructor(t,name,i)
- return nil -- was 0, but that is fuzzy in testing for e.g. own
-end
-
-setmetatableindex(constructor,function(t,k)
- if trace_counters then
- report_counters("unknown constructor %q",tostring(k))
+ else
+ return nil -- was 0, but that is fuzzy in testing for e.g. own
end
- return dummyconstructor
-end)
+end
local function enhance()
for name, cd in next, counterdata do
local data = cd.data
for i=1,#data do
local ci = data[i]
- setmetatableindex(ci, function(t,s) return constructor[s](t,name,i) end)
+ setmetatableindex(ci, function(t,s) return constructor(t,s,name,i) end)
end
end
enhance = nil
@@ -171,7 +126,7 @@ local function allocate(name,i) -- can be metatable
level = 1,
-- block = "", -- todo
numbers = nil,
- state = v_start, -- true
+ state = variables.start, -- true
data = { },
saved = { },
}
@@ -190,7 +145,7 @@ local function allocate(name,i) -- can be metatable
offset = false,
stop = 0, -- via metatable: last, first, stop only for tracing
}
- setmetatableindex(ci, function(t,s) return constructor[s](t,name,i) end)
+ setmetatableindex(ci, function(t,s) return constructor(t,s,name,i) end)
cd[i] = ci
tobesaved[name][i] = { }
else
@@ -209,12 +164,12 @@ local function savevalue(name,i)
local cs = tobesaved[name][i]
local cc = collected[name]
if trace_counters then
- report_counters("saving, counter: %s, value: %s",name,cd.number)
+ report_counters("saving value %s of counter named %s",cd.number,name)
end
local cr = cd.range
local old = (cc and cc[i] and cc[i][cr]) or 0
local number = cd.number
- if cd.method == v_page then
+ if cd.method == variables.page then
-- we can be one page ahead
number = number - 1
end
@@ -231,8 +186,8 @@ function counters.define(specification)
if name and name ~= "" then
-- todo: step
local d = allocate(name,1)
- d.start = tonumber(specification.start) or 0
- d.state = v_state or ""
+ d.start = specification.start
+ d.state = variables.start or ""
local counter = specification.counter
if counter and counter ~= "" then
d.counter = counter -- only for special purposes, cannot be false
@@ -247,15 +202,18 @@ end
function counters.compact(name,level,onlynumbers)
local cd = counterdata[name]
+--~ print(name,cd)
if cd then
local data = cd.data
local compact = { }
for i=1,level or #data do
local d = data[i]
+--~ print(name,i,d.number)
if d.number ~= 0 then
compact[i] = (onlynumbers and d.number) or d
end
end
+--~ print(table.serialize(compact))
return compact
end
end
@@ -288,76 +246,65 @@ function counters.subs(name,n)
return counterdata[name].data[n].subs or 0
end
-local function setvalue(name,tag,value)
+function counters.setvalue(name,tag,value)
local cd = counterdata[name]
if cd then
cd[tag] = value
end
end
-counters.setvalue = setvalue
-
function counters.setstate(name,value) -- true/false
value = variables[value]
if value then
- setvalue(name,"state",value)
+ counters.setvalue(name,"state",value)
end
end
function counters.setlevel(name,value)
- setvalue(name,"level",value)
+ counters.setvalue(name,"level",value)
end
function counters.setoffset(name,value)
- setvalue(name,"offset",value)
+ counters.setvalue(name,"offset",value)
end
local function synchronize(name,d)
local dc = d.counter
if dc then
if trace_counters then
- report_counters("synchronize, counter: %s, name: %s, value: %s, action: setting",dc,name,d.number)
+ report_counters("setting counter %s with name %s to %s",dc,name,d.number)
end
- texsetcount("global",dc,d.number)
+ tex.setcount("global",dc,d.number)
end
local cs = counterspecials[name]
if cs then
if trace_counters then
- report_counters("synchronize, counter: %s, name: %s, action: special",dc,name)
+ report_counters("invoking special for name %s",name)
end
- cs(name)
+ cs()
end
end
-local function reset(name,n)
+function counters.reset(name,n)
local cd = counterdata[name]
if cd then
for i=n or 1,#cd.data do
local d = cd.data[i]
savevalue(name,i)
- local number = d.start or 0
- d.number = number
+ d.number = d.start or 0
d.own = nil
- if trace_counters then
- report_counters("resetting, name: %s, sub: %s, value: %s",name,i,number)
- end
synchronize(name,d)
end
cd.numbers = nil
- else
end
end
-local function set(name,n,value)
+function counters.set(name,n,value)
local cd = counterdata[name]
if cd then
local d = allocate(name,n)
- local number = value or 0
- d.number = number
+ d.number = value or 0
d.own = nil
- if trace_counters then
- report_counters("setting, name: %s, value: %s",name,number)
- end
synchronize(name,d)
end
end
@@ -366,19 +313,12 @@ local function check(name,data,start,stop)
for i=start or 1,stop or #data do
local d = data[i]
savevalue(name,i)
- local number = d.start or 0
- d.number = number
+ d.number = d.start or 0
d.own = nil
- if trace_counters then
- report_counters("checking, name: %s, sub: %s, value: %s",name,i,number)
- end
synchronize(name,d)
end
end
-counters.reset = reset
-counters.set = set
-
function counters.setown(name,n,value)
local cd = counterdata[name]
if cd then
@@ -388,7 +328,7 @@ function counters.setown(name,n,value)
local level = cd.level
if not level or level == -1 then
-- -1 is signal that we reset manually
- elseif level > 0 or level == -3 then
+ elseif level > 0 then
check(name,d,n+1)
elseif level == 0 then
-- happens elsewhere, check this for block
@@ -405,7 +345,7 @@ function counters.restart(name,n,newstart,noreset)
local d = allocate(name,n)
d.start = newstart
if not noreset then
- reset(name,n) -- hm
+ counters.reset(name,n) -- hm
end
end
end
@@ -427,38 +367,24 @@ end
function counters.add(name,n,delta)
local cd = counterdata[name]
- if cd and (cd.state == v_start or cd.state == "") then
+-- inspect(cd)
+ if cd and (cd.state == variables.start or cd.state == "") then
local data = cd.data
local d = allocate(name,n)
d.number = (d.number or d.start or 0) + delta*(d.step or 0)
-- d.own = nil
local level = cd.level
+-- print(name,n,delta,level)
if not level or level == -1 then
-- -1 is signal that we reset manually
- if trace_counters then
- report_counters("adding, name: %s, level: manually, action: no checking",name)
- end
elseif level == -2 then
-- -2 is signal that we work per text
- if trace_counters then
- report_counters("adding, name: %s, level: text, action: checking",name)
- end
check(name,data,n+1)
- elseif level > 0 or level == -3 then
+ elseif level > 0 then
-- within countergroup
- if trace_counters then
- report_counters("adding, name: %s, level: %s, action: checking within group",name,level)
- end
check(name,data,n+1)
elseif level == 0 then
-- happens elsewhere
- if trace_counters then
- report_counters("adding, name: %s, level: %s, action: no checking",name,level)
- end
- else
- if trace_counters then
- report_counters("adding, name: %s, level: unknown, action: no checking",name)
- end
end
synchronize(name,d)
return d.number -- not needed
@@ -466,23 +392,19 @@ function counters.add(name,n,delta)
return 0
end
-function counters.check(level)
+function counters.check(level) -- not used (yet)
for name, cd in next, counterdata do
- if level > 0 and cd.level == -3 then -- could become an option
+ -- report_counters("%s %s %s",name,cd.level,level)
+ if cd.level == level then
if trace_counters then
- report_counters("resetting, name: %s, level: %s (head)",name,level)
+ report_counters("resetting %s at level %s",name,level)
end
- reset(name)
- elseif cd.level == level then
- if trace_counters then
- report_counters("resetting, name: %s, level: %s (normal)",name,level)
- end
- reset(name)
+ counters.reset(name)
end
end
end
-local function get(name,n,key)
+function counters.get(name,n,key)
local d = allocate(name,n)
d = d and d[key]
if not d then
@@ -494,10 +416,8 @@ local function get(name,n,key)
end
end
-counters.get = get
-
function counters.value(name,n) -- what to do with own
- return get(name,n or 1,'number') or 0
+ return counters.get(name,n or 1,'number') or 0
end
function counters.converted(name,spec) -- name can be number and reference to storage
@@ -511,8 +431,9 @@ function counters.converted(name,spec) -- name can be number and reference to st
if cd then
local spec = spec or { }
local numbers, ownnumbers = { }, { }
- local reverse = spec.order == v_reverse
+ local reverse = spec.order == variables.reverse
local kind = spec.type or "number"
+ local v_first, v_next, v_previous, v_last = variables.first, variables.next, variables.previous, variables.last
local data = cd.data
for k=1,#data do
local v = data[k]
@@ -525,7 +446,7 @@ function counters.converted(name,spec) -- name can be number and reference to st
vn = v.first
elseif kind == v_next then
vn = v.next
- elseif kind == v_prev or kind == v_previous then
+ elseif kind == v_previous then
vn = v.prev
elseif kind == v_last then
vn = v.last
@@ -577,7 +498,7 @@ function commands.showcounter(name)
local data = cd.data
for i=1,#data do
local d = data[i]
- context(" (%s: %s,%s,%s s:%s r:%s)",i,d.start or 0,d.number or 0,d.last,d.step or 0,d.range or 0)
+ context(" (%s: %s,%s,%s s:%s r:%s)",i,(d.start or 0),d.number or 0,d.last,d.step or 0,d.range or 0)
end
context("]")
end
@@ -622,7 +543,7 @@ end
--~ return cd, false, "no section data"
--~ end
--~ -- local preferences
---~ local no = v_no
+--~ local no = variables.no
--~ if counterspecification and counterspecification.prefix == no then
--~ return cd, false, "current spec blocks prefix"
--~ end