Module:MilAward

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 StatCount[country] then -- If it is, add one to the count StatCount[country] = StatCount[country] + 1 else -- If it isn't, add the country to the table with a value of 1 StatCount[country] = 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 StatCount[country] then -- If it is, add one to the count StatCount[country] = StatCount[country] + 1 else -- If it isn't, add the country to the table with a value of 1 StatCount[country] = 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 a[2].Description < b[2].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 = pair[1], pair[2] 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 .. "|" .. 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 --tableCode = tableCode .. " " .. note .. " "        end tableCode = tableCode .. "\n" tableCode = tableCode .. "|" .. country .. "\n" tableCode = tableCode .. "|" .. postnom .. "\n" tableCode = tableCode .. "|\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 = templateArgs[1] or 'None' local size = templateArgs[2] 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: " .. data[code].Code .. " "           output = output .. "Code: " .. data[code].Code .. " "           output = output .. "Description: " .. data[code].Description .. " "           output = output .. "Ribbon Image: " .. data[code].RibbonImage .. " "           output = output .. "Post-Nominal: " .. data[code].PostNom .. " "           output = output .. "Page Link: " .. data[code].PageLink .. " "           output = output .. "Country: " .. data[code].Country .. " "   return output end

local function _Ribbon(code, size) local ribbonimage=data[code].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 = "" -- .. " "   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 = templateArgs[1] or 'None' local size = templateArgs[2] 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 = ' Bad Code: '''[' .. code .. ']'''. Replace all * with x ' return output end -- End if

if not code or '' == code then -- return ' Error: missing positional parameter 1 ' return ' (Invalid Code: ' .. code .. ' ) ' end

--	local code = code:upper -- DO NOT DO THIS. Code is case sensitive -- Converts the first argument to uppercase if not data[code] then -- return ' Error: invalid positional parameter 1: ' .. code .. ' '		return ' (Code not found: ' .. code .. ' ) ' 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 .. " " .. data[code].Description .. " " -- add the  pagelink and description if data[code].Class then if string.len(data[code].Class) > 0 then -- Only add the Class if there is something in the field output = output .. " (" .. data[code].Class .. ") " end end if string.len(data[code].PostNom) > 0 then -- Only add the postnom if there is something in the field output = output .. " (" .. data[code].PostNom .. ") " end

if string.len(data[code].Note) > 0 then -- Only add the Note if there is something in the field output = output .. mw.getCurrentFrame:expandTemplate{ title = 'Efn', args = {data[code].Note} } -- Note: Page needs -- output = output .. "" .. data[code].Note .. " "    end if string.len(country) > 0 then -- if a value for country has been specificed if country:upper ~= data[code].Country:upper then -- check that the country specificed does NOT equal that on record output = output .. " (" .. data[code].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(data[code].Org) > 0 then -- Check there is actually something in the org field output = output .. " (" .. data[code].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 = data[code].RecipCat or "" -- If there is a recipient category specified, then add it to the output local categories = {} --categories[#categories+1] = " " -- 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] = " " 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 templateArgs[1] then code = templateArgs[1] end -- check that it is not "nil" before assigning the value if templateArgs[2] then size = templateArgs[2] 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 --	 ' Error: missing positional parameter 1 ' local output = ' (Invalid Code: ' .. code .. ') ' return output end if string.match(code, "%*") then -- The code field has asterisks in it. Raise an error local output = ' Bad Code: '''[' .. code .. ']'''. Replace all * with x ' return output end -- End if

--	local code = templateArgs[1]:upper -- Do not convert to uppercase. Codes are case sensitive if not data[code] then --	return ' Error: invalid positional parameter 1: ' .. code .. ' '		return ' (Code: ' .. code .. ' Not found) ' 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 = GlobalTemplateArgs[i] or "" if rl ~= "" then table.insert(RibbonList, rl) end end local row={} for i, rl in ipairs(RibbonList) do       if rl ~= "" then if data[rl] 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 .. "" -- 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 data[value] 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 = ' '

for key, value in pairs(templateArgs) do       if key ~= "size" and string.len(value) > 1 and data[value] then if string.len(data[value].PostNom) > 1 then output = output .. "" .. data[value].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 .. ' '

return output end

-- Initial code by John Dovey (13 April 2023) User:BoonDock return p