Moduł:Łatki

Z Wikipedii, wolnej encyklopedii
 Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]

Moduł techniczny do obsługi różnorakich wysokospecjalistycznych funkcji lub szablonów.

Plik[edytuj kod]

Funkcja poprawiająca niestandardowe wywołania grafiki w infoboksach.

PoliczLinki[edytuj kod]

Funkcja implementująca szablon {{Policz linki}}.

Liczba artykułów między[edytuj kod]

Funkcja obliczająca liczbę wikilinków między zadanymi znacznikami. Nazwy znaczników podaje się w pierwszym i drugim parametrze. W kodzie strony znaczniki muszą być umieszczone w komentarzu HTML.

Numerowanie w tabeli[edytuj kod]

Funkcja implementująca szablon {{Numerowanie w tabeli}}.

są interwiki[edytuj kod]

Funkcja zwracająca liczbę interwiki do projektów siostrzanych i innych wersji językowych. Wykorzystanie w {{EK}} do generowania dodatkowego ostrzeżenia.

contentMatch[edytuj kod]

Funkcja zwracająca wynik pierwszego wyrażenia regularnego Lua w treści źródłowej strony.

  • Wyszukiwarka szablonów, które jej używają jest tutaj.

Interwiki[edytuj kod]

Funkcja do generowania większej liczby interwiki przez wykorzystanie cechy „uważa się za to samo co”.

Z[edytuj kod]

Funkcja generująca przyimek „z” lub „ze” zależnie od podanego i następującego po nim słowa. Zastosowana w {{przekierowanie}}.

TEMPLATENAME[edytuj kod]

Funkcja zwracająca nazwę szablonu, w którym jest wywołana.

SUBST[edytuj kod]

Funkcja sprawdzająca czy szablon jest wywołany przez subst:.

FormatPluralNum[edytuj kod]

Funkcja wspomagająca generowanie formatowanie liczby naturalnej z opisem w połączeniu z opcjonalnym dodaniem odpowiedniej formy rzeczownika.

{{#invoke:Łatki|FormatPluralNum|liczba|forma 1|forma 2|forma 3|forma 4}}

Przykłady:

{{#invoke:Łatki|FormatPluralNum|chyba 1 |skarpetka|skarpetki|skarpetek}} → chyba 1 skarpetka
{{#invoke:Łatki|FormatPluralNum|mam 2002 |skarpetka|skarpetki|skarpetek}} → mam 2002 skarpetki
{{#invoke:Łatki|FormatPluralNum|około 50000 |skarpetka|skarpetki|skarpetek}} → około 50 000 skarpetek
local m = {}

function m.Plik(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Plik").id
	if not frame then
		return nil
	end
 
	local args = frame.args
	if not args then
		mw.log("brak argumentów")
		return nil
	end
 
	local file = args[1]
	if not file then
		mw.log("brak pliku")
		return nil
	end
	
	local multipleFiles = ""
	if string.match(file, "%]%s*%[") then
		multipleFiles = "[[Kategoria:Łatki - Kilka plików]]"
	end
 
	if string.match(file, "^%s*%[%[") then
		mw.log("to jest link: "..file)
		return file .. "[[Kategoria:Infoboksy – błedne wywołania plików]]"..multipleFiles
	end
 
	if string.match(file, "^%s*%[") then
		mw.log("to jest link zewnętrzny: "..file)
		return file .. "[[Kategoria:Łatki - Plik zewnętrzny]]"..multipleFiles
	end
 
	local builder = {}
	table.insert(builder, "[[Plik:")
	for i, v in ipairs(args) do
		if i > 1 then
			table.insert(builder,"|")
		end
 
		table.insert(builder,v)
	end

	table.insert(builder, "]]")
	local result = table.concat(builder, "")
	mw.log("wynik: "..result)	
	return result
end

m.PoliczLinki = function(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/PoliczLinki").id
	local pf = frame:getParent()
	local text = frame.args[1] or pf.args[1]
	local threshold = tonumber(frame.args["próg"] or pf.args["próg"]) or 1
	if text then
		text = mw.text.trim(text)
		local _, count = mw.ustring.gsub(text, "(%[%[[^%[%]]-%]%])", "%1")
		if count >= threshold then
			local lang = mw.getContentLanguage()
			local number = lang:formatNum(count)
			local articles = lang:convertPlural(count, { "artykuł", "artykuły", "artykułów" })
			return text .. "<small> ("..number.."&nbsp;"..articles..")</small>"
		else
			return text
		end
	end
end

m["Liczba artykułów między"] = function(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Liczba artykułów między").id
	local pf = frame:getParent()
	local start = frame.args[1] or pf.args[1]
	if not start then
		return
	end
	
	local stop =  frame.args[2] or pf.args[2]
	if not stop then
		return
	end
	
	local content = mw.title.getCurrentTitle():getContent()
	if not content then
		return
	end
	
	local startPattern = "<!--"..start.."-->"
	local startPosition = string.find(content, startPattern, 1, true)
	if not startPosition then
		return
	end
	
	startPosition = startPosition + #startPattern
	
	local stopPattern = "<!--"..stop.."-->"
	local stopPosition = string.find(content, stopPattern, startPosition, true)
	if not stopPosition then
		return
	end
	
	stopPosition = stopPosition - 1
	if startPosition >= stopPosition then
		return
	end
	
	local text = string.sub(content, startPosition, stopPosition)
	local _, count = mw.ustring.gsub(text, "(%[%[[^%[%]]-%]%])", "%1")
	local _, files = mw.ustring.gsub(text, "(%[%[Plik:[^%[%]]-%]%])", "%1")
	count = count - files
	
	local threshold = tonumber(frame.args["próg"] or pf.args["próg"]) or 1
	if count < threshold then
		return
	end
	
	local lang = mw.getContentLanguage()
	local number = lang:formatNum(count)
	local articles = lang:convertPlural(count, { frame.args[4] or pf.args[4] or "artykuł", frame.args[5] or pf.args[6] or "artykuły", frame.args[6] or pf.args[6] or "artykułów" })

	local result, _ = string.gsub(frame.args[3] or pf.args[3] or "<small>($1)</small>", "$1", number.."&nbsp;"..articles)
	return result
end

m["Numerowanie w tabeli"] = function(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Numerowanie w tabeli").id
	local counter = 0
	local result = {}
	local pf = frame:getParent()
	local i = 1
 
	table.insert(result, "{") 
	while true do
		local object = pf:getArgument(i)
		if object then
			object = object:expand()
		else
			break
		end
 
		if object then
			table.insert(result, "|")
 
			local length = #object
			if length > 0 then
				if string.byte(object,1) == 35 then
	 				counter = counter + 1
					local counterText = counter..". "
					local userText = length > 1 and string.sub(object, 2, length) or ""
					object = counterText..userText
				end
			end
 
			table.insert(result, object)
			i = i + 1
		else
			break
		end
	end
 
	table.insert(result, "|}")
	return table.concat(result, "")
end

m["są interwiki"] = function(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/są interwiki").id
	local count = 0
	local entity = mw.wikibase.getEntity()
	if entity and entity.sitelinks then
		for k, v in pairs(entity.sitelinks) do
			if k ~= "plwiki" then
				count = count + 1
			end
		end
	end
 
	return count > 0 and count or ""
end

function m.contentMatch(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/contentMatch").id
	mw.logObject(frame.args.pagename, "frame.args.pagename")
	mw.logObject(frame.args.namespace, "frame.args.namespace")
	local pagename = frame.args.pagename
	local namespace = tonumber(frame.args.namespace or 0) or 0
	mw.logObject(pagename, "pagename")
	mw.logObject(namespace, "namespace")
	local title = (pagename and (#pagename > 0)) and mw.title.makeTitle(namespace, pagename) or mw.title.getCurrentTitle()
	mw.logObject(title, "title")
	local content = title and title:getContent() or false
	if not content then
		mw.log("no content")
		return
	end
	
	local i = 1
	while true do
		local p = frame.args[i]
		if not p or (#p==0) then
			mw.log("no pattern "..i)
			return
		end
		
		local result = mw.ustring.match(content, p)
		if result then
			mw.log("match "..result)
			return result
		end
		
		mw.log("no match "..p)
		i = i + 1
	end
end

function m.contentPureTextSize(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/contentPureTextSize").id
	local content = mw.title.getCurrentTitle():getContent()
	if not content then
		mw.log("no content")
		return 0
	end

	-- wyrzucamy szablony (i szablony w szablonach)
	content = mw.ustring.gsub(content, "%{%{[^%{%}]+%}%}", "");
	content = mw.ustring.gsub(content, "%{%{[^%{%}]+%}%}", "");
	content = mw.ustring.gsub(content, "%{%{[^%{%}]+%}%}", "");
	content = mw.ustring.gsub(content, "%{%{[^%{%}]+%}%}", "");

	-- ciąg pusty na jedną spację
	content = mw.ustring.gsub(content, "%s+", " ");

	-- refy bez treści
	content = mw.ustring.gsub(content, "<ref[^<>]*%/>", "");
	-- większość refów z treścią
	content = mw.ustring.gsub(content, "<ref[^<>]*>[^<>]<%/ref>", "");

	return mw.ustring.len(content);
end

function m.Interwiki(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Interwiki").id
	local qid = frame.args.id
	local data = mw.wikibase.getEntity(qid)
	if not data then
		return -- brak danych -> kategoria?
	end
	
	local links = {}
	local appendLink = function(lang, title)
		if not links[lang] then
			links[lang] = { title }
		else
			table.insert(links[lang], title)
		end
	end
	
	local knownLanguages = mw.loadData("Module:Lang/data")
	local extractLinks = function(data)
		if data.sitelinks then
			for k, v in pairs(data.sitelinks) do
				local lang = string.sub(k, 1, -5)
				local project = string.sub(k, -4)
				if (project == "wiki") and knownLanguages[lang] then
					appendLink(lang, v.title)
				end
			end
		end
	end

	extractLinks(data)
	if data.claims and data.claims.P460 then
		for _, v in ipairs(data.claims.P460) do
			if v.mainsnak.snaktype == "value" then
				local seeid = "Q"..tostring(v.mainsnak.datavalue.value["numeric-id"])
				local seedata = mw.wikibase.getEntity(seeid)
				if seedata then
					extractLinks(seedata)
				end
			end
		end
	end

	local result = {}
	local content = mw.title.getCurrentTitle():getContent()
	for k, v in pairs(links) do
		local pattern = "%[%["..mw.ustring.gsub( k, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )..":[^%[%]|]+%]%]"
		local interwiki = mw.ustring.match(content, pattern)
		if not interwiki and (not data.sitelinks or not data.sitelinks[k.."wiki"]) then
			table.insert(result, "[[")
			table.insert(result, k)
			table.insert(result, ":")
			table.insert(result, v[1])
			table.insert(result, "]]")
		end
	end

	return table.concat(result, "")
end

function m.Z(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Z").id
	local ze = {
		"^%s*[Mm][Nn][Ii][Ee]$",
		"^%s*[Mm][Nn][Ii][Ee]%s",
		"^%s*[Mm][Nn][Ąą]$",
		"^%s*[Mm][Nn][Ąą]%s",
		"^%s*[Ss][Oo][Bb][Ąą]$",
		"^%s*[Ss][Oo][Bb][Ąą]%s",
		"^%s*[Ss][Zz][BbCcĆćDdFfGgHhJjKkLlŁłMmNnŃńPpRrSsŚśTtWwZzŹźŻż]",
		"^%s*[Ss][BbCcĆćDdFfGgHhJjKkLlŁłMmNnŃńPpRrSsŚśTtWwŹźŻż]",
		"^%s*[ŹźZz][BbCcĆćDdFfGgHhJjKkLlŁłMmNnŃńPpRrSsŚśTtWwZzŹźŻż]",
		"^%s*%[%[[Ss][Zz][BbCcĆćDdFfGgHhJjKkLlŁłMmNnŃńPpRrSsŚśTtWwZzŹźŻż]",
		"^%s*%[%[[Ss][BbCcĆćDdFfGgHhJjKkLlŁłMmNnŃńPpRrSsŚśTtWwŹźŻż]",
		"^%s*%[%[[ŹźZz][BbCcĆćDdFfGgHhJjKkLlŁłMmNnŃńPpRrSsŚśTtWwZzŹźŻż]",
	}

	local text = frame.args[1]
	if text then
		for _, regex in ipairs(ze) do
			if mw.ustring.match(text, regex) then
				_ = mw.title.new("Module:Łatki/Wywołanie funkcji/ze").id
				return "ze"
			end
		end
	end

	return "z"
end

function m.TEMPLATENAME(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/TEMPLATENAME").id
	local templateTitle = mw.title.new(frame:getParent():getTitle())
	return (templateTitle and (templateTitle.namespace == 10)) and templateTitle.text or nil
end

function m.SUBST(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/SUBST").id
	local title = mw.title.getCurrentTitle()
	mw.logObject(title.text, "title.text")
	local prefixedTitleName = mw.ustring.match(title.prefixedText, "^(.-)/opis")
		or mw.ustring.match(title.prefixedText, "^(.-)/test")
		or mw.ustring.match(title.prefixedText, "^(.-)/brudnopis")
		or title.prefixedText
	if mw.isSubsting() or (prefixedTitleName == frame:getParent():getTitle()) or (frame:getParent().args["usprawiedliwienie na brak 'subst:'"] == "przykład wywołania szablonu przez transkluzję poza stronami testowymi") then
		return frame.args[1]
	end

	mw.log("Brak 'subst:' w wywołaniu '"..frame:getParent():getTitle().."'")
	return "[[Kategoria:Brak 'subst:' w wywołaniu szablonu]]"
end

function m.Format(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Format").id
	local templateTitle = mw.title.new(frame:getParent():getTitle())
	
	local params = {}
	local i = 1
	while i do
		local arg = frame.args[i]
		if arg then
			table.insert(params, arg)
			i = i + 1
		else
			i = false
		end
	end
	
	if #params > 0  then
		return mw.ustring.format(unpack(params))
	end
end

function m.SimpleDuplicates(frame)
	local result = {}
	local wikitext = mw.title.getCurrentTitle():getContent()
	if not wikitext then
		-- no page
		return
	end
	
	while true do
		local templateIterator = mw.ustring.gmatch(wikitext, "{{[^{}]+}}")
		while true do
			local template = templateIterator()
			if not template then
				-- no more templates
				break
			end
	
			mw.log(template)
			local parameters = {}
			local patch, _ = mw.ustring.gsub(template, "(%[%[[^%[%]|]+)|([^%[%]|]-%]%])", "%1<nowiki>&x7C;</nowiki>%2")
			local chunks = mw.text.split(patch, "|")
			local i = 2 -- skip first item which is template name
			local auto = 0
			local emited = false
			while i <= #chunks do
				local chunk = chunks[i]
				local name, value = mw.ustring.match(chunk, "%s*(.-)%s*=(.*)")
				if not name then
					auto = auto + 1
					name = tostring(auto)
					value = chunk
				end
				
				value = mw.ustring.gsub(value, "<nowiki>&x7C;</nowiki>", "|")
				
				if not parameters[name] then
					parameters[name] = { value }
				else
					-- duplicated parameter
					if not emited then
						emited = {}
						table.insert(emited, "<tt>"..mw.text.nowiki(template).."</tt>")
					end
					
					if #parameters[name] == 1 then
						table.insert(emited, name..": "..mw.text.nowiki(parameters[name][1]))
					end
						
					table.insert(parameters[name], value)
					table.insert(emited, name..": "..mw.text.nowiki(value))
				end

				i = i + 1
			end
			
			if emited then
				table.insert(result, table.concat(emited, "<br /> → "))
			end
		end
	
		local count = false
		wikitext, count = mw.ustring.gsub(wikitext, "{{[^{}]+}}", "€")
		if count == 0 then
			break
		end
	end

	if #result > 0 then
		return "<ul><li>"..table.concat(result, "</li><li>").."</li></ul>"
	end
end

function m.NavboxWidth(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/NavboxWidth").id
	local style = frame.args[1]
	if string.match(style, ";%s*float%s*:%s*right%s*;") then
		return string.match(style, ";%s*width%s*:%s*([0-9]+px)%s*;")
			or string.match(style, ";%s*width%s*:%s*([0-9]+em)%s*;")
			or string.match(style, ";%s*width%s*:%s*(auto)%s*;")
	end
end

function m.NoWrapDates(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/NoWrapDates").id
	local yes = "tak"
	local fixedDates = {}
	local fixedMarkerFormat = "\127_FixedDate%d_\127"
	local fixedMarkerPattern = "\127_FixedDate(%d+)_\127"
	local patterns = {
		"%[%[(%d%d?)%s+(%l+)%]%]%s+%[%[(%d%d%d%d) p%.n%.e%.%]%]",
		"(%d%d?)%s+(%l+)%s+(%d%d%d%d) p%.n%.e%.",
		"%[%[(%d%d?)%s+(%l+)%]%]%s+%[%[(%d%d%d%d)%]%]",
		"(%d%d?)%s+(%l+)%s+(%d%d%d%d)",
	}
	local months = require("Moduł:Cytuj/dane").monthparser
	
	function customPattern(variant, plain)
		if not variant then
			return ""
		elseif #variant == 0 then
			return "%s*"
		elseif plain then
			return mw.ustring.gsub( variant, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
		else
			return variant
		end
	end
	
	local text = frame.args[1]
	local plain = (frame.args.plain == yes) or (frame.args.plain == 1)
	local attachLeft = "("..customPattern(frame.args.left, plain)
	local attachRight = customPattern(frame.args.right, plain)..")"

	function NoWrapDate(full, day, month, year)
		local d = tonumber(day)
		local m = months[month]
		local y = tonumber(year)
		
		if not months[month] or (d <= 0) or (d > 31) then
			return null
		end
		
		local result = mw.html.create("span")
			:css("white-space", "nowrap")
			:wikitext(full)
		table.insert(fixedDates, tostring(result))
		local fixedIndex = #fixedDates
		return string.format(fixedMarkerFormat, fixedIndex)
	end
	
	for i, v in ipairs(patterns) do
		text, _ = mw.ustring.gsub(text, attachLeft..v..attachRight, NoWrapDate)
	end
	
	text = string.gsub(text, fixedMarkerPattern, function(n) return fixedDates[tonumber(n)] end)
	return text
end

function m.Encode(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/Encode").id
	local html = frame.args.html
	return html and mw.text.encode(html) or html
end

function m.FormatPluralNum(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/FormatPluralNum").id
	local t = frame.args[1]
	local p = {}
	for i = 2, 5 do
		if not frame.args[i] then
			break
		end
		
		table.insert(p, frame.args[i])
	end
	
	local s, e = mw.ustring.find(t, frame.args.pattern or "[0-9][0-9 ]*")
	local prefix = ''
	local number = t
	local suffix = ''
	local extra = ''
	if s then
		while mw.ustring.sub(t, e, e) == ' ' do
			e = e - 1
		end
		prefix = s > 1 and mw.ustring.sub(t, 1, s-1) or ''
		number = mw.ustring.gsub(mw.ustring.sub(t, s, e), ' ', '')
		suffix = e < mw.ustring.len(t) and mw.ustring.sub(t, e + 1) or ''
	end

	local lang = mw.language.getContentLanguage()
	local count = lang:parseFormattedNumber(number)
	if count then
		local r0 = mw.ustring.match(number, "[%.,]([0-9]-0+)$")
		number = lang:formatNum(count)
		if r0 then
			local l, r = mw.ustring.match(number, "(.-),([0-9]+)$")
			if not r then
				number = number..','..r0
			elseif #r < #r0 then
				number = l..','..r0
			end
		end
	end
	
	if #p > 0 then
		extra = count and lang:convertPlural(count, p) or p[#p]
	end
	
	local result = {prefix, number, suffix, extra}
	return table.concat(result,'')
end

function m.PoliczElementy(frame)
	mw.logObject(frame:getParent():getTitle(), "parent:title")
	_ = mw.title.new("Module:Łatki/Wywołanie funkcji/PoliczElementy").id
	local t = frame.args[1]
	local min = tonumber(frame.args.min)
	local max = tonumber(frame.args.max)
	local t0, c0 = string.gsub(t, "\n[%*:;#]", "") -- elementy listy
	local t1, c1 = string.gsub(t0, "<br ?/?>", "") -- łamane linie
	local t2, c2 = string.gsub(t1, "\n\n", "") -- akapity
	local c = c0 + c1 + c2 + (#t2 > 0 and 1 or 0) -- ostatnia niepusta linia
	if min and (c < min) then return end
	if max and (c > max) then return end
	return tostring(c)
end

function m.Wrap(frame)
	
	local blockPatterns = {
		"\n[*:;#]", -- wikilista
		"\n\n", -- wikiakapit
		"\n{|", -- wikitabela
		"<[Pp][ >]", -- <p>
		"<[Hh][Rr1-6][ >]", -- <hr>, <h1>..<h6>
		"<[UuOoDd][Ll][ >]", -- <ul><ol><dl>
		"<[Ll][Ii][ >]", -- <li>
		"<[Dd][DdTt][ >]", -- <dd><dt>
		"<[Dd][Ii][Vv][ >]", -- <div>
		"<[Tt][Aa][Bb][Ll][Ee][ >]", -- <table>
		"<[Bb][Ll][Oo][Cc][Kk][Qq][uu][Oo][Tt][Ee][ >]", -- <blockquote>
	}
	
	local text = frame.args[1]
	if not text or (#text == 0) then
		mw.logObject(pattern, "WRAP: empty")
		return
	end
	
	local lead = frame.args.leadInline or ""
	local tail = frame.args.tailInline or ""

	for i, pattern in ipairs(blockPatterns) do
		local catch = mw.ustring.match(text, pattern)
		if catch then
			mw.logObject(pattern, "WRAP: pattern")
			mw.logObject(catch, "WRAP: catch")
			lead = frame.args.leadBlock or ""
			tail = frame.args.tailBlock or ""
			break
		end
	end
	
	mw.logObject(lead,"WRAP: lead")
	mw.logObject(tail,"WRAP: tail")
	return lead..text..tail
end

return m