Module:Witkacy table row

Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules


This is custom Lua code used for generating the table in pl:Lista dzieł malarskich Stanisława Ignacego Witkiewicza.

The way to use this code is to:

  • A2=Q-code from above query
  • B2=CONCATENATE("{{subst:User:Jarekt/witkacy row|",A2,"}}")
  • C2=C1+1/490
  • D2=ROUND(C2-0.5,0)
{{subst:User:Jarekt/witkacy row|header}}
|} to it. Than copy content of column B from the spreadsheet, 500 rows at a time, and paste into the table.

queryquery

SELECT ?item WHERE { 
 ?item wdt:P170 wd:Q381238 .          # Witkacy as creator
 MINUS{ ?item wdt:P31 wd:Q3658341 .}  # no literary characters
 MINUS{ ?item wdt:P31 wd:Q125191 .}   # no photographs
 MINUS{ ?item wdt:P31 wd:Q16905563 .} # no cycles of paintings
 MINUS{ ?item wdt:P31 wd:Q2352616 .}  # no catalogues
   
 optional{ ?item p:P528 [ pq:P972 wd:Q106425660; ps:P528 ?kdm] . }
 optional{ ?item wdt:P156/wdt:P528 ?prev .}            
 optional{ ?item wdt:P155/wdt:P528 ?next .}             
 bind( if( bound(?kdm) && strStarts(str(?kdm), "I "), CONCAT(STR( ?kdm  ), ".5"), 
       if( bound(?next),                              CONCAT(STR( ?next ), ".9"),
       if( bound(?prev),                              CONCAT(STR( ?prev ), ".1"), 
       "Z") ) ) as ?kdmn ) .

 OPTIONAL {
   ?item rdfs:label ?Len 
   FILTER((LANG(?Len)) = "en")
 }
} order by ?kdmn

Try it!

Code

local getDate   = require("Module:Wikidata date")._date                 -- used for processing of date properties
local core      = require('Module:Core')
local p = {}

-- ===========================================================================
local function wd(qcode, text)
	return '[[:d:'.. qcode ..'|'.. text ..']]'
end

-- ===========================================================================
local function getLabel_pl(qcode) 
	local label    = mw.wikibase.getLabelByLang(qcode, 'pl' ) or  
	                 mw.wikibase.getLabelByLang(qcode, 'mul') or 'error #6'
	local sitelink = mw.wikibase.getSitelink(qcode, 'plwiki')
	if sitelink==label then
		return '[[' .. label ..']]'
	elseif sitelink then
		return '[[' .. sitelink .. '|' .. label ..']]'
	else	
		return '[[:d:'.. qcode ..'|'.. label ..']]'
	end	
end

-- ===========================================================================
local function getValueByQual(entity, prop, qualID, qvalue, lang)
	local Res = {}
	if entity.claims and entity.claims[prop] then
		for k, statement in ipairs( entity:getBestStatements( prop )) do
			if (statement.mainsnak.snaktype == "value" and statement.qualifiers and statement.qualifiers[qualID]) then
				local snak = statement.qualifiers[qualID][1]
				if (snak.snaktype == "value" and snak.datatype == 'wikibase-item' and snak.datavalue.value.id == qvalue) then 
					return statement.mainsnak.datavalue.value
				end
			end
		end
	end
	return ''
end

-- ===========================================================================
local function getProperty(entity, prop)
	return (core.parseStatements(entity:getBestStatements( prop ), nil ) or {''})[1]
end

-------------------------------------------------------------------------------
local function getItemProperty(item, prop)
	return (core.parseStatements(mw.wikibase.getBestStatements( item, prop ), nil) or {nil})[1]
end

-------------------------------------------------------------------------------
local function getPropertyWithQual(entity, prop, qualifiers, lang)
	local Res = {}
	if entity.claims and entity.claims[prop] then
		for k, statement in ipairs( entity:getBestStatements( prop )) do
			local res, val = {}, nil -- table with fields: key, value, P... (qualifiers)
			if (statement.mainsnak.snaktype == "value") then 
				val = statement.mainsnak.datavalue.value
				if val.id then 
					val = val.id
				elseif val.text then
					res.value_lang = val.language
					val = val.text
				end
			else
				val = statement.mainsnak.snaktype
            end
			res.value = val
			for iQual, qual in ipairs( qualifiers ) do
				if statement.qualifiers and statement.qualifiers[qual] then
					res[qual] = core.parseSnak( statement.qualifiers[qual][1], nil)
				end
			end
			table.insert(Res, res)
		end
	end
	return Res
end

-- ===========================================================================
local function get_image(entity) 
	local image = getProperty(entity, 'P18')
	if image == '' then
		return '[[Plik:Brak zdjecia.svg|center|100px]]'
	else
		return'[[Plik:' .. image .. '|center|200px]]'
	end
end

-- ===========================================================================
local function get_title_pl(entity) 
	local title = (entity:getLabel('pl') or 'error #5')
	title       = "''[[:d:".. entity.id .. '|' .. title .. "]]''"	
	local id    = getProperty(entity, 'P921') -- "main subject" 
	if id ~= '' then
	    if (getItemProperty(id, 'P31') == 'Q5') then
			title = title .. '<br>(osoba: ' .. getLabel_pl(id)  .. ')'
		end
	else
		local people = {} 
		for _, id in ipairs( core.parseStatements( entity:getBestStatements( 'P180' ), nil ) or {}) do
			if (getItemProperty(id, 'P31') == 'Q5') then
				table.insert(people, getLabel_pl(id))
			end
		end
		if #people>0 then
			title = title .. '<br>(osoby: ' .. table.concat( people, ', ') .. ')'
		end
	end
	return title
end

-- ===========================================================================
function p.get_collection_pl(entity)	
	local collection, details = {}, {}
	
	local idx = 0
	local prop = getPropertyWithQual(entity, 'P195', {'P518', 'P580', 'P582', 'P828', 'P2868', 'P3831'}) -- (P3831) and no end time (P582)
	for _, p in ipairs(prop) do
		local val = nil
		if p.P582 then -- has end date -> ignore
			-- do nothing
		elseif p.P518=='Q114187913' then --applies to part = photograph of the artwork
			val = 'praca znana z fotografii'
		elseif p.value=='somevalue' and p.P3831=='Q768717' then -- object has role = private collection
		    val = 'kolekcja prywatna'
			idx = 1
		elseif p.value=='novalue' then
			if p.P828=='Q4140840' then -- has cause = lost artwork
				val = 'praca zaginiona'
			elseif p.P828=='Q328376' then -- has cause = Nazi plunder
				val = 'praca zaginiona w czasie II wojny swiatowej'
			elseif p.P828=='Q21745157' then -- has cause = destroyed artwork (Q21745157)
				val = 'praca zniszczona'
			end
			idx = 4
		elseif (p.value~='novalue' and p.value~='somevalue' and p.P2868=='Q94796160') then -- has subject has role=long-term loan
			val = 'depozyt w ' .. getLabel_pl(p.value)
			idx = 3
		elseif p.value then	-- museum or named private collection
			val = getLabel_pl(p.value)
			idx = 2
			if val ~= '' and p.P580 then
				table.insert(details, 'od ' .. p.P580 )
			end
		end
		table.insert(collection, val)
	end
	local col = table.concat( collection, ',<br>')
	if (col=='') then
		col = 'dzieje nieznane'
	end
	
	-- create more natural transitions
	if #prop>1 then
		col = mw.ustring.gsub(col, ',<br>praca znana z fotografii', ', znana z fotografii')
		col = mw.ustring.gsub(col, ',<br>depozyt w', ', depozyt w')
		col = mw.ustring.gsub(col, 'praca znana z fotografii,<br>praca zaginiona', 'praca zaginiona, znana z fotografii')
		return col
	end
	
	-- add inventory number
	local id = getProperty(entity, 'P217') -- inventory number string
	if id ~= '' then 
		if idx==1 and string.sub(id,1,4)=='N.D.' then
			table.insert(details, "dawny numer inwentarza [[:d:Q116259175|MNK]]: ''" .. id .. "''" )
		else
			table.insert(details, "numer inwentarza: ''" .. id .. "''" )
		end
	end
	
	-- how do we know about it?
	if idx<=1 then -- kolekcja prywatna
		local published = getProperty(entity, 'P1433') -- published in
		local event     = getProperty(entity, 'P793')  -- significant event

		if event == 'Q177923' or event == 'Q781384' or event == 'Q194189' then
			if #published>0 then
				table.insert(details, 'praca znana z publikacji i aukcji')
			elseif event and published then
				table.insert(details, 'praca znana z aukcji')
			end
		elseif #published>0 then
			table.insert(details, 'praca znana z publikacji')
		end
	end	
	
	-- add details
	if #details>0 then
		return col .. '<br>(' .. table.concat( details, ', ') .. ')'
	else
		return col
	end
end

-- ===========================================================================
function p.get_medium_pl(entity, lang)
	-- material used (P186) (item property) /  applies to part (P518) (item property) /color (P462)
	local prop = getPropertyWithQual(entity, 'P186', {'P828', 'P518', 'P462'}, lang)

	if not prop then
		return '' -- if no P186 statements then exit
	end
	
	local LUT1 = { -- mianowniki
		Q189085  = 'pastel',  Q14674 ='olówek',     Q1424515 ='wegiel',   Q296955='olej',  Q1783255 ='kredka',
		Q3374389 ='akwarela', Q127418='atrament',   Q12981547='tusz',     Q204330='gwasz', Q99826317='kredka',
		Q69158   ='kredka',   Q175166='tempera',    Q901944  ='sangwina', Q147690='kreda', Q15123870='litografia', 
		Q22669857='kolaz',    Q133036='litografia', Q174219  ='farba',    Q1261026='druk'
	}
	
	local LUT2 = {
		Q11472 ='papierze', Q14934005 ='tekturze', Q389782='tekturze', Q18668582='tekturze', Q3695916='bawelnie',
		Q219803='dykcie',   Q106857709='desce',    Q287   ='desce',    Q12321255='plótnie', Q8231603='tkaninie'
	}
	
	local LUT3 = {  -- miejscowniki
		Q11472 ='papier', Q14934005 ='tekture', Q389782='tekture', Q18668582='tekture',
		Q219803='dykte',  Q106857709='deske',   Q287   ='deske',   Q12321255='plótno', Q8231603='tkanine'
	}
	
	local color_LUT = {
		Q105996967='szarobezowym ', Q1088='niebieskim ',Q115413960='zóltawym ',Q115858149='fioletowoczerwonym ',
		Q119267340='zielonobrazowym ',Q119985571='rózowawym ',Q121012829='szarozielonym ',Q121012829='zielonoszarym ',
		Q13451045='brazowoszarym ',Q1402829='czerwonofioletowym ',Q19888366='rózowobrazowym ',Q19888381='fioletowobrazowym ',
		Q19888381='brazowofioletowym ',Q19888422='zóltobrazowym ',Q22963901='ciemnozielonym ',Q2334511='wisniowym ',
		Q23444='bialym ',Q23445='czarnym ',Q24837023='jasnoszarym ',Q2730433='kremowym ',Q3133='zielonym ',
		Q3142='czerwonym ',Q3641131='ciemnoniebieskim ',Q39338='pomaranczowym ',Q3985184='ciemnobrazowym ',Q42519='szarym ',
		Q428124='fioletowym ',Q429220='rózowym ',Q4405716='jasnozielonym ',Q47071='brazowym ',Q4928721='szaroniebieskim ',
		Q5223370='ciemnoczerwonym ',Q5975887='granatowym ',Q71392381='ciemnoszarym ',Q71404162='jasnobrazowym ',
		Q71405932='brazowoczerwonym ',Q71405932='czerwonobrazowym ',Q71873134='jasnorózowym ',Q737438='cynobrowym ',
		Q737438='pomaranczowoczerwonym ',Q843607='bezowym ',Q864152='oliwkowym ',Q89328051='ciemnorózowym ',
		Q90809281='ciemnooliwkowym ',Q90809429='jasnozielonkawym ',Q943='zóltym ',Q98111784='ceglastym ',
		Q25614085='ciemnoszarym ', x=''
	}

	local material = {}
	local surface, mount = '', ''
	for _, p in ipairs(prop) do
		if p.P518=='Q861259' then         -- applies to part: painting surface
			surface = ' na ' .. (color_LUT[p.P462 or 'x'] or 'error #2(' .. p.P462 .. ')') 
			                 .. (LUT2[p.value] or 'error #3(' .. p.value .. ')')
		elseif p.P518=='Q107105674' then         -- applies to part: mounted on
			mount = ' naklejony na ' .. (LUT3[p.value] or 'error #3(' .. p.value .. ')')
		else
			table.insert(material, LUT1[p.value] or 'error #3(' .. p.value .. ')')
		end
	end
	return mw.text.listToText( material, ', ', ' i ' ) .. surface
end

-- ===========================================================================
function p.get_date(entity, lang)
	local cdate = getDate (entity, 'P571', lang).str
	local patrn = '%<div style="display: none;"%>date QS:[^%<]+%</div%>'
	cdate = mw.ustring.gsub(cdate, patrn, '')	
	patrn =	'%<time class="dtstart" datetime="%d%d%d%d" lang="%w%w" dir="ltr" style="white%-space:nowrap"%>(%d%d%d%d)%</time%>'
	cdate = mw.ustring.gsub(cdate, patrn, '%1')
	cdate = mw.ustring.gsub(cdate, 'od okolo (%d%d%d%d) do okolo (%d%d%d%d)', 'okolo %1-%2')
	cdate = mw.ustring.gsub(cdate, 'przed srodek 19', 'do polowy 19')
	cdate = mw.ustring.gsub(cdate, '-', '–')
	return cdate
end

-- ===========================================================================
function p.get_size(entity)
	local h = getProperty(entity, 'P2048')
	local w = getProperty(entity, 'P2049')
	local dim = ''
	if h ~= '' and w ~= '' then
		dim = h .. '×' .. w .. ' cm'
		dim = string.gsub(dim, '%.', ',')
	end
	return dim
end

-- ===========================================================================
function p.get_type(entity)
	local LUT = {
		Q131450562 = "T.A",
		Q131534919 = "T.B+D",
		Q131534897 = "T.B+E+d",
		Q131534872 = "T.B+A",
		Q131468128 = "T.D",
		Q131534715 = "T.E+d",
		Q131531531 = "T.B+d",
		Q131521054 = "T.B+E",
		Q131466254 = "T.E",
		Q130453765 = "T.B",
		Q130457796 = "T.C",
	}

	local prop = getPropertyWithQual(entity, 'P136', {}) -- (genre)
	for _, p in ipairs(prop) do
		local val = LUT[p.value]
		if (val) then
			return val
		end
	end
	return ''
end

-- ===========================================================================
function p.get_inscription_pl(entity)
--[[
 Wikidata
	 inscription (P1684) - Monolingual text
	 applies to part (P518) - item property
]]
	local LUT = {
	  -- positions stored in "applies to part (P518)" qualifier
		Q15332388 = "u dolu",
		Q17525439 = "u dolu",
		Q11812678 = "u dolu",
		Q15332375 = "u góry",
		Q17525438 = "u góry",
		Q23595    = "po srodku",
		Q27956567 = "po srodku",
		Q13196750 = "po lewej",
		Q17525441 = "po lewej",
		Q14565199 = "po prawej",
		Q17525442 = "po prawej",
		Q27956549 = "lewy górny róg", 
		Q27956533 = "prawy górny róg", 
		Q27956553 = "lewy dolny róg", 
		Q27956561 = "prawy dolny róg", 
		Q9368452  = "z tylu",
		Q1542661  = "z tylu", -- reverse
		Q32198402 = "z tylu", -- reverse
		Q16938807 = "z tylu"  -- reverse		
	}
	local AllInsc = {}
	local prop = getPropertyWithQual(entity, 'P1684', {'P518'}) -- "inscription (P1684)") and  applies to part (P518)
	for _, p in ipairs(prop) do
		if p.value=='novalue' then
			table.insert(AllInsc, 'niesygnowany')
		elseif p.value=='somevalue' then
			table.insert(AllInsc, 'sygnatura nieczytelna')
		else
			local insc = "''„" .. p.value .. "”''"
			if p.P518 then -- applies to part (P518) used for location
				local pos = LUT[p.P518]
				if pos then
					insc = pos .. ": " .. insc
				end
			end
			table.insert(AllInsc, insc)
		end
	end
	if #AllInsc>0 then
		return table.concat(AllInsc,", <br>")
	end
	return ''
end

-- ===========================================================================
function p.row(frame)
	local qid = frame.args[1]
	if qid=='header' then
		local header = {'{| class="wikitable sortable" style="width:100%"',
		                'class="unsortable"|Ilustracje', 'Tytul', 'Data', '[[:d:Q106425660|KDM]]', 
		                'Kolekcja', 'Technika', 'Wymiary', 'Typ', 'Sygnatury i Inskrypcje'}							
		return table.concat(header, '\n!') .. '\n|-'			  
	elseif qid=='end' then
		return '|}'
	elseif mw.ustring.sub(qid, 1, 1)=='Q' then
		local entity = mw.wikibase.getEntity(qid)
		if not entity then
			return 'error #7:' .. qid .. ' does not exist'
		end
		local D = {}
		table.insert(D, get_image(entity) )
		table.insert(D, get_title_pl(entity) ) -- title
		table.insert(D, p.get_date(entity, 'pl')) -- date
		table.insert(D, getValueByQual(entity, 'P528', 'P972', 'Q106425660' )) -- kdm
		table.insert(D, p.get_collection_pl(entity))	-- collection
		table.insert(D, p.get_medium_pl(entity, 'pl')) -- medium
		table.insert(D, p.get_size(entity)) -- size
		table.insert(D, p.get_type(entity)) -- typ
		table.insert(D, p.get_inscription_pl(entity)) -- sygnatura
		
		for i, v in ipairs(D) do				
			D[i] = v:gsub("^%s*(.-)%s*$", "%1") -- Trim leading and trailing whitespace
		end
		return '| ' .. table.concat(D," \n| ") .. '\n|-'
	else 
		return qid
	end
end

return p