Module:Authors Q

From Wikiversity
Jump to navigation Jump to search

Documentation for this module may be created at Module:Authors Q/doc

--[[
Fetch authors from Wikidata
--]]

p = {}

function p.getAuthors(frame)
	local args= frame.args
	if not args.qid and not args[1] then
		args = frame:getParent().args
	end

	local qid = mw.text.trim(args[1] or args.qid or "")
	if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end
	if not qid then return end

	-- construct a table of tables:
	-- key = series ordinal;
	-- value = {name=author's name, orcid=author's orcid id, emp=author's employer}
	local auths = {}
	-- series ordinal = true when used
	local ords = {}
	-- list of employers
	local emps = {}
	-- keep track of values without series ordinals and max ordinal
	local noord = 0
	local maxord = 0
	-- get authors that have entries
	local prop50 = mw.wikibase.getBestStatements(qid, "P50")
	for i, v in ipairs(prop50) do
		if v.mainsnak.snaktype == "value" then
			-- get author's qid
			local nameid = v.mainsnak.datavalue.value.id
			-- get author's name
			local name = mw.wikibase.getLabel(nameid) or "No label"
			-- get author's orcid id
			local orcid
			local orcidtbl = mw.wikibase.getBestStatements(nameid, "P496")[1]
			if orcidtbl and orcidtbl.mainsnak.snaktype == "value" then
				orcid = orcidtbl.mainsnak.datavalue.value
			end
			-- get author's employer
			local emp
			local emptbl = mw.wikibase.getBestStatements(nameid, "P108")[1]
			if emptbl and emptbl.mainsnak.snaktype == "value" then
				emp = mw.wikibase.getLabel(emptbl.mainsnak.datavalue.value.id)
			end
			if emp then emps[emp] = true end
			-- get ordinal
			local ordinal = noord
			if v.qualifiers then
				qualP1545 = v.qualifiers["P1545"] and v.qualifiers["P1545"][1]
				if qualP1545 then
					ordinal = tonumber(qualP1545.datavalue.value) or noord
				end
			end
			if ordinal == noord then noord = noord -1 end
			-- check for a duplicate ordinal
			if ords[ordinal] then
				repeat ordinal = ordinal + 1 until not ords[ordinal]
			end
			auths[ordinal] = {name = name, orcid = orcid, emp = emp}
			ords[ordinal] = true
			if ordinal > maxord then maxord = ordinal end
		end
	end

	-- add author's name strings to the author's table
	local propP2093 = mw.wikibase.getBestStatements(qid, "P2093")
	for i, v in ipairs(propP2093) do
		if v.mainsnak.snaktype == "value" then
			local name = v.mainsnak.datavalue.value
			local ordinal = noord
			if v.qualifiers then
				qualP1545 = v.qualifiers["P1545"] and v.qualifiers["P1545"][1]
				if qualP1545 then
					ordinal = tonumber(qualP1545.datavalue.value) or noord
				end
			end
			if ordinal == noord then noord = noord -1 end
			-- check for a duplicate ordinal
			if ords[ordinal] then
				repeat ordinal = ordinal + 1 until not ords[ordinal]
			end
			auths[ordinal] = {name = name}
			ords[ordinal] = true
			if ordinal > maxord then maxord = ordinal end
		end
	end

	-- compact the auths table into a sequence
	local authors = {}
	for idx = 1, maxord do
		if auths[idx] then table.insert(authors, auths[idx]) end
	end
	for idx = 0, noord, -1 do
		if auths[idx] then table.insert(authors, auths[idx]) end
	end

	-- create a sequence of employers
	local employers = {}
	for k, v in pairs(emps) do
		table.insert(employers, k)
	end

	-- construct some output
	out = {}
	for i, v in ipairs(authors) do
		out[i] = v.name
		if v.orcid then
			out[i] = out[i] .. " [[file:ORCID_iD.svg|frameless|16px|link=https://orcid.org/" .. v.orcid .. " ]]"
		end
		if v.emp then
			out[i] = out[i] .. frame:expandTemplate{title = 'efn', args =  {name=v.emp , v.emp} }
		end
	end
	-- glue the list of authors together as a comma separated list
	local returntxt = "<p>" .. table.concat(out, ", ") .. "</p>"
	return returntxt
end

return p