Moduł:Narzędzia licencyjne

Z Nonsensopedii, polskiej encyklopedii humoru

local p = {}

function p.showContents(table)
	local string = ""
	for k, v in pairs(table) do
		mw.log(k .. " = " .. v)
		string = string .. type(k) .. " " .. k .. " = " .. v .. "\n"
	end
	return string
end

function p.makeTemplate(name, args, runFunction)
    local code = "<nowiki>{{"
    if runFunction ~= nil then
        -- invoke module
        code = code .. "#invoke:" .. name .. "|" .. runFunction
    else
        -- template
        code = code .. name .. "|"
    end
    for name, value in pairs(args) do
        code = code .. "|" .. name .. "=" .. value
    end
    return "" .. code .. "}}</nowiki>"
end

-- returns name, value from parameter of form abc=def or nil and parameter if name is null
local function parseParameter(param)
    local equalsPos = param:find("=", 1, true)
    if equalsPos == nil then
        return {}, param
    else
        return param:sub(1, equalsPos - 1), param:sub(equalsPos + 1)
    end
end

-- returns template name, table with arguments
function p.stripTemplate(string)
    local arguments = {}
    
    local startingBracePos, endingBracePos = string:find("\{\{.*\}\}")
    if startingBracePos == nil or endingBracePos == nil then
        return string, nil
    end
    
    local templateNameBegin, templateNameEnd = string:find("[^}|]+", startingBracePos + 2)
    local templateName = string:sub(templateNameBegin, templateNameEnd)
    
    local i = templateNameEnd + 2
    local begins = 0
    local argumentString = ""
    local unnamedParameterCounter = 1
    while i < endingBracePos - 1 do
        if string:sub(i, i) == "{" and string:sub(i + 1, i + 1) == "{" then
            begins = begins + 1
        elseif string:sub(i, i) == "}" and string:sub(i + 1, i + 1) == "}" then
            begins = begins - 1
        elseif string:sub(i, i) == "|" and begins == 0 then -- not | inside other template
            -- get argument
            local name, value = parseParameter(argumentString)
            if name == nil then
                name = unnamedParameterCounter
                unnamedParameterCounter = unnamedParameterCounter + 1
            end
            arguments[name] = value
            argumentString = ""
        end
        if not (string:sub(i, i) == "|" and begins == 0) then
            argumentString = argumentString .. string:sub(i, i)
        end
        i = i + 1
    end
    if argumentString ~= "" then
        local name, value = parseParameter(argumentString)
        if name == nil then
            name = unnamedParameterCounter
        end
        arguments[name] = value
    end
    
    return templateName, arguments
end
-- {{domniemanie|{{self|{{PD}}}}}}
-- {{name|param|param2=test|{{test2}}}}
-- {{test|{{test2|{{test3}}}}}}
-- {{test|{{test2|a}}|{{test3|b}}}}

-- zwraca modyfikatory i kod szablonu wewnętrznego
function p.stripLicenseModifierTemplates(string)
	-- przypadek samych nazw szablonów licencji
	if string:find("{{", 1, true) == nil then
		return nil, string
	end
	local template, arguments = string, nil
	local modifiers = {}
	local strippedTemplates = {}
	repeat
		template, arguments = p.stripTemplate(template)
		--mw.log(template)
		--mw.logObject(arguments)
		strippedTemplates[template] = arguments
		if template == "domniemanie" or template == "copydown" then
			template = arguments["lic"]
		end
	until arguments == nil
	
	for name, args in pairs(strippedTemplates) do
		if name == "domniemanie" or mw.ustring.lower(name) == "użytkownik:expert3222/domniemanie" or name == "copydown" then
			modifiers[name] = args
		end
	end
	mw.logObject(strippedTemplates, "Stripped templates")
	return modifiers, template
end

-- https://stackoverflow.com/questions/9790688/escaping-strings-for-gsub
local function escapeRegex(text)
    return text:gsub("([^%w])", "%%%1")
end

function p.getTagEndPosition(code, position, tag)
	tag = mw.ustring.lower(tag)
	--mw.log("Finding end of tag " .. tag)
	local opened = 1
	local currentPos = position
	while true do
		local begin, eend, capture = code:find("<%s*(/?" .. tag .. ").->", currentPos)
		if begin == nil then break end
		currentPos = eend + 1
		if mw.ustring.lower(capture) == "/" .. tag then
			opened = opened - 1
		elseif mw.ustring.lower(capture) == tag then
			opened = opened + 1
		end
		if opened <= 0 then
			--mw.log("Found position: ", begin, eend)
			return begin, eend
		end
	end
	return nil, nil
end

-- returns template and arguments from annotated template code
function p.getTemplateFromCode(code)
	code = code:gsub("'", "\"")
	--mw.log("code = " .. code .. "\n\n")
	local argumentNameRegex = "data%-argument=\"([^\"']+)\""
	local templateNameRegex = "data%-template=\"([^\"']+)\""
	local openingTagRegex = "<%s*([a-zA-Z]+)(.-)>"
	local args = {}
	local lastPos = 1
	local nextParsePosition, templateBegin, templateEnd, templateName
	while true do
		local tagBeginBegin, tagBeginEnd, tagName, tagParams = code:find(openingTagRegex, lastPos)
		--mw.log("tagName, tagParams = ", tagName, tagParams, "\n\n")
		if tagBeginBegin == nil then return nil end
		local tagEndBegin, tagEndEnd = p.getTagEndPosition(code, tagBeginEnd, tagName)
		if tagEndBegin == nil then return nil end
		lastPos = tagBeginEnd + 1
		
		templateBegin = tagBeginEnd
		_, _, templateName = mw.ustring.find(tagParams, templateNameRegex)
		templateEnd = tagEndBegin
		nextParsePosition = tagEndEnd
		if templateName ~= nil then break end
	end
	
	templateName = mw.ustring.lower(templateName)
	local templateCode = code:sub(templateBegin + 1, templateEnd - 1)
	--mw.log("templateCode = " .. templateCode .. "\n\n")
	local lastPos = 1
	while true do
		local tagBeginBegin, tagBeginEnd, tagName, tagParams = templateCode:find(openingTagRegex, lastPos)
		--mw.log("tagName, tagParams = ", tagName, tagParams, "\n\n")
		if tagBeginBegin == nil then break end
		local tagEndBegin, tagEndEnd = p.getTagEndPosition(templateCode, tagBeginEnd, tagName)
		if tagEndBegin == nil then break end
		lastPos = tagBeginEnd + 1
		
		local templateBegin = tagBeginEnd
		local _, _, templateNameInner = mw.ustring.find(tagParams, templateNameRegex)
		
		if templateNameInner ~= nil then templateNameInner = mw.ustring.lower(templateNameInner) end
		
		if templateNameInner ~= nil and templateNameInner ~= templateName then break end
		
		local _, _, argName = mw.ustring.find(tagParams, argumentNameRegex)
		
		local argCode = templateCode:sub(tagBeginEnd + 1, tagEndBegin - 1)
		--mw.log("templateNameInner, argName, argCode = ", templateNameInner, argName, argCode)
		if templateNameInner ~= nil and argName ~= nil and mw.ustring.find(argCode, templateNameRegex) ~= nil then
			local inner = p.getTemplateFromCode(argCode)
			args[argName] = {name = inner.name, args = inner.args}
		elseif templateNameInner ~= nil and argName ~= nil then
			if argCode ~= "" then
				args[argName] = argCode
			end
		end
	end
	mw.log(code, "Code")
	mw.logObject({name = templateName, args = args}, "Processed template")
	return {name = templateName, args = args}, nextParsePosition + 1
end
-- mw.logObject(p.getTemplateFromCode("<!-- begin template domniemanie --><!-- begin arg domniemanie poch --><!-- begin template test --><!-- begin arg test test2 -->abc<!-- end arg test test2 --><!-- end template test --><!-- end arg domniemanie poch --><!-- end template domniemanie -->"))

-- reconstructs template from return value of above function
function p.reconstructTemplateCall(obj)
	local code = "{{" .. obj.name
	for name, value in pairs(obj.args) do
		code = code .. "|" .. name .. "="
		if type(value) ~= "table" then
			code = code .. value
		else
			code = code .. p.reconstructTemplateCall(value)
		end
	end
	
	--mw.log("reconstructed template = " .. code .. "}}")
	return code .. "}}"
end
return p