Module:Sandbox/Marsupium/Technique

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Documentation for this module may be created at Module:Sandbox/Marsupium/Technique/doc

Code

--[=[
a good part of this is taken from [[User:Jarekt]]'s [[Module:Wikidata art]]!

for now this shall become a rewrite of that module's p.get_medium()
p.get_medium() has some issues:
* no support for P462 and other qualifiers
* restricted evaluation of P518 qualifier
* probably complete disrespect for this qualifier when "ok = false",
  meaning when one of the materials is a unrecognized material
  in [[Module:Artwork/Technique LUT]]

start for a testing environment for a new Lua implementation of Template:Technique
that is more flexible and supports medium/"material used" (P186) retrieval from Wikidata more exhaustively
along with full upstream support

linking is planned to be (at least regularly) handed over to Wikidata
(note: for linking to lists, e.g. "yoko-e" on enwiki  "glossary entry at Wikipedia" (P5178) could be used)

## TODO:
* (DONE from retrieval side) add support for multi-value qualifiers
* add support for more(/all?) values of P518
* how to represent non-color adjectives in WD?
]=]

require('strict')
local getLabel         = require("Module:Wikidata label")._getLabel            -- used for creation of name based on wikidata
local technique        = require("Module:Technique/sandbox")._technique 
local core             = require('Module:Core')

-- adapted from [[User:Jarekt]]'s [[Module:Wikidata art]]:
local function getPropertyQual(entity, prop, qualifiers, lang, offset)
	local Res = {}
	if entity.claims and entity.claims[prop] then
		for k, statement in ipairs( entity:getBestStatements( prop )) do
			if (statement.mainsnak.snaktype == "value") then 
				local res = {} -- table with fields: key, value, P... (qualifiers)
--				local jdn = k + (offset or 0) -- "Julian day number" will be used as a key for sorting events; initialize
				local val = statement.mainsnak.datavalue.value
				if val.id then 
					res.value_id = val.id
					val = getLabel(val.id, lang)
				elseif val.text then
					res.value_lang = val.language
					val = val.text
				end
				res.value = val
				for iQual, qual in ipairs( qualifiers ) do
					if statement.qualifiers and statement.qualifiers[qual] then
						-- this is now obsolete and replaced by the stuff following it:
						--[[
						local snak = statement.qualifiers[qual][1]
						if (snak.snaktype == "value" and snak.datatype == 'wikibase-item') then
							-- val = getLabel(snak.datavalue.value.id, lang)
							res[qual ..'_id'] = snak.datavalue.value.id
						else
							val = nil
						end
						res[qual] = val
						]]
						
						local snaks = {}
						for i, snak in ipairs(statement.qualifiers[qual]) do
							local qualsnak = {}
							if (snak.snaktype == "value" and snak.datatype == 'wikibase-item') then
								-- val = getLabel(snak.datavalue.value.id, lang)
								qualsnak[qual ..'_id'] = snak.datavalue.value.id
							else -- don't know what this is for
								qualsnak = nil
							end
							--TODO: implement!
							snaks[#snaks+1] = qualsnak
						end
						res[qual] = snaks
					end
				end
--				res.key = jdn
				table.insert(Res, res)
			end
		end
	end
--	local tableComp = function (rec1, rec2) return rec1.key<rec2.key end
--	table.sort(Res, tableComp)
	return Res
end

local function length(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

local function getAdjTable(p)
	local adjTable = {}
	if p.P462 then
		for _,adj in ipairs(p.P462) do
			table.insert(adjTable, string.lower(adj.P462_id))
		end
	end
	return adjTable
end

local function isInP518PropValues(searchedValue, p)
	local result = false
	if p.P518 then
		for _,claim in ipairs(p.P518) do
			if claim.P518_id == searchedValue then
				result = true
			end
		end
	end
	return result
end

local p = {}

function p.get_medium(frame)
	local entity = mw.wikibase.getEntity(frame.args.item)
	local lang = (frame.args.lang or frame:callParserFunction("int", "lang"))
	-- material used (P186) (item property) / applies to part (P518) (item property) 
	local prop = getPropertyQual(entity, 'P186', {'P462', 'P518'}, lang)
	local prop_id = 'P186'
	if not prop or length(prop)==0 then
		prop = getPropertyQual(entity, 'P2079', {'P462', 'P518'}, lang)
		prop_id = 'P2079'
	end
	if not prop or length(prop)==0 then
		return nil -- if no P186 or P2079 statements than exit
	end
	local caseGroups = {default = {}, over = {}, on = {}, mounted = {}}
	for _, p in ipairs(prop) do
		local lc_value_id = string.lower(p.value_id)
		if isInP518PropValues('Q861259', p) then -- applies to part: painting surface
			caseGroups.on[#caseGroups.on+1] = {noun = lc_value_id, adj = getAdjTable(p)}
		elseif isInP518PropValues('Q107105674', p) then -- applies to part: mount
			caseGroups.mounted[#caseGroups.mounted+1] = {noun = lc_value_id, adj = getAdjTable(p)}
		else
			caseGroups.default[#caseGroups.default+1] = {noun = lc_value_id, adj = getAdjTable(p)}
		end
	end
	
	local medium = technique({lang = lang, system = 'templates', compat = 'yes', caseGroups = caseGroups})
	if medium then
		medium = medium .. core.editAtWikidata(entity.id, prop_id, lang)
	end
	return medium
end

return p