summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua')
-rw-r--r--Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua134
1 files changed, 102 insertions, 32 deletions
diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua
index 1602511d8ee..92fc1d49d72 100644
--- a/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua
+++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua
@@ -1,16 +1,17 @@
--
--- Copyright (c) 2021-2022 Zeping Lee
+-- Copyright (c) 2021-2023 Zeping Lee
-- Released under the MIT license.
-- Repository: https://github.com/zepinglee/citeproc-lua
--
+local util = {}
+
-- load `slnunicode` from LuaTeX
local unicode = require("unicode")
local inspect -- only load it when debugging
+local journal_data = nil -- load as needed
-local util = {}
-
-- Deep copy
function util.deep_copy(obj)
local res
@@ -38,7 +39,16 @@ function util.clone(obj)
end
end
+---Limitation: Hierarchical or multiple inheritance is not supported.
+---@param obj table
+---@param class table
+---@return boolean
+function util.is_instance(obj, class)
+ return (type(obj) == "table" and obj._type == class._type)
+end
+
function util.join(list, delimiter)
+ -- Why not return table.concat(list, delimiter)?
local res = {}
for i, item in ipairs(list) do
if i > 1 then
@@ -117,26 +127,32 @@ end
local remove_all_metatables = nil
function util.debug(obj)
- if not inspect then
- inspect = require("inspect")
- remove_all_metatables = function (item, path)
- if path[#path] ~= inspect.METATABLE then
- return item
+ local text
+ if type(obj) == "table" and obj._debug then
+ text = obj:_debug()
+ else
+ if not inspect then
+ inspect = require("inspect")
+ remove_all_metatables = function (item, path)
+ if path[#path] ~= inspect.METATABLE then
+ return item
+ end
end
end
+ text = inspect(obj, {process = remove_all_metatables})
end
io.stderr:write("[")
io.stderr:write(debug.getinfo(2, "S").source:sub(2))
io.stderr:write(":")
io.stderr:write(debug.getinfo(2, "l").currentline)
io.stderr:write("] ")
- io.stderr:write(inspect(obj, {process = remove_all_metatables}))
+ io.stderr:write(text)
io.stderr:write("\n")
end
-- Similar to re.split() in Python
function util.split(str, sep, maxsplit)
- if not str then
+ if type(str) ~= "string" then
util.error("Invalid string.")
end
sep = sep or "%s+"
@@ -193,28 +209,21 @@ function util.split_multiple(str, seps, include_sep)
local start, sep, stop = table.unpack(sep_tuple)
local item = string.sub(str, previous, start - 1)
if include_sep then
- item = {item, sep}
+ table.insert(res, {item, sep})
+ else
+ table.insert(res, item)
end
- table.insert(res, item)
previous = stop
end
local item = string.sub(str, previous, #str)
if include_sep then
- item = {item, ""}
+ table.insert(res, {item, ""})
+ else
+ table.insert(res, item)
end
- table.insert(res, item)
return res
end
--- TODO: [Unicode word boundaries](https://www.unicode.org/reports/tr29/#Word_Boundaries)
--- Returns: {
--- {word, boundary},
--- {word, boundary},
--- }
-function util.segment_words(str)
- return util.split_multiple(str, util.word_boundaries, true)
-end
-
function util.slice (t, start, stop)
start = start or 1
stop = stop or #t
@@ -296,16 +305,16 @@ function util.strip (str)
end
function util.startswith(str, prefix)
- if not str or type(str) ~= "string" then
- print(debug.traceback())
+ if type(str) ~= "string" then
+ util.error(string.format('\n%s\n"%s" is not a string.', debug.traceback(), str))
end
return string.sub(str, 1, #prefix) == prefix
end
function util.endswith(str, suffix)
- if not str or type(str) ~= "string" then
- print(debug.traceback())
- end
+ -- if not str or type(str) ~= "string" then
+ -- print(debug.traceback())
+ -- end
return string.sub(str, -#suffix) == suffix
end
@@ -544,12 +553,23 @@ util.word_boundaries = {
-- Text-case
-function util.is_lower (str)
- return unicode.utf8.lower(str) == str
+--- Return True if all cased characters in the string are lowercase and there
+--- is at least one cased character, False otherwise.
+---@param str string
+---@return boolean
+function util.is_lower(str)
+ if not str then
+ print(debug.traceback())
+ end
+ return unicode.utf8.lower(str) == str and unicode.utf8.upper(str) ~= str
end
-function util.is_upper (str)
- return unicode.utf8.upper(str) == str
+--- Return True if all cased characters in the string are uppercase and there
+--- is at least one cased character, False otherwise.
+---@param str string
+---@return boolean
+function util.is_upper(str)
+ return unicode.utf8.upper(str) == str and unicode.utf8.lower(str) ~= str
end
function util.capitalize(str)
@@ -1039,4 +1059,54 @@ function util.parse_extra_name(str)
end
+function util.check_journal_abbreviations(item)
+ if item["container-title"] and not item["container-title-short"] then
+ if not journal_data then
+ journal_data = require("citeproc-journal-data")
+ end
+ local key = unicode.utf8.upper(string.gsub(item["container-title"], "%.", ""))
+ local full = journal_data.unabbrevs[key]
+ if full then
+ item["container-title-short"] = item["container-title"]
+ item["container-title"] = full
+ else
+ local abbr = journal_data.abbrevs[key]
+ if abbr then
+ item["container-title-short"] = abbr
+ end
+ end
+ end
+end
+
+
+---CSL-M: `layout` extension
+---Select the layout by
+---@param element Citation | Bibliography
+---@param engine CiteProc
+---@param item any
+---@return Layout
+---@return string
+function util.get_layout_by_language(element, engine, item)
+ if not item then
+ return element.layout, engine.lang
+ end
+
+ local entry_lang = item.language or ""
+ local language = string.sub(entry_lang, 1, 2)
+ local primary_dialect = util.primary_dialects[language] or ""
+
+ local layouts = element.layouts_by_language
+ local active_layout = layouts[entry_lang] or layouts[language] or layouts[primary_dialect]
+
+ local context_lang
+ if active_layout then
+ context_lang = entry_lang
+ else
+ context_lang = engine.lang
+ active_layout = element.layout
+ end
+ return active_layout, context_lang
+end
+
+
return util