Module:PublicationAuthorList
From MaRDI portal
Documentation for this module may be created at Module:PublicationAuthorList/doc
-- Required module containing helper methods
local helper = require('Module:HelperMethods')
-- Required modules for SPARQL queries and HTML table generation
local sparql = require('SPARQL')
local mwHtml = require('mw.html')
-- Main table to hold all functions
local p = {}
-- Function to convert JSON results into a comma-separated string
function p.convertJsonToCommaSeparatedList(jsonResults)
local resultsString = ""
if jsonResults and jsonResults.results and jsonResults.results.bindings then
local bindings = jsonResults.results.bindings
for i = 0, #bindings do
local binding = bindings[i]
if binding.valueLabel and binding.valueLabel.value then
if resultsString ~= "" then
resultsString = resultsString .. ", "
end
local name = binding.valueLabel.value
if string.find(name, "https://") then
name = helper.titleNotAvailableStr("Author name")
end
local link = binding.value.value
if binding.isHuman and binding.isHuman.value == "Y" then
link = link:gsub("entity/Q", "wiki/Person:")
end
resultsString = resultsString .. helper.makeWikiLink(link, name)
end
end
end
return resultsString
end
function p.convertJsonToCommaSeparatedListTextOnly(jsonResults)
local resultsString = ""
if jsonResults and jsonResults.results and jsonResults.results.bindings then
local bindings = jsonResults.results.bindings
for i = 0, #bindings do
local binding = bindings[i]
if binding.value and binding.value.value then
local name = binding.value.value
if resultsString ~= "" then
resultsString = resultsString .. ", "
end
resultsString = resultsString .. name
end
end
end
return resultsString
end
-- Function to build the list
function p.buildAuthorList(frame)
-- Retrieve target1 from frame arguments or return error message if not set
local target1 = frame.args[1]
if not target1 or target1 == '' then
return "No ID given"
end
-- ── Query P16: linked author entities with ordinal ──
local sparqlQueryP16 = [[
PREFIX target1: <https://portal.mardi4nfdi.de/entity/]] .. target1 .. [[>
PREFIX wdt: <https://portal.mardi4nfdi.de/prop/direct/>
PREFIX wd: <https://portal.mardi4nfdi.de/entity/>
PREFIX p: <https://portal.mardi4nfdi.de/prop/>
PREFIX ps: <https://portal.mardi4nfdi.de/prop/statement/>
PREFIX pq: <https://portal.mardi4nfdi.de/prop/qualifier/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX bd: <http://www.bigdata.com/rdf#>
SELECT DISTINCT ?value ?valueLabel ?property ?propertyLabel ?isHuman ?seriesOrdinal
WHERE {
{
SELECT ?value ?seriesOrdinal ?isHuman WHERE {
target1: p:P16 ?authorstatement .
?authorstatement ps:P16 ?value .
BIND(IF(EXISTS { ?value wdt:P31 wd:Q57162 }, "Y", "N") AS ?isHuman)
OPTIONAL { ?authorstatement pq:P146 ?seriesOrdinal. }
}
}
BIND(wdt:P16 AS ?property)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
ORDER BY xsd:integer(?seriesOrdinal)
]]
-- ── Query P43: author name strings with ordinal ──
local sparqlQueryP43 = [[
PREFIX target1: <https://portal.mardi4nfdi.de/entity/]] .. target1 .. [[>
PREFIX wdt: <https://portal.mardi4nfdi.de/prop/direct/>
PREFIX wd: <https://portal.mardi4nfdi.de/entity/>
PREFIX p: <https://portal.mardi4nfdi.de/prop/>
PREFIX ps: <https://portal.mardi4nfdi.de/prop/statement/>
PREFIX pq: <https://portal.mardi4nfdi.de/prop/qualifier/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX bd: <http://www.bigdata.com/rdf#>
SELECT DISTINCT ?value ?seriesOrdinal
WHERE {
target1: p:P43 ?authorstatement .
?authorstatement ps:P43 ?value .
OPTIONAL { ?authorstatement pq:P146 ?seriesOrdinal. }
}
ORDER BY xsd:integer(?seriesOrdinal)
]]
local jsonP16 = sparql.runQuery(sparqlQueryP16)
local jsonP43 = sparql.runQuery(sparqlQueryP43)
local countP16 = 0
local countP43 = 0
if jsonP16 and not jsonP16.error then
countP16 = helper.countElementsInBindings(jsonP16.results.bindings)
end
if jsonP43 and not jsonP43.error then
countP43 = helper.countElementsInBindings(jsonP43.results.bindings)
end
-- ── Only P16 ──
if countP16 > 0 and countP43 == 0 then
return p.convertJsonToCommaSeparatedList(jsonP16)
end
-- ── Only P43 ──
if countP43 > 0 and countP16 == 0 then
return p.convertJsonToCommaSeparatedListTextOnly(jsonP43)
end
-- ── Both P16 and P43: merge by ordinal ──
if countP16 > 0 and countP43 > 0 then
-- Build a combined list keyed by ordinal
local authors = {} -- {ordinal, text}
local bindings16 = jsonP16.results.bindings
for i = 0, #bindings16 do
local b = bindings16[i]
if b and b.valueLabel and b.valueLabel.value then
local name = b.valueLabel.value
if string.find(name, "https://") then
name = helper.titleNotAvailableStr("Author name")
end
local link = b.value.value
if b.isHuman and b.isHuman.value == "Y" then
link = link:gsub("entity/Q", "wiki/Person:")
end
local ordinal = b.seriesOrdinal and tonumber(b.seriesOrdinal.value) or nil
table.insert(authors, {ordinal = ordinal, text = helper.makeWikiLink(link, name)})
end
end
local bindings43 = jsonP43.results.bindings
for i = 0, #bindings43 do
local b = bindings43[i]
if b and b.value and b.value.value then
local ordinal = b.seriesOrdinal and tonumber(b.seriesOrdinal.value) or nil
table.insert(authors, {ordinal = ordinal, text = b.value.value})
end
end
-- Sort by ordinal (nil ordinals go to end)
table.sort(authors, function(a, b)
if a.ordinal and b.ordinal then return a.ordinal < b.ordinal end
if a.ordinal then return true end
return false
end)
local parts = {}
for _, entry in ipairs(authors) do
table.insert(parts, entry.text)
end
return table.concat(parts, ", ")
end
-- ── Fallback: nothing found ──
return nil
end
-- Return the created html table
return p