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 | 307 |
1 files changed, 171 insertions, 136 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-doc.lua b/Master/texmf-dist/tex/context/base/strc-doc.lua index 7faf0d5b393..d50d49b9236 100644 --- a/Master/texmf-dist/tex/context/base/strc-doc.lua +++ b/Master/texmf-dist/tex/context/base/strc-doc.lua @@ -15,32 +15,33 @@ local format, gsub, find, concat, gmatch, match = string.format, string.gsub, st local texsprint, texwrite = tex.sprint, tex.write 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("structure.sectioning", function(v) trace_sectioning = v end) -local trace_detail = false trackers.register("structure.detail", function(v) trace_detail = v 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 function report(...) ---~ print(...) - logs.report("sectioning:",...) -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 -structure = structure or { } -structure.helpers = structure.helpers or { } -structure.documents = structure.documents or { } -structure.sections = structure.sections or { } -structure.sets = structure.sets or { } -structure.processors = structure.processors or { } +local sprintprocessor = processors.sprint +local ignoreprocessor = processors.ignore -local helpers = structure.helpers -local documents = structure.documents -local sections = structure.sections -local sets = structure.sets -local processors = structure.processors +local a_internal = attributes.private('internal') -- -- -- document -- -- -- @@ -73,17 +74,19 @@ documents.initialize() -- -- -- sections -- -- -- -jobsections = jobsections or { } -jobsections.collected = jobsections.collected or { } -jobsections.tobesaved = jobsections.tobesaved or { } -local collected, tobesaved = jobsections.collected, jobsections.tobesaved +local collected = allocate() +local tobesaved = allocate() + +sections.collected = collected +sections.tobesaved = tobesaved --~ local function initializer() ---~ collected, tobesaved = jobsections.collected, jobsections.tobesaved +--~ collected = sections.collected +--~ tobesaved = sections.tobesaved --~ end ---~ job.register('jobsections.collected', jobsections.tobesaved, initializer) +--~ job.register('structures.sections.collected', tobesaved, initializer) function sections.currentid() return #tobesaved @@ -106,7 +109,7 @@ end function sections.load() setmetatable(collected,nil) - local l = structure.lists.collected + local l = lists.collected for i=1,#l do local li = l[i] local lm = li.metadata @@ -129,11 +132,11 @@ setmetatable(collected, { -- -structure.sections.levelmap = structure.sections.levelmap or { } +sections.levelmap = sections.levelmap or { } -local levelmap = structure.sections.levelmap +local levelmap = sections.levelmap -storage.register("structure/sections/levelmap", structure.sections.levelmap, "structure.sections.levelmap") +storage.register("structures/sections/levelmap", sections.levelmap, "structures.sections.levelmap") sections.verbose = true @@ -156,7 +159,7 @@ function sections.getlevel(name) end function sections.way(way,by) - texsprint(ctxcatcodes,(gsub(way,"^"..by,""))) + context((gsub(way,"^"..by,""))) end function sections.setblock(name) @@ -166,7 +169,7 @@ function sections.setblock(name) end function sections.pushblock(name) - structure.counters.check(0) -- we assume sane usage of \page between blocks + 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 @@ -207,7 +210,7 @@ function sections.somelevel(given) -- 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) + 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 @@ -223,7 +226,7 @@ function sections.somelevel(given) for i=olddepth+1,newdepth do local s = tonumber(sets.get("structure:resets",data.block,resetset,i)) 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 "?") + 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 @@ -238,7 +241,7 @@ function sections.somelevel(given) for i=olddepth,newdepth+1,-1 do local s = tonumber(sets.get("structure:resets",data.block,resetset,i)) 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 "?") + 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 @@ -250,7 +253,7 @@ function sections.somelevel(given) status[i] = nil end end - structure.counters.check(newdepth) + counters.check(newdepth) ownnumbers[newdepth] = given.numberdata.ownnumber or "" given.numberdata.ownnumber = nil data.depth = newdepth @@ -270,12 +273,12 @@ function sections.somelevel(given) 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,"")) + 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) + 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)) @@ -287,7 +290,7 @@ function sections.somelevel(given) 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) + report_structure("old depth '%s', new depth '%s, old n '%s', new n '%s', reset",olddepth,newdepth,oldn,newn) end end numbers[newdepth] = newn @@ -313,13 +316,19 @@ function sections.somelevel(given) 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, " ")) + report_structure("name '%s', numbers '%s', own numbers '%s'",givenname,concat(numberdata.numbers, " "),concat(numberdata.ownnumbers, " ")) end - given.references.section = sections.save(given) + + local metadata = given.metadata + local references = given.references + + references.tag = references.tag or tags.getid(metadata.kind,metadata.name) + + references.section = sections.save(given) -- given.numberdata = nil end -function sections.writestatus() +function sections.reportstructure() if sections.verbose then local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth local d = status[depth] @@ -329,11 +338,11 @@ function sections.writestatus() local t = (l ~= "" and l) or d.titledata.title or "[no title]" local m = d.metadata.name if o and not find(o,"^%.*$") then - commands.writestatus("structure","%s @ level %i : (%s) %s -> %s",m,depth,n,o,t) + report_structure("%s @ level %i : (%s) %s -> %s",m,depth,n,o,t) elseif d.directives and d.directives.hidenumber then - commands.writestatus("structure","%s @ level %i : (%s) -> %s",m,depth,n,t) + report_structure("%s @ level %i : (%s) -> %s",m,depth,n,t) else - commands.writestatus("structure","%s @ level %i : %s -> %s",m,depth,n,t) + report_structure("%s @ level %i : %s -> %s",m,depth,n,t) end end end @@ -351,7 +360,7 @@ function sections.setnumber(depth,n) end end -function sections.number_at_depth(depth) +function sections.numberatdepth(depth) return data.numbers[tonumber(depth) or sections.getlevel(depth) or 0] or 0 end @@ -359,7 +368,7 @@ function sections.numbers() return data.numbers end -function sections.matching_till_depth(depth,numbers,parentnumbers) +function sections.matchingtilldepth(depth,numbers,parentnumbers) local dn = parentnumbers or data.numbers local ok = false for i=1,depth do @@ -382,7 +391,7 @@ end function sections.cct() local metadata = data.status[data.depth].metadata - texsprint((metadata and metadata.catcodes) or ctxcatcodes) + context(metadata and metadata.catcodes or ctxcatcodes) end function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: spec table and then also depth @@ -402,20 +411,20 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp local metadata = data.metadata texsprint((metadata and metadata.catcodes) or ctxcatcodes,d) elseif not honorcatcodetable then - texsprint(ctxcatcodes,d) + 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) else - texsprint(ctxcatcodes,d) + context(d) end return end end if default then - texsprint(ctxcatcodes,default) + context(default) end end @@ -426,7 +435,7 @@ function sections.userdata(depth,key,default) userdata = userdata and userdata.userdata userdata = (userdata and userdata[key]) or default if userdata then - texsprint(ctxcatcodes,userdata) + context(userdata) end end end @@ -460,7 +469,7 @@ end -- -function structure.currentsectionnumber() -- brr, namespace wrong +function structures.currentsectionnumber() -- brr, namespace wrong local sc = sections.current() return sc and sc.numberdata end @@ -474,6 +483,53 @@ end -- sign=positive => also zero -- sign=hang => llap sign +--~ todo: test this +--~ + +local function process(index,numbers,ownnumbers,criterium,separatorset,conversion,conversionset,index,entry,result,preceding,done) + -- 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 ~= "" and entry.block) or sections.currentblock() -- added + if preceding then + local separator = sets.get("structure:separators",block,separatorset,preceding,".") + if separator then + if result then + result[#result+1] = ignoreprocessor(separator) + else + sprintprocessor(ctxcatcodes,separator) + end + end + preceding = false + end + if result then + if ownnumber ~= "" then + result[#result+1] = ownnumber + elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups) .. inherited! + result[#result+1] = converters.convert(conversion,number) + else + local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers") + result[#result+1] = converters.convert(theconversion,number) + end + else + if ownnumber ~= "" then + sprintprocessor(ctxcatcodes,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) + end + end + return index, true + else + return preceding or false, done + end +end + function sections.typesetnumber(entry,kind,...) -- kind='section','number','prefix' if entry and entry.hidenumber ~= true then -- can be nil local separatorset = "" @@ -538,113 +594,92 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref local numbers, ownnumbers = entry.numbers, entry.ownnumbers 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 ~= "" and entry.block) or sections.currentblock() -- added - if preceding then - local separator = sets.get("structure:separators",block,separatorset,preceding,".") - if separator then - processors.sprint(ctxcatcodes,separator) - end - preceding = false - end - if ownnumber ~= "" then - processors.sprint(ctxcatcodes,ownnumber) - -- elseif conversion and conversion ~= "" then - -- texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) - elseif conversion and conversion ~= "" then - -- traditional (e.g. used in itemgroups) - texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) - else - 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) - end - preceding, done = index, true - else - preceding = preceding or false - end + -- + local result = kind == "direct" and { } + if result then + connector = false end -- local prefixlist = set and sets.getall("structure:prefixes","",set) -- "" == block if starter then - processors.sprint(ctxcatcodes,starter) + if result then + result[#result+1] = ignoreprocessor(starter) + else + sprintprocessor(ctxcatcodes,starter) + end end - if prefixlist and (kind == 'section' or kind == 'prefix') then + if prefixlist and (kind == 'section' or kind == 'prefix' or kind == 'direct') then -- find valid set (problem: for sectionnumber we should pass the level) - -- if kind == "section" then - -- no holes - local b, e, bb, ee = 1, #prefixlist, 0, 0 - -- find last valid number - for k=e,b,-1 do - local prefix = prefixlist[k] - local index = sections.getlevel(prefix) or k - if index >= firstprefix and index <= lastprefix then - local number = numbers and numbers[index] - if number then - local ownnumber = ownnumbers and ownnumbers[index] or "" - if number > 0 or (ownnumber ~= "") then - break - else - e = k -1 - end + -- no holes + local b, e, bb, ee = 1, #prefixlist, 0, 0 + -- find last valid number + for k=e,b,-1 do + local prefix = prefixlist[k] + local index = sections.getlevel(prefix) or k + if index >= firstprefix and index <= lastprefix then + local number = numbers and numbers[index] + if number then + local ownnumber = ownnumbers and ownnumbers[index] or "" + if number > 0 or (ownnumber ~= "") then + break + else + e = k -1 end end end - -- find valid range - for k=b,e do - local prefix = prefixlist[k] - local index = sections.getlevel(prefix) or k - if index >= firstprefix and index <= lastprefix then - local number = numbers and numbers[index] - if number then - local ownnumber = ownnumbers and ownnumbers[index] or "" - if number > 0 or (ownnumber ~= "") then - if bb == 0 then bb = k end - ee = k - else - bb, ee = 0, 0 - end + end + -- find valid range + for k=b,e do + local prefix = prefixlist[k] + local index = sections.getlevel(prefix) or k + if index >= firstprefix and index <= lastprefix then + local number = numbers and numbers[index] + if number then + local ownnumber = ownnumbers and ownnumbers[index] or "" + if number > 0 or (ownnumber ~= "") then + if bb == 0 then bb = k end + ee = k else - break + bb, ee = 0, 0 end + else + break end end - -- print valid range - for k=bb,ee do - local prefix = prefixlist[k] - local index = sections.getlevel(prefix) or k - if index >= firstprefix and index <= lastprefix then - process(index) - end + end + -- print valid range + for k=bb,ee do + local prefix = prefixlist[k] + local index = sections.getlevel(prefix) or k + if index >= firstprefix and index <= lastprefix then + -- process(index,result) + preceding, done = process(index,numbers,ownnumbers,criterium,separatorset,conversion,conversionset,index,entry,result,preceding,done) end - -- else - -- for k=1,#prefixlist do - -- local prefix = prefixlist[k] - -- local index = sections.getlevel(prefix) or k - -- if index >= firstprefix and index <= lastprefix then - -- process(index) - -- end - -- end - -- end + end else -- also holes check - for prefix=firstprefix,lastprefix do - process(prefix) + for index=firstprefix,lastprefix do + -- process(index,result) + preceding, done = process(index,numbers,ownnumbers,criterium,separatorset,conversion,conversionset,index,entry,result,preceding,done) end end -- if done and connector and kind == 'prefix' then - processors.sprint(ctxcatcodes,connector) + if result then + -- can't happen as we're in 'direct' + else + sprintprocessor(ctxcatcodes,connector) + end elseif done and stopper then - processors.sprint(ctxcatcodes,stopper) + if result then + result[#result+1] = ignoreprocessor(stopper) + else + sprintprocessor(ctxcatcodes,stopper) + end end + return result -- a table ! else - -- report("error: no numbers") + -- report_structure("error: no numbers") end end end @@ -660,7 +695,7 @@ function sections.findnumber(depth,what) local data = data.status[depth or data.depth] if data then local index = data.references.section - local collected = jobsections.collected + local collected = sections.collected local sectiondata = collected[index] if sectiondata and sectiondata.hidenumber ~= true then -- can be nil if what == variables.first then @@ -689,7 +724,7 @@ function sections.findnumber(depth,what) end end -function sections.fullnumber(depth,what,raw) +function sections.fullnumber(depth,what) local sectiondata = sections.findnumber(depth,what) if sectiondata then sections.typesetnumber(sectiondata,'section',sectiondata) |