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
|
--
-- Copyright (c) 2021-2024 Zeping Lee
-- Released under the MIT license.
-- Repository: https://github.com/zepinglee/citeproc-lua
--
local csl_yaml = {}
local yaml
local util
if kpse then
yaml = require("tinyyaml")
util = require("citeproc-util")
else
yaml = require("tinyyaml")
util = require("citeproc.util")
end
-- Convert CSL-YAML string to CSL-JSON
---@param str string
---@return CslData
function csl_yaml.parse(str)
-- lua-tinyyaml 0.4.2 doesn't support dots terminator.
-- See <https://github.com/api7/lua-tinyyaml/issues/22>.
str = string.gsub(str, "%.%.%.%s*$", "")
local status, items = pcall(yaml.parse, str)
if not status then
local err = items
util.error("Failed to parse the YAML contents:\n" .. err)
return {}
end
-- The items exported from Better BibTeX has a {references = []} structure.
if type(items) == 'table' and items.references then
items = items.references
end
for _, item in ipairs(items) do
for field, value in pairs(item) do
if util.variable_types[field] == "date" then
if type(value) == "number" then
value = tostring(value)
end
if type(value) == "string" then
-- "2005-11-22"
-- EDTF is not supported until CSL v1.1.
local date = util.parse_edtf(value)
if not date then
date = {literal = value}
end
item[field] = date
elseif type(value) == "table" and not value["date-parts"] then
local new_date = {
["date-parts"] = {}
}
if value.year then
-- Generated by lua-tinyyaml parser
new_date["date-parts"][1] = {}
for j, part_name in ipairs({"year", "month", "day"}) do
local date_part = value[part_name]
if date_part then
new_date["date-parts"][1][j] = date_part
end
end
elseif #value >= 1 then
-- Exported by Better BibTeX
for i, range_part in ipairs(value) do
new_date["date-parts"][i] = {}
for _, part_name in ipairs({"year", "month", "day"}) do
local date_part = range_part[part_name]
if date_part then
table.insert(new_date["date-parts"][i], date_part)
end
end
end
end
item[field] = new_date
end
end
end
end
return items
end
return csl_yaml
|