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 {{GamesName}} template for that year; when not a number, returns as is

TODO: avoid the template call by implementing {{GamesName}} 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 {{GamesName}} 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

{{#invoke:Sandbox/trappist_the_monk/html|main||}}

]]

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 {{infobox country at games}}

{{#invoke:Sandbox/trappist the monk/html|total_medals_get||}}

]]

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,

}