Module:Tropical cyclone season effects
Appearance
This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
Usage
[edit]This module is available only as a template since it requires a frame. You might want to visit the documentation for the template instead.
-- 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, "'", "'")
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