summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/strc-doc.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-doc.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/strc-doc.lua163
1 files changed, 131 insertions, 32 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-doc.lua b/Master/texmf-dist/tex/context/base/strc-doc.lua
index cb279e32065..7faf0d5b393 100644
--- a/Master/texmf-dist/tex/context/base/strc-doc.lua
+++ b/Master/texmf-dist/tex/context/base/strc-doc.lua
@@ -1,21 +1,28 @@
if not modules then modules = { } end modules ['strc-doc'] = {
version = 1.001,
- comment = "companion to strc-doc.tex",
+ comment = "companion to strc-doc.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
+-- todo: associate counter with head
+
+-- we need to freeze and document this module
+
local next, type = next, type
-local format, gsub, find, concat = string.format, string.gsub, string.find, table.concat
+local format, gsub, find, concat, gmatch, match = string.format, string.gsub, string.find, table.concat, string.gmatch, string.match
local texsprint, texwrite = tex.sprint, tex.write
+local concat = table.concat
+local max, min = math.max, math.min
local ctxcatcodes = tex.ctxcatcodes
local variables = interfaces.variables
-if not trackers then trackers = { register = function() end } end
+--~ if not trackers then trackers = { register = function() end } end
local trace_sectioning = false trackers.register("structure.sectioning", function(v) trace_sectioning = v end)
+local trace_detail = false trackers.register("structure.detail", function(v) trace_detail = v end)
local function report(...)
--~ print(...)
@@ -58,7 +65,7 @@ function documents.reset()
data.forced = { }
data.ownnumbers = { }
data.status = { }
- data.checkers = { }
+--~ data.checkers = { }
data.depth = 0
end
@@ -130,6 +137,8 @@ storage.register("structure/sections/levelmap", structure.sections.levelmap, "st
sections.verbose = true
+levelmap.block = -1
+
function sections.setlevel(name,level) -- level can be number or parent (=string)
local l = tonumber(level)
if not l then
@@ -157,6 +166,7 @@ function sections.setblock(name)
end
function sections.pushblock(name)
+ structure.counters.check(0) -- we assume sane usage of \page between blocks
local block = name or data.block
data.blocks[#data.blocks+1] = block
data.block = block
@@ -187,15 +197,18 @@ end
function sections.somelevel(given)
-- old number
local numbers, ownnumbers, forced, status, olddepth = data.numbers, data.ownnumbers, data.forced, data.status, data.depth
---~ print("old",olddepth,given.metadata.name,levelmap[given.metadata.name])
- local newdepth = tonumber(levelmap[given.metadata.name] or (olddepth > 0 and olddepth) or 1) -- hm, levelmap only works for section-*
---~ print("new",newdepth)
+ local givenname = given.metadata.name
+ local mappedlevel = levelmap[givenname]
+ local newdepth = tonumber(mappedlevel or (olddepth > 0 and olddepth) or 1) -- hm, levelmap only works for section-*
local directives = given.directives
local resetset = (directives and directives.resetset) or ""
- local resetter = sets.getall("structure:resets",data.block,resetset)
+ -- local resetter = sets.getall("structure:resets",data.block,resetset)
-- a trick to permits userdata to overload title, ownnumber and reference
-- normally these are passed as argument but nowadays we provide several
-- interfaces (we need this because we want to be compatible)
+ if trace_detail then
+ logs.report("structure","name '%s', mapped level '%s', old depth '%s', new depth '%s', reset set '%s'",givenname,mappedlevel,olddepth,newdepth,resetset)
+ end
local u = given.userdata
if u then
-- kind of obsolete as we can pass them directly anyway
@@ -209,7 +222,9 @@ function sections.somelevel(given)
if newdepth > olddepth then
for i=olddepth+1,newdepth do
local s = tonumber(sets.get("structure:resets",data.block,resetset,i))
---~ logs.report("structure >","old: %s, new:%s, reset: %s (%s: %s)",olddepth,newdepth,s,resetset,table.concat(resetter,","))
+ if trace_detail then
+ logs.report("structure","new>old (%s>%s), reset set '%s', reset value '%s', current '%s'",olddepth,newdepth,resetset,s or "?",numbers[i] or "?")
+ end
if not s or s == 0 then
numbers[i] = numbers[i] or 0
ownnumbers[i] = ownnumbers[i] or ""
@@ -222,7 +237,9 @@ function sections.somelevel(given)
elseif newdepth < olddepth then
for i=olddepth,newdepth+1,-1 do
local s = tonumber(sets.get("structure:resets",data.block,resetset,i))
---~ logs.report("structure <","old: %s, new:%s, reset: %s (%s: %s)",olddepth,newdepth,s,resetset,table.concat(resetter,","))
+ if trace_detail then
+ logs.report("structure","new<old (%s<%s), reset set '%s', reset value '%s', current '%s'",olddepth,newdepth,resetset,s or "?",numbers[i] or "?")
+ end
if not s or s == 0 then
numbers[i] = numbers[i] or 0
ownnumbers[i] = ownnumbers[i] or ""
@@ -233,13 +250,14 @@ function sections.somelevel(given)
status[i] = nil
end
end
+ structure.counters.check(newdepth)
ownnumbers[newdepth] = given.numberdata.ownnumber or ""
given.numberdata.ownnumber = nil
data.depth = newdepth
-- new number
olddepth = newdepth
if given.metadata.increment then
- local oldn, newn = numbers[newdepth], 0
+ local oldn, newn = numbers[newdepth] or 0, 0
local fd = forced[newdepth]
if fd then
if fd[1] == "add" then
@@ -251,21 +269,31 @@ function sections.somelevel(given)
newn = 1 -- maybe zero is nicer
end
forced[newdepth] = nil
+ if trace_detail then
+ logs.report("structure","old depth '%s', new depth '%s, old n '%s', new n '%s', forced '%s'",olddepth,newdepth,oldn,newn,concat(fd,""))
+ end
elseif newn then
newn = oldn + 1
+ if trace_detail then
+ logs.report("structure","old depth '%s', new depth '%s, old n '%s', new n '%s', increment",olddepth,newdepth,oldn,newn)
+ end
else
local s = tonumber(sets.get("structure:resets",data.block,resetset,newdepth))
---~ logs.report("structure =","old: %s, new:%s, reset: %s (%s: %s)",olddepth,newdepth,s,resetset,table.concat(resetter,","))
- if not s or s == 0 then
+ if not s then
+ newn = oldn or 0
+ elseif s == 0 then
newn = oldn or 0
else
newn = s - 1
end
+ if trace_detail then
+ logs.report("structure","old depth '%s', new depth '%s, old n '%s', new n '%s', reset",olddepth,newdepth,oldn,newn)
+ end
end
numbers[newdepth] = newn
end
status[newdepth] = given or { }
- for k, v in pairs(data.checkers) do
+ for k, v in next, data.checkers do
if v[1] == newdepth and v[2] then
v[2](k)
end
@@ -284,6 +312,9 @@ function sections.somelevel(given)
if #ownnumbers > 0 then
numberdata.ownnumbers = table.fastcopy(ownnumbers)
end
+ if trace_detail then
+ logs.report("structure","name '%s', numbers '%s', own numbers '%s'",givenname,concat(numberdata.numbers, " "),concat(numberdata.ownnumbers, " "))
+ end
given.references.section = sections.save(given)
-- given.numberdata = nil
end
@@ -293,7 +324,7 @@ function sections.writestatus()
local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth
local d = status[depth]
local o = concat(ownnumbers,".",1,depth)
- local n = (numbers and concat(numbers,".",1,depth)) or 0
+ local n = (numbers and concat(numbers,".",1,min(depth,#numbers))) or 0
local l = d.titledata.title or ""
local t = (l ~= "" and l) or d.titledata.title or "[no title]"
local m = d.metadata.name
@@ -310,7 +341,7 @@ end
function sections.setnumber(depth,n)
local forced, depth, new = data.forced, depth or data.depth, tonumber(n)
if type(n) == "string" then
- if n:find("^[%+%-]") then
+ if find(n,"^[%+%-]") then
forced[depth] = { "add", new }
else
forced[depth] = { "set", new }
@@ -324,8 +355,25 @@ function sections.number_at_depth(depth)
return data.numbers[tonumber(depth) or sections.getlevel(depth) or 0] or 0
end
-function sections.getnumber(depth)
- return texwrite(data.numbers[depth] or 0)
+function sections.numbers()
+ return data.numbers
+end
+
+function sections.matching_till_depth(depth,numbers,parentnumbers)
+ local dn = parentnumbers or data.numbers
+ local ok = false
+ for i=1,depth do
+ if dn[i] == numbers[i] then
+ ok = true
+ else
+ return false
+ end
+ end
+ return ok
+end
+
+function sections.getnumber(depth) -- redefined later ...
+ texwrite(data.numbers[depth] or 0)
end
function sections.set(key,value)
@@ -341,7 +389,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp
if not depth or depth == 0 then depth = data.depth end
local data = data.status[depth]
local d = data
- for k in key:gmatch("([^.]+)") do
+ for k in gmatch(key,"([^.]+)") do
if type(d) == "table" then
d = d[k]
if not d then
@@ -383,8 +431,8 @@ function sections.userdata(depth,key,default)
end
end
-function sections.setchecker(name,level,command)
- data.checkers[name] = (name and command and level > 0 and { level, command }) or nil
+function sections.setchecker(name,level,command) -- hm, checkers are not saved
+ data.checkers[name] = (name and command and level >= 0 and { level, command }) or nil
end
function sections.current()
@@ -432,16 +480,20 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
local conversionset = ""
local conversion = ""
local stopper = ""
+ local starter = ""
local connector = ""
local set = ""
local segments = ""
local criterium = ""
- for _, data in ipairs { ... } do -- can be multiple parametersets
+ local dataset = { ... }
+ for d=1,#dataset do
+ local data = dataset[d] -- can be multiple parametersets
if data then
if separatorset == "" then separatorset = data.separatorset or "" end
if conversionset == "" then conversionset = data.conversionset or "" end
if conversion == "" then conversion = data.conversion or "" end
if stopper == "" then stopper = data.stopper or "" end
+ if starter == "" then starter = data.starter or "" end
if connector == "" then connector = data.connector or "" end
if set == "" then set = data.set or "" end
if segments == "" then segments = data.segments or "" end
@@ -449,9 +501,10 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
end
end
if separatorset == "" then separatorset = "default" end
- if conversionset == "" then conversionset = "default" end
+ if conversionset == "" then conversionset = "default" end -- not used
if conversion == "" then conversion = nil end
if stopper == "" then stopper = nil end
+ if starter == "" then starter = nil end
if connector == "" then connector = nil end
if set == "" then set = "default" end
if segments == "" then segments = nil end
@@ -466,9 +519,9 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
criterium = 0
end
--
- local firstprefix, lastprefix = 0, 100
+ local firstprefix, lastprefix = 0, 16
if segments then
- local f, l = (tostring(segments)):match("^(.-):(.+)$")
+ local f, l = match(tostring(segments),"^(.-):(.+)$")
if f and l then
-- 0:100, chapter:subsubsection
firstprefix = tonumber(f) or sections.getlevel(f) or 0
@@ -486,12 +539,13 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
if numbers then
local done, preceding = false, false
local function process(index) -- move to outer
+ -- todo: too much (100 steps)
local number = numbers and (numbers[index] or 0)
local ownnumber = ownnumbers and ownnumbers[index] or ""
if number > criterium or (ownnumber ~= "") then
- local block = entry.block
+ local block = (entry.block ~= "" and entry.block) or sections.currentblock() -- added
if preceding then
- local separator = sets.get("structure:separators",b,s,preceding,".")
+ local separator = sets.get("structure:separators",block,separatorset,preceding,".")
if separator then
processors.sprint(ctxcatcodes,separator)
end
@@ -505,7 +559,7 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
-- traditional (e.g. used in itemgroups)
texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
else
- local theconversion = sets.get("structure:conversions",block,conversion,index,"numbers")
+ local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
processors.sprint(ctxcatcodes,theconversion,function(str)
return format("\\convertnumber{%s}{%s}",str or "numbers",number)
end)
@@ -517,6 +571,9 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
end
--
local prefixlist = set and sets.getall("structure:prefixes","",set) -- "" == block
+ if starter then
+ processors.sprint(ctxcatcodes,starter)
+ end
if prefixlist and (kind == 'section' or kind == 'prefix') then
-- find valid set (problem: for sectionnumber we should pass the level)
-- if kind == "section" then
@@ -587,17 +644,59 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
processors.sprint(ctxcatcodes,stopper)
end
else
- report("error: no numbers")
+ -- report("error: no numbers")
end
end
end
-function sections.fullnumber(depth)
+function sections.title()
+ local sc = sections.current()
+ if sc then
+ helpers.title(sc.titledata.title,sc.metadata)
+ end
+end
+
+function sections.findnumber(depth,what)
local data = data.status[depth or data.depth]
if data then
- local sectiondata = jobsections.collected[data.references.section]
+ local index = data.references.section
+ local collected = jobsections.collected
+ local sectiondata = collected[index]
if sectiondata and sectiondata.hidenumber ~= true then -- can be nil
- sections.typesetnumber(sectiondata,'section',sectiondata)
+ if what == variables.first then
+ for i=index,1,-1 do
+ local s = collected[i]
+ local n = s.numbers
+ if #n == depth and n[depth] and n[depth] ~= 0 then
+ sectiondata = s
+ elseif #n < depth then
+ break
+ end
+ end
+ elseif what == variables.last then
+ for i=index,#collected do
+ local s = collected[i]
+ local n = s.numbers
+ if #n == depth and n[depth] and n[depth] ~= 0 then
+ sectiondata = s
+ elseif #n < depth then
+ break
+ end
+ end
+ end
+ return sectiondata
end
end
end
+
+function sections.fullnumber(depth,what,raw)
+ local sectiondata = sections.findnumber(depth,what)
+ if sectiondata then
+ sections.typesetnumber(sectiondata,'section',sectiondata)
+ end
+end
+
+function sections.getnumber(depth,what) -- redefined here
+ local sectiondata = sections.findnumber(depth,what)
+ texwrite((sectiondata and sectiondata.numbers[depth]) or 0)
+end