diff options
author | Hans Hagen <pragma@wxs.nl> | 2018-06-22 16:42:14 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2018-06-22 16:42:14 +0200 |
commit | da8162d4e816cf49d9790a1c81556b499f442bed (patch) | |
tree | 5c631b1fb8282670a6cea1087afa766a8b94db43 /tex/context/base/mkiv/strc-reg.lua | |
parent | 204057fdc5023b5f4ff55a69bc6593388ea427e7 (diff) | |
download | context-da8162d4e816cf49d9790a1c81556b499f442bed.tar.gz |
2018-06-22 16:02:00
Diffstat (limited to 'tex/context/base/mkiv/strc-reg.lua')
-rw-r--r-- | tex/context/base/mkiv/strc-reg.lua | 266 |
1 files changed, 148 insertions, 118 deletions
diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua index b4d660c2b..b51106e6a 100644 --- a/tex/context/base/mkiv/strc-reg.lua +++ b/tex/context/base/mkiv/strc-reg.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['strc-reg'] = { } local next, type, tonumber = next, type, tonumber -local format, gmatch = string.format, string.gmatch +local char, format, gmatch = string.char, string.format, string.gmatch local equal, concat, remove = table.are_equal, table.concat, table.remove local lpegmatch, P, C, Ct = lpeg.match, lpeg.P, lpeg.C, lpeg.Ct local allocate = utilities.storage.allocate @@ -782,24 +782,28 @@ local function crosslinkseewords(result) -- all words local seeparent = seeparents[text] if seeparent then local seeindex = seewords[text] - local s, ns, d, w, l = { }, 0, data.split, seeparent.split, data.list - -- trick: we influence sorting by adding fake subentries - for i=1,#d do - ns = ns + 1 - s[ns] = d[i] -- parent - end - for i=1,#w do - ns = ns + 1 - s[ns] = w[i] -- see - end - data.split = s - -- we also register a fake extra list entry so that the - -- collapser works okay - l[#l+1] = { text, "" } +-- local s, ns, d, w, l = { }, 0, data.split, seeparent.split, data.list +-- -- trick: we influence sorting by adding fake subentries +-- for i=1,#d do +-- ns = ns + 1 +-- s[ns] = d[i] -- parent +-- end +-- for i=1,#w do +-- ns = ns + 1 +-- s[ns] = w[i] -- see +-- end +-- data.split = s +-- -- we also register a fake extra list entry so that the +-- -- collapser works okay +-- l[#l+1] = { text, "" } data.references.seeindex = seeindex if trace_registers then report_registers("see crosslink %03i: %s",seeindex,text) end + seeword.valid = true + else + report_registers("invalid crosslink : %s",text) + seeword.valid = false end end end @@ -829,11 +833,16 @@ function registers.prepare(data) local splitter = sorters.splitters.utf local result = data.result if result then + local seeprefix = char(0) for i=1, #result do local entry = result[i] local split = { } local list = entry.list if list then +if entry.seeword then + -- we can have multiple seewords, only two levels supported + list[#list+1] = { seeprefix .. strip(entry.seeword.text) } +end for l=1,#list do local ll = list[l] local word = ll[1] @@ -1125,6 +1134,7 @@ function registers.flush(data,options,prefixspec,pagespec) end -- ok, this is tricky: we use e[i] delayed so we need it to be local -- but we don't want to allocate too many entries so there we go + while d < #data do d = d + 1 local entry = data[d] @@ -1163,8 +1173,8 @@ function registers.flush(data,options,prefixspec,pagespec) started = false end if n == i then --- ctx_stopregisterentries() --- ctx_startregisterentries(n) + -- ctx_stopregisterentries() + -- ctx_startregisterentries(n) else while n > i do n = n - 1 @@ -1192,120 +1202,123 @@ function registers.flush(data,options,prefixspec,pagespec) end end end - if kind == 'entry' then - if show_page_number then - ctx_startregisterpages() - if collapse_singles or collapse_ranges then - -- we collapse ranges and keep existing ranges as they are - -- so we get prebuilt as well as built ranges - local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0 - while dd < #data do - dd = dd + 1 - local next = data[dd] - if next and next.metadata.kind == "see" then - dd = dd - 1 - break - else - local el, nl = entry.list, next.list - if not equal(el,nl) then - dd = dd - 1 - --~ first = nil - break - elseif next.references.lastrealpage then - nofpages = nofpages + 1 - pages[nofpages] = first and { first, last or first } or { entry, entry } - nofpages = nofpages + 1 - pages[nofpages] = { next, next } - first, last, prev = nil, nil, nil - elseif not first then - first, prev = next, next - elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ? - last, prev = next, next - else - nofpages = nofpages + 1 - pages[nofpages] = { first, last or first } - first, last, prev = next, nil, next - end - end - end - if first then + + local function case_1() + -- we collapse ranges and keep existing ranges as they are + -- so we get prebuilt as well as built ranges + local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0 + while dd < #data do + dd = dd + 1 + local next = data[dd] + if next and next.metadata.kind == "see" then + dd = dd - 1 + break + else + local el, nl = entry.list, next.list + if not equal(el,nl) then + dd = dd - 1 + --~ first = nil + break + elseif next.references.lastrealpage then + nofpages = nofpages + 1 + pages[nofpages] = first and { first, last or first } or { entry, entry } + nofpages = nofpages + 1 + pages[nofpages] = { next, next } + first, last, prev = nil, nil, nil + elseif not first then + first, prev = next, next + elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ? + last, prev = next, next + else nofpages = nofpages + 1 pages[nofpages] = { first, last or first } + first, last, prev = next, nil, next end - if collapse_ranges and nofpages > 1 then - nofpages = collapsepages(pages) - end - if nofpages > 0 then -- or 0 - d = dd - for p=1,nofpages do - local first, last = pages[p][1], pages[p][2] - if first == last then - if first.references.lastrealpage then - pagerange(first,first,true,prefixspec,pagespec) - else - pagenumber(first,prefixspec,pagespec) - end - elseif last.references.lastrealpage then - pagerange(first,last,true,prefixspec,pagespec) - else - pagerange(first,last,false,prefixspec,pagespec) - end + end + end + if first then + nofpages = nofpages + 1 + pages[nofpages] = { first, last or first } + end + if collapse_ranges and nofpages > 1 then + nofpages = collapsepages(pages) + end + if nofpages > 0 then -- or 0 + d = dd + for p=1,nofpages do + local first, last = pages[p][1], pages[p][2] + if first == last then + if first.references.lastrealpage then + pagerange(first,first,true,prefixspec,pagespec) + else + pagenumber(first,prefixspec,pagespec) end - elseif entry.references.lastrealpage then - pagerange(entry,entry,true,prefixspec,pagespec) + elseif last.references.lastrealpage then + pagerange(first,last,true,prefixspec,pagespec) else - pagenumber(entry,prefixspec,pagespec) + pagerange(first,last,false,prefixspec,pagespec) end - elseif collapse_packed then - local first = nil - local last = nil - while true do - if not first then - first = entry - end - last = entry - if d == #data then - break - else - d = d + 1 - local next = data[d] - if next.metadata.kind == "see" or not equal(entry.list,next.list) then - d = d - 1 - break - else - entry = next - end - end + end + elseif entry.references.lastrealpage then + pagerange(entry,entry,true,prefixspec,pagespec) + else + pagenumber(entry,prefixspec,pagespec) + end + end + + local function case_2() + local first = nil + local last = nil + while true do + if not first then + first = entry + end + last = entry + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next end - packed(first,last) -- returns internals + end + end + packed(first,last) -- returns internals + end + + local function case_3() + while true do + if entry.references.lastrealpage then + pagerange(entry,entry,true,prefixspec,pagespec) else - while true do - if entry.references.lastrealpage then - pagerange(entry,entry,true,prefixspec,pagespec) - else - pagenumber(entry,prefixspec,pagespec) - end - if d == #data then - break - else - d = d + 1 - local next = data[d] - if next.metadata.kind == "see" or not equal(entry.list,next.list) then - d = d - 1 - break - else - entry = next - end - end + pagenumber(entry,prefixspec,pagespec) + end + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next end end - ctx_stopregisterpages() end - elseif kind == 'see' then + end + + local function case_4() local t, nt = { }, 0 while true do +if entry.seeword and entry.seeword.valid then nt = nt + 1 t[nt] = entry +end if d == #data then break else @@ -1319,19 +1332,36 @@ function registers.flush(data,options,prefixspec,pagespec) end end end - ctx_startregisterseewords() for i=1,nt do local entry = t[i] local seeword = entry.seeword local seetext = seeword.text or "" local processor = seeword.processor or (entry.processors and entry.processors[1]) or "" local seeindex = entry.references.seeindex or "" - -- ctx_registerseeword(i,nt,processor,0,seeindex,seetext) ctx_registerseeword(i,nt,processor,0,seeindex,function() h_title(seetext,metadata) end) end + end + + if kind == "entry" then + if show_page_number then + ctx_startregisterpages() + if collapse_singles or collapse_ranges then + case_1() + elseif collapse_packed then + case_2() + else + case_3() + end + ctx_stopregisterpages() + end + elseif kind == "see" then + ctx_startregisterseewords() + case_4() ctx_stopregisterseewords() end + end + if started then ctx_stopregisterentry() started = false |