summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/citation-style-language/citeproc-cli.lua
blob: a9777173369eb5c38b84a880aed4a05cea3e202f (plain)
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