Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]

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

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

PoliczLinki

edytuj

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

Liczba artykułów między

edytuj

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

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

są interwiki

edytuj

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

contentMatch

edytuj

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

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

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

TEMPLATENAME

edytuj

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

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

FormatPluralNum

edytuj

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
Powyższy opis jest dołączany ze strony Moduł:Łatki/opis. (edytuj | historia)
Edytorzy mogą eksperymentować w brudnopisie (edytuj | różnice) tego modułu.
Zobacz podstrony tego modułu.
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