Skip to content

Commit ca906f0

Browse files
Omikhleiaalerque
authored andcommitted
feat(packages): Support @xdata entry type and xdata field in bibTeX bibliography
Note that we do not support here expanding "xdata=" contructs inside other fields i.e. the "granular" per-field inheritance supported by BibLaTeX and originally Biber, expanding xdata=key-field-index inside other field values, which requires list fields (e.g. author) to already have been split and parsed...
1 parent c4ae919 commit ca906f0

File tree

1 file changed

+43
-14
lines changed

1 file changed

+43
-14
lines changed

packages/bibtex/init.lua

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,30 +58,49 @@ local parseBibtex = function (fn)
5858
return entries
5959
end
6060

61-
--- Resolve the 'crossref' field on a bibliography entry.
61+
--- Resolve the 'crossref' and 'xdata' fields on a bibliography entry.
6262
-- (Supplementing the entry with the attributes of the parent entry.)
63-
-- Once resolved recursively, the crossref field is removed from the entry.
63+
-- Once resolved recursively, the crossref and xdata fields are removed
64+
-- from the entry.
6465
-- So this is intended to be called at first use of the entry, and have no
65-
-- effect on subsequent uses: BibTeX does seem to mandate crossref to be
66-
-- defined before the entry that uses it, or even in the same bibliography
66+
-- effect on subsequent uses: BibTeX does seem to mandate cross refererences
67+
-- to be defined before the entry that uses it, or even in the same bibliography
6768
-- file.
69+
-- Implementation note:
70+
-- We are not here to check the consistency of the BibTeX file, so there is
71+
-- no check that xdata refers only to @xdata entries
72+
-- Removing the crossref field implies we won't track its use and implicitely
73+
-- cite referenced entries in the bibliography over a certain threshold.
6874
-- @tparam table bib Bibliography
69-
-- @tparam string key Valid entry key
70-
local function crossrefResolve (bib, key)
71-
local entry = bib[key]
75+
-- @tparam table entry Bibliography entry
76+
local function crossrefAndXDataResolve (bib, entry)
77+
local refs
78+
local xdata = entry.attributes.xdata
79+
if xdata then
80+
refs = xdata and pl.stringx.split(xdata, ",")
81+
entry.attributes.xdata = nil
82+
end
7283
local crossref = entry.attributes.crossref
7384
if crossref then
74-
local parent = bib[crossref]
85+
refs = refs or {}
86+
table.insert(refs, crossref)
7587
entry.attributes.crossref = nil
88+
end
89+
90+
if not refs then
91+
return
92+
end
93+
for _, ref in ipairs(refs) do
94+
local parent = bib[ref]
7695
if parent then
77-
crossrefResolve(bib, crossref)
96+
crossrefAndXDataResolve(bib, parent)
7897
for k, v in pairs(parent.attributes) do
7998
if not entry.attributes[k] then
8099
entry.attributes[k] = v
81100
end
82101
end
83102
else
84-
SU.warn("Unknown crossref " .. crossref .. " in bibliography entry " .. key)
103+
SU.warn("Unknown crossref " .. ref .. " in bibliography entry " .. entry.label)
85104
end
86105
end
87106
end
@@ -115,11 +134,16 @@ function package:registerCommands ()
115134
if not options.key then
116135
options.key = SU.ast.contentToString(content)
117136
end
118-
if not SILE.scratch.bibtex.bib[options.key] then
137+
local entry = SILE.scratch.bibtex.bib[options.key]
138+
if not entry then
119139
SU.warn("Unknown reference in citation " .. options.key)
120140
return
121141
end
122-
crossrefResolve(SILE.scratch.bibtex.bib, options.key)
142+
if entry.type == "xdata" then
143+
SU.warn("Skipped citation of @xdata entry " .. options.key)
144+
return
145+
end
146+
crossrefAndXDataResolve(SILE.scratch.bibtex.bib, entry)
123147
local style = SILE.settings:get("bibtex.style")
124148
local bibstyle = require("packages.bibtex.styles." .. style)
125149
local cite = Bibliography.produceCitation(options, SILE.scratch.bibtex.bib, bibstyle)
@@ -130,11 +154,16 @@ function package:registerCommands ()
130154
if not options.key then
131155
options.key = SU.ast.contentToString(content)
132156
end
133-
if not SILE.scratch.bibtex.bib[options.key] then
157+
local entry = SILE.scratch.bibtex.bib[options.key]
158+
if not entry then
134159
SU.warn("Unknown reference in citation " .. options.key)
135160
return
136161
end
137-
crossrefResolve(SILE.scratch.bibtex.bib, options.key)
162+
if entry.type == "xdata" then
163+
SU.warn("Skipped citation of @xdata entry " .. options.key)
164+
return
165+
end
166+
crossrefAndXDataResolve(SILE.scratch.bibtex.bib, entry)
138167
local style = SILE.settings:get("bibtex.style")
139168
local bibstyle = require("packages.bibtex.styles." .. style)
140169
local cite, err = Bibliography.produceReference(options, SILE.scratch.bibtex.bib, bibstyle)

0 commit comments

Comments
 (0)