fix(code): Fix live zotero gen with quarto 1.4

Quarto 1.4 does not like a bare 'zotero' metadata frontmatter key with
sub keys for the filter options. This commit updates the zotero-live
citations filter plugin by retorque and changes its configuration so
it takes settings either through the 'zotero' key or, if that one is
not found, through the 'zoterolive' key. Same options.
This commit is contained in:
Marty Oehme 2024-02-14 17:29:27 +01:00
parent 1804b08c3f
commit 41b2d651a6
Signed by: Marty
GPG key ID: EDBF2ED917B2EF6A
3 changed files with 84 additions and 72 deletions

View file

@ -8,7 +8,7 @@ project:
- scoping_review.qmd - scoping_review.qmd
toc: true toc: true
format: format:
html: html:
code-fold: true code-fold: true
code-tools: true code-tools: true
@ -26,3 +26,10 @@ format:
echo: false echo: false
number-sections: true number-sections: true
pdf-engine: tectonic pdf-engine: tectonic
bibliography: 02-data/intermediate/zotero-library.bib
csl: /home/marty/documents/library/utilities/styles/APA-7.csl
zoterolive:
library: wow-inequalities
client: zotero
csl-style: apa

View file

@ -1,6 +1,4 @@
--- ---
bibliography: 02-data/intermediate/zotero-library.bib
csl: /home/marty/documents/library/utilities/styles/APA-7.csl
papersize: A4 papersize: A4
linestretch: 1.5 linestretch: 1.5
fontfamily: lmodern fontfamily: lmodern
@ -14,11 +12,7 @@ lang: en
title: Addressing Inequalities in the World of Work title: Addressing Inequalities in the World of Work
subtitle: Scoping Review on 'What Works' subtitle: Scoping Review on 'What Works'
filters: filters:
- src/pandoc-to-zotero-live.lua - src/pandoc-to-zotero-live.lua
zotero:
library: wow-inequalities
client: zotero
csl-style: apa
--- ---
```{python} ```{python}

View file

@ -1,8 +1,8 @@
local pandoc = require("pandoc") local pandoc = require("pandoc")
print("zotero-live-citations caf41cc") print("zotero-live-citations cd1ef3f")
local mt, latest = pandoc.mediabag.fetch("https://retorque.re/zotero-better-bibtex/exporting/zotero.lua.revision") local mt, latest = pandoc.mediabag.fetch("https://retorque.re/zotero-better-bibtex/exporting/zotero.lua.revision")
latest = string.sub(latest, 1, 10) latest = string.sub(latest, 1, 10)
if "caf41cc" ~= latest then if "cd1ef3f" ~= latest then
print('new version "' .. latest .. '" available at https://retorque.re/zotero-better-bibtex/exporting') print('new version "' .. latest .. '" available at https://retorque.re/zotero-better-bibtex/exporting')
end end
@ -1946,6 +1946,21 @@ do
return copy return copy
end end
function module.dump(o)
if type(o) == "table" then
local s = "{ "
for k, v in pairs(o) do
if type(k) ~= "number" then
k = '"' .. k .. '"'
end
s = s .. "[" .. k .. "] = " .. module.dump(v) .. ","
end
return s .. "} "
else
return tostring(o)
end
end
function module.trim(s) function module.trim(s)
if s == nil then if s == nil then
return s return s
@ -1973,42 +1988,6 @@ do
module.citekeys = {} module.citekeys = {}
function module.authors(csl_or_item)
local authors = {}
local author
if csl_or_item.author ~= nil then
for _, author in ipairs(csl_or_item.author) do
if author.literal ~= nil then
table.insert(authors, author.literal)
elseif author.family ~= nil then
table.insert(authors, author.family)
end
end
elseif csl_or_item.creators ~= nil then
for _, author in ipairs(csl_or_item.creators) do
if author.name ~= nil then
table.insert(authors, author.name)
elseif author.lastName ~= nil then
table.insert(authors, author.lastName)
end
end
elseif csl_or_item.reporter ~= nil then
table.insert(authors, csl_or_item.reporter)
end
if utils.tablelength(authors) == 0 then
return nil
end
local last = table.remove(authors)
if utils.tablelength(authors) == 0 then
return last
end
authors = table.concat(authors, ", ")
return table.concat({ authors, last }, " and ")
end
local function load_items() local function load_items()
if state.fetched ~= nil then if state.fetched ~= nil then
return return
@ -2028,15 +2007,19 @@ do
return return
end end
citekeys = table.concat(citekeys, ",") module.request.params.citekeys = citekeys
local url = module.url .. utils.urlencode(citekeys) local url = module.url .. utils.urlencode(json.encode(module.request))
local mt, contents = pandoc.mediabag.fetch(url, ".") local mt, body = pandoc.mediabag.fetch(url, ".")
local ok, fetched = pcall(json.decode, contents) local ok, response = pcall(json.decode, body)
if not ok then if not ok then
print("could not fetch Zotero items: " .. contents) print("could not fetch Zotero items: " .. response .. "(" .. body .. ")")
return return
end end
state.fetched = fetched if response.error ~= nil then
print("could not fetch Zotero items: " .. response.error.message)
return
end
state.fetched = response.result
end end
function module.get(citekey) function module.get(citekey)
@ -2048,7 +2031,11 @@ do
if state.fetched.errors[citekey] ~= nil then if state.fetched.errors[citekey] ~= nil then
state.reported[citekey] = true state.reported[citekey] = true
print("@" .. citekey .. ": " .. state.fetched.errors[citekey]) if state.fetched.errors[citekey] == 0 then
print("@" .. citekey .. ": not found")
else
print("@" .. citekey .. ": duplicates found")
end
return nil return nil
end end
@ -2058,7 +2045,7 @@ do
return nil return nil
end end
return state.fetched.items[citekey], state.fetched.zotero[citekey] return state.fetched.items[citekey]
end end
return module return module
@ -2103,12 +2090,13 @@ local zotero = require("zotero")
local config = { local config = {
client = "zotero", client = "zotero",
scannable_cite = false, scannable_cite = false,
csl_style = "apa7", csl_style = "apa",
format = nil, -- more to document than anything else -- Lua does not store nils in tables format = nil, -- more to document than anything else -- Lua does not store nils in tables
transferable = false, transferable = false,
sorted = true,
} }
-- -- -- bibliography marker generator -- -- -- -- -- bibliography marker generator -- --
function zotero_docpreferences_odt(csl_style) function zotero_docpreferences_odt(csl_style)
return string.format( return string.format(
'<data data-version="3" zotero-version="5.0.89">' '<data data-version="3" zotero-version="5.0.89">'
@ -2180,12 +2168,23 @@ local function zotero_bibl_odt()
) )
end end
-- -- -- citation market generators -- -- -- -- -- -- citation marker generators -- -- --
function clean_csl(item)
local cleaned = {}
for k, v in pairs(item) do
cleaned[k] = v
end
cleaned.custom = nil
return setmetatable(cleaned, getmetatable(item))
end
local function zotero_ref(cite) local function zotero_ref(cite)
local content = pandoc.utils.stringify(cite.content) local content = pandoc.utils.stringify(cite.content)
local csl = { local csl = {
citationID = utils.next_id(8), citationID = utils.next_id(8),
properties = { properties = {
unsorted = not config.sorted,
formattedCitation = content, formattedCitation = content,
plainCitation = nil, -- otherwise we get a barrage of "you have edited this citation" popups plainCitation = nil, -- otherwise we get a barrage of "you have edited this citation" popups
-- dontUpdate = false, -- dontUpdate = false,
@ -2198,24 +2197,27 @@ local function zotero_ref(cite)
notfound = false notfound = false
for k, item in pairs(cite.citations) do for k, item in pairs(cite.citations) do
local itemData, zoteroData = zotero.get(item.id) local itemData = zotero.get(item.id)
if itemData == nil then if itemData == nil then
notfound = true notfound = true
else else
local citation = { local citation = {
id = zoteroData.itemID, id = itemData.custom.itemID,
uris = { zoteroData.uri }, uris = { itemData.custom.uri },
-- uri = { zoteroData.uri }, -- uri = { zoteroData.uri },
itemData = itemData, itemData = clean_csl(itemData),
} }
if item.mode == "AuthorInText" then -- not formally supported in Zotero if item.mode == "AuthorInText" then -- not formally supported in Zotero
if config.author_in_text then if config.author_in_text then
local authors = zotero.authors(itemData) local authors = itemData.custom.author
if authors == nil then if authors == nil or authors == "" then
return cite return cite
else else
author_in_text = pandoc.utils.stringify(pandoc.Str(authors)) .. " " author_in_text = pandoc.utils.stringify(pandoc.Str(authors)) .. " "
author_in_text = '<w:r><w:t xml:space="preserve">'
.. utils.xmlescape(author_in_text)
.. "</w:t></w:r>"
citation["suppress-author"] = true citation["suppress-author"] = true
end end
else else
@ -2258,7 +2260,7 @@ local function zotero_ref(cite)
field = field .. '</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r>' field = field .. '</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r>'
return pandoc.RawInline("openxml", field) return pandoc.RawInline("openxml", field)
elseif config.format == "odt" then else
if config.transferable then if config.transferable then
local field = author_in_text local field = author_in_text
.. '<text:a xlink:type="simple" xlink:href="https://www.zotero.org/" text:style-name="Internet_20_link">' .. '<text:a xlink:type="simple" xlink:href="https://www.zotero.org/" text:style-name="Internet_20_link">'
@ -2380,7 +2382,8 @@ end
function Meta(meta) function Meta(meta)
-- create meta.zotero if it does not exist -- create meta.zotero if it does not exist
if not meta.zotero then if not meta.zotero then
meta.zotero = {} -- ADDED FOR QUARTO 1.4 COMPATIBILITY
meta.zotero = meta.zoterolive or {}
end end
-- copy meta.zotero_<key>, which are likely command line params and take precedence, over to meta.zotero -- copy meta.zotero_<key>, which are likely command line params and take precedence, over to meta.zotero
@ -2401,6 +2404,9 @@ function Meta(meta)
if meta.zotero["csl-style"] ~= nil then if meta.zotero["csl-style"] ~= nil then
config.csl_style = pandoc.utils.stringify(meta.zotero["csl-style"]) config.csl_style = pandoc.utils.stringify(meta.zotero["csl-style"])
if config.csl_style == "apa7" then
config.csl_style = "apa"
end
end end
config.transferable = test_boolean("transferable", meta.zotero["transferable"]) config.transferable = test_boolean("transferable", meta.zotero["transferable"])
@ -2421,26 +2427,31 @@ function Meta(meta)
config.client = meta.zotero.client config.client = meta.zotero.client
if config.client == "zotero" then if config.client == "zotero" then
zotero.url = "http://127.0.0.1:23119/better-bibtex/export/item?pandocFilterData=true" zotero.url = "http://127.0.0.1:23119/better-bibtex/json-rpc?"
elseif config.client == "jurism" then elseif config.client == "jurism" then
zotero.url = "http://127.0.0.1:24119/better-bibtex/export/item?pandocFilterData=true" zotero.url = "http://127.0.0.1:24119/better-bibtex/json-rpc?"
end end
zotero.request = {
jsonrpc = "2.0",
method = "item.pandoc_filter",
params = {
style = config.csl_style or "apa",
},
}
if string.match(FORMAT, "odt") and config.scannable_cite then if string.match(FORMAT, "odt") and config.scannable_cite then
-- scannable-cite takes precedence over csl-style -- scannable-cite takes precedence over csl-style
config.format = "scannable-cite" config.format = "scannable-cite"
zotero.url = zotero.url .. "&translator=jzon" zotero.request.params.asCSL = false
elseif string.match(FORMAT, "odt") or string.match(FORMAT, "docx") then elseif string.match(FORMAT, "odt") or string.match(FORMAT, "docx") then
config.format = FORMAT config.format = FORMAT
zotero.url = zotero.url .. "&translator=json" zotero.request.params.asCSL = true
end end
if type(meta.zotero.library) ~= "nil" then if type(meta.zotero.library) ~= "nil" then
zotero.url = zotero.url .. "&library=" .. utils.urlencode(meta.zotero.library) zotero.request.params.libraryID = meta.zotero.library
end end
zotero.url = zotero.url .. "&citationKeys="
if config.format == "odt" and config.csl_style then if config.format == "odt" and config.csl_style then
-- These will be added to the document metadata by pandoc automatically -- These will be added to the document metadata by pandoc automatically
meta.ZOTERO_PREF_1 = zotero_docpreferences_odt(config.csl_style) meta.ZOTERO_PREF_1 = zotero_docpreferences_odt(config.csl_style)