Moduł:Brudnopis/Paweł Ziemian/NoWrap

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Brudnopis/Paweł Ziemian/NoWrap/opis

local resources = require("Moduł:NoWrap/resources")

function CloneTable(value)
	local result = {}
	for i, v in ipairs(value) do
		result[i] = v
	end
	
	return result
end

local Scanner = {}
local ScannerMetatable = { __index = Scanner }

function Scanner.new()
	local object = {
		patterns = {},
		prefixes = {},
		suffixes = {},
	}
	
	return setmetatable( object, ScannerMetatable )
end

function Scanner:addPrefixes(prefixes)
	for s in mw.ustring.gmatch((prefixes or "").." ", resources.prefix.word) do
		self.prefixes[s] = true
	end
end

function Scanner:addSuffixes(suffixes)
	for s in mw.ustring.gmatch(" "..(suffixes or ""), resources.suffix.word) do
		self.suffixes[s] = true
	end
end

function Scanner:addPattern(pattern)
	if not pattern or (#pattern == 0) then
		return false
	end
	
	table.insert(self.patterns, { pattern = pattern, groups = {} })
end

function Scanner:addDatePatterns(prefixPattern, suffixPattern)
	
	local prefixGroup = string.match(prefixPattern, "%(.+%)") and "prefix" or nil
	local suffixGroup = string.match(suffixPattern, "%(.+%)") and "suffix" or nil
	
	for i, v in ipairs(resources.dates) do
		local g = CloneTable(v.groups)
		if prefixGroup then table.insert(g, 1, prefixGroup) end
		if suffixGroup then table.insert(g, suffixGroup) end
		
		local p = table.concat({"(", resources.prefix.float, prefixPattern, v.pattern, suffixPattern, resources.suffix.float, ")", }, "")
		table.insert(self.patterns, { pattern = p, groups = g })
	end
end

function Scanner:acceptPrefix(value)
	return self.prefixes[value]
end

function Scanner:acceptSuffix(value)
	return self.suffixes[value]
end

function Scanner:acceptDay(value)
	local d = tonumber(value) or 0
	return (d >= 1) and (d <= 31)
end

function Scanner:acceptMonth(value)
	return resources.months[value]
end

function Scanner:acceptYear(value)
	local y = tonumber(value) or 0
	return y > 0
end

Scanner.validators = {
	["prefix"] = Scanner.acceptPrefix,
	["day"] = Scanner.acceptDay,
	["month"] = Scanner.acceptMonth,
	["year"] = Scanner.acceptYear,
	["suffix"] = Scanner.acceptSuffix,
}

function Scanner:noWrapItem(case, full, ...)
	local p = { ... }
	for i, v in ipairs(self.patterns[case].groups) do
		local validator = self.validators[v]
		if validator and not validator(self, p[i]) then
			return false
		end
	end
	
	local result = mw.html.create("span")
		:css("white-space", "nowrap")
		:wikitext(full)
	table.insert(self.fixed, tostring(result))
	return string.format(resources.marker.format, #self.fixed)
end

function Scanner:NoWrap(text)
	self.fixed = {}
	
	for i, v in ipairs(self.patterns) do
		local s, m
		s, m, _ = pcall(mw.ustring.gsub, text, v.pattern, function(...) return self:noWrapItem(i, ...) or nil end)
		if s then
			text = m
		else
			mw.logObject(text, "Scanner:NoWrap ERROR")
			mw.logObject(v, "FAILED pattern")
		end
	end

	text = string.gsub(text, resources.marker.pattern, function(n) return self.fixed[tonumber(n)] end)
	return text
end

return {
	
["Wzór"] = function(frame)
	local text = frame.args[1]
	if not text then
		return
	end
	
	local scanner = Scanner.new()
	local i = 2
	while scanner:addPattern(frame.args[i]) do
		i = i + 1
	end
	
	return scanner:NoWrap(text)
end,

Daty = function(frame)
	local text = frame.args[1]
	if not text then
		return
	end
	
	local scanner = Scanner.new()
	scanner:addDatePatterns("", "")
	return scanner:NoWrap(text)
end,

DatyOdDo = function(frame)
	local text = frame.args[1]
	if not text then
		return
	end
	
	local scanner = Scanner.new()
	scanner:addPrefixes("od do")
	scanner:addDatePatterns(resources.prefix.word, "")
	scanner:addDatePatterns("", "")
	return scanner:NoWrap(text)
end,

}