UWAGA
Strona jest ponownie oddana do uzytku po zabiegach konfiguracyjnych. Jeśli zobaczą Państwo na niej jakieś błedy techniczne, prosimy o ich zgłoszenie.

Większość artykułów w portalu to nasze własne teksty z kluczowych dziedzin związanych z naszą misją. Spora część materiałów pochodzi też z polskiej wersji Wikipedii, gdzie były odrzucone ze względu na politykę redaktorów (przeczytaj o krytyce Wikipedii). Są też i takie, które zostały przeniesione na nasze strony, gdyż stanowią istotne uzupełnienie merytorycznej treści naszego serwisu. Wszystkie artykuły podlegają edycji przez naszych Użytkowników, dlatego ich wersje mogą się różnić od prezentowanych na innych witrynach.

Moduł:Infobox

Z Wedapedia
Przejdź do nawigacji Przejdź do wyszukiwania

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Infobox/opis

require("strict")
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 == nil)
		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 ns == 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
			return "[[:d:Property:"..pid.."|"..pid.."]]"
		end
	
		return "<span class=\"wdimgdemo\">"..pid.."</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

local function SecondaryInfobox(templateTitle, message)
	local contents = mw.title.getCurrentTitle():getContent()
	local infoboxPattern = "{{ *(%f[%a][%a ]-%f[ ] infobox)%s*|"
	local start = 1
	while true do
		mw.logObject(start, "Kolejny:start")
		local s, e, n = mw.ustring.find(contents, infoboxPattern, start, false)
		if not s then
			break
		end
		
		mw.logObject({s, e, n}, "Kolejny:find{s e n}")
		local prefix = mw.ustring.match(n, "^(%a-):")
		mw.logObject(prefix, "Kolejny:prefix")
		local ns = 10
		if prefix then
			prefix = mw.getCurrentLang():ucfirst(prefix)
			ns = mw.site.namespaces[prefix] or ns
		end
		mw.logObject(ns, "Kolejny:ns")
		local infoboxTitle = mw.title.new(n, ns)
		mw.logObject(infoboxTitle, "Kolejny:infoboxTitle")
		if templateTitle == infoboxTitle then
			mw.logObject(start == 1 and "" or message, "Kolejny:return")
			return start == 1 and "" or message
		end
		
		start = e
	end
	
	mw.log("Kolejny: BRAK")
	return mw.title.getCurrentTitle().namespace == 0
		and "?" -- tego przypadku nie powinno być w przestrzeni głównej
		or false -- a poza nią to nie ma takiego znaczenia
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,
	
	["Kolejny"] = function(frame)
		local message = frame.args[1]
		if not message or (#mw.text.trim(message) == 0) then
			message = "tak"
		end
		
		local templateTitle = mw.title.new(frame:getParent():getTitle())
		return SecondaryInfobox(templateTitle, message)
	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 function removeLinks(text)
				--mw.logObject(text, "RemoveLinks:input")
				if text then
					text = mw.ustring.gsub(text, "%s+", " ") -- compact white characters into one space
					text = mw.ustring.gsub(text, "%[https?://[^%[%]%s|]+%]", "") -- remove LZ
					text = mw.ustring.gsub(text, "%[https?://[^%[%]%s|]+ ([^%[%]|]+)%]", "%1") -- remove LZ, leave description
					text = mw.ustring.gsub(text, "%[%[[^%[%]|]+|([^%[%]|]*)%]%]", "%1" ) -- remove wikilinks, leave description
					text = mw.ustring.gsub(text, "%[%[([^%[%]|]*)%]%]", "%1" ) -- remove wikilinks, leave description
					text = mw.ustring.gsub(text, "%s+", " ") -- compact white characters into one space again
					text = mw.text.nowiki(text)
				end
				
				--mw.logObject(text, "RemoveLinks:output")
				return text
			end

			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, removeLinks(alt))
			end
			if description and (#description > 0) then
				table.insert(result, "|")
				table.insert(result, removeLinks(description))
			end
			
			table.insert(result,"]]")
			return table.concat(result)
		end
		
		local function checkIfFileExists(file)
			local pattern, _ = mw.ustring.gsub( file, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
			pattern, _ = mw.ustring.gsub(pattern, "[ _]", "[ _]")
			pattern = "%[%[%s*(%a+)%s*:"..pattern.."%s*[%]|]"
			--mw.logObject(pattern, "Grafika:checkIfFileExists PATTERN")
			local contents = mw.title.getCurrentTitle():getContent()
			local start = 1
			while true do
				--mw.logObject(start, "Grafika:checkIfFileExists NEXT")
				local s, e, n = mw.ustring.find(contents, pattern, start, false)
				if not s then
					--mw.logObject(file, "Grafika:checkIfFileExists FALSE")
					return false
				end
				
				--mw.logObject({n,file}, "Grafika:checkIfFileExists{n,file}")
				local title = mw.title.new(file, n)
				if title and (title.namespace == 6) then
					--mw.logObject(file, "Grafika:checkIfFileExists TRUE")
					return true
				end
				
				start = e
			end
		end
		
		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local cell = frame.args["pole"]
		local format = frame.args["format"]
		local imageTitle = false
		local secondary = false
		local callingTemplate = frame:getParent():getTitle()
		if mw.title.new(callingTemplate) == mw.title.new("Szablon:Infobox grafika") then
			imageTitle = frame:getParent().args["tytuł grafiki"]
			secondary = frame:getParent().args["kolejny"]
		else
			imageTitle = frame.args["tytuł grafiki"]
			if (#callingTemplate > 8) and (mw.ustring.sub(callingTemplate, -8) == " infobox") then
				secondary = SecondaryInfobox(callingTemplate, callingTemplate)
			end
		end

		if format and (#format <= 0) then
			format = nil
		end
		
		mw.logObject(secondary,"secondary")
		
		local wdExists = false
		
		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 = nil
			local patched = false
			if fileProperty then
				alt = mw.wikibase.label(fileProperty)
			end
			
			local demoFile = false
			local demoDescription = false
			if file then
				demoFile = mw.ustring.match(file, "^{{{(.-)}}}$")
				if not demoFile then
					file = mw.ustring.gsub(file, "%s*[Pp]lik%s*:%s*", "Plik:")
					file = mw.ustring.gsub(file, "%s*[Ff]ile%s*:%s*", "Plik:")
					file = mw.ustring.gsub(file, "%s*[Gg]rafika%s*:%s*", "Plik:")
					file = mw.ustring.gsub(file, "%s*[Ii]mage%s*:%s*", "Plik:")
					if mw.ustring.match(file, "^Plik:(.*)") then
					    file = mw.ustring.match(file, "^Plik:(.*)")
					    patched = true
					elseif mw.ustring.match(file, "%[%[Plik:([^%[%]|]+)[|%]]") then
					    file = mw.ustring.match(file, "%[%[Plik:([^%[%]|]+)[|%]]")
					    patched = true
					end
				end
			end
			if description then
				demoDescription = mw.ustring.match(description, "^{{{(.-)}}}$")
			end
			
			if not demo and (not file or demoFile) and fileProperty then
				if secondary and (#secondary > 0) then
					mw.logObject(secondary, "Grafika: nie ładuję obrazka z Wikidanych na drugim lub kolejnym infoboksie")
					return
				end
				
				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
								if checkIfFileExists(commonMedia) then
									mw.logObject(commonMedia, "Grafika: obrazek, który jest oferowany w Wikidanych, już jest umieszczony w kodzie strony")
									wdExists = true
									return
								end
								
								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, format or defaultFormat, desc or description)..(patched and resources.catPatchedFile or ""),
					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(descProperty))
				}
			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 wdExists and secondary and (#secondary == 0) and (mw.title.getCurrentTitle().namespace == 0) then
			table.insert(result, '|- style="display:none"\n| colspan="2" |"')
			table.insert(result, resources.catIgnoreImage)
			table.insert(result, '\n')
		end
		
		if bigImage then
			if imageTitle and (#imageTitle > 0) then
				table.insert(bigImage, 1, '<span style="font-weight: bold>'..imageTitle..'</span>')
			end
			
			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,

	["Państwo"] = function(frame)
		local Q, demo = Qdemo(frame)
		if not Q then
			Q = mw.wikibase.getEntityIdForCurrentPage()
		end
		if not Q then
			return
		end
		
		local statements = mw.wikibase.getBestStatements(Q, "P17")
		local errorCat = frame.args.kategoria
		local link = frame.args.link
		local altlink = frame.args.altlink
		local nazwa = frame.args.nazwa
		local opis = frame.args.opis
		local results = {}
		for i, s in ipairs(statements) do
			local countryName = mw.wikibase.renderSnak(s.mainsnak)
			local templateCountry = mw.title.new("Państwo dane "..countryName, "Szablon")
			local result
			if templateCountry.exists then
				local dependent = frame:expandTemplate{ title = "Terytorium zależne", args = {
					[1] = countryName,
					[2] = countryName
				}}
				if dependent and (#dependent == 0) then
					dependent = nil
				end
				result = frame:expandTemplate{ title = templateCountry.text, args = {
					[1] = "infobox państwo/core",
					wariant = dependent or countryName,
					link = link,
					altlink = altlink,
					nazwa = nazwa,
					rozmiar = i == 1 and opis or "&nbsp;"
				}}
			else -- nie ma szablonu państwa
				result = frame:expandTemplate{ title = "Infobox wiersz", args = {
					[1] = "[[Państwo]]",
					[2] = errorCat.."WD"..tostring(i)..": "..countryName,
					kol2 = 'class="linksInherit" style="background:yellow; color:red;"'
				}}
			end
			if result then
				table.insert(results, result)
			end
		end
		
		return table.concat(results)
	end,

}