diff options
author | Norbert Preining <norbert@preining.info> | 2022-01-22 03:01:16 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-01-22 03:01:16 +0000 |
commit | 26bfc07f2b7829213356de43cf5b81c3ba99e338 (patch) | |
tree | efb3037df2c42c45c904ad131334e8fc626cea19 /biblio/citation-style-language/citeproc | |
parent | 5d5f239204f5c0d1f7573c9ebc64b5ad1ae75b49 (diff) |
CTAN sync 202201220301
Diffstat (limited to 'biblio/citation-style-language/citeproc')
-rwxr-xr-x | biblio/citation-style-language/citeproc | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/biblio/citation-style-language/citeproc b/biblio/citation-style-language/citeproc new file mode 100755 index 0000000000..3a72892ec7 --- /dev/null +++ b/biblio/citation-style-language/citeproc @@ -0,0 +1,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() |