Module:Routelist row

local p = { } -- Package to be exported local lang = mw.getContentLanguage -- Retrieve built-in locale for date formatting local mw = require "Module:mw" -- Import module for HTML tag generation

local routeStates = { } -- Table with route statuses. -- The following tables include the following entries: row: The start of the row, for this particular type (color) removed: The string to be output in the "Removed" column. In the case of routeStates.former, the year that the route was decommissioned is output instead. -- routeStates.current = {row = "|- \n", removed = "present"} -- Data for current routes routeStates.future = {row = '|- style="background-color:#ffdead;" title="Future route"\n', removed = "proposed"} -- Data for future routes routeStates.former = {row = '|- style="background-color:#d3d3d3;" title="Former route"\n'} -- Data for former routes routeStates.unknown = {row = "|- \n", removed = "—"} -- Data for route with unknown status

function getRouteState(args) -- This function is passed the dates given for the established and decommissioned fields to the template.    It then returns the entry in the routeStates table corresponding to the status of the route.    -- local established = args.established -- Date passed to the module via the "established" parameter of    local decommissioned = args.decommissioned -- Date passed to the module via the "decommissioned" parameter of     if decommissioned ~= '' then -- If the route is decommissioned, then it must be a former route. return routeStates.former elseif established == '' then -- Without the establishment date, there is not enough information to determine the status of the route. return routeStates.unknown elseif lang:formatDate("Y-m-d") < established then -- If the current date (from lang:formatDate("Y-m-d")) is less than the date of establishment, then it must be a future route. return routeStates.future else -- If none of the first three conditions are true, then it must be a current route. return routeStates.current end end

function getLength(args) -- This function is passed the length fields from the invocation, and calculates the missing length from the other. local math = require "Module:Math" -- This module contains functions needed later in this function. local precision = math._precision -- The math._precision function provides the precision of a given string representing a number. local round = math._round -- This method rounds a given number to the given number of digits. In Lua, storing these functions locally results in more efficient execution. local length = {} -- This table will store the computed lengths. local km = args["length_km"] -- The kilometer length from the call. local mi = args["length_mi"] -- The length in miles as passed to. if '' == km then -- This signifies that a length in kilometers was not passed. local n = tonumber(mi) -- The first step is to convert the miles (passed as a string from the template) into a number. local prec = precision(mi) -- Retrieve the precision of the passed mile value (as a string). if n then -- If the passed mile value is an empty string, n will equal nil, which would make this statement false. Otherwise, the length in kilometers is computed and stored. length.km = round(n * 1.609344, prec) -- Compute and round the length in kilometers, and store it in the length table. else -- No mile value was passed length.km = 0 end else -- If the length in kilometers was passed, the computed lengths table will simply contain the passed length. length.km = km   end if '' == mi then -- The same as above, but this time converting kilometers to mile if necessary. local n = tonumber(km) -- Kilometers as a number local prec = precision(km) -- Precision of the passed length if n then -- If a kilometer value was passed: length.mi = round(n / 1.609344, prec) -- Compute and store the conversion into miles. else -- If not: length.mi = 0 -- Store 0. end else -- And if the length in miles was passed: length.mi = mi -- Simply store it. end return length -- Return the length table with the computed lengths. end

function dtsYear(date) -- A limited replacement for. This is passed a date and derives a sort key from it. It returns a string with the hidden sort key, along with the year of the original date. if date == '' then return false end -- If the date is an empty string, stop and go back to whence it came. local year = lang:formatDate('Y', date) -- This invocation of lang:formatDate returns just the year. if year == date then -- If the provided date is just the year: date = date .. "-01-01" -- Tack on January 1 for the sort key to work right. end local month = lang:formatDate('m', date) -- Stores the month of the date. local day = lang:formatDate('d', date) -- Stores the day for this date. local dtsStr = string.format("%05d-%02d-%02d", year, month, day) -- Create and store the formatted hidden sort key. The year must be five digits, per convention. local spanParams = {style = "display:none; speak:none"} -- These CSS properties hide the sort key from normal view. local dtsSpan = mw.text.tag({name='span', contents=dtsStr, params=spanParams}) -- This generates the HTML code necessary for the hidden sort key. return dtsSpan .. year -- Return the hidden sort key concatenated with the year for this date end

function sortkey(Key, Type, Route) -- This function return the sort key for the route (not to be confused with the previous function, which generates a sort key for the established and decommissioned dates.) if Key ~= '' then -- If a sort key already exists: return Key -- Simply return it. else -- Otherwise: local PaddedRoute = string.format('%04d', Route) -- This invocation is equivalent to the template. It zero-pads the given route number up to 4 digits. return Type .. PaddedRoute -- Return the sort key for this route, composed of the type and zero-padded route number. end end

function p.rowcolor(frame) -- This function determines if this is a future route, present route, or decommissioned route, and colors the row appropriately. local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template -- Import parameters from template local established = config[1] -- Date established local decommissioned = config[2] -- Date decommissioned local dates = {["established"] = established, ["decommissioned"] = decommissioned} -- This table encapsulates the given dates into one value... local routeState = getRouteState(dates) -- which is passed to getRouteState, which returns one of the entries in routeStates,

return routeState.row -- whose row attribute is returned end

function p.termini(frame) -- This function determines if this is a beltway or not, and displays the termini columns appropriately. local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template -- Import parameters from template local beltway = config[1] -- Text in this parameter will span both termini columns. local terminus_a = config[2] -- Southern or western terminus local terminus_b = config[3] -- Northern or eastern terminus

if beltway ~= '' then -- The template passes this function an empty string if is not specified by the template user. return "|colspan=2 align=center|" .. beltway -- This text will, again, span both columns. else return '|' .. terminus_a .. '||' .. terminus_b -- Fill in the termini columns end end

function removed(routeState, decommissioned) -- This function returns the proper value for the removed column. return routeState.removed or dtsYear(decommissioned) -- Returns the removed attribute of the provided routeState table or, if empty, the dtsYear-formatted decommissioned date. end

function formed(established) -- This function returns the proper value for the formed column. return dtsYear(established) or "—" -- Returns the dtsYear-formatted established date or, if none was provided, an em-dash. end

function p.dates(frame) -- This function displays the date columns. local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template -- Import parameters from template local established = config[1] -- Date established local decommissioned = config[2] -- Date decommissioned local dates = {["established"] = established, ["decommissioned"] = decommissioned} -- This table encapsulates the given dates into one value... local routeState = getRouteState(dates) -- which is passed to getRouteState, which returns one of the entries in routeStates, local output = "|align=center|" .. formed(established) .. "||align=center|" .. removed(routeState, decommissioned) -- which is passed to the removed function. This line generates the Wikitext for this part of the row. return output end

function p.length(frame) -- This function generate the length columns, with the appropriate conversions. local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template local miles = config[1] -- Length in miles local kilometers = config[2] -- Length in kilometers local lengths = {length_mi = miles, length_km = kilometers} -- This time, we compile the lengths into a table, local Lengths = getLength(lengths) -- which makes for an easy parameter. This function call will return the lengths in both miles and kilometers, return "|align=right|" .. Lengths.mi .. "||align=right|" .. Lengths.km -- which are then spliced in here and returned to the template. end

function p.sortkey(frame) -- This function generates the route's sort key local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template local SortKey = config[1] -- If a sort key is given, store it here. local Type = config[2] -- The route type (Interstate, State highway, etc.) local Route = config[3] -- The route number. return sortkey(SortKey, Type, Route) -- And then return the sort key from this function to the template. end

return p