-
Notifications
You must be signed in to change notification settings - Fork 0
/
bibexport.lua
140 lines (129 loc) · 3.96 KB
/
bibexport.lua
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
-- from https://github.com/pandoc/lua-filters
--
-- This filter produces two files:
-- - a YAML file `bibexport.yaml` with cite keys and bibliographies
-- used in the document
-- - a bib file containing the BibTeX entries
-- Presupposed is that the bibliographies are BibTeX files.
--
-- Since forking:
-- - use bibtool instead of bibexport
-- - added unlinking of `bibexport.bib` to prevent backups
-- - added YAML file
-- - used get_keys() to simplify code
-- - document a bit
--
-- Last Changed: 2021-07-19, 12:33:42 (CEST)
--
-- local inspect = require('inspect')
-- local utils = require 'pandoc.utils'
local List = require 'pandoc.List'
local utils = require "pandoc.utils"
local utilPath = string.match(PANDOC_SCRIPT_FILE, '.*[/\\]')
if PANDOC_VERSION >= {2,12} then
local path = require 'pandoc.path'
utilPath = path.directory(PANDOC_SCRIPT_FILE) .. path.separator
end
local loc_utils = dofile ((utilPath or '') .. 'utils.lua')
local citation_id_set = {}
local link_set = {}
function Link (link)
if link.target ~= nil then
link_set[link.target] = true
end
end
--- Collect all citation IDs from one citation
function Cite (c)
local cs = c.citations
for i = 1, #cs do
citation_id_set[cs[i].id or cs[i].citationId] = true
end
end
--- adjust file names of bibliographies
-- @param bibliography meta data
function bibdata (bibliography)
--- adjust the file name of one bibliography
local function bibname (bibitem)
if type(bibitem) == 'string' then
return bibitem:gsub('%.bib$', '')
else
-- bibitem is assumed to be a list of inlines
return utils.stringify(bibitem):gsub('%.bib$', '')
end
end
local bibs = type(bibliography) == "table" -- bibliography.t == 'MetaList'
and List.map(bibliography, bibname)
or List:new({bibliography})
return bibs
end
--- write YAML lists of bibliographies and citations
function yamlify(bibs, citations)
local biby = io.open("bibexport.yaml", "w")
biby:write("bibliographies:\n")
for i, b in ipairs(bibs) do
biby:write(string.format("- %s\n", b))
end
biby:write("cite-keys:\n")
for i, b in ipairs(citations) do
biby:write(string.format("- %s\n", b))
end
biby:write("links:\n")
for k, v in pairs(link_set) do
biby:write(string.format("- %s\n", k))
end
biby:close()
end
-- aggregate aux content and bibliography
-- @return aux content, bibs
function aux_content(bibliography)
local cites = loc_utils.get_keys(citation_id_set)
table.sort(cites)
local citations = table.concat(cites, ',')
local bibs = bibdata(bibliography)
yamlify(bibs, cites)
return table.concat(
{
'\\bibstyle{alpha}',
'\\bibdata{' .. table.concat(bibs, ',') .. '}',
'\\citation{' .. citations .. '}',
'',
},
'\n'
), bibs
end
--- write am aux file for processing with bibtool
-- @return the aux file name, the name of the bibliography files
function write_dummy_aux (bibliography, auxfile)
local filename
if type(auxfile) == 'string' then
filename = auxfile
elseif type(auxfile) == 'table' then
-- assume list of inlines
filename = utils.stringify(pandoc.Span(auxfile))
else
filename = 'bibexport.aux'
end
local fh = io.open(filename, 'w')
local aux_cont, bibs = aux_content(bibliography)
fh:write(aux_cont)
fh:close()
io.stderr:write('Aux written to ' .. filename .. '\n')
return filename, bibs
end
--- when processing the document, process citations and write lists of citations
function Pandoc (doc)
local meta = doc.meta
if not meta.bibliography then
return nil
else
-- create a dummy .aux file
local auxfile_name, bibs = write_dummy_aux(meta.bibliography, meta.auxfile)
os.remove('bibexport.bib') -- clean up old files
-- os.execute('bibexport -t ' .. auxfile_name)
local comm = 'bibtool -q -x ' .. auxfile_name .. ' ' .. table.concat(bibs, ' ') .. "> bibexport.bib"
io.stderr:write("Execute: " .. comm)
os.execute(comm)
io.stderr:write('Output written to bibexport.bib\n')
return nil
end
end