diff options
author | Context Git Mirror Bot <phg42.2a@gmail.com> | 2015-03-09 20:15:05 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2015-03-09 20:15:05 +0100 |
commit | dc98ffdc842271d05903846b460fab90d4d83739 (patch) | |
tree | 49603cd805408ebdde3a7eafc59c40279dc7e9ad /tex/context/base/publ-dat.lua | |
parent | 08128a9710f7a34e16f7487b3bccfe7feadb36f1 (diff) | |
download | context-dc98ffdc842271d05903846b460fab90d4d83739.tar.gz |
2015-03-09 19:29:00
Diffstat (limited to 'tex/context/base/publ-dat.lua')
-rw-r--r-- | tex/context/base/publ-dat.lua | 214 |
1 files changed, 131 insertions, 83 deletions
diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua index bfb38645b..be5f1eca8 100644 --- a/tex/context/base/publ-dat.lua +++ b/tex/context/base/publ-dat.lua @@ -33,7 +33,7 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local textoutf = characters and characters.tex.toutf local settings_to_hash, settings_to_array = utilities.parsers.settings_to_hash, utilities.parsers.settings_to_array local formatters = string.formatters -local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash +local sortedkeys, sortedhash, keys = table.sortedkeys, table.sortedhash, table.keys local xmlcollected, xmltext, xmlconvert = xml.collected, xml.text, xml.convert local setmetatableindex = table.setmetatableindex @@ -42,6 +42,7 @@ local setmetatableindex = table.setmetatableindex local P, R, S, V, C, Cc, Cs, Ct, Carg, Cmt, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Carg, lpeg.Cmt, lpeg.Cp local p_whitespace = lpegpatterns.whitespace +local p_utf8character = lpegpatterns.utf8character local trace = false trackers.register("publications", function(v) trace = v end) local trace_duplicates = true trackers.register("publications.duplicates", function(v) trace = v end) @@ -145,17 +146,22 @@ local defaulttypes = allocate { url = "url", } +local defaultsets = allocate { + page = { "page", "pages" }, +} + tables.implicits = implicits tables.origins = origins tables.virtuals = virtuals tables.types = defaulttypes +tables.sets = defaultsets tables.privates = privates tables.specials = specials local variables = interfaces and interfaces.variables or setmetatableindex("self") local v_all = variables.all -local v_standard = variables.standard +local v_default = variables.default if not publications.usedentries then function publications.usedentries() @@ -196,8 +202,9 @@ local unknowncategory = function(t,k) required = false, optional = false, virtual = false, - fields = setmetatableindex(unknownfield), - types = defaulttypes, + fields = setmetatableindex(unknownfield), -- this will remember them + types = unknowntypes, + sets = setmetatableindex(defaultsets), -- new, but rather small } t[k] = v return v @@ -219,7 +226,7 @@ local default = { types = setmetatableindex(defaulttypes,unknowntype), } --- maybe at some point we can han da handlers table with per field +-- maybe at some point we can have a handlers table with per field -- a found, fetch, ... method local function checkfield(specification,category,data) @@ -279,10 +286,10 @@ local specifications = setmetatableindex(function(t,name) end setmetatableindex(types,unknowntype) -- - local fields = setmetatableindex(unknownfield) + local fields = setmetatableindex(unknownfield) specification.fields = fields -- - local virtual = specification.virtual + local virtual = specification.virtual if virtual == nil then -- so false is valid virtual = virtuals specification.virtual = virtual @@ -405,7 +412,10 @@ do ----- command = P("\\") * Cc("btxcmd{") * (R("az","AZ")^1) * Cc("}") ----- command = P("\\") * (Carg(1) * C(R("az","AZ")^1) / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end) + ----- command = P("\\") * (Carg(1) * C(R("az","AZ")^1) * space^0 / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end) local command = P("\\") * (Carg(1) * C(R("az","AZ")^1) * space^0 / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end) + local whatever = P("\\") * P(" ")^1 / " " + + P("\\") * ( P("hbox") + P("raise") ) -- bah local somemath = P("$") * ((1-P("$"))^1) * P("$") -- let's not assume nested math ----- character = lpegpatterns.utf8character local any = P(1) @@ -414,15 +424,24 @@ do local one_r = P("}") / "" local two_l = P("{{") / "" local two_r = P("}}") / "" - local special = P("#") / "\\letterhash" + local zero_l_r = P("{}") / "" * #P(1) + local special = P("#") / "\\letterhash " - local filter_0 = S('\\{}') + local filter_0 = S('\\{}#') local filter_1 = (1-filter_0)^0 * filter_0 local filter_2 = Cs( -- {{...}} ... {{...}} -- two_l * (command + special + any - two_r - done)^0 * two_r * done + -- one_l * (command + special + any - one_r - done)^0 * one_r * done + - (somemath + command + special + collapsed + any)^0 + ( + somemath + + whatever + + command + + special + + collapsed + + zero_l_r + + any + )^0 ) -- Currently we expand shortcuts and for large ones (like the acknowledgements @@ -443,57 +462,57 @@ do publicationsstats.nofdefinitions = publicationsstats.nofdefinitions + 1 local fields = dataset.fields local luadata = dataset.luadata + local hashtag = tag if luadata[tag] then local t = tags[tag] local d = dataset.name local n = (t[n] or 0) + 1 t[d] = n + hashtag = tag .. "-" .. n if trace_duplicates then local p = { } for k, v in sortedhash(t) do p[#p+1] = formatters["%s:%s"](k,v) end - report_duplicates("tag %a is present multiple times: % t",tag,p) + report_duplicates("tag %a is present multiple times: % t, assigning hashtag %a",tag,p,hashtag) end - else - local found = luadata[tag] - local index = getindex(dataset,luadata,tag) - local entries = { - category = lower(category), - tag = tag, - index = index, - } - for i=1,#tab,2 do - local original = tab[i] - local normalized = fields[original] - if not normalized then - normalized = lower(original) -- we assume ascii fields - fields[original] = normalized + end + local index = getindex(dataset,luadata,hashtag) + local entries = { + category = lower(category), + tag = tag, + index = index, + } + for i=1,#tab,2 do + local original = tab[i] + local normalized = fields[original] + if not normalized then + normalized = lower(original) -- we assume ascii fields + fields[original] = normalized + end + -- if entries[normalized] then + if rawget(entries,normalized) then + if trace_duplicates then + report_duplicates("redundant field %a is ignored for tag %a in dataset %a",normalized,tag,dataset.name) end - -- if entries[normalized] then - if rawget(entries,normalized) then - if trace_duplicates then - report_duplicates("redundant field %a is ignored for tag %a in dataset %a",normalized,tag,dataset.name) - end - else - local value = tab[i+1] - value = textoutf(value) - if lpegmatch(filter_1,value) then - value = lpegmatch(filter_2,value,1,dataset.commands) -- we need to start at 1 for { } - end - if normalized == "crossref" then - local parent = luadata[value] - if parent then - setmetatableindex(entries,parent) - else - -- warning - end + else + local value = tab[i+1] + value = textoutf(value) + if lpegmatch(filter_1,value) then + value = lpegmatch(filter_2,value,1,dataset.commands) -- we need to start at 1 for { } + end + if normalized == "crossref" then + local parent = luadata[value] + if parent then + setmetatableindex(entries,parent) + else + -- warning end - entries[normalized] = value end + entries[normalized] = value end - luadata[tag] = entries end + luadata[hashtag] = entries end local function resolve(s,dataset) @@ -534,17 +553,17 @@ do local collapsed = p_whitespace^1/" " local nospaces = p_whitespace^1/"" - local p_left = (p_whitespace^0 * left * p_whitespace^0) / "" - local p_right = (p_whitespace^0 * right * p_whitespace^0) / "" + local p_left = (p_whitespace^0 * left) / "" + local p_right = (right * p_whitespace^0) / "" local balanced = P { - [1] = ((escape * (left+right)) + collapsed + (1 - (left+right))^1 + V(2))^0, + [1] = ((escape * (left+right)) + (collapsed + 1 - (left+right))^1 + V(2))^0, [2] = left * V(1) * right, } local unbalanced = P { [1] = left * V(2) * right, - [2] = ((escape * (left+right)) + collapsed + (1 - (left+right))^1 + V(1))^0, + [2] = ((escape * (left+right)) + (collapsed + 1 - (left+right))^1 + V(1))^0, } local keyword = C((R("az","AZ","09") + S("@_:-"))^1) @@ -555,20 +574,7 @@ do local s_quoted = ((escape*single) + collapsed + (1-single))^0 local d_quoted = ((escape*double) + collapsed + (1-double))^0 - -- local p_strip = C((1-(p_whitespace * P(-1)))^1) - -- - -- local function stripendspace(s) - -- return lpegmatch(p_strip,s) or s - -- end - - local p_strip = (Cp() * p_whitespace^1 * P(-1) + 1)^1 - - local function stripendspace(s) - local p = lpegmatch(p_strip,s) - return p and sub(s,1,p-1) or s - end - - local b_value = p_left * (Cs(balanced)/stripendspace) * p_right + local b_value = p_left * balanced * p_right local u_value = p_left * unbalanced * p_right -- get rid of outer { } local s_value = (single/"") * (u_value + s_quoted) * (single/"") local d_value = (double/"") * (u_value + d_quoted) * (double/"") @@ -577,6 +583,8 @@ do local somevalue = d_value + b_value + s_value + r_value local value = Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0)) + value = value / function(s) return lpegmatch(lpegpatterns.stripper,s) end + local forget = percent^1 * (1-lineending)^0 local spacing = spacing * forget^0 * spacing local assignment = spacing * key * spacing * equal * spacing * value * spacing @@ -618,14 +626,7 @@ do current.loaded[source] = kind or true end current.newtags = #current.luadata > 0 and { } or current.newtags - local before = #current.luadata lpegmatch(bibtotable,content or "",1,current) - local after = #current.luadata - if before == after then - report("no entries added") - else - report("%s entries added",after-before) - end statistics.stoptiming(publications) end @@ -751,6 +752,36 @@ do publications.resolvedname = resolvedname + local cleaner = false + local cleaned = false + + function loaders.registercleaner(what,fullname) + if not fullname or fullname == "" then + report("no %s file %a",what,fullname) + return + end + local list = table.load(fullname) + if not list then + report("invalid %s file %a",what,fullname) + return + end + list = list.replacements + if not list then + report("no replacement table in %a",fullname) + return + end + if cleaned then + report("adding replacements from %a",fullname) + for k, v in next, list do + cleaned[k] = v + end + else + report("using replacements from %a",fullname) + cleaned = list + end + cleaner = true + end + function loaders.bib(dataset,filename,kind) local dataset, fullname = resolvedname(dataset,filename) if not fullname then @@ -761,6 +792,12 @@ do report("empty file %a, nothing loaded",fullname) return end + if cleaner == true then + cleaner = Cs((lpeg.utfchartabletopattern(keys(cleaned)) / cleaned + p_utf8character)^1) + end + if cleaner ~= false then + data = lpegmatch(cleaner,data) + end if trace then report("loading file %a",fullname) end @@ -840,7 +877,7 @@ do end) function publications.load(specification) - local current = datasets[specification.dataset or v_standard] + local current = datasets[specification.dataset or v_default] local files = settings_to_array(specification.filename) local kind = specification.kind local dataspec = specification.specification @@ -931,6 +968,14 @@ do end +function publications.tags(dataset) + return sortedkeys(datasets[dataset].luadata) +end + +function publications.sortedentries(dataset) + return sortedhash(datasets[dataset].luadata) +end + -- a helper: function publications.concatstate(i,n) @@ -954,17 +999,17 @@ do local savers = { } local s_preamble = [[ - % this is an export from context mkiv - - @preamble{ - \ifdefined\btxcmd - % we're probably in context - \else - \def\btxcmd#1{\csname#1\endcsname} - \fi - } +% this is an export from context mkiv + +@preamble{ + \ifdefined\btxcmd + % we're probably in context + \else + \def\btxcmd#1{\csname#1\endcsname} + \fi +} - ]] +]] function savers.bib(dataset,filename,usedonly) local current = datasets[dataset] @@ -1074,12 +1119,12 @@ do local pagessplitter = lpeg.splitat(P("-")^1) - casters.pagenumber = function(str) + casters.range = function(str) local first, last = lpegmatch(pagessplitter,str) return first and last and { first, last } or str end - writers.pagenumber = function(p) + writers.range = function(p) if type(p) == "table" then return concat(p,"-") else @@ -1087,4 +1132,7 @@ do end end + casters.pagenumber = casters.range + writers.pagenumber = writers.range + end |