diff options
Diffstat (limited to 'tex/context/base/strc-reg.lua')
-rw-r--r-- | tex/context/base/strc-reg.lua | 158 |
1 files changed, 106 insertions, 52 deletions
diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua index 74dbf90e2..b406ea1b0 100644 --- a/tex/context/base/strc-reg.lua +++ b/tex/context/base/strc-reg.lua @@ -6,7 +6,10 @@ if not modules then modules = { } end modules ['strc-reg'] = { license = "see context related readme files" } -local texwrite, texsprint, count, format, gmatch = tex.write, tex.sprint, tex.count, string.format, string.gmatch +local next, type = next, type +local texwrite, texsprint, texcount = tex.write, tex.sprint, tex.count +local format, gmatch = string.format, string.gmatch +local utfchar = utf.char local ctxcatcodes = tex.ctxcatcodes @@ -118,12 +121,16 @@ local function filter_collected(names,criterium,number,collected,prevmode) local number = tonumber(number) or 0 for i=1,#collected do local v = collected[i] - local sectionnumber = jobsections.collected[v.references.section] - if sectionnumber then - local cnumbers = sectionnumber.numbers - if (all or hash[v.metadata.name]) and #cnumbers >= depth then -- was > - if cnumbers[depth] == number then - result[#result+1] = v + local r = v.references + if r then + local sectionnumber = jobsections.collected[r.section] + if sectionnumber then + local metadata = v.metadata + local cnumbers = sectionnumber.numbers + if cnumbers then + if (all or hash[metadata.name or false]) and #cnumbers >= depth and (number == 0 or cnumbers[depth] == number) then + result[#result+1] = v + end end end end @@ -146,6 +153,20 @@ local tobesaved, collected = jobregisters.tobesaved, jobregisters.collected local function initializer() tobesaved, collected = jobregisters.tobesaved, jobregisters.collected + local internals = jobreferences.internals + for name, list in next, collected do + local entries = list.entries + for e=1,#entries do + local entry = entries[e] + local r = entry.references + if r then + local internal = r and r.internal + if internal then + internals[internal] = entry + end + end + end + end end job.register('jobregisters.collected', jobregisters.tobesaved, initializer) @@ -170,34 +191,68 @@ jobregisters.define = allocate local entrysplitter = lpeg.Ct(lpeg.splitat('+')) -function jobregisters.store(rawdata) - local data = allocate(rawdata.metadata.name).entries +local tagged = { } + +local function preprocessentries(rawdata) local entries = rawdata.entries - local et = entrysplitter:match(entries[1]) -- alse & - local kt = entrysplitter:match(entries[2]) -- alse & - entries = { } - for k=1,#et do - entries[k] = { et[k] or "", kt[k] or "" } + if entries then + local et = entrysplitter:match(entries[1]) -- alse & + local kt = entrysplitter:match(entries[2]) -- alse & + entries = { } + for k=1,#et do + entries[k] = { et[k] or "", kt[k] or "" } + end + rawdata.list = entries + rawdata.entries = nil + else + rawdata.list = { "", "" } -- br end - rawdata.list = entries - rawdata.entries = nil +end + +function jobregisters.store(rawdata) -- metadata, references, entries + local data = allocate(rawdata.metadata.name).entries + local references = rawdata.references + references.realpage = references.realpage or 0 -- just to be sure as it can be refered to + preprocessentries(rawdata) data[#data+1] = rawdata + local label = references.label + if label and label ~= "" then tagged[label] = #data end texwrite(#data) end function jobregisters.enhance(name,n) local r = tobesaved[name].entries[n] if r then - r.references.realpage = tex.count[0] + r.references.realpage = texcount.realpageno end end -function jobregisters.extend(name,n,lastsection) - local r = tobesaved[name].entries[n] - if r then - r.references.lastrealpage = tex.count[0] - r.references.lastsection = lastsection - +function jobregisters.extend(name,tag,rawdata) -- maybe do lastsection internally + if type(tag) == "string" then + tag = tagged[tag] + end + if tag then + local r = tobesaved[name].entries[tag] + if r then + local rr = r.references + rr.lastrealpage = texcount.realpageno + rr.lastsection = structure.sections.currentid() + if rawdata then + preprocessentries(rawdata) + for k,v in pairs(rawdata) do + if not r[k] then + r[k] = v + else + local rk = r[k] + for kk,vv in pairs(v) do + if vv ~= "" then + rk[kk] = vv + end + end + end + end + end + end end end @@ -225,7 +280,10 @@ function jobregisters.compare(a,b) return -1 elseif a.metadata.kind == 'entry' then -- e/f/t local page_a, page_b = a.references.realpage, b.references.realpage - if page_a < page_b then + if not page_a or not page_b then +--~ print(table.serialize(a),table.serialize(b)) + return 0 + elseif page_a < page_b then return -1 elseif page_a > page_b then return 1 @@ -248,13 +306,15 @@ function jobregisters.prepare(data) for i=1, #result do local entry, split = result[i], { } local list = entry.list - for l=1,#list do - local ll = list[l] - local key, word = ll[1], ll[2] - if key == "" then - key = word + if list then + for l=1,#list do + local ll = list[l] + local word, key = ll[1], ll[2] + if not key or key == "" then + key = word + end + split[l] = splitter(strip(key)) end - split[l] = splitter(strip(key)) end entry.split = split end @@ -262,7 +322,7 @@ function jobregisters.prepare(data) end function jobregisters.sort(data,options) - sorters.sort(data.entries,jobregisters.compare) + sorters.sort(data.result,jobregisters.compare) end function jobregisters.unique(data,options) @@ -298,23 +358,13 @@ function jobregisters.finalize(data,options) data.metadata.nofsorted = #result local split = { } -- maps character to index (order) - local se = sorters.entries[options.language or sorters.defaultlanguage] or sorters.entries[sorters.defaultlanguage] for k=1,#result do local v = result[k] - local entry, tag = v.split[1][1], "" - if se and se[entry] then - if type(se[entry]) == "number" then - entry = se[entry] - end - tag = se[entry] - else - entry = 0 - tag = "unknown" - end - local s = split[entry] + local entry, tag = sorters.firstofsplit(v.split) + local s = split[tag] -- keeps track of change if not s then s = { tag = tag, data = { } } - split[entry] = s + split[tag] = s end s.data[#s.data+1] = v end @@ -324,6 +374,7 @@ end function jobregisters.analysed(class,options) local data = collected[class] if data and data.entries then + sorters.language = options.language or sorters.defaultlanguage jobregisters.filter(data,options) -- filter entries into results (criteria) jobregisters.prepare(data,options) -- adds split table parallel to list table jobregisters.sort(data,options) -- sorts results @@ -346,18 +397,21 @@ function jobregisters.flush(data,options,prefixspec,pagespec) local result = data.result -- todo ownnumber local function pagenumber(entry) - texsprint(ctxcatcodes,"\\registeronepage{") + local er = entry.references + texsprint(ctxcatcodes,format("\\registeronepage{%s}{%s}{",er.internal or 0,er.realpage or 0)) -- internal realpage content helpers.prefixpage(entry,prefixspec,pagespec) texsprint(ctxcatcodes,"}") end local function pagerange(f_entry,t_entry,is_last) - texsprint(ctxcatcodes,"\\registerpagerange{") + local er = f_entry.references + texsprint(ctxcatcodes,format("\\registerpagerange{%s}{%s}{",er.internal or 0,er.realpage or 0)) helpers.prefixpage(f_entry,prefixspec,pagespec) - texsprint(ctxcatcodes,"}{") + local er = t_entry.references + texsprint(ctxcatcodes,format("}{%s}{%s}{",er.internal or 0,er.realpage or 0)) if is_last then - helpers.prefixpage(t_entry,prefixspec,pagespec) + helpers.prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys else - helpers.prefixlastpage(t_entry,prefixspec,pagespec) + helpers.prefixpage(t_entry,prefixspec,pagespec) end texsprint(ctxcatcodes,"}") end @@ -424,7 +478,7 @@ function jobregisters.flush(data,options,prefixspec,pagespec) first, last, prev = nil, nil, nil elseif not first then first, prev = next, next - elseif next.references.realpage - prev.references.realpage == 1 then + elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ? last, prev = next, next else pages[#pages+1] = { first, last or first } @@ -449,7 +503,7 @@ function jobregisters.flush(data,options,prefixspec,pagespec) local first_last_pn = first_last .references.realpage local second_first_pn = second_first.references.realpage local second_last_pn = second_last .references.realpage - local first_last_last = first_last.references.lastrealpage + local first_last_last = first_last .references.lastrealpage local second_first_last = second_first.references.lastrealpage if first_last_last then first_last_pn = first_last_last @@ -550,7 +604,7 @@ function jobregisters.flush(data,options,prefixspec,pagespec) elseif kind == 'see' then -- maybe some day more words texsprint(ctxcatcodes,"\\startregisterseewords") - texsprint(ctxcatcodes,format("\\registeroneword{%s}",entry.seeword.text)) + texsprint(ctxcatcodes,format("\\registeroneword{0}{0}{%s}",entry.seeword.text)) -- todo: internal texsprint(ctxcatcodes,"\\stopregisterseewords") end end |