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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
#!/usr/bin/env texlua
kpse.set_program_name("luatex")
require("lualibs")
local citeproc = require("citeproc")
local util = require("citeproc-util")
local core = require("csl-core")
local function getopt( arg, options )
local tab = {}
for k, v in ipairs(arg) do
if string.sub( v, 1, 2) == "--" then
local x = string.find( v, "=", 1, true )
if x then tab[ string.sub( v, 3, x-1 ) ] = string.sub( v, x+1 )
else tab[ string.sub( v, 3 ) ] = true
end
elseif string.sub( v, 1, 1 ) == "-" then
local y = 2
local l = string.len(v)
local jopt
while ( y <= l ) do
jopt = string.sub( v, y, y )
if string.find( options, jopt, 1, true ) then
if y < l then
tab[ jopt ] = string.sub( v, y+1 )
y = l
else
tab[ jopt ] = arg[ k + 1 ]
end
else
tab[ jopt ] = true
end
y = y + 1
end
else
if tab.file then
error(string.format('Invalid argument "%s"', v))
end
tab.file = v
end
end
return tab
end
local function print_version()
io.write(string.format("CiteProc-Lua %s\n", citeproc.__VERSION__))
end
local function print_help()
io.write("Usage: citeproc [options] auxname[.aux]\n")
io.write("Options:\n")
io.write(" -h, --help Print this message and exit.\n")
io.write(" -V, --version Print the version number and exit.\n")
end
local function convert_bib(path, output_path)
local contents = util.read_file(path)
local bib = citeproc.parse_bib(contents)
if not output_path then
output_path = string.gsub(path, "%.bib$", ".json")
end
local file = io.open(output_path, "w")
file:write(utilities.json.tojson(bib))
file:write('\n')
file:close()
end
local function read_aux_file(aux_file)
local bib_style = nil
local bib_files = {}
local citations = {}
local csl_options = {}
local file = io.open(aux_file, "r")
if not file then
error(string.format('Failed to open "%s"', aux_file))
return
end
for line in file:lines() do
local match
match = string.match(line, "^\\bibstyle%s*(%b{})")
if match then
bib_style = string.sub(match, 2, -2)
else
match = string.match(line, "^\\bibdata%s*(%b{})")
if match then
for _, bib in ipairs(util.split(string.sub(match, 2, -2), "%s*,%s*")) do
table.insert(bib_files, bib)
end
else
match = string.match(line, "^\\citation%s*(%b{})")
if match then
local citation = core.make_citation(string.sub(match, 2, -2))
table.insert(citations, citation)
else
match = string.match(line, "^\\csloptions%s*(%b{})")
if match then
for key, value in string.gmatch(match, "([%w-]+)=(%w+)") do
csl_options[key] = value
end
end
end
end
end
end
file:close()
return bib_style, bib_files, citations, csl_options
end
local function process_aux_file(aux_file)
if not util.endswith(aux_file, ".aux") then
aux_file = aux_file .. ".aux"
end
local style_name, bib_files, citations, csl_options = read_aux_file(aux_file)
local lang = csl_options.locale
local engine = core.init(style_name, bib_files, lang)
if csl_options.linking == "true" then
engine:enable_linking()
end
local style_class = engine:get_style_class()
local citation_strings = core.process_citations(engine, citations)
local output_string = ""
for _, citation in ipairs(citations) do
local citation_id = citation.citationID
if citation_id ~= "nocite" then
local citation_str = citation_strings[citation_id]
output_string = output_string .. string.format("\\cslcite{%s}{{%s}{%s}}\n", citation_id, style_class, citation_str)
end
end
output_string = output_string .. "\n"
local result = core.make_bibliography(engine)
output_string = output_string .. result
local output_path = string.gsub(aux_file, "%.aux$", ".bbl")
local bbl_file = io.open(output_path, "w")
bbl_file:write(output_string)
bbl_file:close()
end
local function main()
local args = getopt(arg, "o")
-- for k, v in pairs(args) do
-- print( k, v )
-- end
if args.V or args.version then
print_version()
return
elseif args.h or args.help then
print_help()
return
end
if not args.file then
error("citeproc: Need exactly one file argument.\n")
end
local path = args.file
local output_path = args.o or args.output
if util.endswith(path, ".bib") then
convert_bib(path, output_path)
else
process_aux_file(path)
end
end
main()
|