Przejdź do zawartości

Moduł:Infobox

Z Wikibooks, biblioteki wolnych podręczników.
 Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]

Funkcja zwraca wartość opcjonalnego pola Q w wywołaniu szablonu (infoboksu), który ma wskazywać na źródłowy element w Wikidanych, jeśli szablon jest używany poza przestrzenią główną. Na stronie definiującej szablon (kod źródłowy infoboksu) zwraca wartość „demo”. Jeśli parametr nie został podany zwraca tekst pusty. Z tego parametru domyślnie korzystają pozostałe funkcje modułu, które próbują uzupełnić automatycznie brakujące dane.

Demo

[edytuj]

Funkcja renderująca zapis pola z demonstracją odwołania do Wikidanych. Przyjmuję listę nazw argumentów będących nazwami pól szablonu lub cech z Wikidanych. Cechy są identyfikowane pustą nazwą poprzedzającą.

{{#invoke:Infobox|Demo|nazwa||wd}} → {{{nazwa|Wikidane wd}}}

Test

[edytuj]

Funkcja sprawdzająca czy istnieje jakakolwiek zdefiniowana cecha w Wikidanych z podanej listy. Każdą cechę należy podać w oddzielnym parametrze. Na stronie definiującej szablon zwraca niepustą wartość („demo”).

pole wartość domyślna opis
parametr indeksowany brak Identyfikator cechy w postaci Pnnnn.

Tytuł

[edytuj]
{{{1}}}
{{{2}}}
{{{3}}}

Funkcja generuje nagłówek infoboksu – odpowiednik {{infobox tytuł}}. Jest to pole nagłówka tabeli definiowane jako |+. Teksty kolejnych poziomów są oddzielane znacznikiem nowej linii (<br>).

pole wartość domyślna opis
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli wygenerowany nagłówek jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
pole brak Atrybuty nagłówka tabeli.
cecha P1705 P1448 Lista cech, z których pierwsza niepusta wartość będzie użyta jako treść drugiego poziomu, jeśli nie podano jej jawnie w parametrze. Domyślnie są to „nazwa oryginalna” lub „nazwa oficjalna”.
1 Etykieta z Wikidanych Tekst główny nagłówka infoboksu. Niepusta treść jest owijana w <span class="iboxt1">.
2 Pierwsza niepusta wartość cechy z listy przekazanej przez pole cecha Tekst drugiego poziomu nagłówka infoboksu. Niepusta treść jest owijana w <span class="iboxt2">.
3 brak Tekst trzeciego poziomu nagłówka infoboksu. Niepusta treść jest owijana w <span class="iboxt3">.

Grafika

[edytuj]

Funkcja do wstawiania sekcji obrazkowej. Składa się ona z jednego opcjonalnego dużego obrazka i opcjonalnej listy małych ilustracji umieszczanych w parach obok siebie.

pole wartość domyślna opis
wiersz brak Opcjonalne atrybuty wiersza.
dodaj brak Dodatkowy warunek wyświetlania treści infoboksu. Wartość pusta oznacza, że nie zostania wygenerowana żadna treść w infoboksie.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
format 240x240px lub 100x100px Zwykle rozmiar obrazka.
grafika brak Nazwa pliku na commons użytego jako ilustracja albo wartość nie w celu wyłączenia wyświetlania ilustracji. Domyślnym formatem dla tej grafiki jest 240x240px.
opis grafiki brak Opcjonalny opis umieszczany pod ilustracją.
cecha brak Identyfikator cechy w Wikidanych zawierającą wskazanie do pliku na commons.
cecha opisu brak Identyfikator cechy z artykułem opisującym ilustrację (np. herb lub flagę).
N. grafika[mini 1] brak Nazwa pliku na commons użytego jako ilustracja albo wartość nie w celu wyłączenia wyświetlania ilustracji. Domyślnym formatem dla tej grafiki jest 100x100px.
N. opis grafiki[mini 1] brak Opcjonalny opis umieszczany pod ilustracją.
N. cecha[mini 1] brak Identyfikator cechy w Wikidanych zawierającą wskazanie do pliku na commons.
N. cecha opisu[mini 1] brak Identyfikator cechy z artykułem opisującym ilustrację (np. herb lub flagę).

Grupa uwag

  1. 1,0 1,1 1,2 1,3 Lista małych obrazków wprowadzana jest przez parametry z dodatkowym indeksem N. numerowanym od 1 w górę. Są one umieszczane w dwukolumnowej tabeli ze stylem class="ibox2".

Grupa

[edytuj]

Funkcja ułatwiająca generowanie grup wierszy z nagłówkiem.

pole wartość domyślna opis
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli podany (wygenerowany) nagłówek jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
nagłówek brak Tytuł nagłówka grupy.
pole nagłówka brak Atrybuty pola nagłówka.
wiersz nagłówka brak Atrybuty wiersza nagłówka.
klasa kreski iboxs Klasa dodawana do atrybutu class wiersza tabeli, gdy wymagana jest kreska. Odpowiedni styl powinien być zdefiniowany w globalnym common.css.
parametry indeksowane brak Treść wierszy infoboksu lub „-” w miejscu gdzie ma być separator. Wiersze infoboksu muszą być generowane jako fragment tabeli w wikikodzie.

Blok

[edytuj]
{{{nagłówek}}}
{{{1}}}

Elementarny generator pionowego pola infoboksu (z opisem nad wartością). Generowane są tylko niepuste wartości. Domyślnie generowana treść ma postać:

|-
!colspan="2"|{{{nagłówek}}}
|-
|-
|class="iboxa" colspan="2"|{{{1}}}
|-
pole wartość domyślna opis
wiersz nagłówka brak Atrybuty wiersza tabeli z nagłówkiem.
pole nagłówka brak Atrybuty komórki tabeli z nagłówkiem.
wiersz brak Atrybuty wiersza tabeli z wartością wyświetlaną.
nagłówek brak Tytuł nagłówka.
dodaj brak Dodatkowy warunek wyświetlania treści infoboksu. Wartość pusta oznacza, że nie zostania wygenerowana żadna treść w infoboksie.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
cecha brak Identyfikator cechy w Wikidanych, której wartość będzie wyświetlana jeśli nie zostanie jawnie przekazana w wywołaniu. Może być również źródłem nazwy nagłówka, jeśli nie jest podany, a jednocześnie istnieje polska etykieta dla podanej cechy w Wikidanych.
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli wygenerowany tekst jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
1 brak Wartość wyświetlana.

Wiersz

[edytuj]
{{{etykieta}}} {{{1}}}

Elementarny generator pola infoboksu. Generowane są tylko niepuste wartości. Domyślnie generowana treść ma postać:

|-
!{{{etykieta}}}
|class="iboxa"|{{{1}}}
|-
pole wartość domyślna opis
wiersz brak Opcjonalne atrybuty wiersza.
etykieta brak Tytuł pola opisu wartości.
dodaj brak Dodatkowy warunek wyświetlania treści infoboksu. Wartość pusta oznacza, że nie zostania wygenerowana żadna treść w infoboksie.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
cecha brak Identyfikator cechy w Wikidanych, której wartość będzie wyświetlana jeśli nie zostanie jawnie przekazana w wywołaniu. Może być również źródłem nazwy nagłówka, jeśli nie jest podany, a jednocześnie istnieje polska etykieta dla podanej cechy w Wikidanych.
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli wygenerowany tekst jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
1 brak Wartość wyświetlana.

Drzewo

[edytuj]

TODO

Projekt

[edytuj]
W projektach Wikimedia

Generator linków do projektów siostrzanych. Aby włączyć linkowanie do określonego projektu siostrzanego należy podać jawny parametr (nawet pusty) odpowiedzialny za jego prezentację.

pole wartość domyślna opis
wiersz nagłówka brak Atrybuty wiersza tabeli z nagłówkiem.
pole nagłówka brak Atrybuty komórki tabeli z nagłówkiem.
wiersz brak Atrybuty wiersza tabeli z wartością wyświetlaną.
nagłówek W projektach Wikimedia Tytuł nagłówka. Jeśli podany pusty to nagłówek nie jest wyświetlany.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
wikipedia brak Włącza generowanie linku do innej wersji językowej Wikipedii. Zastosowanie dla {{język infobox}}.
c brak Włącza generowanie linku do commons.
n brak Włącza generowanie linku do Wikinews.
q brak Włącza generowanie linku do Wikicytatów.
s brak Włącza generowanie linku do Wikiźródeł.
wikt brak Włącza generowanie linku do hasła w Wikisłowniku.
wikispecies brak Włącza generowanie linku do Wikispecies.
voy brak Włącza generowanie linku do Wikipodróży.
b brak Włącza generowanie linku do Wikibooks.
wikt:cat brak Włącza generowanie linku do kategorii w Wikisłowniku.
local resources = mw.loadData("Moduł:Infobox/resources")

local function P(frame, qid, pid)
	local sd = require("Module:Wikidane/select")
	return sd.selectProperty(pid, sd.prepareFilters(frame), qid)
end

local function isNullOrWhiteSpace(text)
	return (text == null)
		or (#text <= 0)
		or string.match(text, "^%s+$")
end

local function addClass(attributes, class)
	if not class or (#class == 0) then
		return attributes
	end
	
	if not attributes or (#attributes == 0) then
		return "class=\""..class.."\""
	end
	
	local r, c = string.gsub(attributes or "", "%f[%w]class%s*=%s*['\"]", "%0"..class.." ", 1)
	if c == 1 then
		return r
	end
	
	return "class=\""..class.."\" "..attributes
end

local function iboxSpan(header, text, row, cell)
	assert(type(header) == "boolean")

	local result = {}
	table.insert(result, "|-")
	if row and (#row > 0) then
		table.insert(result, " ")
		table.insert(result, row)
	end

	table.insert(result, "\n")
	table.insert(result, header and "!" or "|")
	if cell and (#cell > 0) then
		table.insert(result, cell)
		table.insert(result,' ')
	end
	
	table.insert(result, 'colspan="2"|')
	table.insert(result, text)
	table.insert(result, "\n|-\n")
	return table.concat(result)
end

local function emptyCategory(frame, emptyCat)
	if not emptyCat or (mw.title.getCurrentTitle().namespace ~= 0) then
		return ""
	end
	
	if mw.ustring.match(emptyCat, "%[%[[Kk]ategoria:.-%]%]") then
		return emptyCat
	end
	
	local template = frame:getParent():getTitle()
	local infobox = mw.ustring.match(template, "^Szablon:(.- infobox)$")
	return mw.ustring.format(resources.catMissingData, infobox or template, emptyCat)
end

local function InputData(frame, Q, demo, source, sourcepropid)
	local ns = mw.title.getCurrentTitle().namespace
	local add = frame.args["dodaj"]
	local cell = frame.args["pole"]
	local propid = frame.args[sourcepropid or "cecha"]
	local emptyCat = frame.args["kategoria brak"]
	local value = frame.args[source or 1]
	
	add = (add == nil) or (#add > 0)

	if emptyCat and (#emptyCat == 0) then
		emptyCat = false
	end

	if propid and (#propid == 0) then
		propid = false
	end
	
	if isNullOrWhiteSpace(value) then
		value = false
	end
	
	local demovalue = false
	if value then
		demovalue = mw.ustring.match(value, "^%s*{{{(.-)}}}%s*$")
	end
	
	local wdvalue = false
	if add and not demo and (not value or demovalue) and propid then
		local pid, qid, prop = P(frame, Q, propid)
		if pid and qid and prop then
			value = require("Moduł:Wikidane/format").run(frame, pid, prop)
			if not value or (#value <= 0) then
				value = false
			else
				wdvalue = true
			end
		end
	end

	if add and not demo and (not value or (demovalue and not wdvalue)) and emptyCat then
		cell = addClass(cell, resources.classEmpty)
		value = (value or "") .. emptyCategory(frame, emptyCat)
	end
	
	if not demo and demovalue then
		cell = addClass(cell, resources.classMissingArg)
		if namespace == 0 then
			value = value..resources.catMissingArg
		end
	end
	
	return add and value or false, cell, demovalue, propid
end

local function Qdemo(frame)
	local Q = frame:getParent().args.Q
	if Q and string.match(Q, "^%d") then
		Q = "Q"..Q
	end
	
	if Q then
		-- jest Q to nie demo
		return Q, false
	end
	
	for k, v in pairs(frame:getParent().args) do
		-- nie ma Q lecz dowolny argument to również nie demo
		return nil, false
	end

	-- nie ma Q ani żadnego parametru, jeśli to źródło szablonu, to musi to być demo
	return nil, (mw.title.getCurrentTitle().fullText == frame:getParent():getTitle())
end

local function editWDlink(qid, pid)
	return "<span class=\"plainlinks wdlink\" title=\"edytuj dane z infoboxu w Wikidanych\">&#x5B;[https://www.wikidata.org/wiki/"..qid.."#"..pid.." e]&#x5D;</span>"
end

local function imageWDdemo(pid)
	if pid then
		if string.match(pid, "^P%d+$") then
			pid = "[[:d:Property:"..pid.."|"..pid.."]]"
		end
		return "<span style=\"white-space: nowrap;\">[[Plik:Wikidata-logo-en.svg|22x20px|link=|Wikidane]] <tt>"..pid.."</tt></span>"
	end
end

local function propertyLabel(frame, propid, propid2)
	local lang = mw.getContentLanguage()
	if not propid2 then
		local pid, qid, prop = P(frame, propid, "P1629")
		if pid and qid and prop then
			mw.logObject(prop, "P1629")
			local value = require("Moduł:Wikidane/format").run(frame, pid, prop)
			if value and (#value > 0) then
				value = mw.ustring.gsub(value, "(|)(%l)", function(bar, lcase) return bar..lang:ucfirst(lcase) end)
				return lang:ucfirst(value)
			end
		end
	end

	local label1 = mw.wikibase.label(propid)
	if not label1 or (#label1 <= 0) then
		return false
	end
	
	if not propid2 then
		return lang:ucfirst(label1)
	end
		
	local label2 = mw.wikibase.label(propid2)
	if not label2 or (#label2 <= 0) then
		return false
	end
		
	local cp1 = { mw.ustring.codepoint(label1, 1, mw.ustring.len(label1)) }
	local cp2 = { mw.ustring.codepoint(label2, 1, mw.ustring.len(label2)) }
	local len = #cp1 < #cp2 and #cp1 or #cp2
	-- find common suffix
	local suffix = false
	for i = 1, len do
		if cp1[#cp1-i+1] ~= cp2[#cp2-i+1] then
			suffix = len - i + 1
			break
		end
	end

	while (suffix < len) and (cp1[#cp1 - suffix + 1] ~= 32) do
		suffix = suffix + 1
	end
	
	if suffix < len then
		label1 = mw.ustring.char(unpack(cp1, 1, #cp1 - suffix))
	end
	
	return lang:ucfirst(mw.text.trim(label1).." i "..mw.text.trim(label2))
end

local function makeDemoArg(wrap, ...)
	local count = select('#', ...)
	if count <= 0 then
		return
	end

	local items = {}
	local index = 1
	while index <= count do
		local v = select(index, ...)
		if v and (type(v) == "string") then
			table.insert(items, v)
		end
		
		index = index + 1
	end
	
	if #items <= 0 then
		return
	end

	local prefix = wrap and "{{{" or ""
	local suffix = wrap and "}}}" or ""
	return prefix..table.concat(items,"&#x7C;")..suffix
end

return {
	["Q"] = function(frame)
		local Q, demo = Qdemo(frame)
		return demo and "demo" or Q
	end,
	
	["Demo"] = function(frame)
		local args = require('Module:Arguments').getArgs(frame, { trim = false, removeBlanks = false })
		local result = {}
		local i = 1
		local wd = false
		while true do
			local v = args[i]
			i = i + 1
			if not v then
				break
			end
			
			if #v == 0 then
				if wd then
					table.insert(result, "")
				end
				
				wd = true
			else
				table.insert(result, wd and imageWDdemo(v) or v)
				wd = false
			end
		end
		
		if #result then
			local result = "{{{"..table.concat(result,"&#x7C;").."}}}"
			mw.logObject(result, "result")
			return result
		end
	end,
	
	["Test"] = function(frame)
		local Q, demo = Qdemo(frame)
		if demo then
			return "demo"
		end
		
		local i = 1
		local sd = require("Module:Wikidane/select")
		while true do
			local pid = frame.args[i]
			if not pid then
				return
			end
			
			local pid, qid, prop = sd.selectProperty(pid, {}, Q)
			if qid then
				return pid
			end
			
			i = i + 1
		end
	end,

	["Tytuł"] = function(frame)
		local Q, demo = Qdemo(frame)
		local emptyCat = frame.args["kategoria brak"]
		local attrs = frame.args["pole"]
		local props = frame.args["cecha"] or resources.defaultTitle2Property
		local text1 = frame.args[1]
		local text2 = frame.args[2]
		local text3 = frame.args[3]
		
		if isNullOrWhiteSpace(text1) then
			text1 = false
		end
		if isNullOrWhiteSpace(text2) then
			text2 = false
		end
		if isNullOrWhiteSpace(text3) then
			text3 = false
		end

		local demo1 = false
		if text1 then
			demo1 = mw.ustring.match(text1, "^{{{(.-)}}}$")
		end
		local demo2 = false
		if text2 then
			demo2 = mw.ustring.match(text2, "^{{{(.-)}}}$")
		end
		local demo3 = false
		if text3 then
			demo3 = mw.ustring.match(text3, "^{{{(.-)}}}$")
		end

		local Q, demo = Qdemo(frame)

		local builder = mw.html.create()
		builder:wikitext("|+")
		if attrs and (#attrs > 0) then
			builder:wikitext(" ", attrs, " | ")
		end

		local titleWithText = false
		local function appendPart(class)
			if titleWithText then
				builder:tag("br")
			end
			
			titleWithText = true
			return builder:tag("span"):addClass(class)
		end
		
		local label = false
		if demo and demo1 then
			appendPart(resources.classTitle1):wikitext("{{{", demo1, "&#x7C;", imageWDdemo("Etykieta"), "}}}")
		elseif demo then
			appendPart(resources.classTitle1):wikitext(imageWDdemo("Etykieta"))
		elseif text1 and (#text1 > 0) then
			appendPart(resources.classTitle1):wikitext(text1)
		else
			label = mw.wikibase.label(Q)
			if label then
				appendPart(resources.classTitle1):wikitext(label)
			end
		end
		
		local props1 = {}
		local props2 = {}
		for propid in string.gmatch(props, "%S+") do
			table.insert(props1, propid)
			table.insert(props2, "&#x7C;")
			table.insert(props2, imageWDdemo(propid))
		end
		props2 = table.concat(props2, "")
		
		mw.text.split(props, "%s")
		if demo and demo2 then
			appendPart(resources.classTitle2):wikitext("{{{", demo2, props2, "}}}")
		elseif demo and (#props1 > 0) then
			appendPart(resources.classTitle2):wikitext("{{{", props2, "}}}")
		elseif text2 and (#text2 > 0) then
			appendPart(resources.classTitle2):wikitext(text2)
		elseif #props1 > 0 then
			local pid, qid, prop
			for _, propid in ipairs(props1) do
				pid, qid, prop = P(frame, Q, propid)
				if qid and prop then
					local text2 = require("Moduł:Wikidane/format").run(frame, pid, prop)
					if text2 then
						local lang = mw.getContentLanguage()
						local l = label and lang:caseFold(label) or label
						local t1 = text1 and lang:caseFold(text1) or text1
						local t2, _ = mw.ustring.gsub(text2, "</?[A-Za-z]+ ?[^<>]*/?>", "") -- remove HTML tags
						t2 = lang:caseFold(t2)
						if (t2 ~= t1) and (t2 ~= l) then
							appendPart(resources.classTitle2):wikitext(text2)
							break
						end
					end
				end
			end
		end
		
		if text3 and (#text3 > 0) then
			appendPart(resources.classTitle3):wikitext(text3)
		end
		
		if not titleWithText then
			-- use page title
			local title = mw.title.getCurrentTitle()
			local text = title.text
			local nodisambig = mw.ustring.match(text, "^(.-)%s+%([^%(%)]+%)$")
			if nodisambig and (#nodisambig > 0) then
				text = nodisambig
			end
			
			appendPart(resources.classEmpty):wikitext(text, emptyCategory(frame, emptyCat))
		end
		
		if not titleWithText then
			-- no text
			return
		end
		
		builder:wikitext("\n")
		return builder:allDone()
	end,

	["Grafika"] = function(frame)
		local add = frame.args["dodaj"]
		add = (add == nil) or (#add > 0)
		if not add then
			return
		end
		
		local function formatFile(file, alt, format, description)
			local result = {}
			table.insert(result, "[[Plik:")
			table.insert(result, file)
			if format and (#format > 0) then
				table.insert(result, "|")
				table.insert(result, format)
				if mw.ustring.match(format, "^%s*alt%s*=") or mw.ustring.match(format, "|%s*alt%s*=") then
					alt = false
				end
			end
			if alt and (#alt > 0) then
				table.insert(result, "|alt=")
				table.insert(result, alt)
			end
			if description and (#description > 0) then
				table.insert(result, "|")
				table.insert(result, description)
			end
			
			table.insert(result,"]]")
			return table.concat(result)
		end

		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local cell = frame.args["pole"]
		local format = frame.args["format"]
		
		local function loadPicture(file, description, fileProperty, descProperty, defaultFormat)
			if file == "nie" then
				return
			end
			
			if isNullOrWhiteSpace(file)	then
				file = false
				description = false
			elseif isNullOrWhiteSpace(description) then
				description = false
			end
			
			if isNullOrWhiteSpace(fileProperty) then
				fileProperty = false
				descProperty = false
			elseif isNullOrWhiteSpace(descProperty) then
				descProperty = false
			end
			
			local alt = false
			local desc = false
			if fileProperty then
				alt = mw.wikibase.label(fileProperty)
			end
			
			local demoFile = false
			local demoDescription = false
			if file then
				demoFile = mw.ustring.match(file, "^{{{(.-)}}}$")
			end
			if description then
				demoDescription = mw.ustring.match(description, "^{{{(.-)}}}$")
			end
			
			if not demo and (not file or demoFile) and fileProperty then
				local pid, qid, prop = P(frame, Q, fileProperty)
				if pid and qid and prop then
					for _, v in ipairs(prop) do
						if v.mainsnak and (v.mainsnak.snaktype == "value") and (v.mainsnak.datatype == "commonsMedia") and v.mainsnak.datavalue and (v.mainsnak.datavalue.type == "string") then
							local commonMedia = v.mainsnak.datavalue.value
							if not isNullOrWhiteSpace(commonMedia) then
								file = commonMedia
								alt = mw.wikibase.label(v.mainsnak.property)
								desc = require("Moduł:Wikidane/format/qualifiers").TEXT1(v, nil, "P2096")
								break
							end
						end
					end
				end
			
				if file and descProperty then
					pid, qid, prop = P(frame, Q, descProperty)
					if pid and qid and prop then
						local v = require("Moduł:Wikidane/format").run(frame, pid, prop)
						if not isNullOrWhiteSpace(v) then
							description = v
						end
					end
				end
			end
		
			if not demo and file then
				return {
					formatFile(file, alt, defaultFormat, desc or description),
					description or desc
				}
			end
		
			if demo and (demoFile or fileProperty) then
				return {
					formatFile(makeDemoArg(true, demoFile, imageWDdemo(fileProperty)), alt, format or defaultFormat, false),
					makeDemoArg(true, demoDescription, imageWDdemo(demoProperty))
				}
			end
		end

		local args = {
			file = "grafika", description = "opis grafiki", fileProperty = "cecha", descProperty = "cecha opisu", defaultFormat = "240x240px",
			fileN = "%d. grafika", descriptionN = "%d. opis grafiki", filePropertyN = "%d. cecha", descPropertyN = "%d. cecha opisu", defaultFormatN = "100x100px",
		}
		
		local bigImage = loadPicture(frame.args[args.file], frame.args[args.description], frame.args[args.fileProperty], frame.args[args.descProperty], args.defaultFormat)
		mw.logObject(bigImage, "bigImage")
		local smallImages = {}
		local index = 1
		while true do
			local file = frame.args[mw.ustring.format(args.fileN, index)]
			local description = frame.args[mw.ustring.format(args.descriptionN, index)]
			local fileProperty = frame.args[mw.ustring.format(args.filePropertyN, index)]
			local descProperty = frame.args[mw.ustring.format(args.descPropertyN, index)]
			if not file and not fileProperty then
				break
			end
			
			index = index + 1
			local image = loadPicture(file, description, fileProperty, descProperty, args.defaultFormatN)
			if image then
				table.insert(smallImages, image)
			end
		end
		
		local result = {}		
		if bigImage then
			table.insert(result, iboxSpan(false, table.concat(bigImage, "<br />"), row, cell))
		end
		
		if #smallImages > 0 then
			local index = 1
			table.insert(result, '|-')
			table.insert(result, row)
			table.insert(result, '\n|colspan="2" padding="0" ')
			table.insert(result, cell)
			table.insert(result, '|\n{| class="ibox2"\n')
			
			-- display images in pairs
			while (index + 1) <= #smallImages do
				local image1 = smallImages[index + 0]
				local image2 = smallImages[index + 1]
				-- both files must exists
				table.insert(result, '|-\n|')
				table.insert(result, image1[1])
				table.insert(result, '\n|')
				table.insert(result, image2[1])
				table.insert(result, '\n')
				-- descriptions are optional
				if image1[2] or image2[2] then
					table.insert(result, '|-\n|')
					table.insert(result, image1[2] or "")
					table.insert(result, '\n|')
					table.insert(result, image2[2] or "")
					table.insert(result, '\n')
				end
				
				-- next pair
				index = index + 2
			end
			
			-- display last odd image
			if index == #smallImages then
				local image = smallImages[index]
				table.insert(result, '|-\n|colspan=2|')
				table.insert(result, image[1])
				table.insert(result, '\n')
				if image[2] then
					table.insert(result, '|-\n|colspan=2|')
					table.insert(result, image[2])
					table.insert(result, '\n')
				end
			end
		
			table.insert(result, '|-\n|}\n|-\n')
		end
		if #result > 0 then
			return table.concat(result)
		end
	end,
	
	["Grupa"] = function(frame)
		local Q, demo = Qdemo(frame)
		local emptyCat = frame.args["kategoria brak"]
		local header = frame.args["nagłówek"]
		local headerRow = frame.args["wiersz nagłówka"]
		local headerCell = frame.args["pole nagłówka"]
		local lineClass = frame.args["klasa kreski"]
		local result = {}
		
		local append = function(text)
			if (#result == 0) and header then
				local cell = headerCell
				if #header == 0 then
					cell = addClass(headerCell, resources.classEmpty)
					header = emptyCategory(frame, emptyCat)
				elseif not demo and mw.ustring.match(header, "^{{{(.-)}}}$") then
					cell = addClass(headerCell, resources.classMissingArg)
				end
				
				table.insert(result, iboxSpan(true, header, headerRow, cell))
			end
		
			table.insert(result, text)
		end
		
		local total = false
		local sep = false
		local i = 1
		while true do
			local arg = frame.args[i]
			if not arg then
				break
			end
			
			i = i + 1
			arg = string.match(arg, "^(.-)%s*$") -- trim remaing space
			if arg == "-" then
				sep = true
			elseif #arg > 0 then -- real content
				local next = false
				for line in mw.text.gsplit(arg, "\n%f[|!]", false) do
					if next then
						append("\n")
					end
					
					next = true
					if sep and (#line >= 2) and (string.byte(line, 1) == 124) and (string.byte(line, 2) == 45) then
						-- row with separator line
						local class = string.match(line, 'class="(.-)"')
						local newClass = resources.classSeparator
						if lineClass and (#lineClass > 0) then
							newClass = newClass.." "..lineClass
						end
						
						if class then
							line = string.gsub(line, 'class="', 'class="'..newClass.." ", 1)
						else
							line = mw.text.trim(line)..' class="'..newClass..'"'
						end
					else
						-- content or row without separator line
						sep = false
					end
					
					append(line)
				end
			end
		end
	
		return table.concat(result)
	end,
	
	["Blok"] = function(frame)
		local Q, demo = Qdemo(frame)
		local headerRow = frame.args["wiersz nagłówka"]
		local headerCell = frame.args["pole nagłówka"]
		local row = frame.args["wiersz"]
		local label = frame.args["nagłówek"]
		local value, cell, demovalue, propid = InputData(frame, Q, demo)

		if label == "-" then
			label = false
			row = addClass(row, resources.classSeparator)
		elseif label and (#label == 0) then
			label = false
		elseif not label and propid then
			label = propertyLabel(frame, propid)
		end
		
		local demolabel = false
		if label then
			demolabel = mw.ustring.match(label, "^{{{(.-)}}}$")
		end
		
		local text = false
		if demo and demovalue and propid then
			text = "{{{"..demovalue.."&#x7C;"..imageWDdemo(propid).."}}}"
		elseif demo and propid then
			text = "{{{"..imageWDdemo(propid).."}}}"
		elseif demo and demolabel then
			text = "{{{"..demovalue.."}}}"
		elseif value then
			text = value
		end
		
		if not text then
			return
		end
		
		local header
		if label == false then
			header = false
		elseif label and (#label > 0) then
			header = label
		elseif demo and demolabel and propid then
			header = "{{{"..demolabel.."&#x7C;"..imageWDdemo("label").."}}}"
		elseif demo and propid then
			header = "{{{"..imageWDdemo("label").."}}}"
		elseif demo and demolabel then
			header = "{{{"..demolabel.."}}}"
		elseif propid then
			header = "{{{nagłówek}}}"..resources.catMissingLabel
		elseif demo then
			header = "{{{nagłówek}}}"
		end
		
		local result = {}
		if header then
			table.insert(result, iboxSpan(true, header, headerRow, headerCell))
		end
		
		table.insert(result, iboxSpan(false, text, row, cell))
		return table.concat(result)
	end,

	["Wiersz"] = function(frame)
		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local label = frame.args["etykieta"]
		local value, cell, demovalue, propid = InputData(frame, Q, demo)

		if label and (#label == 0) then
			label = false
		end
		
		if not label and propid then
			label = propertyLabel(frame, propid)
		end
		
		local demolabel = false
		if label then
			demolabel = mw.ustring.match(label, "^{{{(.-)}}}$")
		end
		
		local builder = mw.html.create()
		builder:wikitext("|-")
		if row and (#row > 0) then
			builder:wikitext(" ", row, " | ")
		end

		builder:wikitext("\n!")
		
		if label and (#label > 0) then
			builder:wikitext(label)
		elseif demo and demolabel and propid then
			builder:wikitext("{{{", demolabel, "&#x7C;", imageWDdemo("label"), "}}}")
		elseif demo and propid then
			builder:wikitext("{{{", imageWDdemo("label"), "}}}")
		elseif demo and demolabel then
			builder:wikitext("{{{", demolabel, "}}}")
		elseif propid then
			builder:wikitext("{{{etykieta}}}", resources.catMissingLabel)
		else
			builder:wikitext("{{{etykieta}}}")
		end
		
		builder:wikitext("\n|")
		if cell and (#cell > 0) then
			builder:wikitext(cell)
			builder:wikitext("|")
		end
		
		if demo and demovalue and propid then
			builder:wikitext("{{{", demovalue, "&#x7C;", imageWDdemo(propid), "}}}")
		elseif demo and propid then
			builder:wikitext("{{{", imageWDdemo(propid), "}}}")
		elseif demo and demovalue then
			builder:wikitext("{{{", demovalue, "}}}")
		elseif value then
			builder:wikitext(value)
		else
			return
		end
		
		builder:wikitext("\n|-")
		return builder:allDone()
	end,
	
	["Wiersz2"] = function(frame)
		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local label = frame.args["etykieta"]
		local label1 = frame.args["etykieta 1"]
		local label2 = frame.args["etykieta 2"]
		local value1, cell, demovalue1, propid1 = InputData(frame, Q, demo, 1, "cecha 1")
		local value2, _, demovalue2, propid2 = InputData(frame, Q, demo, 2, "cecha 2")

		if label and (#label == 0) then
			label = false
		end
		
		if not label and propid1 and propid2 then
			label = propertyLabel(frame, propid1, propid2)
		end

		if label1 and (#label1 == 0) then
			label1 = false
		end
		
		if not label1 and propid1 then
			label1 = propertyLabel(frame, propid1)
		end

		if label2 and (#label2 == 0) then
			label2 = false
		end
		
		if not label2 and propid2 then
			label2 = propertyLabel(frame, propid2)
		end

		local demolabel1 = false
		if label1 then
			demolabel1 = mw.ustring.match(label1, "^{{{(.-)}}}$")
		end
		
		local demolabel2 = false
		if label2 then
			demolabel2 = mw.ustring.match(label2, "^{{{(.-)}}}$")
		end
		
		local builder = mw.html.create()
		builder:wikitext("|-")
		if row and (#row > 0) then
			builder:wikitext(" ", row, " | ")
		end

		builder:wikitext("\n!")
		
		if demo then
			if label and (#label > 0) then
				builder:wikitext(label)
			else
				if label1 and (#label1 > 0) then
					builder:wikitext(label1)
				elseif demolabel1 and propid1 then
					builder:wikitext("{{{", demolabel1, "&#x7C;", imageWDdemo("label1"), "}}}")
				elseif propid1 then
					builder:wikitext("{{{", imageWDdemo("label1"), "}}}")
				elseif demolabel1 then
					builder:wikitext("{{{", demolabel1, "}}}")
				elseif propid1 then
					builder:wikitext("{{{etykieta 1}}}", resources.catMissingLabel)
				else
					builder:wikitext("{{{etykieta 1}}}")
				end
				builder:wikitext(" i ")
				if label2 and (#label2 > 0) then
					builder:wikitext(label2)
				elseif demolabel2 and propid2 then
					builder:wikitext("{{{", demolabel2, "&#x7C;", imageWDdemo("label2"), "}}}")
				elseif propid2 then
					builder:wikitext("{{{", imageWDdemo("label2"), "}}}")
				elseif demolabel2 then
					builder:wikitext("{{{", demolabel2, "}}}")
				elseif propid2 then
					builder:wikitext("{{{etykieta 2}}}", resources.catMissingLabel)
				else
					builder:wikitext("{{{etykieta 2}}}")
				end
			end
		elseif value1 and value2 and label then
			builder:wikitext(label)
		elseif value1 and value2 and label1 and label2 then
			builder:wikitext(label1, " i ", label2)
		elseif value1 and value2 then
			builder:wikitext("{{{etykieta}}}", resources.catMissingLabel)
		elseif value1 and label1 then
			builder:wikitext(label1)
		elseif value1 then
			builder:wikitext("{{{etykieta 1}}}", resources.catMissingLabel)
		elseif value2 and label2 then
			builder:wikitext(label2)
		elseif value2 then
			builder:wikitext("{{{etykieta 2}}}", resources.catMissingLabel)
		else
			return
		end

		builder:wikitext("\n|")
		if cell and (#cell > 0) then
			builder:wikitext(cell)
			builder:wikitext("|")
		end
		
		local br = true
		if demo and demovalue1 and propid1 then
			builder:wikitext("{{{", demovalue1, "&#x7C;", imageWDdemo(propid1), "}}}")
		elseif demo and propid1 then
			builder:wikitext("{{{", imageWDdemo(propid1), "}}}")
		elseif demo and demovalue1 then
			builder:wikitext("{{{", demovalue1, "}}}")
		elseif value1 then
			builder:wikitext(value1)
		else
			br = false
		end
		
		if demo and demovalue2 and propid2 then
			if br then builder:tag("br") end
			builder:wikitext("{{{", demovalue2, "&#x7C;", imageWDdemo(propid2), "}}}")
		elseif demo and propid2 then
			if br then builder:tag("br") end
			builder:wikitext("{{{", imageWDdemo(propid2), "}}}")
		elseif demo and demovalue2 then
			if br then builder:tag("br") end
			builder:wikitext("{{{", demovalue2, "}}}")
		elseif value2 then
			if br then builder:tag("br") end
			builder:wikitext(value2)
		end
		
		builder:wikitext("\n|-")
		return builder:allDone()
	end,
	
	["Fragment"] = function(frame)
		local Q, demo = Qdemo(frame)
		local value, unused, demovalue, propid = InputData(frame, Q, demo)
		local text = false
		if demo and demovalue and propid then
			text = "{{{"..demovalue.."&#x7C;"..imageWDdemo(propid).."}}}"
		elseif demo and propid then
			text = "{{{"..imageWDdemo(propid).."}}}"
		elseif demo and demolabel then
			text =  "{{{"..demovalue.."}}}"
		elseif value then
			return value
		end
		
		return text and '|-\n|colspan="2"|'..text.."\n" or ""
	end,
	
	["Drzewo"] = function(frame)
		local Q, demo = Qdemo(frame)
		local headerRow = frame.args["wiersz nagłówka"]
		local headerCell = frame.args["pole nagłówka"]
		local header = frame.args["nagłówek"]
		local row = frame.args["wiersz"] or 'class="tree"'
		local cell = frame.args["pole"]
		
		local text = false
		if demo then
			text = imageWDdemo("'''Skrypt Lua'''")
		else
			if not Q then
				local entity = mw.wikibase.getEntity()
				if not entity then
					return
				end
				
				Q = entity.id
			end
			
			text = require("Module:Wikidane/Tree").classTree(frame, Q)
		end
		
		if not text then
			return
		end
		
		if header == "-" then
			header = false
			row = addClass(row, resources.classSeparator)
		elseif header and (#header == 0) then
			label = false
		end
		
		local result = {}
		if header then
			table.insert(result, iboxSpan(true, header, headerRow, headerCell))
		end
		
		table.insert(result, iboxSpan(false, text, row, cell))
		return table.concat(result, "")
	end,

	["Projekt"] = function(frame)
		local Q, demo = Qdemo(frame)
		local entity = mw.wikibase.getEntity(Q)
		local standardLink = function(sitelink)
			return entity and entity.sitelinks and entity.sitelinks[sitelink] and entity.sitelinks[sitelink].title
		end
		local standardProp = function(pid)
			local pid, qid, prop = require("Module:Wikidane/select").selectProperty(pid, {}, Q)
			if prop and prop[1] then
				local snak = prop[1].mainsnak
				if (snak.snaktype == "value") and (snak.datatype == "string") then
					return snak.datavalue.value
				end
			end
		end
		local demoProp = function(sitelink, arg)
			local demovalue = false
			if arg then
				demovalue = mw.ustring.match(arg, "^{{{(.-)}}}$")
			end
			
			local result = {}
			if demovalue then
				table.insert(result, "&#8203;") -- wrap here
				table.insert(result, "{{{")
				table.insert(result, demovalue)
				table.insert(result, "&#x7C;&#8203;")
				table.insert(result, imageWDdemo(sitelink))
				table.insert(result, "}}}&#8203;")
			else
				table.insert(result, "&#8203;")
				table.insert(result, imageWDdemo(sitelink))
				table.insert(result, "&#8203;")
			end
			
			return table.concat(result)
		end
		local projects = {
			{
				arg = "wikipedia",
				icon = "wikipedia",
				text = function()
					if demo then
						return "Wikipedia w języku [[:d:Property:P424|P424]]"
					end
					
					local wikilang = arg or standardProp("P424")
					if wikilang == "pl" then
						return "Wikipedia w [[Wikipedia:Strona główna|języku polskim]]"
					end
					
					if wikilang then
						return mw.ustring.format("Wikipedia w [[:%s:|języku %s]]", wikilang, mw.loadData("Module:Lang/data")[wikilang].miejscownik)
					end
				end,
			},
			{
				arg = "c",
				icon = "commons",
				text = function(arg)
					local link = false
					if demo then
						link = demoProp("commonswiki", arg)
					elseif arg then
						link = arg
					else
						link = standardLink("commonswiki")
						if not link then
							local cat = standardProp("P373")
							if cat then
								link = "Category:"..cat
							else
								--or standardProp("P910") -- main category article
							end
						end
					end
				
					if link then
						return mw.ustring.format("[[commons:%s|Multimedia w Wikimedia Commons]]", link)
					end
				end,
			},
			{
				arg = "n",
				icon = "wikinews",
				text = function(arg)
					local link = demo and demoProp("plwikinews", arg) or (arg or standardLink("plwikinews"))
					if link then
						return mw.ustring.format("[[n:%s|Wiadomości w Wikinews]]", link)
					end
				end,
			},
			{
				arg = "q",
				icon = "wikicytaty",
				text = function(arg)
					local link = demo and demoProp("plwikiquote", arg) or (arg or standardLink("plwikiquote"))
					if link then
						return mw.ustring.format("[[q:%s|Teksty w Wikicytatach]]", link)
					end
				end,
			},
			{
				arg = "s",
				icon = "wikiźródła",
				text = function(arg)
					local link = demo and demoProp("plwikisource", arg) or (arg or standardLink("plwikisource"))
					if link then
						return mw.ustring.format("[[s:%s|Teksty w Wikiźródłach]]", link)
					end
				end,
			},
			{
				arg = "wikt",
				icon = "wikisłownik",
				text = function(arg)
					-- nie ma jeszcze linków w Wikidanych
					local link = arg or (demo and "" or false)
					if link then
						return mw.ustring.format("[[wikt:%s|Hasło w Wikisłowniku]]", link)
					end
				end,
			},
			{
				arg = "wikispecies",
				icon = "wikispecies",
				text = function(arg)
					local link = demo and demoProp("specieswiki", arg) or (arg or standardLink("specieswiki"))
					if link then
						return mw.ustring.format("[[wikispecies:%s|Systematyka w Wikispecies]]", link)
					end
				end,
			},
			{
				arg = "voy",
				icon = "wikipodróże",
				text = function(arg)
					local link = demo and demoProp("plwikivoyage", arg) or (arg or standardLink("plwikivoyage"))
					if link then
						return mw.ustring.format("[[voy:%s|Informacje w Wikipodróżach]]", link)
					end
				end,
			},
			{
				arg = "b",
				icon = "wikibooks",
				text = function(arg)
					local link = demo and demoProp("plwikibooks", arg) or (arg or standardLink("plwikibooks"))
					if link then
						return mw.ustring.format("[[b:%s|Książki w Wikibooks]]", link)
					end
				end,
			},
			{
				arg = "wikt:cat",
				icon = "wikisłownik",
				text = function(arg)
					if demo then
						return "W Wikisłowniku: słownik języka [[:d:Property:P424|P424]]"
					end
					
					if arg then
						local data = mw.loadData("Module:Lang/data")[standardProp("P424") or ""]
						return mw.ustring.format("W Wikisłowniku: [[wikt:Kategoria:%s|słownik języka%s]]", arg, data and (" "..data["dopełniacz"]) or "")
					end
				end,
			},
		}
	
		local result = {}
		for _, project in ipairs(projects) do
			local param = frame.args[project.arg]
			if param then
				local text = project.text(#param > 0 and param or nil)
				if text then
					if #result == 0 then
						local header = frame.args["nagłówek"] or resources.defaultProjectHeader
						if #header > 0 then
							table.insert(result, iboxSpan(true, header, frame.args["wiersz nagłówka"], frame.args["pole nagłówka"]))
						end
					end
					
					--local icon = "<div style=\"float:left; margin-right: 0.5em\">[[Plik:"..require("Module:Ikona").plik(project.icon).."|20px]]</div>"
					local icon = "[[Plik:"..require("Module:Ikona").plik(project.icon).."|20px|link=|alt=]]"
					table.insert(result, iboxSpan(false, icon..text, addClass(frame.args["wiersz"], resources.classSisterProject), frame.args["pole"]))
				end
			end
		end
		
		return table.concat(result, "")
	end,

}