summaryrefslogtreecommitdiff
path: root/biblio/citation-style-language/citeproc-engine.lua
diff options
context:
space:
mode:
Diffstat (limited to 'biblio/citation-style-language/citeproc-engine.lua')
-rw-r--r--biblio/citation-style-language/citeproc-engine.lua165
1 files changed, 152 insertions, 13 deletions
diff --git a/biblio/citation-style-language/citeproc-engine.lua b/biblio/citation-style-language/citeproc-engine.lua
index e8a77450eb..83cc2654ee 100644
--- a/biblio/citation-style-language/citeproc-engine.lua
+++ b/biblio/citation-style-language/citeproc-engine.lua
@@ -1,5 +1,5 @@
--
--- Copyright (c) 2021-2022 Zeping Lee
+-- Copyright (c) 2021-2023 Zeping Lee
-- Released under the MIT license.
-- Repository: https://github.com/zepinglee/citeproc-lua
--
@@ -22,8 +22,17 @@ local SortStringFormat = require("citeproc-output").SortStringFormat
local util = require("citeproc-util")
+---@class CiteProc
+---@field style any
+---@field lang string
local CiteProc = {}
+---comment
+---@param sys table
+---@param style string
+---@param lang string?
+---@param force_lang boolean?
+---@return CiteProc
function CiteProc.new(sys, style, lang, force_lang)
if not sys then
error("\"citeprocSys\" required")
@@ -52,6 +61,7 @@ function CiteProc.new(sys, style, lang, force_lang)
o.opt = {
-- Similar to citeproc-js's development_extensions.wrap_url_and_doi
wrap_url_and_doi = false,
+ citation_link = false,
title_link = false,
}
@@ -121,6 +131,11 @@ function CiteProc:updateItems(ids)
self.cite_first_note_numbers = {}
self.cite_last_note_numbers = {}
self.note_citations_map = {}
+
+ for _, item in ipairs(self.registry.registry) do
+ item.year_suffix_number = nil
+ item["year-suffix"] = nil
+ end
end
function CiteProc:updateUncitedItems(uncited_ids)
@@ -169,7 +184,7 @@ end
function CiteProc:processCitationCluster(citation, citationsPre, citationsPost)
- -- util.debug(citation)
+ -- util.debug(citation.citationID)
citation = self:normalize_citation_input(citation)
-- Registor citation
@@ -578,7 +593,9 @@ function CiteProc:makeCitationCluster(citation_items)
return res
end
-function CiteProc:makeBibliography()
+function CiteProc:makeBibliography(bibsection)
+ -- The bibsection works as a filter described in
+ -- <https://citeproc-js.readthedocs.io/en/latest/running.html#selective-output-with-makebibliography>.
if not self.style.bibliography then
return {{}, {}}
end
@@ -588,7 +605,11 @@ function CiteProc:makeBibliography()
self.registry.longest_label = ""
self.registry.maxoffset = 0
- for _, id in ipairs(self:get_sorted_refs()) do
+ local ids = self:get_sorted_refs()
+ if bibsection then
+ ids = self:filter_with_bibsection(ids, bibsection)
+ end
+ for _, id in ipairs(ids) do
local str = self.style.bibliography:build_bibliography_str(id, self)
table.insert(res, str)
end
@@ -623,6 +644,128 @@ function CiteProc:get_sorted_refs()
return self.registry.reflist
end
+function CiteProc:filter_with_bibsection(ids, bibsection)
+ if bibsection.quash then
+ return self:filter_quash(ids, bibsection)
+ elseif bibsection.select then
+ return self:filter_select(ids, bibsection)
+ elseif bibsection.include then
+ return self:filter_include(ids, bibsection)
+ elseif bibsection.exclude then
+ return self:filter_exclude(ids, bibsection)
+ else
+ return ids
+ end
+end
+
+function CiteProc:match_bibsection_object(item, bibsection_object)
+ local field = bibsection_object.field
+ local value = bibsection_object.value
+ -- util.debug(item.id)
+ -- util.debug(field)
+ -- util.debug(value)
+ -- util.debug(item[field])
+ local match = false
+ if value == "" then
+ if not item[field] or item[field] == "" then
+ match = true
+ end
+ else
+ if type(item[field]) == "table" then
+ if util.in_list(value, item[field]) then
+ match = true
+ end
+ elseif field == "keyword" then
+ if item.keyword and util.in_list(value, util.split(item.keyword, "%s*[;,]%s*")) then
+ match = true
+ end
+ elseif item[field] == value then
+ match = true
+ end
+ end
+ if bibsection_object.negative then
+ match = not match
+ end
+ -- util.debug(match)
+ return match
+end
+
+function CiteProc:filter_select(ids, bibsection)
+ -- Include the item if, and only if, all of the objects match.
+ local res = {}
+ for _, id in ipairs(ids) do
+ local item = self.registry.registry[id]
+ local match = true
+ for _, bibsection_object in ipairs(bibsection.select) do
+ if not self:match_bibsection_object(item, bibsection_object) then
+ match = false
+ break
+ end
+ end
+ if match then
+ table.insert(res, id)
+ end
+ end
+ return res
+end
+
+function CiteProc:filter_include(ids, bibsection)
+ -- Include the item if any of the objects match.
+ local res = {}
+ for _, id in ipairs(ids) do
+ local item = self.registry.registry[id]
+ local match = false
+ for _, bibsection_object in ipairs(bibsection.include) do
+ if self:match_bibsection_object(item, bibsection_object) then
+ match = true
+ break
+ end
+ end
+ if match then
+ table.insert(res, id)
+ end
+ end
+ return res
+end
+
+function CiteProc:filter_exclude(ids, bibsection)
+ -- Include the item if none of the objects match.
+ local res = {}
+ for _, id in ipairs(ids) do
+ local item = self.registry.registry[id]
+ local match = false
+ for _, bibsection_object in ipairs(bibsection.exclude) do
+ if self:match_bibsection_object(item, bibsection_object) then
+ match = true
+ break
+ end
+ end
+ if not match then
+ table.insert(res, id)
+ end
+ end
+ return res
+end
+
+function CiteProc:filter_quash(ids, bibsection)
+ -- Skip the item if all of the objects match.
+ local res = {}
+ for _, id in ipairs(ids) do
+ local item = self.registry.registry[id]
+ local match = true
+ for _, bibsection_object in ipairs(bibsection.quash) do
+ if not self:match_bibsection_object(item, bibsection_object) then
+ match = false
+ break
+ end
+ end
+ if not match then
+ table.insert(res, id)
+ end
+ end
+ return res
+end
+
function CiteProc:set_output_format(format)
if format == "latex" then
self.output_format = LatexWriter:new()
@@ -633,10 +776,12 @@ end
function CiteProc:enable_linking()
self.opt.wrap_url_and_doi = true
+ self.opt.citation_link = true
end
function CiteProc:disable_linking()
self.opt.wrap_url_and_doi = false
+ self.opt.citation_link = false
end
function CiteProc.create_element_tree(node)
@@ -784,15 +929,9 @@ function CiteProc:sort_bibliography()
end
function CiteProc:get_locale(lang)
- if string.len(lang) == 2 then
- lang = util.primary_dialects[lang] or lang
- end
- local locale = self.locales[lang]
- if locale then
- return locale
- else
- return self:get_merged_locales(lang)
- end
+ lang = util.primary_dialects[lang] or lang
+ local locale = self.locales[lang] or self:get_merged_locales(lang)
+ return locale
end
function CiteProc:get_merged_locales(lang)