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
|
--
-- Copyright (c) 2021-2025 Zeping Lee
-- Released under the MIT license.
-- Repository: https://github.com/zepinglee/citeproc-lua
--
local cli = {}
local lpeg = require("lpeg")
require("lualibs")
local citeproc_manager = require("citeproc-manager")
local citeproc = require("citeproc")
local bibtex2csl -- = require("citeproc-bibtex-parser") -- load on demand
local util = require("citeproc-util")
local latex_parser = require("citeproc-latex-parser")
-- http://lua-users.org/wiki/AlternativeGetOpt
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-lua [options] auxname[.aux]\n")
io.write("Options:\n")
io.write(" -h, --help Print this message and exit.\n")
io.write(" -q, --quiet Quiet mode: suppress the banner and progress reports.\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)
bibtex2csl = bibtex2csl or require("citeproc-bibtex2csl")
local csl_data = bibtex2csl.parse_bibtex_to_csl(contents, true, true, true, true)
if not output_path then
output_path = string.gsub(path, "%.bib$", ".json")
end
util.write_file(utilities.json.tojson(csl_data) .. "\n", output_path)
end
---@param aux_file string
local function process_aux_file(aux_file)
if not util.endswith(aux_file, ".aux") then
aux_file = aux_file .. ".aux"
end
local blg_file = string.gsub(aux_file, "%.aux$", ".blg")
util.set_logging_file(blg_file)
local banner = string.format("This is citeproc-lua, Version %s", citeproc.__VERSION__)
util.info(banner)
util.info(string.format("The top-level auxiliary file: %s", aux_file))
local csl_citation_manager = citeproc_manager.CslCitationManager:new()
local aux_content = util.read_file(aux_file)
if not aux_content then
return
end
local bbl_str = csl_citation_manager:read_aux_file(aux_content)
local output_path = string.gsub(aux_file, "%.aux$", ".bbl")
util.write_file(bbl_str, output_path)
util.quiet_mode = false;
if util.num_errors > 1 then
util.info(string.format("(There were %d error messages)", util.num_errors))
elseif util.num_errors == 1 then
util.info("(There was 1 error message)")
end
if util.num_warnings > 1 then
util.info(string.format("(There were %d warning messages)", util.num_warnings))
elseif util.num_warnings == 1 then
util.info("(There was 1 warning message)")
end
util.close_logging_file()
end
function cli.main()
local args = getopt(arg, "")
-- 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
elseif args.q or args.quiet then
util.quiet_mode = true
end
if not args.file then
error("citeproc-lua: 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
if util.num_errors > 0 then
return 1
end
return 0
end
return cli
|