diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
commit | fc4466b32ed330a956ac603b00fd145524cff49a (patch) | |
tree | 2c50e2b8de13aa9233b2c76dffe201558f169e86 /Master/texmf-dist/tex/context/base/strc-lst.lua | |
parent | 50e2368597d5f6fe2057195d0ae6a9f2044923e4 (diff) |
context (22apr16)
git-svn-id: svn://tug.org/texlive/trunk@40691 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-lst.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/strc-lst.lua | 1307 |
1 files changed, 0 insertions, 1307 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-lst.lua b/Master/texmf-dist/tex/context/base/strc-lst.lua deleted file mode 100644 index fd79bbd7a9c..00000000000 --- a/Master/texmf-dist/tex/context/base/strc-lst.lua +++ /dev/null @@ -1,1307 +0,0 @@ -if not modules then modules = { } end modules ['strc-lst'] = { - version = 1.001, - comment = "companion to strc-lst.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- when all datastructures are stable a packer will be added which will --- bring down memory consumption a bit; we can use for instance a pagenumber, --- section, metadata cache (internal then has to move up one level) or a --- shared cache [we can use a fast and stupid serializer] - --- todo: tag entry in list is crap --- --- move more to commands - -local tonumber, type = tonumber, type -local concat, insert, remove, sort = table.concat, table.insert, table.remove, table.sort -local lpegmatch = lpeg.match - -local setmetatableindex = table.setmetatableindex -local sortedkeys = table.sortedkeys - -local settings_to_set = utilities.parsers.settings_to_set -local allocate = utilities.storage.allocate -local checked = utilities.storage.checked - -local trace_lists = false trackers.register("structures.lists", function(v) trace_lists = v end) - -local report_lists = logs.reporter("structure","lists") - -local context = context -local commands = commands -local implement = interfaces.implement - -local structures = structures -local lists = structures.lists -local sections = structures.sections -local helpers = structures.helpers -local documents = structures.documents -local tags = structures.tags -local counters = structures.counters -local references = structures.references - -local collected = allocate() -local tobesaved = allocate() -local cached = allocate() -local pushed = allocate() -local kinds = allocate() -local names = allocate() - -lists.collected = collected -lists.tobesaved = tobesaved - -lists.enhancers = lists.enhancers or { } ------.internals = allocate(lists.internals or { }) -- to be checked -lists.ordered = allocate(lists.ordered or { }) -- to be checked -lists.cached = cached -lists.pushed = pushed -lists.kinds = kinds -lists.names = names - -local sorters = sorters -local sortstripper = sorters.strip -local sortsplitter = sorters.splitters.utf -local sortcomparer = sorters.comparers.basic - -local sectionblocks = allocate() -lists.sectionblocks = sectionblocks - -references.specials = references.specials or { } - -local matchingtilldepth = sections.matchingtilldepth -local numberatdepth = sections.numberatdepth -local getsectionlevel = sections.getlevel -local typesetnumber = sections.typesetnumber -local autosectiondepth = sections.autodepth - -local variables = interfaces.variables - -local v_all = variables.all -local v_reference = variables.reference -local v_title = variables.title -local v_number = variables.reference -local v_command = variables.command -local v_text = variables.text -local v_current = variables.current -local v_previous = variables.previous -local v_next = variables.next -local v_intro = variables.intro -local v_here = variables.here -local v_component = variables.component -local v_reference = variables.reference -local v_local = variables["local"] -local v_default = variables.default - --- for the moment not public -- - -local function zerostrippedconcat(t,separator) - local f, l = 1, #t - for i=f,l do - if t[i] == 0 then - f = f + 1 - end - end - for i=l,f,-1 do - if t[i] == 0 then - l = l - 1 - end - end - return concat(t,separator,f,l) -end - --- -- -- -- -- -- - -local function initializer() - -- create a cross reference between internal references - -- and list entries - local collected = lists.collected - local internals = checked(references.internals) - local ordered = lists.ordered - local usedinternals = references.usedinternals - local blockdone = { } - for i=1,#collected do - local c = collected[i] - local m = c.metadata - local r = c.references - if m then - -- access by internal reference - if r then - local internal = r.internal - if internal then - internals[internal] = c - usedinternals[internal] = r.used - end - local block = r.block - if block and not blockdone[block] then - blockdone[block] = true - sectionblocks[#sectionblocks+1] = block - end - end - -- access by order in list - local kind = m.kind - local name = m.name - if kind and name then - local ok = ordered[kind] - if ok then - local on = ok[name] - if on then - on[#on+1] = c - else - ok[name] = { c } - end - else - ordered[kind] = { [name] = { c } } - end - kinds[kind] = true - names[name] = true - elseif kind then - kinds[kind] = true - elseif name then - names[name] = true - end - end - if r then - r.listindex = i -- handy to have - end - end -end - -local function finalizer() - local flaginternals = references.flaginternals - local usedviews = references.usedviews - for i=1,#tobesaved do - local r = tobesaved[i].references - if r then - local i = r.internal - local f = flaginternals[i] - if f then - r.used = usedviews[i] or true - end - end - end -end - -job.register('structures.lists.collected', tobesaved, initializer, finalizer) - -local groupindices = setmetatableindex("table") - -function lists.groupindex(name,group) - local groupindex = groupindices[name] - return groupindex and groupindex[group] or 0 -end - --- we could use t (as hash key) in order to check for dup entries - -function lists.addto(t) -- maybe more more here (saves parsing at the tex end) - local metadata = t.metadata - local userdata = t.userdata - local numberdata = t.numberdata - if userdata and type(userdata) == "string" then - t.userdata = helpers.touserdata(userdata) - end - if not metadata.level then - metadata.level = structures.sections.currentlevel() -- this is not used so it will go away - end - if numberdata then - local numbers = numberdata.numbers - if type(numbers) == "string" then - numberdata.numbers = counters.compact(numbers,nil,true) - end - end - local group = numberdata and numberdata.group - local name = metadata.name - if not group then - -- forget about it - elseif group == "" then - group, numberdata.group = nil, nil - else - local groupindex = groupindices[name][group] - if groupindex then - numberdata.numbers = cached[groupindex].numberdata.numbers - end - end - local setcomponent = references.setcomponent - if setcomponent then - setcomponent(t) -- can be inlined - end - local r = t.references - if r and not r.section then - r.section = structures.sections.currentid() - end - local i = r and r.internal or 0 -- brrr - local p = pushed[i] - if not p then - p = #cached + 1 - cached[p] = helpers.simplify(t) - pushed[i] = p - r.listindex = p - end - if group then - groupindices[name][group] = p - end - if trace_lists then - report_lists("added %a, internal %a",name,p) - end - return p -end - -function lists.discard(n) - n = tonumber(n) - if not n then - -- maybe an error message - elseif n == #cached then - cached[n] = nil - n = n -1 - while n > 0 and cached[n] == false do - cached[n] = nil -- collect garbage - n = n - 1 - end - else - cached[n] = false - end -end - -function lists.iscached(n) - return cached[tonumber(n)] -end - --- this is the main pagenumber enhancer - -local enhanced = { } - -local synchronizepage = function(r) -- bah ... will move - synchronizepage = references.synchronizepage - return synchronizepage(r) -end - -function lists.enhance(n) - local l = cached[n] - if not l then - report_lists("enhancing %a, unknown internal",n) - elseif enhanced[n] then - if trace_lists then - report_lists("enhancing %a, name %a, duplicate ignored",n,name) - end - else - local metadata = l.metadata - local references = l.references - -- - l.directives = nil -- might change - -- save in the right order (happens at shipout) - lists.tobesaved[#lists.tobesaved+1] = l - -- default enhancer (cross referencing) - synchronizepage(references) - -- tags - local kind = metadata.kind - local name = metadata.name - if trace_lists then - report_lists("enhancing %a, name %a",n,name) - end - if references then - -- is this used ? - local tag = tags.getid(kind,name) - if tag and tag ~= "?" then - references.tag = tag - end - end - -- specific enhancer (kind of obsolete) - local enhancer = kind and lists.enhancers[kind] - if enhancer then - enhancer(l) - end - -- - enhanced[n] = true - return l - end -end - --- we can use level instead but we can also decide to remove level from the metadata - -local nesting = { } - -function lists.pushnesting(i) - local parent = lists.result[i] - local name = parent.metadata.name - local numberdata = parent and parent.numberdata - local numbers = numberdata and numberdata.numbers - local number = numbers and numbers[getsectionlevel(name)] or 0 - insert(nesting, { - number = number, - name = name, - result = lists.result, - parent = parent - }) -end - -function lists.popnesting() - local old = remove(nesting) - if old then - lists.result = old.result - else - report_lists("nesting error") - end -end - --- Historically we had blocks but in the mkiv approach that could as well be a level --- which would simplify things a bit. - -local splitter = lpeg.splitat(":") -- maybe also :: or have a block parameter - -local listsorters = { - [v_command] = function(a,b) - if a.metadata.kind == "command" or b.metadata.kind == "command" then - return a.references.internal < b.references.internal - else - return a.references.order < b.references.order - end - end, - [v_all] = function(a,b) - return a.references.internal < b.references.internal - end, - [v_title] = function(a,b) - local da = a.titledata - local db = b.titledata - if da and db then - local ta = da.title - local tb = db.title - if ta and tb then - local sa = da.split - if not sa then - sa = sortsplitter(sortstripper(ta)) - da.split = sa - end - local sb = db.split - if not sb then - sb = sortsplitter(sortstripper(tb)) - db.split = sb - end - return sortcomparer(da,db) == -1 - end - end - return a.references.internal < b.references.internal - end -} - --- was: names, criterium, number, collected, forced, nested, sortorder - -local filters = setmetatableindex(function(t,k) return t[v_default] end) - -local function filtercollected(specification) - -- - local names = specification.names or { } - local criterium = specification.criterium or v_default - local number = 0 -- specification.number - local reference = specification.reference or "" - local collected = specification.collected or lists.collected - local forced = specification.forced or { } - local nested = specification.nested or false - local sortorder = specification.sortorder or specification.order - -- - local numbers = documents.data.numbers - local depth = documents.data.depth - local block = false -- all - local wantedblock, wantedcriterium = lpegmatch(splitter,criterium) -- block:criterium - if wantedblock == "" or wantedblock == v_all or wantedblock == v_text then - criterium = wantedcriterium ~= "" and wantedcriterium or criterium - elseif not wantedcriterium then - block = documents.data.block - else - block, criterium = wantedblock, wantedcriterium - end - if block == "" then - block = false - end - if type(names) == "string" then - names = settings_to_set(names) - end - local all = not next(names) or names[v_all] or false - -- - specification.names = names - specification.criterium = criterium - specification.number = 0 -- obsolete - specification.reference = reference -- new - specification.collected = collected - specification.forced = forced -- todo: also on other branched, for the moment only needed for bookmarks - specification.nested = nested - specification.sortorder = sortorder - specification.numbers = numbers - specification.depth = depth - specification.block = block - specification.all = all - -- - if trace_lists then - report_lists("filtering names %,t, criterium %a, block %a",sortedkeys(names), criterium, block or "*") - end - local result = filters[criterium](specification) - if trace_lists then - report_lists("criterium %a, block %a, found %a",specification.criterium, specification.block or "*", #result) - end - -- - if sortorder then -- experiment - local sorter = listsorters[sortorder] - if sorter then - if trace_lists then - report_lists("sorting list using method %a",sortorder) - end - for i=1,#result do - result[i].references.order = i - end - sort(result,sorter) - end - end - -- - return result -end - -filters[v_intro] = function(specification) - local collected = specification.collected - local result = { } - local nofresult = #result - local all = specification.all - local names = specification.names - for i=1,#collected do - local v = collected[i] - local metadata = v.metadata - if metadata and (all or names[metadata.name or false]) then - local r = v.references - if r and r.section == 0 then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - return result -end - -filters[v_reference] = function(specification) - local collected = specification.collected - local result = { } - local nofresult = #result - local names = specification.names - local sections = sections.collected - local reference = specification.reference - if reference ~= "" then - local prefix, rest = lpegmatch(references.prefixsplitter,reference) -- p::r - local r = prefix and rest and references.derived[prefix][rest] or references.derived[""][reference] - local s = r and r.numberdata -- table ref ! - if s then - local depth = getsectionlevel(r.metadata.name) - local numbers = s.numbers - for i=1,#collected do - local v = collected[i] - local r = v.references - if r and (not block or not r.block or block == r.block) then - local metadata = v.metadata - if metadata and names[metadata.name or false] then - local sectionnumber = (r.section == 0) or sections[r.section] - if sectionnumber then - if matchingtilldepth(depth,numbers,sectionnumber.numbers) then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - end - end - else - report_lists("unknown reference %a specified",reference) - end - else - report_lists("no reference specified") - end - return result -end - -filters[v_all] = function(specification) - local collected = specification.collected - local result = { } - local nofresult = #result - local block = specification.block - local all = specification.all - local forced = specification.forced - local names = specification.names - local sections = sections.collected - for i=1,#collected do - local v = collected[i] - local r = v.references - if r and (not block or not r.block or block == r.block) then - local metadata = v.metadata - if metadata then - local name = metadata.name or false - local sectionnumber = (r.section == 0) or sections[r.section] - if forced[name] or (sectionnumber and not metadata.nolist and (all or names[name])) then -- and not sectionnumber.hidenumber then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - end - return result -end - -filters[v_text] = filters[v_all] - -filters[v_current] = function(specification) - if specification.depth == 0 then - specification.nested = false - specification.criterium = v_intro - return filters[v_intro](specification) - end - local collected = specification.collected - local result = { } - local nofresult = #result - local depth = specification.depth - local block = specification.block - local all = specification.all - local names = specification.names - local numbers = specification.numbers - local sections = sections.collected - for i=1,#collected do - local v = collected[i] - local r = v.references - if r and (not block or not r.block or block == r.block) then - local sectionnumber = sections[r.section] - if sectionnumber then -- and not sectionnumber.hidenumber then - local cnumbers = sectionnumber.numbers - local metadata = v.metadata - if cnumbers then - if metadata and not metadata.nolist and (all or names[metadata.name or false]) and #cnumbers > depth then - local ok = true - for d=1,depth do - local cnd = cnumbers[d] - if not (cnd == 0 or cnd == numbers[d]) then - ok = false - break - end - end - if ok then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - end - end - end - return result -end - -filters[v_here] = function(specification) - -- this is quite dirty ... as cnumbers is not sparse we can misuse #cnumbers - if specification.depth == 0 then - specification.nested = false - specification.criterium = v_intro - return filters[v_intro](specification) - end - local collected = specification.collected - local result = { } - local nofresult = #result - local depth = specification.depth - local block = specification.block - local all = specification.all - local names = specification.names - local numbers = specification.numbers - local sections = sections.collected - for i=1,#collected do - local v = collected[i] - local r = v.references - if r then -- and (not block or not r.block or block == r.block) then - local sectionnumber = sections[r.section] - if sectionnumber then -- and not sectionnumber.hidenumber then - local cnumbers = sectionnumber.numbers - local metadata = v.metadata - if cnumbers then - if metadata and not metadata.nolist and (all or names[metadata.name or false]) and #cnumbers >= depth then - local ok = true - for d=1,depth do - local cnd = cnumbers[d] - if not (cnd == 0 or cnd == numbers[d]) then - ok = false - break - end - end - if ok then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - end - end - end - return result -end - -filters[v_previous] = function(specification) - if specification.depth == 0 then - specification.nested = false - specification.criterium = v_intro - return filters[v_intro](specification) - end - local collected = specification.collected - local result = { } - local nofresult = #result - local block = specification.block - local all = specification.all - local names = specification.names - local numbers = specification.numbers - local sections = sections.collected - local depth = specification.depth - for i=1,#collected do - local v = collected[i] - local r = v.references - if r and (not block or not r.block or block == r.block) then - local sectionnumber = sections[r.section] - if sectionnumber then -- and not sectionnumber.hidenumber then - local cnumbers = sectionnumber.numbers - local metadata = v.metadata - if cnumbers then - if metadata and not metadata.nolist and (all or names[metadata.name or false]) and #cnumbers >= depth then - local ok = true - for d=1,depth-1 do - local cnd = cnumbers[d] - if not (cnd == 0 or cnd == numbers[d]) then - ok = false - break - end - end - if ok then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - end - end - end - return result -end - -filters[v_local] = function(specification) - local numbers = specification.numbers - local nested = nesting[#nesting] - if nested then - return filtercollected { - names = specification.names, - criterium = nested.name, - collected = specification.collected, - forced = specification.forced, - nested = nested, - sortorder = specification.sortorder, - } - else - specification.criterium = autosectiondepth(numbers) == 0 and v_all or v_current - specification.nested = false - return filtercollected(specification) -- rechecks, so better (for determining all) - end -end - - -filters[v_component] = function(specification) - -- special case, no structure yet - local collected = specification.collected - local result = { } - local nofresult = #result - local all = specification.all - local names = specification.names - local component = resolvers.jobs.currentcomponent() or "" - if component ~= "" then - for i=1,#collected do - local v = collected[i] - local r = v.references - local m = v.metadata - if r and r.component == component and (m and names[m.name] or all) then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - return result -end - --- local number = tonumber(number) or numberatdepth(depth) or 0 --- if number > 0 then --- ... --- end - -filters[v_default] = function(specification) -- is named - local collected = specification.collected - local result = { } - local nofresult = #result - ----- depth = specification.depth - local block = specification.block - local criterium = specification.criterium - local all = specification.all - local names = specification.names - local numbers = specification.numbers - local sections = sections.collected - local reference = specification.reference - local nested = specification.nested - -- - if reference then - reference = tonumber(reference) - end - -- - local depth = getsectionlevel(criterium) - local pnumbers = nil - local pblock = block - local parent = nested and nested.parent - -- - if parent then - pnumbers = parent.numberdata.numbers or pnumbers -- so local as well as nested - pblock = parent.references.block or pblock - if trace_lists then - report_lists("filtering by block %a and section %a",pblock,criterium) - end - end - -- - for i=1,#collected do - local v = collected[i] - local r = v.references - if r and (not block or not r.block or pblock == r.block) then - local sectionnumber = sections[r.section] - if sectionnumber then - local metadata = v.metadata - local cnumbers = sectionnumber.numbers - if cnumbers then - if all or names[metadata.name or false] then - if reference then - -- filter by number - if reference == cnumbers[depth] then - nofresult = nofresult + 1 - result[nofresult] = v - end - else - if #cnumbers >= depth and matchingtilldepth(depth,cnumbers,pnumbers) then - nofresult = nofresult + 1 - result[nofresult] = v - end - end - end - end - end - end - end - return result -end - --- names, criterium, number, collected, forced, nested, sortorder) -- names is hash or string - -lists.filter = filtercollected - -lists.result = { } - -function lists.getresult(r) - return lists.result[r] -end - -function lists.process(specification) - lists.result = filtercollected(specification) - local specials = settings_to_set(specification.extras or "") - specials = next(specials) and specials or nil - for i=1,#lists.result do - local r = lists.result[i] - local m = r.metadata - local s = specials and r.numberdata and specials[zerostrippedconcat(r.numberdata.numbers,".")] or "" - context.strclistsentryprocess(m.name,m.kind,i,s) - end -end - -function lists.analyze(specification) - lists.result = filtercollected(specification) -end - -function lists.userdata(name,r,tag) -- to tex (todo: xml) - local result = lists.result[r] - if result then - local userdata, metadata = result.userdata, result.metadata - local str = userdata and userdata[tag] - if str then - return str, metadata - end - end -end - -function lists.uservalue(name,r,tag,default) -- to lua - local str = lists.result[r] - str = str and str.userdata - str = str and str[tag] - return str or default -end - -function lists.size() - return #lists.result -end - -function lists.location(n) - local l = lists.result[n] - return l and l.references.internal or n -end - -function lists.label(n,default) - local l = lists.result[n] - local t = l.titledata - return t and t.label or default or "" -end - -function lists.sectionnumber(name,n,spec) - local data = lists.result[n] - local sectiondata = sections.collected[data.references.section] - -- hm, prefixnumber? - typesetnumber(sectiondata,"prefix",spec,sectiondata) -- data happens to contain the spec too -end - --- some basics (todo: helpers for pages) - -function lists.title(name,n,tag) -- tag becomes obsolete - local data = lists.result[n] - if data then - local titledata = data.titledata - if titledata then - helpers.title(titledata[tag] or titledata.list or titledata.title or "",data.metadata) - end - end -end - -function lists.hastitledata(name,n,tag) - local data = cached[tonumber(n)] - if data then - local titledata = data.titledata - if titledata then - return (titledata[tag] or titledata.title or "") == "" - end - end - return false -end - -function lists.haspagedata(name,n) - local data = lists.result[n] - if data then - local references = data.references - if references and references.realpage then -- or references.pagedata - return true - end - end - return false -end - -function lists.hasnumberdata(name,n) - local data = lists.result[n] - if data then - local numberdata = data.numberdata - if numberdata and not numberdata.hidenumber then -- th ehide number is true - return true - end - end - return false -end - -function lists.prefix(name,n,spec) - helpers.prefix(lists.result[n],spec) -end - -function lists.page(name,n,pagespec) - helpers.page(lists.result[n],pagespec) -end - -function lists.prefixedpage(name,n,prefixspec,pagespec) - helpers.prefixpage(lists.result[n],prefixspec,pagespec) -end - -function lists.realpage(name,n) - local data = lists.result[n] - if data then - local references = data.references - return references and references.realpage or 0 - else - return 0 - end -end - --- numbers stored in entry.numberdata + entry.numberprefix - -function lists.number(name,n,spec) - local data = lists.result[n] - if data then - local numberdata = data.numberdata - if numberdata then - typesetnumber(numberdata,"number",spec or false,numberdata or false) - end - end -end - -function lists.prefixednumber(name,n,prefixspec,numberspec,forceddata) - local data = lists.result[n] - if data then - helpers.prefix(data,prefixspec) - local numberdata = data.numberdata or forceddata - if numberdata then - typesetnumber(numberdata,"number",numberspec or false,numberdata or false) - end - end -end - --- todo, do this in references namespace ordered instead (this is an experiment) --- --- also see lpdf-ano (maybe move this there) - -local splitter = lpeg.splitat(":") - -function references.specials.order(var,actions) -- references.specials ! - local operation = var.operation - if operation then - local kind, name, n = lpegmatch(splitter,operation) - local order = lists.ordered[kind] - order = order and order[name] - local v = order[tonumber(n)] - local r = v and v.references.realpage - if r then - actions.realpage = r - var.operation = r -- brrr, but test anyway - return references.specials.page(var,actions) - end - end -end - --- interface (maybe strclistpush etc) - -if not lists.reordered then - function lists.reordered(data) - return data.numberdata - end -end - -implement { name = "pushlist", actions = lists.pushnesting, arguments = "integer" } -implement { name = "poplist", actions = lists.popnesting } - -implement { - name = "addtolist", - actions = { lists.addto, context }, - arguments = { - { - { "references", { - { "internal", "integer" }, - { "block" }, - { "section", "integer" }, - { "location" }, - { "prefix" }, - { "reference" }, - { "order", "integer" }, - } - }, - { "metadata", { - { "kind" }, - { "name" }, - { "level", "integer" }, - { "catcodes", "integer" }, - { "coding" }, - { "xmlroot" }, - { "setup" }, - } - }, - { "userdata" }, - { "titledata", { - { "label" }, - { "title" }, - { "bookmark" }, - { "marking" }, - { "list" }, - } - }, - { "prefixdata", { - { "prefix" }, - { "separatorset" }, - { "conversionset" }, - { "conversion" }, - { "set" }, - { "segments" }, - { "connector" }, - } - }, - { "numberdata", { - { "numbers" }, - { "groupsuffix" }, - { "group" }, - { "counter" }, - { "separatorset" }, - { "conversionset" }, - { "conversion" }, - { "starter" }, - { "stopper" }, - { "segments" }, - } - } - } - } -} - -implement { - name = "enhancelist", - actions = lists.enhance, - arguments = "integer" -} - -implement { - name = "processlist", - actions = lists.process, - arguments = { - { - { "names" }, - { "criterium" }, - { "reference" }, - { "extras" }, - { "order" }, - } - } -} - -implement { - name = "analyzelist", - actions = lists.analyze, - arguments = { - { - { "names" }, - { "criterium" }, - { "reference" }, - } - } -} - -implement { - name = "listtitle", - actions = lists.title, - arguments = { "string", "integer" } -} - -implement { - name = "listprefixednumber", - actions = lists.prefixednumber, - arguments = { - "string", - "integer", - { - { "prefix" }, - { "separatorset" }, - { "conversionset" }, - { "starter" }, - { "stopper" }, - { "set" }, - { "segments" }, - { "connector" }, - }, - { - { "separatorset" }, - { "conversionset" }, - { "starter" }, - { "stopper" }, - { "segments" }, - } - } -} - -implement { - name = "listprefixedpage", - actions = lists.prefixedpage, - arguments = { - "string", - "integer", - { - { "separatorset" }, - { "conversionset" }, - { "set" }, - { "segments" }, - { "connector" }, - }, - { - { "prefix" }, - { "conversionset" }, - { "starter" }, - { "stopper" }, - } - } -} - -implement { name = "listsize", actions = { lists.size, context } } -implement { name = "listlocation", actions = { lists.location, context }, arguments = "integer" } -implement { name = "listlabel", actions = { lists.label, context }, arguments = { "integer", "string" } } -implement { name = "listrealpage", actions = { lists.realpage, context }, arguments = { "string", "integer" } } -implement { name = "listgroupindex", actions = { lists.groupindex, context }, arguments = { "string", "string" } } - -implement { - name = "currentsectiontolist", - actions = { sections.current, lists.addto, context } -} - -local function userdata(name,r,tag) - local str, metadata = lists.userdata(name,r,tag) - if str then - -- local catcodes = metadata and metadata.catcodes - -- if catcodes then - -- context.sprint(catcodes,str) - -- else - -- context(str) - -- end - helpers.title(str,metadata) - end -end - -implement { - name = "listuserdata", - actions = userdata, - arguments = { "string", "integer", "string" } -} - --- we could also set variables .. names will change (when this module is done) --- maybe strc_lists_savedtitle etc - -implement { name = "doifelselisthastitle", actions = { lists.hastitledata, commands.doifelse }, arguments = { "string", "integer" } } -implement { name = "doifelselisthaspage", actions = { lists.haspagedata, commands.doifelse }, arguments = { "string", "integer" } } -implement { name = "doifelselisthasnumber", actions = { lists.hasnumberdata, commands.doifelse }, arguments = { "string", "integer" } } -implement { name = "doifelselisthasentry", actions = { lists.iscached, commands.doifelse }, arguments = { "integer" } } - -local function savedlisttitle(name,n,tag) - local data = cached[tonumber(n)] - if data then - local titledata = data.titledata - if titledata then - helpers.title(titledata[tag] or titledata.title or "",data.metadata) - end - end -end - -local function savedlistnumber(name,n) - local data = cached[tonumber(n)] - if data then - local numberdata = data.numberdata - if numberdata then - typesetnumber(numberdata,"number",numberdata or false) - end - end -end - -local function savedlistprefixednumber(name,n) - local data = cached[tonumber(n)] - if data then - local numberdata = lists.reordered(data) - if numberdata then - helpers.prefix(data,data.prefixdata) - typesetnumber(numberdata,"number",numberdata or false) - end - end -end - -lists.savedlisttitle = savedlisttitle -lists.savedlistnumber = savedlistnumber -lists.savedlistprefixednumber = savedlistprefixednumber - -implement { - name = "savedlistnumber", - actions = savedlistnumber, - arguments = { "string", "integer" } -} - -implement { - name = "savedlisttitle", - actions = savedlisttitle, - arguments = { "string", "integer" } -} - -implement { - name = "savedlistprefixednumber", - actions = savedlistprefixednumber, - arguments = { "string", "integer" } -} - -implement { - name = "discardfromlist", - actions = lists.discard, - arguments = { "integer" } -} - --- new and experimental and therefore off by default - -lists.autoreorder = false -- true - -local function addlevel(t,k) - local v = { } - setmetatableindex(v,function(t,k) - local v = { } - t[k] = v - return v - end) - t[k] = v - return v -end - -local internals = setmetatableindex({ }, function(t,k) - - local sublists = setmetatableindex({ },addlevel) - - local collected = lists.collected or { } - - for i=1,#collected do - local entry = collected[i] - local numberdata = entry.numberdata - if numberdata then - local metadata = entry.metadata - if metadata then - local references = entry.references - if references then - local kind = metadata.kind - local name = numberdata.counter or metadata.name - local internal = references.internal - if kind and name and internal then - local sublist = sublists[kind][name] - sublist[#sublist + 1] = { internal, numberdata } - end - end - end - end - end - - for k, v in next, sublists do - for k, v in next, v do - local tmp = { } - for i=1,#v do - tmp[i] = v[i] - end - sort(v,function(a,b) return a[1] < b[1] end) - for i=1,#v do - t[v[i][1]] = tmp[i][2] - end - end - end - - setmetatableindex(t,nil) - - return t[k] - -end) - -function lists.reordered(entry) - local numberdata = entry.numberdata - if lists.autoreorder then - if numberdata then - local metadata = entry.metadata - if metadata then - local references = entry.references - if references then - local kind = metadata.kind - local name = numberdata.counter or metadata.name - local internal = references.internal - if kind and name and internal then - return internals[internal] or numberdata - end - end - end - end - else - function lists.reordered(entry) - return entry.numberdata - end - end - return numberdata -end |