-
Notifications
You must be signed in to change notification settings - Fork 2
/
pwcite.js
94 lines (78 loc) · 2.13 KB
/
pwcite.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* Implements the pwcite script.
*/
const wcite = require('./wcite')
const pandoc = require('./util/pandoc')
const { metadata, metavalues, walk } = pandoc
/**
* Process each citation in a Pandoc document in-place.
*/
function processCitations (doc, action) {
const nocite = metavalues(doc, 'nocite')
walk([doc, nocite], (type, value) => {
if (type === 'Cite') {
value[0].forEach(action)
}
})
}
/**
* Extract citekeys from metadata fields `citekeys` and `nocite` and from
* Wikidata identifiers used as citation identifiers in the document.
*/
function getCitekeys (doc) {
let citekeys = metavalues(doc, 'citekeys') || {}
processCitations(doc, c => {
if (!(c.citationId in citekeys)) {
citekeys[c.citationId] = true
}
})
return citekeys
}
/**
* Replace citation keys in a document.
*/
function replaceCitekeys (doc, citekeys) {
processCitations(doc, c => {
const key = citekeys[c.citationId]
if (typeof key === 'string' && key !== '') {
c.citationId = citekeys[c.citationId]
}
})
}
/**
* The actual Pandoc filter.
*/
function filter (root, format, meta) {
let { bibliography, nocite } = metavalues(root)
if (Array.isArray(bibliography)) {
bibliography = bibliography.find(f => f.match(/\.json$/))
} else if (bibliography && !bibliography.match(/.json$/)) {
bibliography = undefined
}
let citekeys = getCitekeys(root)
// TODO: set output to quiet or specify logfile?
let out = process.stderr
let cite = wcite({ bibliography, citekeys, nocite, out })
let missing = Object.keys(cite.doc.citekeys).filter(id => cite.doc.citekeys[id] === false)
cite.add(missing)
if (!bibliography) {
let refs = cite.doc.bibliography.references
refs = Object.keys(refs).reduce((arr, key) => { // Object.values
arr.push(refs[key])
return arr
}, [])
meta.references = metadata(refs)
}
replaceCitekeys(root, citekeys)
if (format && format.match(/^html/)) {
require('./inject-wikidata-links')(meta)
}
return root
}
module.exports = {
processCitations,
getCitekeys,
replaceCitekeys,
filter,
run: args => pandoc.filter(filter, args)
}