From 41b2d651a631245324cdfdbc80e827dc46e88099 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Wed, 14 Feb 2024 17:29:27 +0100 Subject: [PATCH] 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. --- _quarto.yml | 9 ++- scoping_review.qmd | 8 +- src/pandoc-to-zotero-live.lua | 139 ++++++++++++++++++---------------- 3 files changed, 84 insertions(+), 72 deletions(-) diff --git a/_quarto.yml b/_quarto.yml index c48d11a..e68fb5d 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -8,7 +8,7 @@ project: - scoping_review.qmd toc: true -format: +format: html: code-fold: true code-tools: true @@ -26,3 +26,10 @@ format: echo: false number-sections: true 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 diff --git a/scoping_review.qmd b/scoping_review.qmd index 483df1b..ac08201 100644 --- a/scoping_review.qmd +++ b/scoping_review.qmd @@ -1,6 +1,4 @@ --- -bibliography: 02-data/intermediate/zotero-library.bib -csl: /home/marty/documents/library/utilities/styles/APA-7.csl papersize: A4 linestretch: 1.5 fontfamily: lmodern @@ -14,11 +12,7 @@ lang: en title: Addressing Inequalities in the World of Work subtitle: Scoping Review on 'What Works' filters: - - src/pandoc-to-zotero-live.lua -zotero: - library: wow-inequalities - client: zotero - csl-style: apa + - src/pandoc-to-zotero-live.lua --- ```{python} diff --git a/src/pandoc-to-zotero-live.lua b/src/pandoc-to-zotero-live.lua index d9ff0b9..2e57463 100644 --- a/src/pandoc-to-zotero-live.lua +++ b/src/pandoc-to-zotero-live.lua @@ -1,8 +1,8 @@ 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") 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') end @@ -1946,6 +1946,21 @@ do return copy 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) if s == nil then return s @@ -1973,42 +1988,6 @@ do 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() if state.fetched ~= nil then return @@ -2028,15 +2007,19 @@ do return end - citekeys = table.concat(citekeys, ",") - local url = module.url .. utils.urlencode(citekeys) - local mt, contents = pandoc.mediabag.fetch(url, ".") - local ok, fetched = pcall(json.decode, contents) + module.request.params.citekeys = citekeys + local url = module.url .. utils.urlencode(json.encode(module.request)) + local mt, body = pandoc.mediabag.fetch(url, ".") + local ok, response = pcall(json.decode, body) if not ok then - print("could not fetch Zotero items: " .. contents) + print("could not fetch Zotero items: " .. response .. "(" .. body .. ")") return 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 function module.get(citekey) @@ -2048,7 +2031,11 @@ do if state.fetched.errors[citekey] ~= nil then 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 end @@ -2058,7 +2045,7 @@ do return nil end - return state.fetched.items[citekey], state.fetched.zotero[citekey] + return state.fetched.items[citekey] end return module @@ -2103,12 +2090,13 @@ local zotero = require("zotero") local config = { client = "zotero", scannable_cite = false, - csl_style = "apa7", + csl_style = "apa", format = nil, -- more to document than anything else -- Lua does not store nils in tables transferable = false, + sorted = true, } --- -- -- bibliography marker generator -- -- -- +-- -- bibliography marker generator -- -- function zotero_docpreferences_odt(csl_style) return string.format( '' @@ -2180,12 +2168,23 @@ local function zotero_bibl_odt() ) 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 content = pandoc.utils.stringify(cite.content) local csl = { citationID = utils.next_id(8), properties = { + unsorted = not config.sorted, formattedCitation = content, plainCitation = nil, -- otherwise we get a barrage of "you have edited this citation" popups -- dontUpdate = false, @@ -2198,24 +2197,27 @@ local function zotero_ref(cite) notfound = false 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 notfound = true else local citation = { - id = zoteroData.itemID, - uris = { zoteroData.uri }, + id = itemData.custom.itemID, + uris = { itemData.custom.uri }, -- uri = { zoteroData.uri }, - itemData = itemData, + itemData = clean_csl(itemData), } if item.mode == "AuthorInText" then -- not formally supported in Zotero if config.author_in_text then - local authors = zotero.authors(itemData) - if authors == nil then + local authors = itemData.custom.author + if authors == nil or authors == "" then return cite else author_in_text = pandoc.utils.stringify(pandoc.Str(authors)) .. " " + author_in_text = '' + .. utils.xmlescape(author_in_text) + .. "" citation["suppress-author"] = true end else @@ -2258,7 +2260,7 @@ local function zotero_ref(cite) field = field .. '' return pandoc.RawInline("openxml", field) - elseif config.format == "odt" then + else if config.transferable then local field = author_in_text .. '' @@ -2380,7 +2382,8 @@ end function Meta(meta) -- create meta.zotero if it does not exist if not meta.zotero then - meta.zotero = {} + -- ADDED FOR QUARTO 1.4 COMPATIBILITY + meta.zotero = meta.zoterolive or {} end -- copy meta.zotero_, 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 config.csl_style = pandoc.utils.stringify(meta.zotero["csl-style"]) + if config.csl_style == "apa7" then + config.csl_style = "apa" + end end config.transferable = test_boolean("transferable", meta.zotero["transferable"]) @@ -2421,26 +2427,31 @@ function Meta(meta) config.client = meta.zotero.client 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 - 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 + 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 -- scannable-cite takes precedence over csl-style 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 config.format = FORMAT - zotero.url = zotero.url .. "&translator=json" + zotero.request.params.asCSL = true end 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 - zotero.url = zotero.url .. "&citationKeys=" - if config.format == "odt" and config.csl_style then -- These will be added to the document metadata by pandoc automatically meta.ZOTERO_PREF_1 = zotero_docpreferences_odt(config.csl_style)