diff options
author | Mojca Miklavec <mojca.miklavec@gmail.com> | 2014-05-05 20:29:55 +0000 |
---|---|---|
committer | Mojca Miklavec <mojca.miklavec@gmail.com> | 2014-05-05 20:29:55 +0000 |
commit | ba9a57343987f1c2c72396e7c38f1fa30352c24c (patch) | |
tree | 66a8b12cdf67427ce96770fd0e9e581759aade1c /Master/texmf-dist/tex/context/base/publ-aut.lua | |
parent | 15242121b8ddf7d4a041fb3998d295dd8232e1eb (diff) |
ConTeXt 2014.04.28 23:24
git-svn-id: svn://tug.org/texlive/trunk@33856 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/publ-aut.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/publ-aut.lua | 550 |
1 files changed, 550 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/publ-aut.lua b/Master/texmf-dist/tex/context/base/publ-aut.lua new file mode 100644 index 00000000000..ba492a93bd6 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/publ-aut.lua @@ -0,0 +1,550 @@ +if not modules then modules = { } end modules ['publ-aut'] = { + version = 1.001, + comment = "this module part of publication support", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not characters then + dofile(resolvers.findfile("char-def.lua")) + dofile(resolvers.findfile("char-ini.lua")) +end + +local context = context +local chardata = characters.data + +local tostring = tostring +local concat = table.concat +local lpeg = lpeg +local utfchar = utf.char + +local publications = publications or { } + +local datasets = publications.datasets or { } +publications.datasets = datasets + +publications.authors = publications.authors or { } +local authors = publications.authors + +local P, C, V, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns + +-- local function makesplitter(separator) +-- return Ct { "start", +-- start = (Cs((V("outer") + (1-separator))^1) + separator^1)^1, +-- start = Cs(V("outer")) + (Cs((V("inner") + (1-separator))^1) + separator^1)^1, +-- outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^0) * (P("}")/""), +-- inner = P("{") * ((V("inner") + P(1-P("}")))^0) * P("}"), +-- } +-- end + +local space = P(" ") +local comma = P(",") +local firstcharacter = lpegpatterns.utf8byte + +-- local andsplitter = lpeg.tsplitat(space^1 * "and" * space^1) +-- local commasplitter = lpeg.tsplitat(space^0 * comma * space^0) +-- local spacesplitter = lpeg.tsplitat(space^1) + +local p_and = space^1 * "and" * space^1 +local p_comma = space^0 * comma * space^0 +local p_space = space^1 + +local andsplitter = Ct { "start", + start = (Cs((V("inner") + (1-p_and))^1) + p_and)^1, + inner = P("{") * ((V("inner") + P(1-P("}")))^1) * P("}"), +} + +local commasplitter = Ct { "start", + start = Cs(V("outer")) + (Cs((V("inner") + (1-p_comma))^1) + p_comma)^1, + outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^1) * (P("}")/""), + inner = P("{") * ((V("inner") + P(1-P("}")))^1) * P("}"), +} + +local spacesplitter = Ct { "start", + start = Cs(V("outer")) + (Cs((V("inner") + (1-p_space))^1) + p_space)^1, + outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^1) * (P("}")/""), + inner = P("{") * ((V("inner") + P(1-P("}")))^1) * P("}"), +} + +local function is_upper(str) + local first = lpegmatch(firstcharacter,str) + local okay = chardata[first] + return okay and okay.category == "lu" +end + +local cache = { } -- 33% reuse on tugboat.bib +local nofhits = 0 +local nofused = 0 + +local function splitauthorstring(str) + if not str then + return + end + nofused = nofused + 1 + local authors = cache[str] + if authors then + -- hit 1 + -- print("hit 1",author,nofhits,nofused,math.round(100*nofhits/nofused)) + return { authors } -- we assume one author + end + local authors = lpegmatch(andsplitter,str) + for i=1,#authors do + local author = authors[i] + local detail = cache[author] + if detail then + -- hit 2 + -- print("hit 2",author,nofhits,nofused,math.round(100*nofhits/nofused)) + end + if not detail then + local firstnames, vons, surnames, initials, juniors + local split = lpegmatch(commasplitter,author) +-- inspect(split) + local n = #split + if n == 1 then + -- First von Last + local words = lpegmatch(spacesplitter,author) + firstnames, vons, surnames = { }, { }, { } + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + firstnames[#firstnames+1], i = w, i + 1 + else + break + end + end + while i <= n do + local w = words[i] + if is_upper(w) then + break + else + vons[#vons+1], i = w, i + 1 + end + end + if i <= n then + while i <= n do + surnames[#surnames+1], i = words[i], i + 1 + end + elseif #vons == 0 then + surnames[1] = firstnames[#firstnames] + firstnames[#firstnames] = nil + else + -- mess + end + -- safeguard + if #surnames == 0 then + firstnames = { } + vons = { } + surnames = { author } + end + elseif n == 2 then + -- von Last, First + firstnames, vons, surnames = { }, { }, { } + local words = lpegmatch(spacesplitter,split[1]) + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + break + else + vons[#vons+1], i = w, i + 1 + end + end + while i <= n do + surnames[#surnames+1], i = words[i], i + 1 + end + -- + local words = lpegmatch(spacesplitter,split[2]) + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + firstnames[#firstnames+1], i = w, i + 1 + else + break + end + end + while i <= n do + vons[#vons+1], i = words[i], i + 1 + end + else + -- von Last, Jr ,First + firstnames = lpegmatch(spacesplitter,split[1]) + juniors = lpegmatch(spacesplitter,split[2]) + surnames = lpegmatch(spacesplitter,split[3]) + if n > 3 then + -- error + end + end + if #surnames == 0 then + surnames[1] = firstnames[#firstnames] + firstnames[#firstnames] = nil + end + if firstnames then + initials = { } + for i=1,#firstnames do + initials[i] = utfchar(lpegmatch(firstcharacter,firstnames[i])) + end + end + detail = { + original = author, + firstnames = firstnames, + vons = vons, + surnames = surnames, + initials = initials, + juniors = juniors, + } + cache[author] = detail + nofhits = nofhits + 1 + end + authors[i] = detail + end + return authors +end + +-- local function splitauthors(dataset,tag,field) +-- local entries = datasets[dataset] +-- local luadata = entries.luadata +-- if not luadata then +-- return { } +-- end +-- local entry = luadata[tag] +-- if not entry then +-- return { } +-- end +-- return splitauthorstring(entry[field]) +-- end + +local function the_initials(initials,symbol) + local t, symbol = { }, symbol or "." + for i=1,#initials do + t[i] = initials[i] .. symbol + end + return t +end + +-- authors + +local settings = { } + +-- local defaultsettings = { +-- firstnamesep = " ", +-- vonsep = " ", +-- surnamesep = " ", +-- juniorsep = " ", +-- surnamejuniorsep = ", ", +-- juniorjuniorsep = ", ", +-- surnamefirstnamesep = ", ", +-- surnameinitialsep = ", ", +-- namesep = ", ", +-- lastnamesep = " and ", +-- finalnamesep = " and ", +-- etallimit = 1000, +-- etaldisplay = 1000, +-- etaltext = "", +-- } + +local defaultsettings = { + firstnamesep = [[\btxlistvariantparameter{firstnamesep}]], + vonsep = [[\btxlistvariantparameter{vonsep}]], + surnamesep = [[\btxlistvariantparameter{surnamesep}]], + juniorsep = [[\btxlistvariantparameter{juniorsep}]], + surnamejuniorsep = [[\btxlistvariantparameter{surnamejuniorsep}]], + juniorjuniorsep = [[\btxlistvariantparameter{juniorjuniorsep}]], + surnamefirstnamesep = [[\btxlistvariantparameter{surnamefirstnamesep}]], + surnameinitialsep = [[\btxlistvariantparameter{surnameinitialsep}]], + namesep = [[\btxlistvariantparameter{namesep}]], + lastnamesep = [[\btxlistvariantparameter{lastnamesep}]], + finalnamesep = [[\btxlistvariantparameter{finalnamesep}]], + -- + etaltext = [[\btxlistvariantparameter{etaltext}]], + -- + etallimit = 1000, + etaldisplay = 1000, +} + +function authors.setsettings(s) +end + +authors.splitstring = splitauthorstring + +-- [firstnames] [firstnamesep] [vons] [vonsep] [surnames] [juniors] [surnamesep] (Taco, von Hoekwater, jr) + +function authors.normal(author,settings) + local firstnames, vons, surnames, juniors = author.firstnames, author.vons, author.surnames, author.juniors + local result, settings = { }, settings or defaultsettings + if firstnames and #firstnames > 0 then + result[#result+1] = concat(firstnames," ") + result[#result+1] = settings.firstnamesep or defaultsettings.firstnamesep + end + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames and #surnames > 0 then + result[#result+1] = concat(surnames," ") + if juniors and #juniors > 0 then + result[#result+1] = settings.surnamejuniorsep or defaultsettings.surnamejuniorsep + result[#result+1] = concat(juniors," ") + end + elseif juniors and #juniors > 0 then + result[#result+1] = concat(juniors," ") + end + return concat(result) +end + +-- [initials] [initialsep] [vons] [vonsep] [surnames] [juniors] [surnamesep] (T, von Hoekwater, jr) + +function authors.normalshort(author,settings) + local initials, vons, surnames, juniors = author.initials, author.vons, author.surnames, author.juniors + local result, settings = { }, settings or defaultsettings + if initials and #initials > 0 then + result[#result+1] = concat(initials," ") + result[#result+1] = settings.initialsep or defaultsettings.initialsep + end + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames and #surnames > 0 then + result[#result+1] = concat(surnames," ") + if juniors and #juniors > 0 then + result[#result+1] = settings.surnamejuniorsep or defaultsettings.surnamejuniorsep + result[#result+1] = concat(juniors," ") + end + elseif juniors and #juniors > 0 then + result[#result+1] = concat(juniors," ") + end + return concat(result) +end + +-- vons surnames juniors, firstnames + +-- [vons] [vonsep] [surnames] [surnamejuniorsep] [juniors] [surnamefirstnamesep] [firstnames] (von Hoekwater jr, Taco) + +function authors.inverted(author,settings) + local firstnames, vons, surnames, juniors = author.firstnames, author.vons, author.surnames, author.juniors + local result, settings = { }, settings or defaultsettings + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames and #surnames > 0 then + result[#result+1] = concat(surnames," ") + if juniors and #juniors > 0 then + result[#result+1] = settings.surnamejuniorsep or defaultsettings.surnamejuniorsep + result[#result+1] = concat(juniors," ") + end + elseif juniors and #juniors > 0 then + result[#result+1] = concat(juniors," ") + end + if firstnames and #firstnames > 0 then + result[#result+1] = settings.surnamefirstnamesep or defaultsettings.surnamefirstnamesep + result[#result+1] = concat(firstnames," ") + end + return concat(result) +end + +-- [vons] [vonsep] [surnames] [surnamejuniorsep] [juniors] [surnamefirstnamesep] [initials] (von Hoekwater jr, T) + +function authors.invertedshort(author,settings) + local vons, surnames, initials, juniors = author.vons, author.surnames, author.initials, author.juniors + local result, settings = { }, settings or defaultsettings + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames and #surnames > 0 then + result[#result+1] = concat(surnames," ") + if juniors and #juniors > 0 then + result[#result+1] = settings.surnamejuniorsep or defaultsettings.surnamejuniorsep + result[#result+1] = concat(juniors," ") + end + elseif juniors and #juniors > 0 then + result[#result+1] = concat(juniors," ") + end + if initials and #initials > 0 then + result[#result+1] = settings.surnameinitialsep or defaultsettings.surnameinitialsep + result[#result+1] = concat(the_initials(initials)," ") + end + return concat(result) +end + +local lastconcatsize = 1 + +local function concatnames(t,settings) + local namesep = settings.namesep + local lastnamesep = settings.lastnamesep + local finalnamesep = settings.finalnamesep + local lastconcatsize = #t + if lastconcatsize > 2 then + local s = { } + for i=1,lastconcatsize-2 do + s[i] = t[i] .. namesep + end + s[lastconcatsize-1], s[lastconcatsize] = t[lastconcatsize-1] .. finalnamesep, t[lastconcatsize] + return concat(s) + elseif lastconcatsize > 1 then + return concat(t,lastnamesep) + elseif lastconcatsize > 0 then + return t[1] + else + return "" + end +end + +function authors.concat(dataset,tag,field,settings) + table.setmetatableindex(settings,defaultsettings) + local combiner = settings.combiner + if not combiner or type(combiner) == "string" then + combiner = authors[combiner or "normal"] or authors.normal + end + local split = datasets[dataset].details[tag][field] + local etallimit = settings.etallimit or 1000 + local etaldisplay = settings.etaldisplay or etallimit + local max = split and #split or 0 + if max == 0 then + -- error + end + if max > etallimit and etaldisplay < max then + max = etaldisplay + end + local combined = { } + for i=1,max do + combined[i] = combiner(split[i],settings) + end + local result = concatnames(combined,settings) + if #combined <= max then + return result + else + return result .. settings.etaltext + end +end + +function commands.btxauthor(...) + context(authors.concat(...)) +end + +function authors.short(author,year) + -- todo +-- local result = { } +-- if author then +-- local authors = splitauthors(author) +-- for a=1,#authors do +-- local aa = authors[a] +-- local initials = aa.initials +-- for i=1,#initials do +-- result[#result+1] = initials[i] +-- end +-- local surnames = aa.surnames +-- for s=1,#surnames do +-- result[#result+1] = utfchar(lpegmatch(firstcharacter,surnames[s])) +-- end +-- end +-- end +-- if year then +-- result[#result+1] = year +-- end +-- return concat(result) +end + +-- We can consider creating a hashtable key -> entry but I wonder if +-- pays off. + +local compare = sorters.comparers.basic -- (a,b) +local strip = sorters.strip +local splitter = sorters.splitters.utf + +function authors.preparedsort(dataset,list,sorttype_a,sorttype_b,sorttype_c) + local luadata = datasets[dataset].luadata + local details = datasets[dataset].details + local valid = { } + local splitted = { } + table.setmetatableindex(splitted,function(t,k) -- could be done in the sorter but seldom that many shared + local v = splitter(k,true) -- in other cases + t[k] = v + return v + end) + local snippets = { } + for i=1,#list do + -- either { tag, tag, ... } or { { tag, index }, { tag, index } } + local li = list[i] + local tag = type(li) == "string" and li or li[1] + local entry = luadata[tag] + local detail = details[tag] + local suffix = tostring(i) + local year = nil + local assembled = nil + if entry and detail then + local key = detail[sorttype_a] or detail[sorttype_b] or detail[sorttype_c] + if key then + -- maybe an option is to also sort the authors first + local n = #key + local s = 0 + for i=1,n do + local k = key[i] + local vons = k.vons + local surnames = k.surnames + local initials = k.initials + if vons and #vons > 0 then + s = s + 1 ; snippets[s] = concat(vons," ") + end + if surnames and #surnames > 0 then + s = s + 1 ; snippets[s] = concat(surnames," ") + end + if initials and #initials > 0 then + s = s + 1 ; snippets[s] = concat(initials," ") + end + end + assembled = concat(snippets," ",1,s) + else + assembled = "" + end + year = entry.year or "9998" + else + assembled = "" + year = "9999" + end + valid[i] = { + index = i, + split = { + splitted[strip(assembled)], + splitted[year], + splitted[suffix], + }, +-- names = assembled, +-- year = year, +-- suffix = suffix, + } + end + return valid +end + +function authors.sorted(dataset,list,sorttype) -- experimental + local valid = authors.preparedsort(dataset,list,sorttype) + if #valid == 0 or #valid ~= #list then + return list + else + sorters.sort(valid,compare) + for i=1,#valid do + valid[i] = valid[i].index + end + return valid + end +end + +-- local dataset = publications.datasets.test +-- +-- local function add(str) +-- dataset.details[str] = { author = publications.authors.splitstring(str) } +-- end +-- +-- add("Hagen, Hans and Hoekwater, Taco Whoever T. Ex. and Henkel Hut, Hartmut Harald von der") +-- add("Hans Hagen and Taco Whoever T. Ex. Hoekwater and Hartmut Harald von der Henkel Hut") +-- add("de Gennes, P. and Gennes, P. de") +-- add("van't Hoff, J. H. and {van't Hoff}, J. H.") +-- +-- local list = table.keys(dataset.details) +-- local sort = publications.authors.sorted("test",list,"author") +-- local test = { } for i=1,#sort do test[i] = dataset.details[list[sort[i]]] end |