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.lua393
1 files changed, 292 insertions, 101 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-doc.lua b/Master/texmf-dist/tex/context/base/strc-doc.lua
index d50d49b9236..f10b175a463 100644
--- a/Master/texmf-dist/tex/context/base/strc-doc.lua
+++ b/Master/texmf-dist/tex/context/base/strc-doc.lua
@@ -7,41 +7,57 @@ if not modules then modules = { } end modules ['strc-doc'] = {
}
-- todo: associate counter with head
-
+-- we need to better split the lua/tex end
-- we need to freeze and document this module
+-- keep this as is:
+--
+-- in section titles by default a zero aborts, so there we need: sectionset=bagger with \definestructureprefixset [bagger] [section-2,section-4] []
+-- in lists however zero's are ignored, so there numbersegments=2:4 gives result
+
local next, type = next, type
-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 format, gsub, find, gmatch, match = string.format, string.gsub, string.find, string.gmatch, string.match
local concat = table.concat
local max, min = math.max, math.min
-local allocate, mark = utilities.storage.allocate, utilities.storage.mark
-
-local ctxcatcodes = tex.ctxcatcodes
-local variables = interfaces.variables
-
---~ if not trackers then trackers = { register = function() end } end
-
-local trace_sectioning = false trackers.register("structures.sectioning", function(v) trace_sectioning = v end)
-local trace_detail = false trackers.register("structures.detail", function(v) trace_detail = v end)
-
-local report_structure = logs.reporter("structure","sectioning")
-
-local structures, context = structures, context
-
-local helpers = structures.helpers
-local documents = structures.documents
-local sections = structures.sections
-local lists = structures.lists
-local counters = structures.counters
-local sets = structures.sets
-local tags = structures.tags
-local processors = structures.processors
-
-local sprintprocessor = processors.sprint
-local ignoreprocessor = processors.ignore
-
-local a_internal = attributes.private('internal')
+local allocate, mark, accesstable = utilities.storage.allocate, utilities.storage.mark, utilities.tables.accesstable
+
+local catcodenumbers = catcodes.numbers
+local ctxcatcodes = tex.ctxcatcodes
+local variables = interfaces.variables
+
+local v_last = variables.last
+local v_first = variables.first
+local v_previous = variables.previous
+local v_next = variables.next
+local v_auto = variables.auto
+local v_strict = variables.strict
+local v_all = variables.all
+local v_positive = variables.positive
+local v_by = variables.by
+
+local trace_sectioning = false trackers.register("structures.sectioning", function(v) trace_sectioning = v end)
+local trace_detail = false trackers.register("structures.detail", function(v) trace_detail = v end)
+
+local report_structure = logs.reporter("structure","sectioning")
+
+local structures = structures
+local context = context
+
+local helpers = structures.helpers
+local documents = structures.documents
+local sections = structures.sections
+local lists = structures.lists
+local counters = structures.counters
+local sets = structures.sets
+local tags = structures.tags
+
+local processors = typesetters.processors
+local applyprocessor = processors.apply
+local startapplyprocessor = processors.startapply
+local stopapplyprocessor = processors.stopapply
+local strippedprocessor = processors.stripped
+
+local a_internal = attributes.private('internal')
-- -- -- document -- -- --
@@ -49,37 +65,49 @@ local data
function documents.initialize()
data = {
- numbers = { },
- forced = { },
+ numbers = { },
+ forced = { },
ownnumbers = { },
- status = { },
- checkers = { },
- depth = 0,
- blocks = { },
- block = "",
+ status = { },
+ checkers = { },
+ depth = 0,
+ blocks = { },
+ block = "",
}
documents.data = data
end
function documents.reset()
- data.numbers = { }
- data.forced = { }
+ data.numbers = { }
+ data.forced = { }
data.ownnumbers = { }
- data.status = { }
---~ data.checkers = { }
- data.depth = 0
+ data.status = { }
+ -- data.checkers = { }
+ data.depth = 0
end
documents.initialize()
--- -- -- sections -- -- --
+-- -- -- components -- -- --
+function documents.preset(numbers)
+ local nofnumbers = #numbers
+ data.numbers = numbers
+ data.depth = nofnumbers
+ data.ownnumbers = { }
+ for i=1,nofnumbers do
+ data.ownnumbers[i] = ""
+ end
+ sections.setnumber(nofnumbers,"-1")
+end
-local collected = allocate()
-local tobesaved = allocate()
+-- -- -- sections -- -- --
+
+local collected = allocate()
+local tobesaved = allocate()
-sections.collected = collected
-sections.tobesaved = tobesaved
+sections.collected = collected
+sections.tobesaved = tobesaved
--~ local function initializer()
--~ collected = sections.collected
@@ -88,6 +116,15 @@ sections.tobesaved = tobesaved
--~ job.register('structures.sections.collected', tobesaved, initializer)
+sections.registered = sections.registered or allocate()
+local registered = sections.registered
+
+storage.register("structures/sections/registered", registered, "structures.sections.registered")
+
+function sections.register(name,specification)
+ registered[name] = specification
+end
+
function sections.currentid()
return #tobesaved
end
@@ -158,14 +195,16 @@ function sections.getlevel(name)
return levelmap[name] or 0
end
-function sections.way(way,by)
- context((gsub(way,"^"..by,"")))
+local byway = "^" .. v_by
+
+function sections.way(way)
+ context((gsub(way,byway,"")))
end
function sections.setblock(name)
local block = name or data.block or "unknown" -- can be used to set the default
data.block = block
- texwrite(block)
+ context(block)
end
function sections.pushblock(name)
@@ -174,7 +213,7 @@ function sections.pushblock(name)
data.blocks[#data.blocks+1] = block
data.block = block
documents.reset()
- texwrite(block)
+ context(block)
end
function sections.popblock()
@@ -182,7 +221,7 @@ function sections.popblock()
local block = data.blocks[#data.blocks] or data.block
data.block = block
documents.reset()
- texwrite(block)
+ context(block)
end
function sections.currentblock()
@@ -194,17 +233,21 @@ function sections.currentlevel()
end
function sections.getcurrentlevel()
- texwrite(data.depth)
+ context(data.depth)
end
function sections.somelevel(given)
-- old number
- local numbers, ownnumbers, forced, status, olddepth = data.numbers, data.ownnumbers, data.forced, data.status, data.depth
- local givenname = given.metadata.name
+ local numbers = data.numbers
+ local ownnumbers = data.ownnumbers
+ local forced = data.forced
+ local status = data.status
+ local olddepth = data.depth
+ 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 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)
-- a trick to permits userdata to overload title, ownnumber and reference
-- normally these are passed as argument but nowadays we provide several
@@ -324,6 +367,11 @@ function sections.somelevel(given)
references.tag = references.tag or tags.getid(metadata.kind,metadata.name)
+ local setcomponent = structures.references.setcomponent
+ if setcomponent then
+ setcomponent(given) -- might move to the tex end
+ end
+
references.section = sections.save(given)
-- given.numberdata = nil
end
@@ -382,7 +430,7 @@ function sections.matchingtilldepth(depth,numbers,parentnumbers)
end
function sections.getnumber(depth) -- redefined later ...
- texwrite(data.numbers[depth] or 0)
+ context(data.numbers[depth] or 0)
end
function sections.set(key,value)
@@ -394,42 +442,56 @@ function sections.cct()
context(metadata and metadata.catcodes or ctxcatcodes)
end
+-- this one will become: return catcode, d (etc)
+
function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: spec table and then also depth
- if not depth or depth == 0 then depth = data.depth end
+ if depth then
+ depth = levelmap[depth] or tonumber(depth)
+ end
+ if not depth or depth == 0 then
+ depth = data.depth
+ end
local data = data.status[depth]
- local d = data
- for k in gmatch(key,"([^.]+)") do
- if type(d) == "table" then
- d = d[k]
- if not d then
- -- unknown key
- break
- end
+ local d
+ if data then
+ if find(key,"%.") then
+ d = accesstable(key,data)
+ else
+ d = data.titledata
+ d = d and d[key]
end
- if type(d) == "string" then
- if honorcatcodetable == true or honorcatcodetable == variables.auto then
- local metadata = data.metadata
- texsprint((metadata and metadata.catcodes) or ctxcatcodes,d)
- elseif not honorcatcodetable then
+ end
+ if d and type(d) ~= "table" then
+ if honorcatcodetable == true or honorcatcodetable == v_auto then
+ local metadata = data.metadata
+ local catcodes = metadata and metadata.catcodes
+ if catcodes then
+ context.sprint(catcodes,d)
+ else
context(d)
- elseif type(honorcatcodetable) == "number" then
- texsprint(honorcatcodetable,d)
- elseif type(honorcatcodetable) == "string" and honorcatcodetable ~= "" then
- honorcatcodetable = tex[honorcatcodetable] or ctxcatcodes-- we should move ctxcatcodes to another table, ctx or so
- texsprint(honorcatcodetable,d)
+ end
+ elseif not honorcatcodetable or honorcatcodetable == "" then
+ context(d)
+ else
+ local catcodes = catcodenumbers[honorcatcodetable]
+ if catcodes then
+ context.sprint(catcodes,d)
else
context(d)
end
- return
end
- end
- if default then
+ elseif default then
context(default)
end
end
function sections.userdata(depth,key,default)
- if not depth or depth == 0 then depth = data.depth end
+ if depth then
+ depth = levelmap[depth] or tonumber(depth)
+ end
+ if not depth or depth == 0 then
+ depth = data.depth
+ end
if depth > 0 then
local userdata = data.status[depth]
userdata = userdata and userdata.userdata
@@ -455,7 +517,7 @@ function sections.depthnumber(n)
elseif n < 0 then
n = depth + n
end
- return texwrite(data.numbers[n] or 0)
+ return context(data.numbers[n] or 0)
end
function sections.autodepth(numbers)
@@ -496,9 +558,9 @@ local function process(index,numbers,ownnumbers,criterium,separatorset,conversio
local separator = sets.get("structure:separators",block,separatorset,preceding,".")
if separator then
if result then
- result[#result+1] = ignoreprocessor(separator)
+ result[#result+1] = strippedprocessor(separator)
else
- sprintprocessor(ctxcatcodes,separator)
+ applyprocessor(separator)
end
end
preceding = false
@@ -514,14 +576,14 @@ local function process(index,numbers,ownnumbers,criterium,separatorset,conversio
end
else
if ownnumber ~= "" then
- sprintprocessor(ctxcatcodes,ownnumber)
+ applyprocessor(ownnumber)
elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups)
context.convertnumber(conversion,number)
else
local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
- sprintprocessor(ctxcatcodes,theconversion,function(str)
- return format("\\convertnumber{%s}{%s}",str or "numbers",number)
- end)
+ local data = startapplyprocessor(theconversion)
+ context.convertnumber(data or "numbers",number)
+ stopapplyprocessor()
end
end
return index, true
@@ -565,11 +627,11 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
if set == "" then set = "default" end
if segments == "" then segments = nil end
--
- if criterium == variables.strict then
+ if criterium == v_strict then
criterium = 0
- elseif criterium == variables.positive then
+ elseif criterium == v_positive then
criterium = -1
- elseif criterium == variables.all then
+ elseif criterium == v_all then
criterium = -1000000
else
criterium = 0
@@ -578,6 +640,9 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
local firstprefix, lastprefix = 0, 16
if segments then
local f, l = match(tostring(segments),"^(.-):(.+)$")
+ if l == "*" then
+ l = 100 -- new
+ end
if f and l then
-- 0:100, chapter:subsubsection
firstprefix = tonumber(f) or sections.getlevel(f) or 0
@@ -603,9 +668,9 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
local prefixlist = set and sets.getall("structure:prefixes","",set) -- "" == block
if starter then
if result then
- result[#result+1] = ignoreprocessor(starter)
+ result[#result+1] = strippedprocessor(starter)
else
- sprintprocessor(ctxcatcodes,starter)
+ applyprocessor(starter)
end
end
if prefixlist and (kind == 'section' or kind == 'prefix' or kind == 'direct') then
@@ -668,13 +733,13 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
if result then
-- can't happen as we're in 'direct'
else
- sprintprocessor(ctxcatcodes,connector)
+ applyprocessor(connector)
end
elseif done and stopper then
if result then
- result[#result+1] = ignoreprocessor(stopper)
+ result[#result+1] = strippedprocessor(stopper)
else
- sprintprocessor(ctxcatcodes,stopper)
+ applyprocessor(stopper)
end
end
return result -- a table !
@@ -691,29 +756,36 @@ function sections.title()
end
end
-function sections.findnumber(depth,what)
+function sections.findnumber(depth,what) -- needs checking (looks wrong and slow too)
local data = data.status[depth or data.depth]
if data then
local index = data.references.section
local collected = sections.collected
local sectiondata = collected[index]
if sectiondata and sectiondata.hidenumber ~= true then -- can be nil
- if what == variables.first then
+ local quit = what == v_previous or what == v_next
+ if what == v_first or what == v_previous 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
+ if quit then
+ break
+ end
elseif #n < depth then
break
end
end
- elseif what == variables.last then
+ elseif what == v_last or what == v_next 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
+ if quit then
+ break
+ end
elseif #n < depth then
break
end
@@ -724,6 +796,62 @@ function sections.findnumber(depth,what)
end
end
+function sections.finddata(depth,what)
+ local data = data.status[depth or data.depth]
+ if data then
+ -- if sectiondata and sectiondata.hidenumber ~= true then -- can be nil
+ local index = data.references.listindex
+ if index then
+ local collected = structures.lists.collected
+ local quit = what == v_previous or what == v_next
+ if what == v_first or what == v_previous then
+ for i=index-1,1,-1 do
+ local s = collected[i]
+ if not s then
+ break
+ elseif s.metadata.kind == "section" then -- maybe check on name
+ local n = s.numberdata.numbers
+ if #n == depth and n[depth] and n[depth] ~= 0 then
+ data = s
+ if quit then
+ break
+ end
+ elseif #n < depth then
+ break
+ end
+ end
+ end
+ elseif what == v_last or what == v_next then
+ for i=index+1,#collected do
+ local s = collected[i]
+ if not s then
+ break
+ elseif s.metadata.kind == "section" then -- maybe check on name
+ local n = s.numberdata.numbers
+ if #n == depth and n[depth] and n[depth] ~= 0 then
+ data = s
+ if quit then
+ break
+ end
+ elseif #n < depth then
+ break
+ end
+ end
+ end
+ end
+ end
+ return data
+ end
+end
+
+function sections.internalreference(sectionname,what) -- to be used in pagebuilder (no marks used)
+ local r = type(sectionname) == "number" and sectionname or registered[sectionname]
+ if r then
+ local data = sections.finddata(r.level,what)
+ return data and data.references and data.references.internal
+ end
+end
+
function sections.fullnumber(depth,what)
local sectiondata = sections.findnumber(depth,what)
if sectiondata then
@@ -733,5 +861,68 @@ end
function sections.getnumber(depth,what) -- redefined here
local sectiondata = sections.findnumber(depth,what)
- texwrite((sectiondata and sectiondata.numbers[depth]) or 0)
+ context((sectiondata and sectiondata.numbers[depth]) or 0)
+end
+
+-- experimental
+
+local levels = { }
+
+--~ function commands.autonextstructurelevel(level)
+--~ if level > #levels then
+--~ for i=#levels+1,level do
+--~ levels[i] = ""
+--~ end
+--~ end
+--~ local finish = concat(levels,"\n",level) or ""
+--~ for i=level+1,#levels do
+--~ levels[i] = ""
+--~ end
+--~ levels[level] = [[\finalizeautostructurelevel]]
+--~ context(finish)
+--~ end
+
+--~ function commands.autofinishstructurelevels()
+--~ local finish = concat(levels,"\n") or ""
+--~ levels = { }
+--~ context(finish)
+--~ end
+
+function commands.autonextstructurelevel(level)
+ if level > #levels then
+ for i=#levels+1,level do
+ levels[i] = false
+ end
+ else
+ for i=level,#levels do
+ if levels[i] then
+ context.finalizeautostructurelevel()
+ levels[i] = false
+ end
+ end
+ end
+ levels[level] = true
end
+
+function commands.autofinishstructurelevels()
+ for i=1,#levels do
+ if levels[i] then
+ context.finalizeautostructurelevel()
+ end
+ end
+ levels = { }
+end
+
+-- interface (some are actually already commands, like sections.fullnumber)
+
+commands.structurenumber = function() sections.fullnumber() end
+commands.structuretitle = function() sections.title () end
+
+commands.structurevariable = function(name) sections.structuredata(nil,name) end
+commands.structureuservariable = function(name) sections.userdata (nil,name) end
+commands.structurecatcodedget = function(name) sections.structuredata(nil,name,nil,true) end
+commands.structuregivencatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end
+commands.structureautocatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end
+
+commands.namedstructurevariable = function(depth,name) sections.structuredata(depth,name) end
+commands.namedstructureuservariable = function(depth,name) sections.userdata (depth,name) end