Moduł:Źródło

Z Nonsensopedii, polskiej encyklopedii humoru

local p = {}
local allLanguages, allInterwikis
local tools = require('Moduł:Narzędzia')
local linki = require('Moduł:Linki')
local hasPlaintext = false		-- paskudny global, nk naprawi

local invalidSources = {
	'nieznan',
	'brak',
	'nie wiem',
	'internet',
	'z sieci',
	'po sieci'
}

local badUrls = {
	'wikipedia',
	'nonsa',
	'nonsensopedia',
	'commons',
	'uncyclopedia'
}

local function isSourceInvalid(a)
	a = mw.ustring.lower(a)
	
	for _,val in ipairs(invalidSources) do
		if mw.ustring.find(a, val, 1, true) then
			return true
		end
	end
	
	return false
end

-- funkcja pomocnicza do scalania tabel atrybutów
local function appendSubtable(t, key, value)
	t[key] = t[key] or {}
	table.insert(t[key], value)
end

local function addWarning(t, value)
	appendSubtable(t, 'Ma ostrzeżenie źródła', value)
	return ' ' .. mw.smw.info(value, 'warning')
end

-- przetwórz link wewnętrzny
local function processInternal(val, desc, surelink)
	local props = {}
	local parts = mw.text.split(mw.ustring.gsub(val, '^:', ''), ':', true)
	local warn = ''
	
	local iw, ns, title = '', '', ''
	if #parts == 0 then
		return props, s .. addWarning(props, 'Nierozpoznany format źródła')
	elseif #parts == 1 then
		title = parts[1]
	elseif #parts == 2 then
		-- zakładamy że IW zawsze odnoszą się do jakiejś strony nie w głównej ns
		-- np. commons:File:Coś.jpg, :en:File:xd.png
		ns = parts[1]
		title = parts[2]
	elseif #parts >= 3 then
		iw = parts[1]
		ns = parts[2]
		title = table.concat(parts, ':', 3)
	end
	
	local linkTitle = mw.text.trim(desc)
	iw = mw.ustring.lower(mw.text.trim(iw))
	ns = mw.ustring.lower(mw.text.trim(ns))
	title = mw.text.trim(title)
	
	local function doInterwiki(prefix)
		if allLanguages == nil then
			allLanguages = mw.language.fetchLanguageNames()		-- lazy
			allInterwikis = mw.site.interwikiMap()
		end
		
		if allLanguages[prefix] then
			appendSubtable(props, 'Ma źródło z innej wersji językowej', val)
			
			if mw.ustring.sub(val, 1, 1) ~= ':' then
				val = ':' .. val
			end
		elseif prefix == 'commons' then
			appendSubtable(props, 'Ma źródło z Wikimedia Commons', val)
		elseif allInterwikis[prefix] then
			appendSubtable(props, 'Ma źródło interwiki', val)
		else
			return false
		end
		
		return true
	end
	
	-- interwiki
	if iw ~= '' then
		if not doInterwiki(iw) then
			warn = addWarning(props, 'Nieznany prefiks interwiki')
		end
	-- wewnętrzne (raczej)
	else
		if ns == 'plik' or ns == 'grafika' or ns == 'file' or ns == 'image' then
			if mw.ustring.sub(val, 1, 1) ~= ':' then
				val = ':' .. val
			end
			
			appendSubtable(props, 'Ma źródło wewnętrzne (plik)', val)
		elseif ns ~= '' and mw.site.namespaces[ns] then
			appendSubtable(props, 'Ma źródło wewnętrzne', val)
		elseif doInterwiki(ns) then
			-- no to fajnie, gituwina
		elseif surelink then
			if ns == '' then
				appendSubtable(props, 'Ma źródło wewnętrzne', val)
			else
				warn = addWarning(props, 'Nierozpoznany format źródła')
			end
		elseif mw.ustring.find('praca własna', mw.ustring.lower(val), 1, true) then
			appendSubtable(props, 'Ma źródło', 'praca własna')
			appendSubtable(props, 'Jest pracą własną', true)
			hasPlaintext = true
			return props, val
		else
			-- lepszego pomysłu nie mamy
			appendSubtable(props, 'Ma źródło', val)
			hasPlaintext = true
			return props, val
		end
	end
	
	if linkTitle == '' then
		appendSubtable(props, 'Ma źródło', val)
		return props, '[[' .. val .. ']]' .. warn
	else
		appendSubtable(props, 'Ma źródło', linkTitle)
		return props, '[[' .. val .. '|' .. linkTitle .. ']]' .. warn
	end
end

-- przetwórz link zewnętrzny
local function processExternal(val, desc)
	local props = {}
	local val2 = mw.ustring.gsub(val, ';', '\\;')
	local warn = ''
	
	for _,v in ipairs(badUrls) do
		if mw.ustring.find(val, v, 1, true) then
			warn = addWarning(props, 'Zbędny link zewnętrzny')
		end
	end
	
	if mw.text.trim(desc) ~= '' then
		appendSubtable(props, 'Ma źródło', desc)
		appendSubtable(props, 'Ma źródło zewnętrzne', val2 .. ';' .. mw.ustring.gsub(desc, ';', '\\;'))
		return props, '[' .. val .. ' ' .. desc .. ']' .. warn
	else
		appendSubtable(props, 'Ma źródło zewnętrzne', val2)
		return props, '[' .. val .. ']' .. addWarning(props, 'Brak nazwy źródła')
	end
end

-- do użytku prosto w Information
function p.source(frame)
	local s = frame.args[1]
	
	if s == nil then
		error("Ta funkcja wymaga podania dokładnie jednego argumentu.")
	end
	
	local props, s = p.process(s)
	mw.smw.set(props)
	return s
end

-- zwraca listę atrybutów SMW do ustawienia i tekst wyjściowy
function p.process(s)
	hasPlaintext = false
	local props = {}
	local strings = {}
	if not s then s = '' end
	-- wycinamy wszelkie szablony, które mogły tu wleźć niepostrzeżenie
	s = mw.ustring.gsub(s, '<table.-</table>', '')
	s = mw.ustring.gsub(s, '%[%[.-z podanymi wskazówkami co do źródła *%]%]', '')
	s = mw.text.trim(s)
	
	local function mergeStuff(wProps, wS)
		table.insert(strings, wS)
		
		-- scalanie tabel atrybutów
		for p, pv in pairs(wProps) do
			for i, ppv in ipairs(pv) do
				appendSubtable(props, p, ppv)
			end
		end
	end
	
	local c = 0
	
	-- linki zewnętrzne
	for v, d in pairs(linki.wExtLink(s)) do
		mergeStuff(processExternal(v, d))
		c = c + 1
	end
	
	-- podwójne kwadratowe
	for v, d in pairs(linki.wLink(s)) do
		mergeStuff(processInternal(v, d, true))
		c = c + 1
	end
	
	local plainC, invalid = 0, false
	if c == 0 then
		-- linków nie było, potraktujmy to jako plaintext
		local parts = mw.text.split(s, ',', true)
		
		for i, p in ipairs(parts) do
			local pp = mw.text.trim(p)
			
			if pp ~= '' then
				mergeStuff(processInternal(pp, '', false))
				plainC = plainC + 1
				
				if not invalid and isSourceInvalid(pp) then
					invalid = true
				end
			end
		end
	end
	
	local out = ''
	
	if #strings == 0 then
		appendSubtable(props, 'Nie ma podanego źródła', 'true')
		
		if mw.ustring.match(s, '[^%s]') ~= nil then
			appendSubtable(props, 'Ma ostrzeżenie źródła', 'Zachowany oryginalny opis źródła')
		end
		
		out = s
	else
		if plainC == 1 and not hasPlaintext then
			out = strings[1]
		else
			-- czyścimy z linków, by ustalić czy coś straciliśmy w procesie
			local clean = mw.ustring.gsub(s, '%[%[.-|?.-%]%]', '')
			clean = mw.ustring.gsub(clean, 'https?://[^%s]*', '')
			clean = mw.ustring.gsub(clean, '%[[^%[]-%]', '')
			
			if mw.ustring.match(clean, '[^%s:,;]') ~= nil then
				appendSubtable(props, 'Ma ostrzeżenie źródła', 'Zachowany oryginalny opis źródła')
				out = s
			else
				out = table.concat(strings, ', ')
			end
		end
		
		appendSubtable(props, 'Ma opis źródła', out)
	end
	
	if invalid then
		out = out .. addWarning(props, 'Niepotrzebny opis źródła')
	end
	
	if not props['Jest pracą własną'] then
		appendSubtable(props, 'Jest pracą własną', false)
	end
	
	return props, out
end

return p