publ-tra.lua /size: 17 Kb    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['publ-tra'] = {
2    version   = 1.001,
3    comment   = "this module part of publication support",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- todo: use context.tt .. more efficient, less code
10
11local next, type, rawget = next, type, rawget
12
13local sortedhash        = table.sortedhash
14local sortedkeys        = table.sortedkeys
15local settings_to_array = utilities.parsers.settings_to_array
16local formatters        = string.formatters
17local concat            = table.concat
18
19local context           = context
20local commands          = commands
21
22local v_default         = interfaces.variables.default
23
24local publications      = publications
25local tracers           = publications.tracers
26local tables            = publications.tables
27local datasets          = publications.datasets
28local specifications    = publications.specifications
29local citevariants      = publications.citevariants
30
31local getfield          = publications.getfield
32local getcasted         = publications.getcasted
33
34local ctx_NC, ctx_NR, ctx_HL, ctx_FL, ctx_ML, ctx_LL, ctx_EQ = context.NC, context.NR, context.HL, context.FL, context.ML, context.LL, context.EQ
35
36local ctx_starttabulate = context.starttabulate
37local ctx_stoptabulate  = context.stoptabulate
38
39local ctx_formatted     = context.formatted
40local ctx_bold          = ctx_formatted.monobold
41local ctx_monobold      = ctx_formatted.monobold
42local ctx_verbatim      = ctx_formatted.verbatim
43
44local ctx_rotate        = context.rotate
45local ctx_rlap          = context.rlap
46local ctx_page          = context.page
47
48local privates = tables.privates
49local specials = tables.specials
50
51local report   = logs.reporter("publications","tracers")
52
53function tracers.showdatasetfields(settings)
54    local dataset       = settings.dataset
55    local current       = datasets[dataset]
56    local luadata       = current.luadata
57    local specification = settings.specification
58    local fielddata     = specification and specifications[specification] or specifications.apa
59    local categories    = fielddata.categories
60    if next(luadata) then
61        ctx_starttabulate { "|lT|lT|pTl|" }
62            ctx_NC() ctx_bold("tag")
63            ctx_NC() ctx_bold("category")
64            ctx_NC() ctx_bold("fields")
65            ctx_NC() ctx_NR()
66            ctx_FL()
67            for tag, entry in sortedhash(luadata) do
68                local category = entry.category
69                local catedata = categories[category]
70                local fields   = catedata and catedata.fields or { }
71                ctx_NC() context(tag)
72                ctx_NC() context(category)
73                ctx_NC() -- grouping around colors needed
74                for key, value in sortedhash(entry) do
75                    if privates[key] then
76                        -- skip
77                    elseif specials[key] then
78                        context("{\\darkblue %s} ",key)
79                    else
80                        local kind = fields[key]
81                        if kind == "required" then
82                            context("{\\darkgreen %s} ",key)
83                        elseif kind == "optional" then
84                            context("%s ",key)
85                        else
86                            context("{\\darkyellow %s} ",key)
87                        end
88                    end
89                end
90                ctx_NC() ctx_NR()
91            end
92        ctx_stoptabulate()
93    end
94end
95
96function tracers.showdatasetcompleteness(settings)
97    local dataset       = settings.dataset
98    local current       = datasets[dataset]
99    local luadata       = current.luadata
100    local specification = settings.specification
101    local fielddata     = specification and specifications[specification] or specifications.apa
102    local categories    = fielddata.categories
103
104    local preamble = { "|lTBw(5em)|lBTp(10em)|plT|" }
105
106    local function do_identified(tag,category,crossref,index)
107        ctx_NC() ctx_monobold(index)
108        ctx_NC() ctx_monobold(category)
109        ctx_NC() if crossref then
110                ctx_monobold("%s\\hfill\\darkblue => %s",tag,crossref)
111             else
112                ctx_monobold(tag)
113             end
114        ctx_NC() ctx_NR()
115    end
116
117    local function do_required(done,found,key,value,indirect)
118        ctx_NC() if not done then ctx_monobold("required") end
119        ctx_NC() context(key)
120        ctx_NC()
121            if indirect then
122                if value then
123                    context("\\darkblue")
124                    ctx_verbatim(value)
125                else
126                    context("\\darkred\\tttf [missing crossref]")
127                end
128            elseif value then
129                ctx_verbatim(value)
130            else
131                context("\\darkred\\tttf [missing value]")
132            end
133        ctx_NC() ctx_NR()
134        found[key] = nil
135        return done or true
136    end
137
138    local function do_optional(done,found,key,value,indirect)
139        ctx_NC() if not done then ctx_monobold("optional") end
140        ctx_NC() context(key)
141        ctx_NC()
142            if indirect then
143                context("\\darkblue")
144            end
145            if value then
146                ctx_verbatim(value)
147            end
148        ctx_NC() ctx_NR()
149        found[key] = nil
150        return done or true
151    end
152
153    local function do_special(done,key,value)
154        ctx_NC() if not done then ctx_monobold("special") end
155        ctx_NC() context(key)
156        ctx_NC() if value then ctx_verbatim(value) end
157        ctx_NC() ctx_NR()
158        return done or true
159    end
160
161    local function do_extra(done,key,value)
162        ctx_NC() if not done then ctx_monobold("extra") end
163        ctx_NC() context(key)
164        ctx_NC() if value then ctx_verbatim(value) end
165        ctx_NC() ctx_NR()
166        return done or true
167    end
168
169    if next(luadata) then
170        for tag, entry in sortedhash(luadata) do
171            local category = entry.category
172            local fields   = categories[category]
173            local found    = { }
174            local flushed  = { }
175            for k, v in next, entry do
176                found[k] = true
177            end
178            ctx_starttabulate(preamble)
179            do_identified(tag,category,entry.crossref,entry.index)
180            ctx_FL()
181            if fields then
182                local required = fields.required
183                local sets     = fields.sets or { }
184                local done     = false
185                if required then
186                    for i=1,#required do
187                        local r = required[i]
188                        local r = sets[r] or r
189                        if type(r) == "table" then
190                            local okay = false
191                            for i=1,#r do
192                                local ri = r[i]
193                                if not flushed[ri] then
194                                    -- already done
195                                    if rawget(entry,ri) then
196                                        done = do_required(done,found,ri,entry[ri])
197                                        okay = true
198                                        flushed[ri] = true
199                                    elseif entry[ri] then
200                                        done = do_required(done,found,ri,entry[ri],true)
201                                        okay = true
202                                        flushed[ri] = true
203                                    end
204                                end
205                            end
206                            if not okay and not flushed[r] then
207                                done = do_required(done,found,concat(r," {\\letterbar} "))
208                                flushed[r] = true
209                            end
210                        elseif rawget(entry,r) then
211                            if not flushed[r] then
212                                done = do_required(done,found,r,entry[r])
213                                flushed[r] = true
214                            end
215                        elseif entry[r] then
216                            if not flushed[r] then
217                                done = do_required(done,found,r,entry[r],true)
218                                flushed[r] = true
219                            end
220                        else
221                            if not flushed[r] then
222                                done = do_required(done,found,r)
223                                flushed[r] = true
224                            end
225                        end
226                    end
227                end
228                local optional = fields.optional
229                local done     = false
230                if optional then
231                    for i=1,#optional do
232                        local o = optional[i]
233                        local o = sets[o] or o
234                        if type(o) == "table" then
235                            for i=1,#o do
236                                local oi = o[i]
237                                if not flushed[oi] then
238                                    if rawget(entry,oi) then
239                                        done = do_optional(done,found,oi,entry[oi])
240                                        flushed[oi] = true
241                                    elseif entry[oi] then
242                                        done = do_optional(done,found,oi,entry[oi],true)
243                                        flushed[oi] = true
244                                    end
245                                end
246                            end
247                        elseif rawget(entry,o) then
248                            if not flushed[o] then
249                                done = do_optional(done,found,o,entry[o])
250                                flushed[o] = true
251                            end
252                        elseif entry[o] then
253                            if not flushed[o] then
254                                done = do_optional(done,found,o,entry[o],true)
255                                flushed[o] = true
256                            end
257                        end
258                    end
259                end
260            end
261            local done = false
262            for k, v in sortedhash(found) do
263                if privates[k] then
264                    -- skip
265                elseif specials[k] and not flushed[k] then
266                    done = do_special(done,k,entry[k])
267                    flushed[k] = true
268                end
269            end
270            local done = false
271            for k, v in sortedhash(found) do
272                if privates[k] then
273                    -- skip
274                elseif not specials[k] and not flushed[k] then
275                    done = do_extra(done,k,entry[k])
276                    flushed[k] = true
277                end
278            end
279            ctx_stoptabulate()
280        end
281    end
282
283end
284
285function tracers.showfields(settings)
286    local rotation      = settings.rotation
287    local specification = settings.specification
288    local fielddata     = specification and specifications[specification] or specifications.apa
289    local categories    = fielddata.categories
290    local validfields   = { }
291    for category, data in next, categories do
292        local sets   = data.sets
293        local fields = data.fields
294        for name, list in next, fields do
295            validfields[name] = true
296        end
297    end
298    local s_categories = sortedkeys(categories)
299    local s_fields     = sortedkeys(validfields)
300    ctx_starttabulate { "|l" .. string.rep("|c",#s_categories) .. "|" }
301    ctx_FL()
302    ctx_NC()
303    if rotation then
304        rotation = { rotation = rotation }
305    end
306    for i=1,#s_categories do
307        ctx_NC()
308        local txt = formatters["\\bf %s"](s_categories[i])
309        if rotation then
310            ctx_rotate(rotation,txt)
311        else
312            context(txt)
313        end
314    end
315    ctx_NC() ctx_NR()
316    ctx_FL()
317    for i=1,#s_fields do
318        local field  = s_fields[i]
319        ctx_NC()
320        ctx_bold(field)
321        for j=1,#s_categories do
322            ctx_NC()
323            local kind = categories[s_categories[j]].fields[field]
324            if kind == "required" then
325                context("\\darkgreen*")
326            elseif kind == "optional" then
327                context("*")
328            end
329        end
330        ctx_NC() ctx_NR()
331    end
332    ctx_LL()
333    ctx_stoptabulate()
334end
335
336function tracers.showtables(settings)
337    for name, list in sortedhash(tables) do
338        ctx_starttabulate { "|Tl|Tl|" }
339        ctx_FL()
340        ctx_NC()
341        ctx_rlap(function() ctx_bold(name) end)
342        ctx_NC()
343        ctx_NC()
344        ctx_NR()
345        ctx_FL()
346        for k, v in sortedhash(list) do
347            ctx_NC()
348            context(k)
349            ctx_NC()
350            if type(v) == "table" then
351                context("% t",v)
352            else
353                context(tostring(v))
354            end
355            ctx_NC()
356            ctx_NR()
357        end
358        ctx_LL()
359        ctx_stoptabulate()
360    end
361end
362
363function tracers.showdatasetauthors(settings)
364
365    local dataset = settings.dataset
366    local field   = settings.field
367
368    local sortkey = publications.writers.author
369
370    if not dataset or dataset == "" then dataset = v_default end
371    if not field   or field   == "" then field   = "author"  end
372
373    local function row(i,k,v)
374        ctx_NC()
375        if i then
376            ctx_verbatim(i)
377        end
378        ctx_NC()
379        if k then
380            ctx_verbatim(k)
381        end
382        ctx_EQ()
383        if type(v) == "table" then
384            local t = { }
385            for i=1,#v do
386                local vi = v[i]
387                if type(vi) == "table" then
388                    t[i] = concat(vi,"-")
389                else
390                    t[i] = vi
391                end
392            end
393            v = concat(t, " | ")
394        end
395        if v then
396            ctx_verbatim(v)
397        end
398        ctx_NC()
399        ctx_NR()
400    end
401
402    local function authorrow(ai,k,i)
403        local v = ai[k]
404        if v then
405            row(i,k,v)
406        end
407    end
408
409    local function commonrow(key,value)
410        ctx_NC() if key then ctx_rlap(function() ctx_verbatim(key) end) end
411        ctx_NC()
412        ctx_EQ() if value then ctx_verbatim(value) end
413        ctx_NC() ctx_NR()
414    end
415
416    local d = datasets[dataset].luadata
417
418    local trialtypesetting = context.trialtypesetting()
419
420    for tag, entry in sortedhash(d) do
421
422        local a, f, k = getcasted(dataset,tag,field)
423
424        if type(a) == "table" and #a > 0 and k == "author" then
425            context.start()
426            context.tt()
427            ctx_starttabulate { "|B|Bl|p|" }
428                ctx_FL()
429                local original = getfield(dataset,tag,field)
430                commonrow("tag",tag)
431                commonrow("field",field)
432                commonrow("original",original)
433                commonrow("sortkey",sortkey(a))
434                for i=1,#a do
435                    ctx_ML()
436                    local ai = a[i]
437                    if ai then
438                        authorrow(ai,"original",i)
439                        authorrow(ai,"snippets")
440                        authorrow(ai,"initials")
441                        authorrow(ai,"firstnames")
442                        authorrow(ai,"vons")
443                        authorrow(ai,"surnames")
444                        authorrow(ai,"juniors")
445                        local options = ai.options
446                        if options then
447                            row(false,"options",sortedkeys(options))
448                        end
449                    elseif not trialtypesetting then
450                        report("bad author name: %s",original or "?")
451                    end
452                end
453                ctx_LL()
454            ctx_stoptabulate()
455            context.stop()
456        end
457
458    end
459
460end
461
462function tracers.showentry(dataset,tag)
463    local dataset = datasets[dataset]
464    if dataset then
465        local entry = dataset.luadata[tag]
466        local done  = false
467        for k, v in sortedhash(entry) do
468            if not privates[k] then
469                ctx_verbatim("%w[%s: %s]",done and 1 or 0,k,v)
470                done = true
471            end
472        end
473    end
474end
475
476local skipped = { index = true, default = true }
477
478function tracers.showvariants(dataset,pages)
479    local variants = sortedkeys(citevariants)
480    for tag in publications.sortedentries(dataset or v_default) do
481        if pages then
482            ctx_page()
483        end
484        ctx_starttabulate { "|T||" }
485        for i=1,#variants do
486            local variant = variants[i]
487            if not skipped[variant] then
488                ctx_NC() context(variant)
489             -- ctx_EQ() citevariants[variant] { dataset = v_default, reference = tag, variant = variant }
490                ctx_EQ() context.cite({variant},{dataset .. "::" .. tag})
491                ctx_NC() ctx_NR()
492            end
493        end
494        ctx_stoptabulate()
495        if pages then
496            ctx_page()
497        end
498    end
499end
500
501function tracers.showhashedauthors(dataset,pages)
502    local components = publications.components.author
503    ctx_starttabulate { "|T|T|T|T|T|T|" }
504    ctx_NC() ctx_bold("hash")
505    ctx_NC() ctx_bold("vons")
506    ctx_NC() ctx_bold("surnames")
507    ctx_NC() ctx_bold("initials")
508    ctx_NC() ctx_bold("firstnames")
509    ctx_NC() ctx_bold("juniors")
510    ctx_NC() ctx_NR() ctx_HL()
511    for hash, data in sortedhash(publications.authorcache) do
512        local vons, surnames, initials, firstnames, juniors = components(data)
513        ctx_NC() context(hash)
514        ctx_NC() context(vons)
515        ctx_NC() context(surnames)
516        ctx_NC() context(initials)
517        ctx_NC() context(firstnames)
518        ctx_NC() context(juniors)
519        ctx_NC() ctx_NR()
520    end
521    ctx_stoptabulate()
522end
523
524commands.showbtxdatasetfields       = tracers.showdatasetfields
525commands.showbtxdatasetcompleteness = tracers.showdatasetcompleteness
526commands.showbtxfields              = tracers.showfields
527commands.showbtxtables              = tracers.showtables
528commands.showbtxdatasetauthors      = tracers.showdatasetauthors
529commands.showbtxhashedauthors       = tracers.showhashedauthors
530commands.showbtxentry               = tracers.showentry
531commands.showbtxvariants            = tracers.showvariants
532