summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/publ-aut.lua
diff options
context:
space:
mode:
authorMojca Miklavec <mojca.miklavec@gmail.com>2014-05-05 20:29:55 +0000
committerMojca Miklavec <mojca.miklavec@gmail.com>2014-05-05 20:29:55 +0000
commitba9a57343987f1c2c72396e7c38f1fa30352c24c (patch)
tree66a8b12cdf67427ce96770fd0e9e581759aade1c /Master/texmf-dist/tex/context/base/publ-aut.lua
parent15242121b8ddf7d4a041fb3998d295dd8232e1eb (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.lua550
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