summaryrefslogtreecommitdiff
path: root/tex/context/base/publ-ini.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/publ-ini.lua')
-rw-r--r--tex/context/base/publ-ini.lua1425
1 files changed, 0 insertions, 1425 deletions
diff --git a/tex/context/base/publ-ini.lua b/tex/context/base/publ-ini.lua
deleted file mode 100644
index 6bf6714da..000000000
--- a/tex/context/base/publ-ini.lua
+++ /dev/null
@@ -1,1425 +0,0 @@
-if not modules then modules = { } end modules ['publ-ini'] = {
- 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"
-}
-
--- for the moment here
-
-local lpegmatch = lpeg.match
-local P, C, Ct, Cs = lpeg.P, lpeg.C, lpeg.Ct, lpeg.Cs
-
-local lpegmatch = lpeg.match
-local pattern = Cs((1 - P(1) * P(-1))^0 * (P(".")/"" + P(1)))
-
-local manipulators = {
- stripperiod = function(str) return lpegmatch(pattern,str) end,
- uppercase = characters.upper,
- lowercase = characters.lower,
-}
-
-local manipulation = C((1-P("->"))^1) * P("->") * C(P(1)^0)
-
-local pattern = manipulation / function(operation,str)
- local manipulator = manipulators[operation]
- return manipulator and manipulator(str) or str
-end
-
-local function manipulated(str)
- return lpegmatch(pattern,str) or str
-end
-
-utilities.parsers.manipulation = manipulation
-utilities.parsers.manipulators = manipulators
-utilities.parsers.manipulated = manipulated
-
-function commands.manipulated(str)
- context(manipulated(str))
-end
-
--- use: for rest in gmatch(reference,"[^, ]+") do
-
-local next, rawget, type = next, rawget, type
-local match, gmatch, format, gsub = string.match, string.gmatch, string.format, string.gsub
-local concat, sort = table.concat, table.sort
-local utfsub = utf.sub
-local formatters = string.formatters
-local allocate = utilities.storage.allocate
-local settings_to_array, settings_to_set = utilities.parsers.settings_to_array, utilities.parsers.settings_to_set
-local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash
-local lpegmatch = lpeg.match
-local P, C, Ct = lpeg.P, lpeg.C, lpeg.Ct
-
-local report = logs.reporter("publications")
-local trace = false trackers.register("publications", function(v) trace = v end)
-
-local datasets = publications.datasets
-
-local variables = interfaces.variables
-
-local v_local = variables["local"]
-local v_global = variables["global"]
-
-local v_force = variables.force
-local v_standard = variables.standard
-local v_start = variables.start
-local v_none = variables.none
-local v_left = variables.left
-local v_right = variables.right
-local v_middle = variables.middle
-local v_inbetween = variables.inbetween
-
-local v_short = variables.short
-local v_cite = variables.cite
-local v_default = variables.default
-local v_reference = variables.reference
-local v_dataset = variables.dataset
-local v_author = variables.author or "author"
-local v_editor = variables.editor or "editor"
-
-local numbertochar = converters.characters
-
-local logsnewline = logs.newline
-local logspushtarget = logs.pushtarget
-local logspoptarget = logs.poptarget
-local csname_id = token.csname_id
-
-local basicsorter = sorters.basicsorter -- (a,b)
-local sortcomparer = sorters.comparers.basic -- (a,b)
-local sortstripper = sorters.strip
-local sortsplitter = sorters.splitters.utf
-
-local context = context
-
-local ctx_btxlistparameter = context.btxlistparameter
-local ctx_btxcitevariantparameter = context.btxcitevariantparameter
-local ctx_btxlistvariantparameter = context.btxlistvariantparameter
-local ctx_btxdomarkcitation = context.btxdomarkcitation
-local ctx_setvalue = context.setvalue
-local ctx_firstoftwoarguments = context.firstoftwoarguments
-local ctx_secondoftwoarguments = context.secondoftwoarguments
-local ctx_firstofoneargument = context.firstofoneargument
-local ctx_gobbleoneargument = context.gobbleoneargument
-local ctx_btxdirectlink = context.btxdirectlink
-local ctx_btxhandlelistentry = context.btxhandlelistentry
-local ctx_btxchecklistentry = context.btxchecklistentry
-local ctx_dodirectfullreference = context.dodirectfullreference
-local ctx_directsetup = context.directsetup
-
-statistics.register("publications load time", function()
- local publicationsstats = publications.statistics
- local nofbytes = publicationsstats.nofbytes
- if nofbytes > 0 then
- return string.format("%s seconds, %s bytes, %s definitions, %s shortcuts",
- statistics.elapsedtime(publications),nofbytes,publicationsstats.nofdefinitions,publicationsstats.nofshortcuts)
- else
- return nil
- end
-end)
-
-luatex.registerstopactions(function()
- logspushtarget("logfile")
- logsnewline()
- report("start used btx commands")
- logsnewline()
- local undefined = csname_id("undefined*crap")
- for name, dataset in sortedhash(datasets) do
- for command, n in sortedhash(dataset.commands) do
- local c = csname_id(command)
- if c and c ~= undefined then
- report("%-20s %-20s % 5i %s",name,command,n,"known")
- else
- local u = csname_id(utf.upper(command))
- if u and u ~= undefined then
- report("%-20s %-20s % 5i %s",name,command,n,"KNOWN")
- else
- report("%-20s %-20s % 5i %s",name,command,n,"unknown")
- end
- end
- end
- end
- logsnewline()
- report("stop used btxcommands")
- logsnewline()
- logspoptarget()
-end)
-
--- multipass, we need to sort because hashing is random per run and not per
--- version (not the best changed feature of lua)
-
-local collected = allocate()
-local tobesaved = allocate()
-
--- we use a a dedicated (and efficient as it know what it deals with) serializer,
--- also because we need to ignore the 'details' field
-
-local function serialize(t)
- local f_key_table = formatters[" [%q] = {"]
- local f_key_string = formatters[" %s = %q,"]
- local r = { "return {" }
- local m = 1
- for tag, entry in sortedhash(t) do
- m = m + 1
- r[m] = f_key_table(tag)
- local s = sortedkeys(entry)
- for i=1,#s do
- local k = s[i]
- -- if k ~= "details" then
- m = m + 1
- r[m] = f_key_string(k,entry[k])
- -- end
- end
- m = m + 1
- r[m] = " },"
- end
- r[m] = "}"
- return concat(r,"\n")
-end
-
-local function finalizer()
- local prefix = tex.jobname -- or environment.jobname
- local setnames = sortedkeys(datasets)
- for i=1,#setnames do
- local name = setnames[i]
- local dataset = datasets[name]
- local userdata = dataset.userdata
- local checksum = nil
- local username = file.addsuffix(file.robustname(formatters["%s-btx-%s"](prefix,name)),"lua")
- if userdata and next(userdata) then
- if job.passes.first then
- local newdata = serialize(userdata)
- checksum = md5.HEX(newdata)
- io.savedata(username,newdata)
- end
- else
- os.remove(username)
- username = nil
- end
- local loaded = dataset.loaded
- local sources = dataset.sources
- local used = { }
- for i=1,#sources do
- local source = sources[i]
- if loaded[source.filename] ~= "previous" then -- or loaded[source.filename] == "current"
- used[#used+1] = source
- end
- end
- tobesaved[name] = {
- usersource = {
- filename = username,
- checksum = checksum,
- },
- datasources = used,
- }
- end
-end
-
-local function initializer()
- statistics.starttiming(publications)
-collected = publications.collected or collected -- for the moment as we load runtime
- for name, state in next, collected do
- local dataset = datasets[name]
- local datasources = state.datasources
- local usersource = state.usersource
- if datasources then
- for i=1,#datasources do
- local filename = datasources[i].filename
- publications.load(dataset,filename,"previous")
- end
- end
- if usersource then
- dataset.userdata = table.load(usersource.filename) or { }
- end
- end
- statistics.stoptiming(publications)
- function initializer() end -- will go, for now, runtime loaded
-end
-
-job.register('publications.collected',tobesaved,initializer,finalizer)
-
-if not publications.authors then
- initializer() -- for now, runtime loaded
-end
-
--- basic access
-
-local function getfield(dataset,tag,name)
- local d = datasets[dataset].luadata[tag]
- return d and d[name]
-end
-
-local function getdetail(dataset,tag,name)
- local d = datasets[dataset].details[tag]
- return d and d[name]
-end
-
-function commands.btxsingularorplural(dataset,tag,name) -- todo: make field dependent
- local d = datasets[dataset].details[tag]
- if d then
- d = d[name]
- end
- if d then
- d = #d <= 1
- end
- commands.doifelse(d)
-end
-
--- basic loading
-
-function commands.usebtxdataset(name,filename)
- publications.load(datasets[name],filename,"current")
-end
-
-function commands.convertbtxdatasettoxml(name,nice)
- publications.converttoxml(datasets[name],nice)
-end
-
--- enhancing
-
-local splitauthorstring = publications.authors.splitstring
-
-local pagessplitter = lpeg.splitat(P("-")^1)
-
--- maybe not redo when already done
-
-function publications.enhance(dataset) -- for the moment split runs (maybe publications.enhancers)
- statistics.starttiming(publications)
- if type(dataset) == "string" then
- dataset = datasets[dataset]
- end
- local luadata = dataset.luadata
- local details = dataset.details
- -- author, editor
- for tag, entry in next, luadata do
- local author = entry.author
- local editor = entry.editor
- details[tag] = {
- author = author and splitauthorstring(author),
- editor = editor and splitauthorstring(editor),
- }
- end
- -- short
- local shorts = { }
- for tag, entry in next, luadata do
- local author = details[tag].author
- if author then
- -- number depends on sort order
- local t = { }
- if #author == 0 then
- -- what
- else
- local n = #author == 1 and 3 or 1
- for i=1,#author do
- local surnames = author[i].surnames
- if not surnames or #surnames == 0 then
- -- error
- else
- t[#t+1] = utfsub(surnames[1],1,n)
- end
- end
- end
- local year = tonumber(entry.year) or 0
- local short = formatters["%t%02i"](t,math.mod(year,100))
- local s = shorts[short]
- if not s then
- shorts[short] = tag
- elseif type(s) == "string" then
- shorts[short] = { s, tag }
- else
- s[#s+1] = tag
- end
- else
- --
- end
- end
- for short, tags in next, shorts do
- if type(tags) == "table" then
- sort(tags)
- for i=1,#tags do
--- details[tags[i]].short = short .. numbertochar(i)
-local detail = details[tags[i]]
-detail.short = short
-detail.suffix = numbertochar(i)
- end
- else
- details[tags].short = short
- end
- end
- -- pages
- for tag, entry in next, luadata do
- local pages = entry.pages
- if pages then
- local first, last = lpegmatch(pagessplitter,pages)
- details[tag].pages = first and last and { first, last } or pages
- end
- end
- -- keywords
- for tag, entry in next, luadata do
- local keyword = entry.keyword
- if keyword then
- details[tag].keyword = settings_to_set(keyword)
- end
- end
- statistics.stoptiming(publications)
-end
-
-function commands.addbtxentry(name,settings,content)
- local dataset = datasets[name]
- if dataset then
- publications.addtexentry(dataset,settings,content)
- end
-end
-
-function commands.setbtxdataset(name)
- local dataset = rawget(datasets,name)
- if dataset then
- context(name)
- else
- report("unknown dataset %a",name)
- end
-end
-
-function commands.setbtxentry(name,tag)
- local dataset = rawget(datasets,name)
- if dataset then
- if dataset.luadata[tag] then
- context(tag)
- else
- report("unknown tag %a in dataset %a",tag,name)
- end
- else
- report("unknown dataset %a",name)
- end
-end
-
--- rendering of fields (maybe multiple manipulators)
-
-local manipulation = utilities.parsers.manipulation
-local manipulators = utilities.parsers.manipulators
-
--- local function checked(field)
--- local m, f = lpegmatch(manipulation,field)
--- if m then
--- return manipulators[m], f or field
--- else
--- return nil, field
--- end
--- end
-
-local manipulation = Ct((C((1-P("->"))^1) * P("->"))^1) * C(P(1)^0)
-
-local function checked(field)
- local m, f = lpegmatch(manipulation,field)
- if m then
- return m, f or field
- else
- return nil, field
- end
-end
-
-local function manipulated(actions,str)
- for i=1,#actions do
- local action = manipulators[actions[i]]
- if action then
- str = action(str) or str
- end
- end
- return str
-end
-
-function commands.btxflush(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local fields = dataset.luadata[tag]
- if fields then
- local manipulator, field = checked(field)
- local value = fields[field]
- if type(value) == "string" then
- -- context(manipulator and manipulator(value) or value)
- context(manipulator and manipulated(manipulator,value) or value)
- return
- end
- local details = dataset.details[tag]
- if details then
- local value = details[field]
- if type(value) == "string" then
- -- context(manipulator and manipulator(value) or value)
- context(manipulator and manipulated(manipulator,value) or value)
- return
- end
- end
- report("unknown field %a of tag %a in dataset %a",field,tag,name)
- else
- report("unknown tag %a in dataset %a",tag,name)
- end
- else
- report("unknown dataset %a",name)
- end
-end
-
-function commands.btxdetail(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local details = dataset.details[tag]
- if details then
- local manipulator, field = checked(field)
- local value = details[field]
- if type(value) == "string" then
- -- context(manipulator and manipulator(value) or value)
- context(manipulator and manipulated(manipulator,value) or value)
- else
- report("unknown detail %a of tag %a in dataset %a",field,tag,name)
- end
- else
- report("unknown tag %a in dataset %a",tag,name)
- end
- else
- report("unknown dataset %a",name)
- end
-end
-
-function commands.btxfield(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local fields = dataset.luadata[tag]
- if fields then
- local manipulator, field = checked(field)
- local value = fields[field]
- if type(value) == "string" then
- -- context(manipulator and manipulator(value) or value)
- context(manipulator and manipulated(manipulator,value) or value)
- else
- report("unknown field %a of tag %a in dataset %a",field,tag,name)
- end
- else
- report("unknown tag %a in dataset %a",tag,name)
- end
- else
- report("unknown dataset %a",name)
- end
-end
-
--- testing: to be speed up with testcase
-
-function commands.btxdoifelse(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local data = dataset.luadata[tag]
- local value = data and data[field]
- if value and value ~= "" then
- ctx_firstoftwoarguments()
- return
- end
- end
- ctx_secondoftwoarguments()
-end
-
-function commands.btxdoif(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local data = dataset.luadata[tag]
- local value = data and data[field]
- if value and value ~= "" then
- ctx_firstofoneargument()
- return
- end
- end
- ctx_gobbleoneargument()
-end
-
-function commands.btxdoifnot(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local data = dataset.luadata[tag]
- local value = data and data[field]
- if value and value ~= "" then
- ctx_gobbleoneargument()
- return
- end
- end
- ctx_firstofoneargument()
-end
-
--- -- alternative approach: keep data at the tex end
-
-function publications.listconcat(t)
- local n = #t
- if n > 0 then
- context(t[1])
- if n > 1 then
- if n > 2 then
- for i=2,n-1 do
- ctx_btxlistparameter("sep")
- context(t[i])
- end
- ctx_btxlistparameter("finalsep")
- else
- ctx_btxlistparameter("lastsep")
- end
- context(t[n])
- end
- end
-end
-
-function publications.citeconcat(t)
- local n = #t
- if n > 0 then
- context(t[1])
- if n > 1 then
- if n > 2 then
- for i=2,n-1 do
- ctx_btxcitevariantparameter("sep")
- context(t[i])
- end
- ctx_btxcitevariantparameter("finalsep")
- else
- ctx_btxcitevariantparameter("lastsep")
- end
- context(t[n])
- end
- end
-end
-
-function publications.singularorplural(singular,plural)
- if lastconcatsize and lastconcatsize > 1 then
- context(plural)
- else
- context(singular)
- end
-end
-
--- function commands.makebibauthorlist(settings) -- ?
--- if not settings then
--- return
--- end
--- local dataset = datasets[settings.dataset]
--- if not dataset or dataset == "" then
--- return
--- end
--- local tag = settings.tag
--- if not tag or tag == "" then
--- return
--- end
--- local asked = settings_to_array(tag)
--- if #asked == 0 then
--- return
--- end
--- local compress = settings.compress
--- local interaction = settings.interactionn == v_start
--- local limit = tonumber(settings.limit)
--- local found = { }
--- local hash = { }
--- local total = 0
--- local luadata = dataset.luadata
--- for i=1,#asked do
--- local tag = asked[i]
--- local data = luadata[tag]
--- if data then
--- local author = data.a or "Xxxxxxxxxx"
--- local year = data.y or "0000"
--- if not compress or not hash[author] then
--- local t = {
--- author = author,
--- name = name, -- first
--- year = { [year] = name },
--- }
--- total = total + 1
--- found[total] = t
--- hash[author] = t
--- else
--- hash[author].year[year] = name
--- end
--- end
--- end
--- for i=1,total do
--- local data = found[i]
--- local author = data.author
--- local year = table.keys(data.year)
--- table.sort(year)
--- if interaction then
--- for i=1,#year do
--- year[i] = formatters["\\bibmaybeinteractive{%s}{%s}"](data.year[year[i]],year[i])
--- end
--- end
--- ctx_setvalue("currentbibyear",concat(year,","))
--- if author == "" then
--- ctx_setvalue("currentbibauthor","")
--- else -- needs checking
--- local authors = settings_to_array(author) -- {{}{}},{{}{}}
--- local nofauthors = #authors
--- if nofauthors == 1 then
--- if interaction then
--- author = formatters["\\bibmaybeinteractive{%s}{%s}"](data.name,author)
--- end
--- ctx_setvalue("currentbibauthor",author)
--- else
--- limit = limit or nofauthors
--- if interaction then
--- for i=1,#authors do
--- authors[i] = formatters["\\bibmaybeinteractive{%s}{%s}"](data.name,authors[i])
--- end
--- end
--- if limit == 1 then
--- ctx_setvalue("currentbibauthor",authors[1] .. "\\bibalternative{otherstext}")
--- elseif limit == 2 and nofauthors == 2 then
--- ctx_setvalue("currentbibauthor",concat(authors,"\\bibalternative{andtext}"))
--- else
--- for i=1,limit-1 do
--- authors[i] = authors[i] .. "\\bibalternative{namesep}"
--- end
--- if limit < nofauthors then
--- authors[limit+1] = "\\bibalternative{otherstext}"
--- ctx_setvalue("currentbibauthor",concat(authors,"",1,limit+1))
--- else
--- authors[limit-1] = authors[limit-1] .. "\\bibalternative{andtext}"
--- ctx_setvalue("currentbibauthor",concat(authors))
--- end
--- end
--- end
--- end
--- -- the following use: currentbibauthor and currentbibyear
--- if i == 1 then
--- context.ixfirstcommand()
--- elseif i == total then
--- context.ixlastcommand()
--- else
--- context.ixsecondcommand()
--- end
--- end
--- end
-
-local patterns = { "publ-imp-%s.mkiv", "publ-imp-%s.tex" }
-
-local function failure(name)
- report("unknown library %a",name)
-end
-
-local function action(name,foundname)
- context.input(foundname)
-end
-
-function commands.loadbtxdefinitionfile(name) -- a more specific name
- commands.uselibrary {
- name = gsub(name,"^publ%-",""),
- patterns = patterns,
- action = action,
- failure = failure,
- onlyonce = false,
- }
-end
-
--- lists:
-
-publications.lists = publications.lists or { }
-local lists = publications.lists
-
-local context = context
-local structures = structures
-
-local references = structures.references
-local sections = structures.sections
-
--- per rendering
-
-local renderings = { } --- per dataset
-
-table.setmetatableindex(renderings,function(t,k)
- local v = {
- list = { },
- done = { },
- alldone = { },
- used = { },
- registered = { },
- ordered = { },
- shorts = { },
- method = v_none,
- currentindex = 0,
- }
- t[k] = v
- return v
-end)
-
--- why shorts vs tags: only for sorting
-
-function lists.register(dataset,tag,short) -- needs checking now that we split
- local r = renderings[dataset]
- if not short or short == "" then
- short = tag
- end
- if trace then
- report("registering publication entry %a with shortcut %a",tag,short)
- end
- local top = #r.registered + 1
- -- do we really need these
- r.registered[top] = tag
- r.ordered [tag] = top
- r.shorts [tag] = short
-end
-
-function lists.nofregistered(dataset)
- return #renderings[dataset].registered
-end
-
-function lists.setmethod(dataset,method)
- local r = renderings[dataset]
- r.method = method or v_none
- r.list = { }
- r.done = { }
-end
-
-local function validkeyword(dataset,tag,keyword)
- local ds = datasets[dataset]
- if not ds then
- report("unknown dataset %a",dataset)
- return
- end
- local dt = ds.details[tag]
- if not dt then
- report("no details for tag %a",tag)
- return
- end
- local kw = dt.keyword
- if kw then
--- inspect(keyword)
--- inspect(kw)
- for k in next, keyword do
- if kw[k] then
- return true
- end
- end
- end
-end
-
-function lists.collectentries(specification)
- local dataset = specification.btxdataset
- if not dataset then
- return
- end
- local rendering = renderings[dataset]
--- specification.names = "btx"
- local method = rendering.method
- if method == v_none then
- return
- end
--- method=v_local --------------------
- local result = structures.lists.filter(specification)
- --
- local keyword = specification.keyword
- if keyword and keyword ~= "" then
- keyword = settings_to_set(keyword)
- else
- keyword = nil
- end
- lists.result = result
- local section = sections.currentid()
- local list = rendering.list
- local done = rendering.done
- local alldone = rendering.alldone
- if method == v_local then
- for listindex=1,#result do
- local r = result[listindex]
- local u = r.userdata
- if u and u.btxset == dataset then
- local tag = u.btxref
- if tag and done[tag] ~= section then
- if not keyword or validkeyword(dataset,tag,keyword) then
- done[tag] = section
- alldone[tag] = true
- list[#list+1] = { tag, listindex }
- end
- end
- end
- end
- elseif method == v_global then
- for listindex=1,#result do
- local r = result[listindex]
- local u = r.userdata
- if u and u.btxset == dataset then
- local tag = u.btxref
- if tag and not alldone[tag] and done[tag] ~= section then
- if not keyword or validkeyword(dataset,tag,keyword) then
- done[tag] = section
- alldone[tag] = true
- list[#list+1] = { tag, listindex }
- end
- end
- end
- end
- elseif method == v_force then
- -- only for checking, can have duplicates, todo: collapse page numbers, although
- -- we then also needs deferred writes
- for listindex=1,#result do
- local r = result[listindex]
- local u = r.userdata
- if u and u.btxset == dataset then
- local tag = u.btxref
- if tag then
- if not keyword or validkeyword(dataset,tag,keyword) then
- list[#list+1] = { tag, listindex }
- end
- end
- end
- end
- elseif method == v_dataset then
- local luadata = datasets[dataset].luadata
- for tag, data in table.sortedhash(luadata) do
- if not keyword or validkeyword(dataset,tag,keyword) then
- list[#list+1] = { tag }
- end
- end
- end
-end
-
-lists.sorters = {
- [v_short] = function(dataset,rendering,list)
- local shorts = rendering.shorts
- local function compare(a,b)
- local aa, bb = a and a[1], b and b[1]
- if aa and bb then
- aa, bb = shorts[aa], shorts[bb]
- return aa and bb and aa < bb
- end
- return false
- end
- sort(list,compare)
- end,
- [v_reference] = function(dataset,rendering,list)
- local function compare(a,b)
- local aa, bb = a and a[1], b and b[1]
- if aa and bb then
- return aa and bb and aa < bb
- end
- return false
- end
- sort(list,compare)
- end,
- [v_dataset] = function(dataset,rendering,list)
- local function compare(a,b)
- local aa, bb = a and a[1], b and b[1]
- if aa and bb then
- aa, bb = list[aa].index or 0, list[bb].index or 0
- return aa and bb and aa < bb
- end
- return false
- end
- sort(list,compare)
- end,
- -- [v_default] = function(dataset,rendering,list) -- not really needed
- -- local ordered = rendering.ordered
- -- local function compare(a,b)
- -- local aa, bb = a and a[1], b and b[1]
- -- if aa and bb then
- -- aa, bb = ordered[aa], ordered[bb]
- -- return aa and bb and aa < bb
- -- end
- -- return false
- -- end
- -- sort(list,compare)
- -- end,
- [v_author] = function(dataset,rendering,list)
- local valid = publications.authors.preparedsort(dataset,list,v_author,v_editor)
- if #valid == 0 or #valid ~= #list then
- -- nothing to sort
- else
- -- if needed we can wrap compare and use the list directly but this is cleaner
- sorters.sort(valid,sortcomparer)
- for i=1,#valid do
- local v = valid[i]
- valid[i] = list[v.index]
- end
- return valid
- end
- end,
-}
-
-function lists.flushentries(dataset,sortvariant)
- local rendering = renderings[dataset]
- local list = rendering.list
- local sort = lists.sorters[sortvariant] or lists.sorters[v_default]
- if type(sort) == "function" then
- list = sort(dataset,rendering,list) or list
- end
- for i=1,#list do
- ctx_setvalue("currentbtxindex",i)
- ctx_btxhandlelistentry(list[i][1]) -- we can pass i here too ... more efficient to avoid the setvalue
- end
-end
-
-function lists.fetchentries(dataset)
- local list = renderings[dataset].list
- for i=1,#list do
- ctx_setvalue("currentbtxindex",i)
- ctx_btxchecklistentry(list[i][1])
- end
-end
-
-function lists.filterall(dataset)
- local r = renderings[dataset]
- local list = r.list
- local registered = r.registered
- for i=1,#registered do
- list[i] = { registered[i], i }
- end
-end
-
-function lists.registerplaced(dataset,tag)
- renderings[dataset].used[tag] = true
-end
-
-function lists.doifalreadyplaced(dataset,tag)
- commands.doifelse(renderings[dataset].used[tag])
-end
-
--- we ask for <n>:tag but when we can't find it we go back
--- to look for previous definitions, and when not found again
--- we look forward
-
-local function compare(a,b)
- local aa, bb = a and a[3], b and b[3]
- return aa and bb and aa < bb
-end
-
--- maybe hash subsets
--- how efficient is this? old leftovers?
-
--- rendering ?
-
-local f_reference = formatters["r:%s:%s:%s"] -- dataset, instance (block), tag
-local f_destination = formatters["d:%s:%s:%s"] -- dataset, instance (block), tag
-
-function lists.resolve(dataset,reference) -- maybe already feed it split
- -- needs checking (the prefix in relation to components)
- local subsets = nil
- local block = tex.count.btxblock
- local collected = references.collected
- local prefix = nil -- todo: dataset ?
- if prefix and prefix ~= "" then
- subsets = { collected[prefix] or collected[""] }
- else
- local components = references.productdata.components
- local subset = collected[""]
- if subset then
- subsets = { subset }
- else
- subsets = { }
- end
- for i=1,#components do
- local subset = collected[components[i]]
- if subset then
- subsets[#subsets+1] = subset
- end
- end
- end
--- inspect(subsets)
- if #subsets > 0 then
- local result, nofresult, done = { }, 0, { }
- for i=1,#subsets do
- local subset = subsets[i]
- for rest in gmatch(reference,"[^, ]+") do
- local blk, tag, found = block, nil, nil
- if block then
- tag = f_destination(dataset,blk,rest)
- found = subset[tag]
- if not found then
- for i=block-1,1,-1 do
- tag = f_destination(dataset,blk,rest)
--- tag = i .. ":" .. rest
- found = subset[tag]
- if found then
- blk = i
- break
- end
- end
- end
- end
- if not found then
- blk = "*"
- tag = f_destination(dataset,blk,rest)
- found = subset[tag]
- end
- if found then
- local current = tonumber(found.entries and found.entries.text) -- tonumber needed
- if current and not done[current] then
- nofresult = nofresult + 1
- result[nofresult] = { blk, rest, current }
- done[current] = true
- end
- end
- end
- end
- local first, last, firsti, lasti, firstr, lastr
- local collected, nofcollected = { }, 0
- for i=1,nofresult do
- local r = result[i]
- local current = r[3]
- if not first then
- first, last, firsti, lasti, firstr, lastr = current, current, i, i, r, r
- elseif current == last + 1 then
- last, lasti, lastr = current, i, r
- else
- if last > first + 1 then
- nofcollected = nofcollected + 1
- collected[nofcollected] = { firstr, lastr }
- else
- nofcollected = nofcollected + 1
- collected[nofcollected] = firstr
- if last > first then
- nofcollected = nofcollected + 1
- collected[nofcollected] = lastr
- end
- end
- first, last, firsti, lasti, firstr, lastr = current, current, i, i, r, r
- end
- end
- if first and last then
- if last > first + 1 then
- nofcollected = nofcollected + 1
- collected[nofcollected] = { firstr, lastr }
- else
- nofcollected = nofcollected + 1
- collected[nofcollected] = firstr
- if last > first then
- nofcollected = nofcollected + 1
- collected[nofcollected] = lastr
- end
- end
- end
- if nofcollected > 0 then
--- inspect(reference)
--- inspect(result)
--- inspect(collected)
- for i=1,nofcollected do
- local c = collected[i]
- if i == nofcollected then
- ctx_btxlistvariantparameter("lastpubsep")
- elseif i > 1 then
- ctx_btxlistvariantparameter("pubsep")
- end
- if #c == 3 then -- a range (3 is first or last)
- ctx_btxdirectlink(f_reference(dataset,c[1],c[2]),c[3])
- else
- local f, l = c[2], c[2]
- ctx_btxdirectlink(f_reference(dataset,f[1],f[2]),f[3])
- context.endash() -- to do
- ctx_btxdirectlink(f_reference(dataset,l[4],l[5]),l[6])
- end
- end
- else
- context("[btx error 1]")
- end
- else
- context("[btx error 2]")
- end
-end
-
-local done = { }
-
-function commands.btxreference(dataset,block,tag,data)
- local ref = f_reference(dataset,block,tag)
- if not done[ref] then
- done[ref] = true
--- context("<%s>",data)
- ctx_dodirectfullreference(ref,data)
- end
-end
-
-local done = { }
-
-function commands.btxdestination(dataset,block,tag,data)
- local ref = f_destination(dataset,block,tag)
- if not done[ref] then
- done[ref] = true
--- context("<<%s>>",data)
- ctx_dodirectfullreference(ref,data)
- end
-end
-
-commands.btxsetlistmethod = lists.setmethod
-commands.btxresolvelistreference = lists.resolve
-commands.btxregisterlistentry = lists.registerplaced
-commands.btxaddtolist = lists.addentry
-commands.btxcollectlistentries = lists.collectentries
-commands.btxfetchlistentries = lists.fetchentries
-commands.btxflushlistentries = lists.flushentries
-commands.btxdoifelselistentryplaced = lists.doifalreadyplaced
-
-local citevariants = { }
-publications.citevariants = citevariants
-
--- helper
-
-local function sortedtags(dataset,list,sorttype)
- local luadata = datasets[dataset].luadata
- local valid = { }
- for i=1,#list do
- local tag = list[i]
- local entry = luadata[tag]
- if entry then
- local key = entry[sorttype]
- if key then
- valid[#valid+1] = {
- tag = tag,
- split = sortsplitter(sortstripper(key))
- }
- else
- end
- end
- end
- if #valid == 0 or #valid ~= #list then
- return list
- else
- sorters.sort(valid,basicsorter)
- for i=1,#valid do
- valid[i] = valid[i].tag
- end
- return valid
- end
-end
-
--- todo: standard : current
-
-local prefixsplitter = lpeg.splitat("::")
-
-function commands.btxhandlecite(dataset,tag,mark,variant,sorttype,setup) -- variant for tracing
- local prefix, rest = lpegmatch(prefixsplitter,tag)
- if rest then
- dataset = prefix
- else
- rest = tag
- end
- ctx_setvalue("currentbtxdataset",dataset)
- local tags = settings_to_array(rest)
- if #tags > 0 then
- if sorttype and sorttype ~= "" then
- tags = sortedtags(dataset,tags,sorttype)
- end
- ctx_btxcitevariantparameter(v_left)
- for i=1,#tags do
- local tag = tags[i]
- ctx_setvalue("currentbtxtag",tag)
- if i > 1 then
- ctx_btxcitevariantparameter(v_middle)
- end
- if mark ~= false then
- ctx_btxdomarkcitation(dataset,tag)
- end
- ctx_directsetup(setup) -- cite can become alternative
- end
- ctx_btxcitevariantparameter(v_right)
- else
- -- error
- end
-end
-
-function commands.btxhandlenocite(dataset,tag,mark)
- if mark ~= false then
- local prefix, rest = lpegmatch(prefixsplitter,tag)
- if rest then
- dataset = prefix
- else
- rest = tag
- end
- ctx_setvalue("currentbtxdataset",dataset)
- local tags = settings_to_array(rest)
- for i=1,#tags do
- ctx_btxdomarkcitation(dataset,tags[i])
- end
- end
-end
-
-function commands.btxcitevariant(dataset,block,tags,variant)
- local action = citevariants[variant] or citevariants.default
- if action then
- action(dataset,tags,variant)
- end
-end
-
-function citevariants.default(dataset,tags,variant)
- local content = getfield(dataset,tags,variant)
- if content then
- context(content)
- end
-end
-
--- todo : sort
--- todo : choose between publications or commands namespace
--- todo : use details.author
--- todo : sort details.author
-
-local function collectauthoryears(dataset,tags)
- local luadata = datasets[dataset].luadata
- local list = settings_to_array(tags)
- local found = { }
- local result = { }
- local order = { }
- for i=1,#list do
- local tag = list[i]
- local entry = luadata[tag]
- if entry then
- local year = entry.year
- local author = entry.author
- if author and year then
- local a = found[author]
- if not a then
- a = { }
- found[author] = a
- order[#order+1] = author
- end
- local y = a[year]
- if not y then
- y = { }
- a[year] = y
- end
- y[#y+1] = tag
- end
- end
- end
- -- found = { author = { year_1 = { e1, e2, e3 } } }
- for i=1,#order do
- local author = order[i]
- local years = found[author]
- local yrs = { }
- for year, entries in next, years do
- if subyears then
- -- -- add letters to all entries of an author and if so shouldn't
- -- -- we tag all years of an author as soon as we do this?
- -- if #entries > 1 then
- -- for i=1,#years do
- -- local entry = years[i]
- -- -- years[i] = year .. string.char(i + string.byte("0") - 1)
- -- end
- -- end
- else
- yrs[#yrs+1] = year
- end
- end
- result[i] = { author = author, years = yrs }
- end
- return result, order
-end
-
--- (name, name and name) .. how names? how sorted?
--- todo: we loop at the tex end .. why not here
--- \cite[{hh,afo},kvm]
-
--- maybe we will move this tex anyway
-
-function citevariants.author(dataset,tags)
- local result, order = collectauthoryears(dataset,tags,method,what) -- we can have a collectauthors
- publications.citeconcat(order)
-end
-
-local function authorandyear(dataset,tags,formatter)
- local result, order = collectauthoryears(dataset,tags,method,what) -- we can have a collectauthors
- for i=1,#result do
- local r = result[i]
- order[i] = formatter(r.author,r.years) -- reuse order
- end
- publications.citeconcat(order)
-end
-
-function citevariants.authoryear(dataset,tags)
- authorandyear(dataset,tags,formatters["%s (%, t)"])
-end
-
-function citevariants.authoryears(dataset,tags)
- authorandyear(dataset,tags,formatters["%s, %, t"])
-end
-
-function citevariants.authornum(dataset,tags)
- local result, order = collectauthoryears(dataset,tags,method,what) -- we can have a collectauthors
- publications.citeconcat(order)
- ctx_btxcitevariantparameter(v_inbetween)
- lists.resolve(dataset,tags) -- left/right ?
-end
-
--- function citevariants.short(dataset,tags)
--- local short = getdetail(dataset,tags,"short")
--- if short then
--- context(short)
--- end
--- end
-
-function citevariants.short(dataset,tags)
- local short = getdetail(dataset,tags,"short")
- local suffix = getdetail(dataset,tags,"suffix")
- if suffix then
- context(short .. suffix)
- elseif short then
- context(short)
- end
-end
-
-function citevariants.page(dataset,tags)
- local pages = getdetail(dataset,tags,"pages")
- if not pages then
- -- nothing
- elseif type(pages) == "table" then
- context(pages[1])
- ctx_btxcitevariantparameter(v_inbetween)
- context(pages[2])
- else
- context(pages)
- end
-end
-
-function citevariants.num(dataset,tags)
--- ctx_btxdirectlink(f_destination(dataset,block,tags),listindex) -- not okay yet
- lists.resolve(dataset,tags)
-end
-
-function citevariants.serial(dataset,tags) -- the traditional fieldname is "serial" and not "index"
- local index = getfield(dataset,tags,"index")
- if index then
- context(index)
- end
-end
-
--- List variants
-
-local listvariants = { }
-publications.listvariants = listvariants
-
--- function commands.btxhandlelist(dataset,block,tag,variant,setup)
--- if sorttype and sorttype ~= "" then
--- tags = sortedtags(dataset,tags,sorttype)
--- end
--- ctx_setvalue("currentbtxtag",tag)
--- ctx_btxlistvariantparameter(v_left)
--- ctx_directsetup(setup)
--- ctx_btxlistvariantparameter(v_right)
--- end
-
-function commands.btxlistvariant(dataset,block,tags,variant,listindex)
- local action = listvariants[variant] or listvariants.default
- if action then
- action(dataset,block,tags,variant,tonumber(listindex) or 0)
- end
-end
-
-function listvariants.default(dataset,block,tags,variant)
- context("?")
-end
-
-function listvariants.num(dataset,block,tags,variant,listindex)
- ctx_btxdirectlink(f_destination(dataset,block,tags),listindex) -- not okay yet
-end
-
--- function listvariants.short(dataset,block,tags,variant,listindex)
--- local short = getdetail(dataset,tags,variant,variant)
--- if short then
--- context(short)
--- end
--- end
-
-function listvariants.short(dataset,block,tags,variant,listindex)
- local short = getdetail(dataset,tags,"short","short")
- local suffix = getdetail(dataset,tags,"suffix","suffix")
- if suffix then
- context(short .. suffix)
- elseif short then
- context(short)
- end
-end