diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-doc.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/strc-doc.lua | 393 |
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 |