Module:WikiJournal/sandbox

From Wikiversity
Jump to navigation Jump to search

Documentation for this module may be created at Module:WikiJournal/sandbox/doc

p = {}

-- Return the entity ID of the item linked to the current page.
function p.QID(frame)
	if not mw.wikibase then
		return "no mw.wikibase"
	end
	return mw.wikibase.getEntityIdForTitle( mw.title.getCurrentTitle().subjectPageTitle.text) or ""
end




--[[
Fetch info from Wikidata and format lists 

Author info (name, employer, orcid)
--]]

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

    -- qualID is a string list of wanted qualifiers or "ALL"
	local qualID = mw.text.trim(args.qual or ""):upper()
    local allflag = (qualID == "ALL")
    -- create table of wanted qualifiers as key
    local qwanted = {}
    -- create sequence of wanted qualifiers
    local qorder = {}
    for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate
        local qtrim = mw.text.trim(q)
        if qtrim ~= "" then
            qwanted[mw.text.trim(q)] = true
            qorder[#qorder+1] = qtrim
        end
    end

	-- construct a table of tables:
	-- key = series ordinal;
	-- value = {name=author's name, orcid=author's orcid id, emp=author's employer. quals = qualifiers}
	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 authorqid = v.mainsnak.datavalue.value.id
			-- get author's name
			local name = mw.wikibase.getLabel(authorqid) or "No label"
			-- get author's orcid id
			local orcid
			local orcidtbl = mw.wikibase.getBestStatements(authorqid, "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(authorqid, "P108")[1]
			if emptbl and emptbl.mainsnak.snaktype == "value" then
				emp = mw.wikibase.getLabel(emptbl.mainsnak.datavalue.value.id)
			end
			-- get employer's location
			local prop108 = mw.wikibase.getBestStatements(authorqid, "P108")
			for i, v in ipairs(prop108) do
				if v.mainsnak.snaktype == "value" then
					-- get employer's qid
					local employerqid = v.mainsnak.datavalue.value.id
					-- get employer's name
					local name = mw.wikibase.getLabel(employerqid) or "No label"
					-- get employer's location
					local emploc
					local emploctbl = mw.wikibase.getBestStatements(employerqid, "P131")[1]
					if emploc and emploc.mainsnak.snaktype == "value" then
						emploc = emploc.mainsnak.datavalue.value
					end
					-- get employer's country
					local empcon
					local empcontbl = mw.wikibase.getBestStatements(employerqid, "P17")[1]
					if empcon and empcontbl.mainsnak.snaktype == "value" then
						empcon = mw.wikibase.getLabel(empcontbl.mainsnak.datavalue.value.id)
					end
				end
			end	
			if emp then emps[emp] = true end
			-- get author's qualifiers if wanted
			local qtbl = {}
			local qualtxt = ""
			if v.qualifiers and (allflag or #qorder > 0) then
				for prop, val in pairs(v.qualifiers) do
					if allflag or qwanted[prop] then
						-- render the first value of each qualifier
						qtbl[#qtbl + 1] = mw.wikibase.renderSnak(val[1])
					end
				end
				qualtxt = table.concat(qtbl, ", ") -- use comma space separators
			end
			-- get ordinal
			local ordinal = noord
			if v.qualifiers then
				qualP1545 = 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, emploc = emploc, empcon = empcon, quals = qualtxt}
			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"][1]
				if qualP1545 then
					ordinal = tonumber(qualP1545.datavalue.value) or noord
				end
			end
			-- get author string's qualifiers if wanted
			local qtbl = {}
			local qualtxt = ""
			if v.qualifiers and (allflag or #qorder > 0) then
				for prop, val in pairs(v.qualifiers) do
					if allflag or qwanted[prop] then
						-- render the first value of each qualifier
						qtbl[#qtbl + 1] = mw.wikibase.renderSnak(val[1])
					end
				end
				qualtxt = table.concat(qtbl, ", ") -- use comma space separators
			end
			-- get ordinal
			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, quals = qualtxt}
			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|text-bottom|16px|link=https://orcid.org/" .. v.orcid .. " ]]"
		end
		if v.emp then
			out[i] = out[i] .. " {{efn|name= " .. v.emp .. ", " .. v.emploc .. ", " .. v.empcon .."}}"
		end
		if v.quals ~= "" then
			out[i] = out[i] .. frame:expandTemplate{title = 'efn-lr', args =  {name=v.quals , v.quals} }
		end
	end
	-- glue the list of authors together as a comma separated list
	local returntxt = table.concat(out, ", ")
	return returntxt
end


--[[
Author plain info (name only)
--]]

function p.getAuthorsPlain(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}
	local auths = {}
	-- series ordinal = true when used
	local ords = {}
	-- 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 ordinal
			local ordinal = noord
			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

	-- 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
			-- get ordinal
			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

	-- construct some output
	out = {}
	for i, v in ipairs(authors) do
		out[i] = v.name
	end
	-- glue the list of authors together as a comma separated list
	local returntxt = table.concat(out, ", ")
	return returntxt
end


--[[
Editor info (name, role)
--]]

function p.getEditors(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

    -- qualID is a string list of wanted qualifiers or "ALL"
	local qualID = mw.text.trim(args.qual or ""):upper()
    local allflag = (qualID == "ALL")
    -- create table of wanted qualifiers as key
    local qwanted = {}
    -- create sequence of wanted qualifiers
    local qorder = {}
    for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate
        local qtrim = mw.text.trim(q)
        if qtrim ~= "" then
            qwanted[mw.text.trim(q)] = true
            qorder[#qorder+1] = qtrim
        end
    end

	-- construct a table of tables:
	-- key = series ordinal;
	-- value = {name=editor's name, orcid=editor's orcid id, quals=qualtxt}
	local eds = {}
	-- series ordinal = true when used
	local ords = {}
	-- list of roles
	local roles = {}
	-- keep track of values without series ordinals and max ordinal
	local noord = 0
	local maxord = 0
	-- get editors that have entries
	local prop98 = mw.wikibase.getBestStatements(qid, "P98")
	for i, v in ipairs(prop98) do
		if v.mainsnak.snaktype == "value" then
			-- get editor's qid
			local nameid = v.mainsnak.datavalue.value.id
			-- get editor's name
			local name = mw.wikibase.getLabel(nameid) or "No label"
			-- get editor'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 editor's qualifiers if wanted
			local qtbl = {}
			local qualtxt = ""
			if v.qualifiers and (allflag or #qorder > 0) then
				for prop, val in pairs(v.qualifiers) do
					if allflag or qwanted[prop] then
						-- render the first value of each qualifier
						qtbl[#qtbl + 1] = mw.wikibase.renderSnak(val[1])
					end
				end
				qualtxt = table.concat(qtbl, ", ") -- use comma space separators
			end
			-- get ordinal
			local ordinal = noord
			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
			eds[ordinal] = {name = name, orcid = orcid, quals = qualtxt}
			ords[ordinal] = true
			if ordinal > maxord then maxord = ordinal end
		end
	end

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

	-- construct some output
	out = {}
	for i, v in ipairs(editors) do
		out[i] = v.name
		if v.orcid then
			out[i] = out[i] .. " [[file:ORCID_iD.svg|frameless|text-bottom|16px|link=https://orcid.org/" .. v.orcid .. " ]]"
		end
		if v.role then
			out[i] = out[i] .. " (" .. v.orcid .. ")"
		end
		if v.quals ~= "" then
			out[i] = out[i] .. " <small>(" .. v.quals ..")</small>"
		end
	end
	-- glue the list of editors together as a vertical list
	local returntxt = "<p>" .. table.concat(out, "<br>") .. "</p>"
	return returntxt
end


--[[
Reviewer info (name, orcid)
--]]

function p.getReviewers(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=reviewer's name, orcid=reviewer's orcid id, role=reviewer's role}
	local eds = {}
	-- series ordinal = true when used
	local ords = {}
	-- list of roles
	local roles = {}
	-- keep track of values without series ordinals and max ordinal
	local noord = 0
	local maxord = 0
	-- get reviewers that have entries
	local prop4032 = mw.wikibase.getBestStatements(qid, "P4032")
	for i, v in ipairs(prop4032) do
		if v.mainsnak.snaktype == "value" then
			-- get reviewer's qid
			local nameid = v.mainsnak.datavalue.value.id
			-- get reviewer's name
			local name = mw.wikibase.getLabel(nameid) or "No label"
			-- get reviewer'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 ordinal
			local ordinal = noord
			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
			eds[ordinal] = {name = name, orcid = orcid}
			ords[ordinal] = true
			if ordinal > maxord then maxord = ordinal end
		end
	end

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

	-- construct some output
	out = {}
	for i, v in ipairs(reviewers) do
		out[i] = v.name
		if v.orcid then
			out[i] = out[i] .. " [[file:ORCID_iD.svg|frameless|text-bottom|16px|link=https://orcid.org/" .. v.orcid .. " ]]"
		end
	end
	-- glue the list of reviewers together as a vertical list
	local returntxt = "<p>" .. table.concat(out, "<br>") .. "</p>"
	return returntxt
end

--[[
Extract fig from article (page, fig_number)
--]]

local Transcluder = require('Module:Transcluder')

-- Helper function to handle errors
function getError(message, value)
	if type(message) == 'string' then
		message = Transcluder.getError(message, value)
	end
	return message
end

function p.getFig(frame)
	local args = Transcluder.parseArgs(frame)

	-- Make sure the requested page exists
	local page = args[1]
	if not page then return getError('no-page') end
	local title = mw.title.new(page)
	if not title then return getError('no-page') end
	if title.isRedirect then title = title.redirectTarget end
	if not title.exists then return getError('page-not-found', page) end
	page = title.prefixedText

	-- Get the nth fig file
	local ok, figs = pcall(Transcluder.get, page, { only = 'templates', templates = 'fig' })
	if ok then
		local fig = Transcluder.getTemplates(figs, args.fig_number)[1]
		local parameters = Transcluder.getParameters(fig)
		local file = parameters['image']
		local caption = parameters['caption'] or ''
		output = file 
	end
	return output
end


return p