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.lua80
1 files changed, 63 insertions, 17 deletions
diff --git a/biblio/citation-style-language/citeproc-engine.lua b/biblio/citation-style-language/citeproc-engine.lua
index ac50da02d8..a9feeb6f6f 100644
--- a/biblio/citation-style-language/citeproc-engine.lua
+++ b/biblio/citation-style-language/citeproc-engine.lua
@@ -47,9 +47,37 @@ local HtmlWriter = output.HtmlWriter
local SortStringFormat = output.SortStringFormat
+---@alias ItemId string
+---@alias NoteIndex integer
+---@alias CitationId string
+---@alias CitationData {citationID: CitationId, citationItems: table[], properties: table}
+---@alias ItemData {id: ItemId, type: string, [string]: any}
+
+
+---@class Registry
+---@field citations_by_id table<ItemId, CitationData>
+---@field citation_list CitationData[]
+---@field citations_by_item_id table<ItemId, CitationData[]>
+---@field registry table<ItemId, ItemData>
+---@field reflist ItemId[]
+---@field uncited_list ItemId[]
+---@field previous_citation CitationData?
+---@field requires_sorting boolean
+---@field widest_label string
+---@field maxoffset integer
+local Registry = {}
+
+
---@class CiteProc
---@field style any
+---@field sys any
+---@field lcoales any
+---@field system_locales any
---@field lang string
+---@field output_format any
+---@field opt table
+---@field registry Registry
+---@field cite_first_note_numbers table<ItemId, NoteIndex>
local CiteProc = {}
---comment
@@ -244,7 +272,7 @@ function CiteProc:processCitationCluster(citation, citationsPre, citationsPost)
self.registry.citations_by_item_id[cite_item.id] = {}
table.insert(item_ids, cite_item.id)
end
- self.registry.citations_by_item_id[cite_item.id][citation_.citationID] = true
+ table.insert(self.registry.citations_by_item_id[cite_item.id], citation_)
end
end
self:updateItems(item_ids)
@@ -255,8 +283,19 @@ function CiteProc:processCitationCluster(citation, citationsPre, citationsPost)
}
local output = {}
- local tainted_citation_ids = self:get_tainted_citaion_ids(citation_note_pairs)
+ local tainted_citation_ids = self:get_tainted_citation_ids(citation_note_pairs)
tainted_citation_ids[citation.citationID] = true
+
+ -- Citeproc-js marks all related citations as tainted but I don't think it's
+ -- necessary.
+ if self.style.class == "note" and self.style.has_disambiguate then
+ for _, cite_item in ipairs(citation.citationItems) do
+ for _, citation_ in ipairs(self.registry.citations_by_item_id[cite_item.id]) do
+ tainted_citation_ids[citation_.citationID] = true
+ end
+ end
+ end
+
-- util.debug(tainted_citation_ids)
-- params.bibchange = #tainted_citation_ids > 0
@@ -322,14 +361,14 @@ function CiteProc:normalize_cite_item(cite_item)
if cite_item.prefix == "" then
cite_item.prefix = nil
else
- cite_item.prefix = InlineElement:parse(cite_item.prefix)
+ cite_item.prefix = InlineElement:parse(cite_item.prefix, nil, true)
end
end
if cite_item.suffix then
if cite_item.suffix == "" then
cite_item.suffix = nil
else
- cite_item.suffix = InlineElement:parse(cite_item.suffix)
+ cite_item.suffix = InlineElement:parse(cite_item.suffix, nil, true)
end
end
@@ -360,7 +399,7 @@ function CiteProc:process_citation(citation)
if not self.registry.citations_by_item_id[cite_item.id] then
self.registry.citations_by_item_id[cite_item.id] = {}
end
- self.registry.citations_by_item_id[cite_item.id][citation.citationID] = true
+ table.insert(self.registry.citations_by_item_id[cite_item.id], citation)
end
-- self:updateItems(item_ids)
@@ -368,7 +407,7 @@ function CiteProc:process_citation(citation)
self:get_item(cite_item.id)
end
- local tainted_citation_ids = self:get_tainted_citaion_ids(citation_note_pairs)
+ local tainted_citation_ids = self:get_tainted_citation_ids(citation_note_pairs)
local mode = citation.properties.mode
if mode == "suppress-author" and self.style.class == "note" then
@@ -385,7 +424,7 @@ function CiteProc:process_citation(citation)
end
-function CiteProc:get_tainted_citaion_ids(citation_note_pairs)
+function CiteProc:get_tainted_citation_ids(citation_note_pairs)
local tainted_citation_ids = {}
self.cite_first_note_numbers = {}
@@ -435,8 +474,8 @@ function CiteProc:get_tainted_citaion_ids(citation_note_pairs)
-- The self.tainted_item_ids were added in the sort_bibliography() procedure.
for item_id, _ in pairs(self.tainted_item_ids) do
if self.registry.citations_by_item_id[item_id] then
- for citation_id, _ in pairs(self.registry.citations_by_item_id[item_id]) do
- tainted_citation_ids[citation_id] = true
+ for _, citation in ipairs(self.registry.citations_by_item_id[item_id]) do
+ tainted_citation_ids[citation.citationID] = true
end
end
end
@@ -555,7 +594,7 @@ function CiteProc:makeCitationCluster(citation_items)
-- Create a wrapper of the orignal item from registry so that
-- it may hold different `locator` or `position` values for cites.
- local item = setmetatable(cite_item, {__index = item_data})
+ local cite_item = setmetatable(cite_item, {__index = item_data})
if not special_form then
for _, form in ipairs({"author-only", "suppress-author", "coposite"}) do
@@ -565,9 +604,16 @@ function CiteProc:makeCitationCluster(citation_items)
end
end
- item.position_level = util.position_map["first"]
+ -- Set "first-reference-note-number" variable when called from
+ -- processCitationCluster() > updateItems()
+ local citations = self.registry.citations_by_item_id[cite_item.id]
+ if citations and #citations > 0 then
+ item_data["first-reference-note-number"] = citations[1].properties.noteIndex
+ end
+
+ cite_item.position_level = util.position_map["first"]
if self.cite_first_note_numbers[cite_item.id] then
- item.position_level = util.position_map["subsequent"]
+ cite_item.position_level = util.position_map["subsequent"]
else
self.cite_first_note_numbers[cite_item.id] = 0
end
@@ -576,19 +622,19 @@ function CiteProc:makeCitationCluster(citation_items)
if i == 1 then
local previous_citation = self.registry.previous_citation
if previous_citation then
- if #previous_citation.citationItems == 1 and previous_citation.citationItems[1].id == item.id then
+ if #previous_citation.citationItems == 1 and previous_citation.citationItems[1].id == cite_item.id then
preceding_cite = previous_citation.citationItems[1]
end
end
- elseif citation_items[i - 1].id == item.id then
+ elseif citation_items[i - 1].id == cite_item.id then
preceding_cite = citation_items[i - 1]
end
if preceding_cite then
- item.position_level = self:_get_cite_position(item, preceding_cite)
+ cite_item.position_level = self:_get_cite_position(cite_item, preceding_cite)
end
- table.insert(items, item)
+ table.insert(items, cite_item)
end
if self.registry.requires_sorting then
@@ -857,7 +903,7 @@ function CiteProc:_retrieve_item(id)
local res = {}
local item = self.sys.retrieveItem(id)
if not item then
- util.warning(string.format('Database entry "%s" not found', id))
+ util.warning(string.format("Didn't find a database entry for '%s'", id))
return nil
end