diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/sort-ini.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/sort-ini.lua | 196 |
1 files changed, 82 insertions, 114 deletions
diff --git a/Master/texmf-dist/tex/context/base/sort-ini.lua b/Master/texmf-dist/tex/context/base/sort-ini.lua index e14c927d7b2..5f045938f1a 100644 --- a/Master/texmf-dist/tex/context/base/sort-ini.lua +++ b/Master/texmf-dist/tex/context/base/sort-ini.lua @@ -1,8 +1,10 @@ --- filename : sort-ini.lua --- comment : companion to sort-ini.tex --- author : Hans Hagen, PRAGMA-ADE, Hasselt NL --- copyright: PRAGMA ADE / ConTeXt Development Team --- license : see context related readme files +if not modules then modules = { } end modules ['sort-ini'] = { + version = 1.001, + comment = "companion to sort-ini.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} -- todo: -- @@ -11,7 +13,9 @@ -- texutil compatible -- always expand to utf -if not versions then versions = { } end versions['sort-ini'] = 1.001 +local utf = unicode.utf8 +local gsub, rep = string.gsub, string.rep +local utfcharacters, utfvalues, strcharacters = string.utfcharacters, string.utfvalues, string.characters sorters = { } sorters.comparers = { } @@ -21,18 +25,28 @@ sorters.mappings = { } sorters.replacements = { } sorters.language = 'en' -function sorters.comparers.basic(a,b,i) -- [2] has entry, key, cmp - local sort_a, sort_b = a[2][i][3], b[2][i][3] +function sorters.comparers.basic(sort_a,sort_b) + -- sm assignment is slow, will become sorters.initialize + local sm = sorters.mappings[sorters.language or sorters.defaultlanguage] or sorters.mappings.en if #sort_a > #sort_b then if #sort_b == 0 then return 1 else for i=1,#sort_b do local ai, bi = sort_a[i], sort_b[i] - if ai > bi then - return 1 - elseif ai < bi then - return -1 + local am, bm = sm[ai], sm[bi] + if am and bm then + if am > bm then + return 1 + elseif am < bm then + return -1 + end + else + if ai > bi then + return 1 + elseif ai < bi then + return -1 + end end end return 1 @@ -43,10 +57,19 @@ function sorters.comparers.basic(a,b,i) -- [2] has entry, key, cmp else for i=1,#sort_a do local ai, bi = sort_a[i], sort_b[i] - if ai > bi then - return 1 - elseif ai < bi then - return -1 + local am, bm = sm[ai], sm[bi] + if am and bm then + if am > bm then + return 1 + elseif am < bm then + return -1 + end + else + if ai > bi then + return 1 + elseif ai < bi then + return -1 + end end end return -1 @@ -56,126 +79,71 @@ function sorters.comparers.basic(a,b,i) -- [2] has entry, key, cmp else for i=1,#sort_a do local ai, bi = sort_a[i], sort_b[i] - if ai > bi then - return 1 - elseif ai < bi then - return -1 - end - end - sort_a, sort_b = a[2][i][2], b[2][i][2] - if sort_a == "" then sort_a = a[2][i][1] end - if sort_b == "" then sort_b = b[2][i][1] end - if sort_a < sort_b then - return -1 - elseif sort_a > sort_b then - return 1 - else - return 0 - end - end -end - -function sorters.prepare(data,split,n) - local strip = sorters.strip - for k,v in ipairs(data) do - for i=1,n do - local vv = v[2][i] - if vv then - if vv[2] then - if vv[2] ~= "" then - vv[3] = split(strip(vv[2])) - else - vv[3] = split(strip(vv[1])) - end - else - vv[2] = { } - vv[3] = split(strip(vv[1])) + local am, bm = sm[ai], sm[bi] + if am and bm then + if am > bm then + return 1 + elseif am < bm then + return -1 end else - v[2][i] = { {}, {}, {} } + if ai > bi then + return 1 + elseif ai < bi then + return -1 + end end end + return 0 end end +local function padd(s) return rep(" ",10-#s) .. s end -- or format with padd + function sorters.strip(str) -- todo: only letters and such utf.gsub("([^%w%d])","") - str = str:gsub("\\%S*","") - str = str:gsub("[%s%[%](){}%$\"\']*","") - str = str:gsub("(%d+)",function(s) return (" "):rep(10-#s) .. s end) -- sort numbers properly - return str + if str then + str = gsub(str,"\\%S*","") + str = gsub(str,"[%s%[%](){}%$\"\']*","") + str = gsub(str,"(%d+)",padd) -- sort numbers properly + return str + else + return "" + end +end + +function sorters.firstofsplit(split) + -- numbers are left padded by spaces + local se = sorters.entries[sorters.language or sorters.defaultlanguage] -- slow, will become sorters.initialize + local vs = split[1] + local entry = (vs and vs[1]) or "" + return entry, (se and se[entry]) or "\000" end sorters.defaultlanguage = 'en' -function sorters.splitters.utf(str) +-- beware, numbers get spaces in front + +function sorters.splitters.utf(str) -- brrr, todo: language local r = sorters.replacements[sorters.language] or sorters.replacements[sorters.defaultlanguage] or { } - local m = sorters.mappings [sorters.language] or sorters.mappings [sorters.defaultlanguage] or { } +--~ local m = sorters.mappings [sorters.language] or sorters.mappings [sorters.defaultlanguage] or { } local u = characters.uncompose local b = utf.byte local t = { } - for _,v in pairs(r) do - str = str:gsub(v[1],v[2]) + for _,v in next, r do + str = gsub(str,v[1],v[2]) end - for c in string.utfcharacters(str) do - if m[c] then - t[#t+1] = m[c] - elseif #c == 1 then - t[#t+1] = b(c) + for c in utfcharacters(str) do -- maybe an lpeg + if #c == 1 then + t[#t+1] = c else - for cc in string.characters(u(c)) do - t[#t+1] = m[cc] or b(cc) + for cc in strcharacters(c) do + t[#t+1] = cc end end end return t end -function sorters.sort(data,cmp) - table.sort(data,function(a,b) return cmp(a,b) == -1 end) -end - -function sorters.cleanup(data) - for k,v in ipairs(data) do - for kk,vv in ipairs(v[2]) do - if vv and #vv[1] == 0 then - v[1][kk] = nil - else - vv[3] = nil - end - end - for kk,vv in pairs(v) do - if vv == "" then - v[kk] = nil - end - end - end -end - -function sorters.unique(data) - local prev, last = nil, 0 - for _,v in ipairs(data) do - if not prev or not table.are_equal(prev,v,2,3) then -- check range - last = last + 1 - data[last] = v - prev = v - end - end - for i=last+1,#data do - data[i] = nil - end -end - -function sorters.process(kind,data) - if data.entries then - if not data.sorted then - sorters.language = data.language or sorters.language - sorters[kind].prepare(data.entries) - sorters[kind].sort(data.entries) - sorters[kind].unique(data.entries) - data.sorted = true - end - return sorters[kind].flush(sorters[kind].finalize(data.entries),data.class,data.flush) - else - return { } - end +function sorters.sort(entries,cmp) + table.sort(entries,function(a,b) return cmp(a,b) == -1 end) end |