Module:Sandbox/trappist the monk/html

--[[

build a table of Olymipc medals and country ranks for an individual country. This example supports Mexico and Serbia. Needs better data organization but serves as proof of concept

]]

require ('strict')

local data_t = mw.loadData ('Module:Sandbox/trappist the monk/html/data');

--[[--< G A M E S _ T E M P L A T E _ M A K E >

when is a number, returns a template for that year; when not a number, returns as is

TODO: avoid the template call by implementing within this module (the template would invoke this module when used outside of the creation of these medal tables)

]]

local function games_template_make (games, year) if tonumber (year) then														-- if is a number or can be converted to a number return string.format (data_t.format_strings_t.game, games, year);		-- return a template else return year;															-- return as plain text else end end

--[[--< H T M L _ T A B L E _ B U I L D >--

create summer and winter Olympic games medals table

]]

local function html_table_build (frame) local args = require ('Module:Arguments').getArgs (frame); if not args[1] or '' == args[1] then return ' missing required ISO 3166 country tag ' end --args[1] = 'MEX' local tag = args[1]:upper;												-- args[1] is Olympics country tag if not data_t.country_data_t[tag] then return ' no country data for ISO 3166 country tag: ' .. tag .. ' ';	end

local games = args[2]:upper;												-- SOG or WOG if 'SOG' ~= games and 'WOG' ~= games then return ' unknown games: ' .. games .. ' ';	end --games='WOG' local html_tbl = mw.html.create ('table');									-- create the wikitable html_tbl :attr ('class', 'wikitable'):attr ('style', 'text-align:center')		-- add table attributes :tag ('caption'):wikitext (string.format (data_t.format_strings_t.caption, data_t.country_data_t[tag].country, ('SOG' == games) and 'Summer' or 'Winter')):done	-- caption for accessibility :tag ('tr') :tag ('th'):wikitext ('Games')											-- add table headers :tag ('th'):wikitext ('Athletes') :tag ('th'):attr ('scope', 'col'):wikitext ('Gold') :tag ('th'):attr ('scope', 'col'):wikitext ('Silver') :tag ('th'):attr ('scope', 'col'):wikitext ('Bronze') :tag ('th'):attr ('scope', 'col'):attr ('style', 'width:3em; font-weight:bold;'):wikitext ('Total') :tag ('th'):attr ('scope', 'col'):attr ('style', 'width:3em; font-weight:bold;'):wikitext ('Rank') local gold_total = 0;														-- we will accumulate totals here local silver_total = 0; local bronze_total = 0; local total_total = 0;														-- total of totals

local row_count = 0;														-- used as flag when rowspan used for future and no_participate messaging for _, row_t in ipairs (data_t.country_data_t[tag][games]) do				-- for each row sequence in the data table local games_template = games_template_make (games, row_t.year); if row_t.athletes then													-- only when there are athletes local athletes = string.format (data_t.format_strings_t.athletes, data_t.country_data_t[tag].country, row_t.year, ('SOG' == games) and 'Summer' or 'Winter', row_t.athletes); local rank = string.format (data_t.format_strings_t.rank, row_t.year, ('SOG' == games) and 'Summer' or 'Winter', row_t.rank); html_tbl:tag ('tr'):attr ('style', ('yes' == row_t.host) and 'border: 3px solid purple' or nil)	-- create an html row and populate with :tag ('td'):attr ('style', 'text-align:left'):wikitext (games_template):done	-- game name :tag ('td'):wikitext (athletes):done							-- number of athletes :tag ('td'):wikitext (row_t.gold):done						-- number of medals :tag ('td'):wikitext (row_t.silver):done :tag ('td'):wikitext (row_t.bronze):done :tag ('td'):wikitext (row_t.gold + row_t.silver + row_t.bronze):done	-- calculate the total number of medals for the row :tag ('td'):wikitext (rank):done								-- country's rank gold_total = gold_total + row_t.gold;								-- update totals silver_total = silver_total + row_t.silver; bronze_total = bronze_total + row_t.bronze; total_total = total_total + row_t.gold + row_t.silver + row_t.bronze	-- update total of totals elseif row_t.message then if row_t.rowspan then row_count = row_t.rowspan - 1; html_tbl:tag ('tr') :tag ('td'):attr ('style', 'text-align:left'):wikitext (games_template):done	-- game name :tag ('td'):attr ('colspan', 6):attr ('rowspan', row_t.rowspan):wikitext (data_t.messages_t[row_t.message] or row_t.message):done else																-- here when single-row message (no rowspan) html_tbl:tag ('tr') :tag ('td'):attr ('style', 'text-align:left'):wikitext (games_template):done	-- game name :tag ('td'):attr ('colspan', 6):attr ('rowspan', row_t.rowspan):wikitext (data_t.messages_t[row_t.message] or row_t.message):done end -- here when no  and no  elseif 0 < row_count then												-- when not 0, must be in a rowspan row_count = row_count - 1;											-- count down the counter html_tbl:tag ('tr')													-- add row that is				:tag ('td'):attr ('style', 'text-align:left'):wikitext (games_template):done	-- games name only end end

html_tbl :tag ('tr')																-- and create the bottom header :tag ('th'):attr ('colspan', '2'):wikitext ('Totals')					-- with all of the totals :tag ('th'):wikitext (gold_total) :tag ('th'):wikitext (silver_total) :tag ('th'):wikitext (bronze_total) :tag ('th'):wikitext (total_total) :tag ('th'):wikitext ( .. data_t.country_data_t[tag].all_time_rank .. ) mw.log (tostring (html_tbl)) return frame:preprocess (tostring (html_tbl));								-- make a big string, preprocess the game templates, and done end

--[[--< T O T A L _ M E D A L S _ G E T >--

calculate total gold/silver/bronze medal totals from country's data in ~/data for use in

]]

local function total_medals_get (frame) local args = require ('Module:Arguments').getArgs (frame);

local country = args[1]:upper; local award = args[2]:lower;

if not data_t.country_data_t[country] then return ' unknown country: ' .. args[1] .. ' ';	end if not ({['gold']=true, ['silver']=true, ['bronze']=true,})[award] then return ' unknown award: ' .. args[2] .. ' ';	end

local total = 0;

for _, games in ipairs ({'SOG', 'WOG'}) do		for _, v_t in ipairs (data_t.country_data_t[country][games]) do			if v_t[award] then total = total + v_t[award] end end end return total; end

----< E X P O R T E D  F U N C T I O N S >--

return {	html_table_build = html_table_build, total_medals_get = total_medals_get, }