Permanently protected module
From Wikipedia, the free encyclopedia


require('strict')

local p = {}

local data = mw.loadData('Module:MilAward/data')

local getArgs = require('Module:Arguments').getArgs

local GlobalTemplateArgs = '' -- define as global (to this module) variable



function p.GraphData (frame)

    -- This routine is simply to create the x and y data lines for the graph of number of entries poer country

    -- It iterates through the data, counting the number of entries for each country and then 

    -- create two lines holding those values as comma seperated values

    -- This function should geenerate only two lines containing the  data for the graph and 

    -- should be invoked at the correct place in the graph setup.



    -- Create an empty local table called "StatCount"

    local StatCount = {}

    

    -- Iterate through the data in the table "data"

    for code, record in pairs(data) do

        local country = record.Country

        -- Check if the country is already in StatCount

        if StatCountcountry then

            -- If it is, add one to the count

            StatCountcountry = StatCountcountry + 1

        else

            -- If it isn't, add the country to the table with a value of 1

            StatCountcountry = 1

        end

    end

    local xGraphValues = "| x=" -- Create the start of the x values line for a graph

    local yGraphValues = "| y=" -- Create the start of the y values line for a graph

    -- Iterate through the StatCount table using pairs

    for country, count in pairs(StatCount) do

        xGraphValues = xGraphValues .. ", " .. country -- add the name of the country as a comma seperated value

        yGraphValues = yGraphValues .. ", " .. count -- add the count for the country as a comma seperated value

    end

    local output =  " \n" .. xGraphValues .. " \n" .. yGraphValues .. "\n"

    return output

end

function p.Stats(frame)

    -- Create an empty local table called "StatCount"

    local StatCount = {}

    

    -- Iterate through the data in the table "data"

    for code, record in pairs(data) do

        local country = record.Country

        -- Check if the country is already in StatCount

        if StatCountcountry then

            -- If it is, add one to the count

            StatCountcountry = StatCountcountry + 1

        else

            -- If it isn't, add the country to the table with a value of 1

            StatCountcountry = 1

        end

    end

    

	-- Create an empty table to store the wiki code rows

    local wikiRows = {}

local xGraphValues =''

local yGraphValues =''

    -- Iterate through the StatCount table using pairs

    for country, count in pairs(StatCount) do

        -- Add a row to the wikiRows table with the country and count data

        table.insert(wikiRows, "|-\n|" .. country .. "||" .. count)

         xGraphValues = xGraphValues .. ", " .. country

         yGraphValues = yGraphValues .. ", " .. count

    end



    -- Create the wiki code for the table using the wikiRows table

    local wikiCode = "{| class=\"wikitable sortable col2right\"\n|-\n! Country !! Count\n" .. table.concat(wikiRows, "\n") .. "\n|}"

    local wikiCode = wikiCode .. " \n" .. xGraphValues .. " \n" .. yGraphValues .. "\n"



    -- Return the wiki code

    local tablist= p.PrintStats()

    local output = wikiCode .. "\n\n" .. tablist

    return output

end

function p.PrintStats()

    -- Convert key-value pairs into a list of {code, data[code]} pairs

    local pairsList = {}

    for code, values in pairs(data) do

        table.insert(pairsList, {code, values})

    end



    -- Sort the list based on the "Description" field of each pair

    table.sort(pairsList, function(a, b)

        return a2].Description < b2].Description

    end)



    -- Generate wiki table code for the sorted list

    local tableCode = "{| class=\"wikitable sortable\"\n"

    tableCode = tableCode .. "|-\n"

    tableCode = tableCode .. "! Code !! Old Code !! Description !! Country\n !! Postnom !! Ribbon !! Org\n"



    for i, pair in ipairs(pairsList) do

        local code, values = pair1], pair2

        local oldcode = values.Code or ""

        local country = values.Country or ""

        local description = values.Description or ""

        local class = values.Class or ""

        local postnom = values.PostNom or ""

        local ribbonimage = values.RibbonImage or ""

        local pagelink = values.PageLink or ""

        local note = values.Note or ""

        local org = values.Org or ""



        tableCode = tableCode .. "|-\n"

        tableCode = tableCode .. "|" .. code .. "\n"

        if code == oldcode then

        	tableCode = tableCode .. "| \n"

        else

        	tableCode = tableCode .. "|" .. oldcode .. "\n"

        end

        tableCode = tableCode .. "|[[" .. pagelink .. "|" .. description 

        if string.len(class) > 0 then

        	tableCode = tableCode .. "]] '''(" .. class .. ")'''"

		else

        	tableCode = tableCode .. "]]"

        end

        if string.len(note) > 0 then

            tableCode = tableCode .. mw.getCurrentFrame():expandTemplate{ title = 'Efn', args = {note} } -- Note: Page needs {{notelist}}

        	--tableCode = tableCode .. " <sup>" .. note .. "</sup> " 

        end

        tableCode = tableCode .. "\n"

        tableCode = tableCode .. "|" .. country .. "\n"

        tableCode = tableCode .. "|" .. postnom .. "\n"

        tableCode = tableCode .. "|[[File:" .. ribbonimage .. "|x30px]]\n"

        tableCode = tableCode .. "|" .. org .. "\n"

    end



    tableCode = tableCode .. "|}"

    return tableCode

end

function p.Display(frame)

	-- Take parameters out of the frame and pass them to p._Display(). Return the result.

	local templateArgs = getArgs(frame)

	--local templateArgs = frame.args

	local code = templateArgs1 or 'None'

	local size = templateArgs2 or "40px"

	local namedcode = templateArgs"code"

	if namedcode then 

		code = namedcode

	end

	local namedsize = templateArgs"size"

	if namedsize then

		size = namedsize

	end

	return p._Display(code, size)

end



function p._Display(code, size)

    -- data is loaded globally

    

    local output = ""

            output = output .. " '''Found award with code''': " .. datacode].Code .. "<br />"

            output = output .. "''Code'': " .. datacode].Code .. "<br />"

            output = output .. "''Description'': " .. datacode].Description .. "<br />"

            output = output .. "''Ribbon Image'': " .. datacode].RibbonImage .. "<br />"

            output = output .. "''Post-Nominal'': " .. datacode].PostNom .. "<br />"

            output = output .. "''Page Link'': " .. datacode].PageLink .. "<br />"

            output = output .. "''Country'': " .. datacode].Country .. "<br />"

    return output

end



local function _Ribbon(code, size)

	local ribbonimage=datacode].RibbonImage

	if string.len(size) <1 then 

		size="x12px" -- weasel code. Check that there is a value for size and if not, set the value

	end

	if string.len(ribbonimage)<1 then  -- If there is no ribbonimage defined for the record, then assign a default one.

		ribbonimage = "NOT-AVAILABLE-RIBBON.svg"

	end

    local output = "[[File:" .. ribbonimage .. "|".. size .. "|link=" .. datacode].PageLink .. "|" .. datacode].Description .. " ''" .. datacode].PostNom .. "''" .. "]]" -- .. " [[Category:MilAward Ribbon]]"

    return output

end



function p.Ribbon(frame)

	-- Function extracts the parameters from the frame (passed into the function)

	-- It checks that the first argument is not empty, and returns an error if so

	local templateArgs = getArgs(frame)

	--local templateArgs = frame.args

	local code = templateArgs1 or 'None'

	local size = templateArgs2 or "x12px"

	

    local namedcode = templateArgs"code" -- Check for named argument "code" and overwrite the value in the local variable if it has a value

	if namedcode then 

		code = namedcode

	end



	local namedsize = templateArgs"size" -- Check for named argument "size" and overwrite the value in the local variable if it has a value

	if namedsize then

		size = namedsize

	end



	if string.match(code, "%*") then -- The code field has asterisks in it. Raise an error

		-- code = string.gsub(code, "%*", "x")

		local output = '<span style="color:#d33"> Bad Code: <b>[' .. code .. ']</b>. Replace all * with x</span> [[Category:MilAward Error]]'

		return output

	end -- End if



	if not code or '' == code then

		-- return '<span style="color:#d33">Error: missing positional parameter 1</span>'

		return '<span style="color:#d33"> (Invalid Code: <b>' .. code .. '</b> )</span> [[Category:MilAward Error]]'

	end



--	local code = code:upper() -- DO NOT DO THIS. Code is case sensitive -- Converts the first argument to uppercase

	if not datacode then

		-- return '<span style="color:#d33">Error: invalid positional parameter 1: ' .. code .. '</span>'

		return '<span style="color:#d33"> (Code not found: <b>' .. code .. '</b> )</span> [[Category:MilAward Error]]'

	end

	return _Ribbon (code, size)

end





local function _RibbonDesc(code, size, country, norib, nocat, org)

    -- This routine is where the data is structured for output 

    local output =''

    if norib ~= "yes" then -- They do NOT want the ribbon to display if this is yes

    	output = output .. _Ribbon(code, size) -- Start by getting the ribbon. Call the function designed to do that

    end

    local output = output ..  " [[" .. datacode].PageLink .. "|" .. datacode].Description .. "]] "  -- add the  pagelink and description

    if datacode].Class then

    	if string.len(datacode].Class) > 0 then -- Only add the Class if there is something in the field 

    		output = output .. " (''" .. datacode].Class .. "'') " 

    	end

    end

    if string.len(datacode].PostNom) > 0 then -- Only add the postnom if there is something in the field 

    	 output = output .. " ('''" .. datacode].PostNom .. "''') " 

    end



    if string.len(datacode].Note) > 0 then -- Only add the Note if there is something in the field 

    	output = output .. mw.getCurrentFrame():expandTemplate{ title = 'Efn', args = {datacode].Note} } -- Note: Page needs {{notelist}}

		-- output = output .. "<sup>" .. data[code].Note .. "</sup> " 

    end

    if string.len(country) > 0 then -- if a value for country has been specificed

        if country:upper() ~= datacode].Country:upper() then -- check that the country specificed does NOT equal that on record

            output = output .. " (" .. datacode].Country .. ") " -- add the country code to the end of the output

        end

    end

    if string.len(org) > 0 then -- if a value for org has been specificed

        if org:upper() == "YES" then -- check that it is YES

            if string.len(datacode].Org) > 0 then -- Check there is actually something in the org field

                output = output .. " (''" .. datacode].Org .. "'') " -- add the Org code to the end of the output

            end

        end

    end

    



-- Optimised code. string.len is expensive as is 

local nocat_length = string.len(nocat)

if nocat_length > 1 then -- If ANYTHING has been specified as a value for nocat, then it's true

    -- Do nothing or add to tracking category?

else

    -- Need to exclude adding the recipient category if it is not in mainspace.

    -- for now, that means checking it's not in "Template:" or "User:" space

    local current_title = mw.title.getCurrentTitle()

    local namespace = current_title.nsText

    local namespace_length = string.len(namespace)

    if namespace_length < 2 then

        local recipcat = datacode].RecipCat or "" -- If there is a recipient category specified, then add it to the output

        local categories = {}

        --categories[#categories+1] = " [[Category:MilAward Ribbon Description]]" -- Add tracking Category -- Note commented out

        if string.len(recipcat) > 0 then

            local categoryTitle = mw.title.new('Category:' .. mw.text.trim(recipcat))

            if categoryTitle.exists and not categoryTitle.isRedirect then

                -- category exists and is not a redirect

                categories#categories+1 = " [[Category:" .. recipcat .. "]]"

            else

                -- category does not exist or is a redirect

                -- Add to a tracking Category ???

            end

        end

        output = output .. table.concat(categories)

    end

end



    return output

end



function p.RibbonDesc(frame)

	local templateArgs = getArgs(frame)

	-- local templateArgs = frame.args

    local code = 'Unknown' -- initialise a local variable called code to something rational

    local size = 'x20px' -- initialise a local variable called size to something rational

	if templateArgs1 then code = templateArgs1 end -- check that it is not "nil" before assigning the value 

    if templateArgs2 then size = templateArgs2 end -- Check that it is not "nil" before assigning the value



	local namedcode = templateArgs"code" -- assign tha local variable "namedcode" to the value of the argument called code

	if namedcode then  -- if the assignment of value has worked ie there was actially a parameter called code with a value then 

		code = namedcode -- assign the value found above to the variable "code" overwriting any other value it may have had

	end



	local namedsize = templateArgs"size" -- exactly the same as for "code" above

	if namedsize then

		size = namedsize

	end



    local namedcountry = templateArgs"country" or '' -- if the argument "country" has been passed, assign it to a local variable

    local country = namedcountry

    local norib = templateArgs"norib" or ''

	if not size then size = "x20px" end -- this is a weasel statement meant to assign the default value if the 

                                        -- variable doesn't hold one which should never occur 

	



	if not code or '' == code then -- if thre was no code assigned (field empty) then return an error of invalud code

	--	 '<span style="color:#d33">Error: missing positional parameter 1</span>'

		local output =  '<span style="color:#d33"> (Invalid Code: <b>' .. code .. '</b>)</span>'

        return output

	end

	if string.match(code, "%*") then -- The code field has asterisks in it. Raise an error 

		local output = '<span style="color:#d33"> Bad Code: <b>[' .. code .. ']</b>. Replace all * with x</span> [[Category:MilAward Error]]'

		return output

	end -- End if



--	local code = templateArgs[1]:upper() -- Do not convert to uppercase. Codes are case sensitive

	if not datacode then

	--	return '<span style="color:#d33">Error: invalid positional parameter 1: ' .. code .. '</span>'

		return '<span style="color:#d33"> (Code: <b>' .. code .. '</b> Not found)</span>'

	end



    local nocat= templateArgs"nocat" or '' -- Assign local value for nocat parameter

    local org=templateArgs"org" or '' -- Assign local value for org parameter



	return _RibbonDesc (code, size, country, norib, nocat, org)

end

function p.Stack(frame)

    GlobalTemplateArgs = getArgs(frame)

    -- local size = GlobalTemplateArgs[1] or "x12px"

    local size = "x12px"

    local namedsize = GlobalTemplateArgs"size"

    if namedsize then

        size = namedsize

    else

        size = "x12px"

    end



    local output = ''



    local RibbonList = {}

    for i = 1, 40 do -- 40 is the max number of params that will be examined. 

        local rl = GlobalTemplateArgsi or ""

        if rl ~= "" then

            table.insert(RibbonList, rl)

        end

    end

    local row={}

    for i, rl in ipairs(RibbonList) do

        if rl ~= "" then

            if datarl then -- check whether this is found in the data

			    local rowoutput = _Ribbon(rl, size) 

			    table.insert(row,string.format('%s',rowoutput) )

            end

        end

    end

    output = table.concat(row, " ")



    --output = output .. "[[Category:MilAward Stack]]" -- Add tracking category

    return output

end

function p.DescList(frame)

    local templateArgs = getArgs(frame)

    local size = templateArgs"size" or 'x20px'

    local namedcountry = templateArgs"country" or 'yes'

    local output = '\n'



    for key, value in pairs(templateArgs) do

        if string.len(value) > 1 and datavalue then

                output = output .. "* " .. _RibbonDesc(value, size, namedcountry,'','','') .. "\n"

        end

    end

    return output

end



function p.PostNom(frame)

    local templateArgs = getArgs(frame)

    local size = templateArgs"size" or '85%'

    local sep = templateArgs"sep" or ', '

    if sep == "none" then

        sep = " "

    end

    local output = '<span class="noexcerpt nowraplinks" style="font-size:' .. size .. '; font-weight:normal;">'



    for key, value in pairs(templateArgs) do

        if key ~= "size" and string.len(value) > 1 and datavalue then

            if string.len(datavalue].PostNom) > 1 then

                output = output .. "[[" .. datavalue].PageLink .. "|" ..  datavalue].PostNom .. "]]" .. sep .. ""

            end

        end

    end

    local seplen = (string.len(sep) + 1) * -1 -- Take length of sep, add one to it and make it negative (* -1)

    output = output:sub(1, seplen) -- Remove the trailing seperator

    output = output .. '</span>'



    return output

end



-- Initial code by John Dovey (13 April 2023) [[User:BoonDock]]

return p