Module:Tropical cyclone season effects

-- Used for tropical cyclone season articles.

local invocation = require('Module:Template invocation').invocation local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local dateperiod = require('Module:Date period')._main local Date = require('Module:Date')._Date local p = {}

function p.main(frame) local args = getArgs(frame, {		trim = true,		removeBlanks = false	})

return p._main(frame, args) end

--- Used for decoding attributes (encoded by the child template automatically) function unencode(encoded) return string.gsub(encoded, "&apos;", "'") end

-- Guesses the table year from the article title, or from arguments function guessYear(frame, args) if args["year"] or args["start-year"] then return tonumber(args["start-year"] or args["year"]), tonumber(args["end-year"]) end local pageTitle = mw.title.getCurrentTitle.prefixedText -- Note: These are different dashes (dash, ndash, mdash, respectively). rangeB = mw.ustring.match(pageTitle, "^%d+[%-–—](%d+)") rangeA = mw.ustring.match(pageTitle, "^(%d+)") if rangeB ~= nil then return tonumber(rangeA), tonumber(			-- "2021" if "21", "2021" if "2021"			args["end-year"] or (string.len(rangeB) > 2 and rangeB or string.sub(rangeA, 1, 2) .. rangeB)		) elseif rangeA ~= nil then return tonumber(rangeA), nil else return nil, nil end end

-- Module:Convert does not expose a module-friendly conversion system. -- For this reason, we'll need to do this messy hack that is extremely -- inefficient. function convert(frame, args) args["disp"] = "number" args["comma"] = "off" return tonumber(frame:expandTemplate{ title = "convert", args = args }) end

function p._main(frame, args) local basin = args["basin"] or args["Basin"] if not yesno(args["no-header"]) and basin == nil then mw.addWarning("Basin not provided. A link will not be displayed leading to category definitions") end local startYear, endYear = guessYear(frame, args) if startYear == nil then return error("Could not guess starting year. Supply with the year or startYear parameter") end if startYear == nil and endYear ~= nil then return error("End year specified but start year not specified") end local tableEntries = args[1] or "" tableEntries = unencode(tableEntries) local totalStorms = 0 local strongestWinds = nil local tableWindsUnit = args["winds-unit"] -- nullable local lowestPressure = nil local tablePressureUnit = args["pressure-unit"] -- nullable local totalDamages = 0 local totalDeaths = 0 local earliestFormed = nil local latestDissipated = nil local latestPresent = false for entryJSON in mw.ustring.gmatch(tableEntries, "data%-tcse%-entry='(.-)'") do   	entry = mw.text.jsonDecode(entryJSON) totalStorms = totalStorms + 1 if tableWindsUnit == nil then tableWindsUnit = entry["winds-unit"] or "kn" end if tablePressureUnit == nil then tablePressureUnit = entry["pressure-unit"] or "hPa" end -- Convert to table units first convertedWinds = tonumber(entry["winds"]) ~= nil and (   		entry["winds-unit"] == tableWindsUnit    			and entry["winds"]    			or convert( frame, { entry["winds"], entry["winds-unit"] or "kn", tableWindsUnit } )			) or nil convertedPressure = tonumber(entry["pressure"]) ~= nil and (			entry["pressure-unit"] == tablePressureUnit				and entry["pressure"]   			or convert( frame, { entry["pressure"], entry["pressure-unit"] or "hPa", tablePressureUnit } )			) or nil deaths = tonumber(mw.ustring.match(entry["deaths"] or "", "%d+")) damages = tonumber(mw.ustring.match(entry["damages"] or "", "%d+")) -- Compare if convertedWinds ~= nil and (			strongestWinds == nil or convertedWinds > strongestWinds		) then strongestWinds = convertedWinds end if convertedPressure ~= nil and (			lowestPressure == nil or convertedPressure < lowestPressure		) then lowestPressure = convertedPressure end if deaths ~= nil then totalDeaths = totalDeaths + deaths end if damages ~= nil then totalDamages = totalDamages + damages end if string.lower(entry["dissipated"]) == "present" then latestPresent = true end formed = Date(entry["formed"]) dissipated = Date(entry["dissipated"]) if earliestFormed == nil or (formed ~= nil and earliestFormed > formed) then earliestFormed = formed end if latestDissipated == nil or (dissipated ~= nil and latestDissipated < dissipated) then latestDissipated = dissipated end end -- Using expandTemplate for modularity. local tcHeader = frame:expandTemplate{ title = "Tropical cyclone season effects (top)", args = { ["no-sort"] = totalStorms == 0 and "yes" or nil, ["no-header"] = args["no-header"], ["basin"] = basin, ["start-year"] = startYear, ["end-year"] = endYear, ["currency-link"] = args["currency-link"] }	}

-- Template parameters not yet standardized. Hence the usage of capitalized -- parameter names. -- Using expandTemplate for modularity. local tcFooter = frame:expandTemplate{ title = "Tropical cyclone season effects (bottom)", args = { ["TC's"] = totalStorms .. " system" .. (totalStorms == 1 and "" or "s"), ["dates"] = totalStorms == 0 and "Season not started" or				dateperiod(					earliestFormed,					(latestPresent or yesno(args["active"]))					   and "Season ongoing" or latestDissipated:text( args["date-format"] or "mdy" ),				   true				), ["winds"] = (totalStorms == 0 or strongestWinds == nil) and "" or				(					tableWindsUnit == "kn" and ( frame:expandTemplate{ title = "convert", args = { strongestWinds, tableWindsUnit, args["winds-target"] or "kph", round = "5", abbr = "on", disp = "out" }						} .. (args["winds-target2"] ~= "none" and " (" .. frame:expandTemplate{ title = "convert", args = { strongestWinds, tableWindsUnit, args["winds-target2"] or "mph", round = "5", abbr = "on", disp = "out" }						} .. ")" or "") ) or frame:expandTemplate{						title = "convert",						args = {							strongestWinds, 							tableWindsUnit,							args["winds-target"] or "",							round = "5",							abbr = "on"						}					}				), ["pres"] = (totalStorms == 0 or lowestPressure == nil) and "" or				frame:expandTemplate{ title = "convert", args = { lowestPressure, tablePressureUnit, args["pressure-target"] or "inHg", comma = "off", sigfig = 4, abbr = "on" }				},			["damage"] = (totalStorms == 0 or totalDamages == 0) and "" or				frame:expandTemplate{ title = totalDamages == 0 and "nts" or "ntsp", args = { totalDamages, "", totalDamages ~= 0 and (args["currency-symbol"] or "$") } },			["deaths"] = (totalStorms == 0 or totalDeaths == 0) and "" or 				frame:expandTemplate{ title = "nts", args = { totalDeaths } },			["Refs"] = args["footer-refs"] or "" }	}	return tcHeader .. "\n" .. tableEntries .. "\n" .. tcFooter end

return p