diff options
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.lua | 134 |
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 |