diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/bibl-tra.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/bibl-tra.lua | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/bibl-tra.lua b/Master/texmf-dist/tex/context/base/mkiv/bibl-tra.lua new file mode 100644 index 00000000000..223554b4daa --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/bibl-tra.lua @@ -0,0 +1,301 @@ +if not modules then modules = { } end modules ['bibl-tra'] = { + version = 1.001, + comment = "this module is the basis for the lxml-* ones", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- also see bibl-tra-new ! + +-- temporary hack, needed for transition + +if not publications then + + local hacks = utilities.storage.allocate() + + job.register('publications.collected',hacks,function(t) publications.collected = t end) + +end + +-- end of hack + + +local match, gmatch, format, concat, sort = string.match, string.gmatch, string.format, table.concat, table.sort + +bibtex = bibtex or { } +local bibtex = bibtex + +bibtex.hacks = bibtex.hacks or { } +local hacks = bibtex.hacks + +local trace_bibtex = false trackers.register("publications.bibtex", function(v) trace_bibtex = v end) + +local report_tex = logs.reporter("publications","tex") + +local context = context +local structures = structures + +local references = structures.references +local sections = structures.sections + +local variables = interfaces.variables + +local v_short = variables.short +local v_cite = variables.cite +local v_default = variables.default +local v_reference = variables.default + +local list = { } +local done = { } +local alldone = { } +local used = { } +local registered = { } +local ordered = { } +local shorts = { } +local mode = 0 + +local template = [[ +\citation{*} +\bibstyle{cont-%s} +\bibdata{%s} +]] + +local bibtexbin = environment.arguments.mlbibtex and "mlbibcontext" or "bibtex" + +directives.register("publications.usemlbibtex", function(v) + bibtexbin = v and "mlbibcontext" or "bibtex" +end) + +function hacks.process(settings) + local style = settings.style or "" + local database = settings.database or "" + local jobname = tex.jobname + if database ~= "" then + local targetfile = file.addsuffix(jobname,"aux") + interfaces.showmessage("publications",3,targetfile) + io.savedata(targetfile,format(template,style,database)) + if trace_bibtex then + report_tex("processing bibtex file %a using %a",jobname,bibtexbin) + end + os.execute(format("%s %q",bibtexbin,jobname)) + -- purge 'm + end +end + +function hacks.register(tag,short) + if not short or short == "" then + short = tag + end + if trace_bibtex then + report_tex("registering bibtex entry %a with shortcut %a",tag,short) + end + local top = #registered + 1 + registered[top] = tag + ordered [tag] = top + shorts [tag] = short +end + +function hacks.nofregistered() + return #registered +end + +function hacks.reset(m) + mode, list, done = m, { }, { } +end + +function hacks.add(str,listindex) + if not str or mode == 0 then + -- skip + elseif mode == 1 then + -- all locals but no duplicates + local sc = sections.currentid() + if done[str] ~= sc then + done[str], alldone[str] = sc, true + list[#list+1] = { str, listindex } + end + elseif mode == 2 then + -- all locals but no preceding + local sc = sections.currentid() + if not alldone[str] and done[str] ~= sc then + done[str], alldone[str] = sc, true + list[#list+1] = { str, listindex } + end + end +end + +function hacks.flush(sortvariant) + local compare -- quite some checking for non-nil + if sortvariant == "" or sortvariant == v_cite or sortvariant == v_default then + -- order is cite order i.e. same as list + elseif sortvariant == v_short then + compare = function(a,b) + local aa, bb = a and a[1], b and b[1] + if aa and bb then + local oa, ob = shorts[aa], shorts[bb] + return oa and ob and oa < ob + end + return false + end + elseif sortvariant == v_reference then + compare = function(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 + else + compare = function(a,b) + local aa, bb = a and a[1], b and b[1] + if aa and bb then + local oa, ob = ordered[aa], ordered[bb] + return oa and ob and oa < ob + end + return false + end + end + if compare then + sort(list,compare) + end + for i=1,#list do + context.doprocessbibtexentry(list[i][1]) + end +end + +function hacks.filterall() + for i=1,#registered do + list[i] = { registered[i], i } + end +end + +function hacks.registerplaced(str) + used[str] = true +end + +function hacks.doifalreadyplaced(str) + commands.doifelse(used[str]) +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 + +function hacks.resolve(prefix,block,reference) -- maybe already feed it split + -- needs checking (the prefix in relation to components) + local subsets + local collected = references.collected + 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 + if #subsets > 0 then + local result, nofresult, done = { }, 0, { } + block = tonumber(block) + 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 = blk .. ":" .. rest + found = subset[tag] + if not found then + for i=block-1,1,-1 do + tag = i .. ":" .. rest + found = subset[tag] + if found then + blk = i + break + end + end + end + end + if not found then + blk = "*" + tag = 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 + -- todo: ranges so the interface will change + sort(result,compare) + 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[1], firstr[2], lastr[1], lastr[2] } + else + nofcollected = nofcollected + 1 + collected[nofcollected] = { firstr[1], firstr[2] } + if last > first then + nofcollected = nofcollected + 1 + collected[nofcollected] = { lastr[1], lastr[2] } + 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[1], firstr[2], lastr[1], lastr[2] } + else + nofcollected = nofcollected + 1 + collected[nofcollected] = { firstr[1], firstr[2] } + if last > first then + nofcollected = nofcollected + 1 + collected[nofcollected] = { lastr[1], lastr[2] } + end + end + end + if nofcollected > 0 then + for i=1,nofcollected do + local c = collected[i] + if c[3] then + context.dowithbibtexnumrefrange(#collected,i,prefix,c[1],c[2],c[3],c[4]) + else +-- print(#collected,i,prefix,c[1],c[2]) + context.dowithbibtexnumref(#collected,i,prefix,c[1],c[2]) + end + end + else + context.nobibtexnumref("error 1") + end + else + context.nobibtexnumref("error 2") + end +end |