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, "'", "'")
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

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.