summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/publ-aut.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/publ-aut.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/publ-aut.lua739
1 files changed, 387 insertions, 352 deletions
diff --git a/Master/texmf-dist/tex/context/base/publ-aut.lua b/Master/texmf-dist/tex/context/base/publ-aut.lua
index ba492a93bd6..820ac78ff3b 100644
--- a/Master/texmf-dist/tex/context/base/publ-aut.lua
+++ b/Master/texmf-dist/tex/context/base/publ-aut.lua
@@ -11,23 +11,32 @@ if not characters then
dofile(resolvers.findfile("char-ini.lua"))
end
-local context = context
-local chardata = characters.data
+local lpeg = lpeg
-local tostring = tostring
+local type, next, tostring = type, next, tostring
local concat = table.concat
-local lpeg = lpeg
local utfchar = utf.char
+local formatters = string.formatters
+
+local P, C, V, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Cc
+local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+
+local context = context
+----- commands = commands
-local publications = publications or { }
+local implement = interfaces.implement
+local ctx_setmacro = interfaces.setmacro
-local datasets = publications.datasets or { }
-publications.datasets = datasets
+local publications = publications
-publications.authors = publications.authors or { }
-local authors = publications.authors
+local datasets = publications.datasets
+local getcasted = publications.getcasted
-local P, C, V, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns
+local allocate = utilities.storage.allocate
+
+local chardata = characters.data
+
+local report = logs.reporter("publications","authors")
-- local function makesplitter(separator)
-- return Ct { "start",
@@ -38,17 +47,26 @@ local P, C, V, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.V, lpeg.Cs
-- }
-- end
-local space = P(" ")
+-- authorlist = { authorspec and authorspec and authorspec }
+-- authorspec = composedname
+-- authorspec = surnames, firstnames
+-- authorspec = von, surnames, firstnames
+-- authorspec = von, surnames, jr, firstnames
+-- authorspec = von, surnames, jr, firstnames, initials
+
+local space = lpegpatterns.whitespace
local comma = P(",")
+local period = P(".")
+local dash = P("-")
local firstcharacter = lpegpatterns.utf8byte
+local utf8character = lpegpatterns.utf8character
+local p_and = space^1 * (P("and") + P("&&") + P("++")) * space^1
+local p_comma = space^0 * comma * space^0
+local p_space = space^1
+local p_shortone = C((utf8character -dash-period)^1)
+local p_longone = C( utf8character) * (1-dash-period)^0
--- 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 p_empty = P("{}")/"" * #(p_space^0 * (P(-1) + P(",")))
local andsplitter = Ct { "start",
start = (Cs((V("inner") + (1-p_and))^1) + p_and)^1,
@@ -56,7 +74,7 @@ local andsplitter = Ct { "start",
}
local commasplitter = Ct { "start",
- start = Cs(V("outer")) + (Cs((V("inner") + (1-p_comma))^1) + p_comma)^1,
+ start = Cs(V("outer")) + (p_empty + 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("}"),
}
@@ -67,18 +85,40 @@ local spacesplitter = Ct { "start",
inner = P("{") * ((V("inner") + P(1-P("}")))^1) * P("}"),
}
+local p_initial = p_shortone * period * dash^0
+ + p_longone * (period + dash + P(-1))
+local initialsplitter = p_initial * P(-1) + Ct((p_initial)^1)
+
+local optionsplitter = Cf(Ct("") * Cg(C((1-space)^1) * space^0 * Cc(true))^1,rawset)
+
local function is_upper(str)
local first = lpegmatch(firstcharacter,str)
local okay = chardata[first]
return okay and okay.category == "lu"
end
+-- local cleaner = Cs( ( P("{}")/"" + P(1) )^1 )
+
local cache = { } -- 33% reuse on tugboat.bib
local nofhits = 0
local nofused = 0
+publications.authorcache = cache
+
+local function makeinitials(firstnames)
+ if firstnames and #firstnames > 0 then
+ local initials = { }
+ for i=1,#firstnames do
+ initials[i] = lpegmatch(initialsplitter,firstnames[i])
+ end
+ return initials
+ end
+end
+
local function splitauthorstring(str)
- if not str then
+ if str then
+ -- str = lpegmatch(cleaner,str)
+ else
return
end
nofused = nofused + 1
@@ -97,12 +137,15 @@ local function splitauthorstring(str)
-- print("hit 2",author,nofhits,nofused,math.round(100*nofhits/nofused))
end
if not detail then
- local firstnames, vons, surnames, initials, juniors
+ local firstnames, vons, surnames, initials, juniors, options
local split = lpegmatch(commasplitter,author)
--- inspect(split)
local n = #split
+ detail = {
+ original = author,
+ snippets = n,
+ }
if n == 1 then
- -- First von Last
+ -- {First Middle von Last}
local words = lpegmatch(spacesplitter,author)
firstnames, vons, surnames = { }, { }, { }
local i, n = 1, #words
@@ -132,14 +175,17 @@ local function splitauthorstring(str)
else
-- mess
end
- -- safeguard
if #surnames == 0 then
+ -- safeguard
firstnames = { }
vons = { }
surnames = { author }
+ else
+ initials = makeinitials(firstnames)
end
elseif n == 2 then
- -- von Last, First
+ -- {Last, First}
+ -- {von Last, First}
firstnames, vons, surnames = { }, { }, { }
local words = lpegmatch(spacesplitter,split[1])
local i, n = 1, #words
@@ -168,33 +214,44 @@ local function splitauthorstring(str)
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
+ if surnames and firstnames and #surnames == 0 then
+ -- safeguard
+ surnames[1] = firstnames[#firstnames]
+ firstnames[#firstnames] = nil
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]))
+ initials = makeinitials(firstnames)
+ elseif n == 3 then
+ -- {von Last, First, Jr}
+ surnames = lpegmatch(spacesplitter,split[1])
+ juniors = lpegmatch(spacesplitter,split[2])
+ firstnames = lpegmatch(spacesplitter,split[3])
+ initials = makeinitials(firstnames)
+ elseif n == 4 then
+ -- {Von, Last, First, Jr}
+ vons = lpegmatch(spacesplitter,split[1])
+ surnames = lpegmatch(spacesplitter,split[2])
+ juniors = lpegmatch(spacesplitter,split[3])
+ firstnames = lpegmatch(spacesplitter,split[4])
+ initials = makeinitials(firstnames)
+ elseif n >= 5 then
+ -- {Von, Last, First, Jr, F.}
+ -- {Von, Last, First, Jr, Fr., options}
+ vons = lpegmatch(spacesplitter,split[1])
+ surnames = lpegmatch(spacesplitter,split[2])
+ juniors = lpegmatch(spacesplitter,split[3])
+ firstnames = lpegmatch(spacesplitter,split[4])
+ initials = lpegmatch(spacesplitter,split[5])
+ options = split[6]
+ if options then
+ options = lpegmatch(optionsplitter,options)
end
end
- detail = {
- original = author,
- firstnames = firstnames,
- vons = vons,
- surnames = surnames,
- initials = initials,
- juniors = juniors,
- }
+ if firstnames and #firstnames > 0 then detail.firstnames = firstnames end
+ if vons and #vons > 0 then detail.vons = vons end
+ if surnames and #surnames > 0 then detail.surnames = surnames end
+ if initials and #initials > 0 then detail.initials = initials end
+ if juniors and #juniors > 0 then detail.juniors = juniors end
+ if options and next(options) then detail.options = options end
cache[author] = detail
nofhits = nofhits + 1
end
@@ -203,348 +260,326 @@ local function splitauthorstring(str)
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 "."
+local function the_initials(initials,symbol,connector)
+ if not symbol then
+ symbol = "."
+ end
+ if not connector then
+ connector = "-"
+ end
+ local result, r = { }, 0
for i=1,#initials do
- t[i] = initials[i] .. symbol
+ local initial = initials[i]
+ if type(initial) == "table" then
+ local set, s = { }, 0
+ for i=1,#initial do
+ if i > 1 then
+ s = s + 1 ; set[s] = connector
+ end
+ s = s + 1 ; set[s] = initial[i]
+ s = s + 1 ; set[s] = symbol
+ end
+ r = r + 1 ; result[r] = concat(set)
+ else
+ r = r + 1 ; result[r] = initial .. symbol
+ end
end
- return t
+ return result
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)
+local ctx_btxsetconcat = context.btxsetconcat
+local ctx_btxsetoverflow = context.btxsetoverflow
+local ctx_btxsetinitials = context.btxsetinitials
+local ctx_btxsetfirstnames = context.btxsetfirstnames
+local ctx_btxsetvons = context.btxsetvons
+local ctx_btxsetsurnames = context.btxsetsurnames
+local ctx_btxsetjuniors = context.btxsetjuniors
+local ctx_btxciteauthorsetup = context.btxciteauthorsetup
+local ctx_btxlistauthorsetup = context.btxlistauthorsetup
+local ctx_btxsetauthorvariant = context.btxsetauthorvariant
+local ctx_btxstartauthor = context.btxstartauthor
+local ctx_btxstopauthor = context.btxstopauthor
+
+local concatstate = publications.concatstate
+local f_invalid = formatters["<invalid %s: %s>"]
+
+local currentauthordata = nil
+local currentauthorsymbol = nil
+
+local manipulators = typesetters.manipulators
+local splitmanipulation = manipulators.splitspecification
+local applymanipulation = manipulators.applyspecification
+local manipulatormethods = manipulators.methods
+
+local function value(i,field)
+ if currentauthordata then
+ local entry = currentauthordata[i]
+ if entry then
+ local value = entry[field]
+ if value and #value > 0 then
+ return value
+ end
+ end
+ end
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," ")
+implement { name = "btxcurrentfirstnames", arguments = "integer", actions = function(i) local v = value(i,"initials") if v then context(concat(the_initials(v,currentauthorsymbol))) end end }
+implement { name = "btxcurrentinitials", arguments = "integer", actions = function(i) local v = value(i,"firstnames") if v then context(concat(v," ")) end end }
+implement { name = "btxcurrentjuniors", arguments = "integer", actions = function(i) local v = value(i,"juniors") if v then context(concat(v," ")) end end }
+implement { name = "btxcurrentsurnames", arguments = "integer", actions = function(i) local v = value(i,"surnames") if v then context(concat(v," ")) end end }
+implement { name = "btxcurrentvons", arguments = "integer", actions = function(i) local v = value(i,"vons") if v then context(concat(v," ")) end end }
+
+local function btxauthorfield(i,field)
+ if currentauthordata then
+ local entry = currentauthordata[i]
+ if entry then
+ local manipulator, field = splitmanipulation(field)
+ local value = entry[field]
+ if not value or #value == 0 then
+ -- value, no need for message
+ elseif manipulator then
+ for i=1,#value do
+ if i > 1 then
+ context(" ")
+ end
+ context(applymanipulation(manipulator,value) or value)
+ end
+ elseif field == "initials" then
+ context(concat(the_initials(value,currentauthorsymbol)))
+ else
+ context(concat(value," "))
+ end
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)
+-- This is somewhat tricky: an author is not always an author but
+-- can also be a title or key, depending on the (optional) set it's
+-- in. Also, authors can be combined with years and so and they
+-- might be called upon mixed with other calls.
+
+local function btxauthor(dataset,tag,field,settings)
+ local split, usedfield, kind = getcasted(dataset,tag,field)
+ if kind == "author" then
+ local max = split and #split or 0
+ if max == 0 then
+ return
+ -- error
+ end
+ local etallimit = tonumber(settings.etallimit) or 1000
+ local etaldisplay = tonumber(settings.etaldisplay) or etallimit
+ local combiner = settings.combiner
+ local symbol = settings.symbol
+ local index = settings.index
+ if not combiner or combiner == "" then
+ combiner = "normal"
+ end
+ if not symbol then
+ symbol = "."
+ end
+ local ctx_btxsetup = settings.kind == "cite" and ctx_btxciteauthorsetup or ctx_btxlistauthorsetup
+ if max > etallimit and etaldisplay < max then
+ max = etaldisplay
+ end
+ currentauthordata = split
+ currentauthorsymbol = symbol
-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," ")
+ local function oneauthor(i)
+ local author = split[i]
+ if index then
+ ctx_btxstartauthor(i,1,0)
+ else
+ local state = author.state or 0
+ ctx_btxstartauthor(i,max,state)
+ ctx_btxsetconcat(concatstate(i,max))
+ ctx_btxsetauthorvariant(combiner)
+ end
+ local initials = author.initials
+ if initials and #initials > 0 then
+ ctx_btxsetinitials() -- (concat(the_initials(initials,symbol)," "))
+ end
+ local firstnames = author.firstnames
+ if firstnames and #firstnames > 0 then
+ ctx_btxsetfirstnames() -- (concat(firstnames," "))
+ end
+ local vons = author.vons
+ if vons and #vons > 0 then
+ ctx_btxsetvons() -- (concat(vons," "))
+ end
+ local surnames = author.surnames
+ if surnames and #surnames > 0 then
+ ctx_btxsetsurnames() -- (concat(surnames," "))
+ end
+ local juniors = author.juniors
+ if juniors and #juniors > 0 then
+ ctx_btxsetjuniors() -- (concat(juniors," "))
+ end
+ if not index and i == max then
+ local overflow = #split - max
+ if overflow > 0 then
+ ctx_btxsetoverflow(overflow)
+ end
+ end
+ ctx_btxsetup(combiner)
+ ctx_btxstopauthor()
+ end
+ if index then
+ oneauthor(index)
+ else
+ for i=1,max do
+ oneauthor(i)
+ end
end
- elseif juniors and #juniors > 0 then
- result[#result+1] = concat(juniors," ")
+ else
+ report("ignored field %a of tag %a, used field %a is no author",field,tag,usedfield)
end
- return concat(result)
end
--- vons surnames juniors, firstnames
+implement {
+ name = "btxauthorfield",
+ actions = btxauthorfield,
+ arguments = { "integer", "string" }
+}
--- [vons] [vonsep] [surnames] [surnamejuniorsep] [juniors] [surnamefirstnamesep] [firstnames] (von Hoekwater jr, Taco)
+implement {
+ name = "btxauthor",
+ actions = btxauthor,
+ arguments = {
+ "string",
+ "string",
+ "string",
+ {
+ { "combiner" },
+ { "kind" },
+ { "etallimit" },
+ { "etaldisplay" },
+ { "symbol" },
+ }
+ }
+}
-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)
+local function components(snippet,short)
+ local vons = snippet.vons
+ local surnames = snippet.surnames
+ local initials = snippet.initials
+ local firstnames = not short and snippet.firstnames
+ local juniors = snippet.juniors
+ return
+ vons and #vons > 0 and concat(vons," ") or "",
+ surnames and #surnames > 0 and concat(surnames," ") or "",
+ initials and #initials > 0 and concat(the_initials(initials)," ") or "",
+ firstnames and #firstnames > 0 and concat(firstnames," ") or "",
+ juniors and #juniors > 0 and concat(juniors, " ") or ""
end
--- [vons] [vonsep] [surnames] [surnamejuniorsep] [juniors] [surnamefirstnamesep] [initials] (von Hoekwater jr, T)
+local collapsers = allocate { }
-function authors.invertedshort(author,settings)
- local vons, surnames, initials, juniors = author.vons, author.surnames, author.initials, author.juniors
- local result, settings = { }, settings or defaultsettings
+publications.authorcollapsers = collapsers
+
+local function default(author)
+ local vons = author.vons
+ local surnames = author.surnames
+ local initials = author.initials
+ local firstnames = author.firstnames
+ local juniors = author.juniors
+ local result = { }
+ local nofresult = 0
if vons and #vons > 0 then
- result[#result+1] = concat(vons," ")
- result[#result+1] = settings.vonsep or defaultsettings.vonsep
+ nofresult = nofresult + 1 ; result[nofresult] = concat(vons," ")
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," ")
+ nofresult = nofresult + 1 ; result[nofresult] = concat(surnames," ")
end
if initials and #initials > 0 then
- result[#result+1] = settings.surnameinitialsep or defaultsettings.surnameinitialsep
- result[#result+1] = concat(the_initials(initials)," ")
+ nofresult = nofresult + 1 ; result[nofresult] = 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 ""
+ if firstnames and #firstnames > 0 then
+ nofresult = nofresult + 1 ; result[nofresult] = concat(firstnames," ")
end
+ if juniors and #juniors > 0 then
+ nofresult = nofresult + 1 ; result[nofresult] = concat(juniors," ")
+ end
+ return concat(result," ")
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
+collapsers.default = default
+
+local function writer(key,snippets)
+ if not key then
+ return ""
end
- local combined = { }
- for i=1,max do
- combined[i] = combiner(split[i],settings)
+ if type(key) == "string" then
+ return key
end
- local result = concatnames(combined,settings)
- if #combined <= max then
- return result
+ local n = #key
+ if n == 0 then
+ return ""
+ elseif n == 1 then
+ local author = key[1]
+ local options = author.options
+ if options then
+ for option in next, options do
+ local collapse = collapsers[option]
+ if collapse then
+ return collapse(author)
+ end
+ end
+ end
+ return default(author)
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," ")
+ local t = { }
+ local s = 0
+ for i=1,n do
+ local author = key[i]
+ local options = author.options
+ s = s + 1
+ if options then
+ local done = false
+ for option in next, options do
+ local collapse = collapsers[option]
+ if collapse then
+ t[s] = collapse(author)
+ done = true
end
end
- assembled = concat(snippets," ",1,s)
+ if not done then
+ t[s] = default(author)
+ end
else
- assembled = ""
+ t[s] = default(author)
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,
- }
+ return concat(t," & ")
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
+publications.writers .author = writer
+publications.casters .author = splitauthorstring
+publications.components.author = components
--- 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.")
+-- sharedmethods.author = {
+-- { field = "key", default = "", unknown = "" },
+-- { field = "author", default = "", unknown = "" },
+-- { field = "title", default = "", unknown = "" },
+-- }
+
+-- Analysis of the APA by Alan:
--
--- 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
+-- first : key author editor publisher title journal volume number pages
+-- second: year suffix title month day journal volume number
+
+publications.sortmethods.authoryear = {
+ sequence = {
+ { field = "key", default = "", unknown = "" },
+ { field = "author", default = "", unknown = "" },
+ { field = "year", default = "9998", unknown = "9999" },
+ { field = "suffix", default = " ", unknown = " " },
+ { field = "month", default = "13", unknown = "14" },
+ { field = "day", default = "32", unknown = "33" },
+ { field = "journal", default = "", unknown = "" },
+ { field = "volume", default = "", unknown = "" },
+ { field = "number", default = "", unknown = "" },
+ { field = "title", default = "", unknown = "" },
+ { field = "pages", default = "", unknown = "" },
+ },
+}