Permanently protected module
From Wikipedia, the free encyclopedia


local p = { } -- Package to be exported

local getArgs = require('Module:Arguments').getArgs -- Import module function to work with passed arguments

local lang = mw.getContentLanguage() -- Retrieve built-in locale for date formatting

local format = mw.ustring.format -- String formatting function

local frame = mw.getCurrentFrame()



local routeStates = { } -- Table with route statuses.

--[[ The following tables include the following entries:

row: The start of the row, for this particular type (color)

established: The string to be output in the "Formed" column. For future routes, "proposed" is displayed here. Otherwise, display the year passed in the established parameter.

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 = "|-", removed = "current"} -- Data for current routes

routeStates.future = {row = '|- style="background-color:#ffdead;" title="Future route"', established = "proposed", removed = "—"} -- Data for future routes

routeStates.former = {row = '|- style="background-color:#d3d3d3;" title="Former route"'} -- Data for former routes

routeStates.formeroverride = {row = '|- style="background-color:#d3d3d3;" title="Former route"', removed = "—"} -- Data for routes marked as former by override

routeStates.unknown = {row = "|-", removed = "—"} -- Data for route with unknown status



function getRouteState(established, decommissioned)

	--[[ 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.

	]]--

	if decommissioned == 'yes' then --If the decommissioned property just says "yes", then mark it as a former route and display default data.

		return routeStates.formeroverride

	elseif decommissioned then -- If the route is decommissioned, then it must be a former route.

		return routeStates.former

	elseif not established then -- Without the establishment date, there is not enough information to determine the status of the route.

		return routeStates.unknown

	elseif established == 'proposed' then -- If the "established date" is the string 'proposed', 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 dtsYearCore(date, circa)

	-- A limited replacement for {{dts}}. 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 not 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', content=dtsStr, attrs=spanParams}) -- This generates the HTML code necessary for the hidden sort key.

	if circa == 'yes' then -- If the date is tagged as circa,

		return dtsSpan .. "<abbr title=\"circa\">c.</abbr><span style=\"white-space:nowrap;\">&thinsp;" .. year .. "</span>" -- Add the circa abbreviation to the display. Derived from {{circa}}

	else -- Otherwise,

		return dtsSpan .. year -- Return the hidden sort key concatenated with the year for this date.

	end

end



function dtsYear(date, circa)

	local success, result = pcall(dtsYearCore, date, circa)

	if success then

		return result

	else

		return string.format('%s<span class="error">Error: Invalid date "%s".</span>', circa and '<abbr title="circa">c.</abbr>&thinsp;' or '', date)

	end

end



function removed(routeState, decommissioned, circa)

	-- This function returns the proper value for the removed column.

	return routeState.removed or dtsYear(decommissioned, circa) -- Returns the removed attribute of the provided routeState table or, if empty, the dtsYear-formatted decommissioned date.

end



function formed(routeState, established, circa)

	-- This function returns the proper value for the formed column.

	return routeState.established or dtsYear(established, circa) or "—" -- Returns 'proposed' if the route is proposed, the dtsYear-formatted established date if one was provided, or an em-dash.

end



function sortkey(args)

	-- 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.)

	local key = args.sortkey

	local type = args.type

	local route = args.route or ''

	if key then -- If a sort key already exists:

		return key -- Simply return it.

	else -- Otherwise:

		local routeKey

		local routeNum = tonumber(route)

		if routeNum then

			routeKey = string.format('%04d', route) -- This invocation is equivalent to the {{0000expr}} template. It zero-pads the given route number up to 4 digits.

		else

			local num, suffix = string.match(route, "(%d*)(.+)")

			routeKey = (tonumber(num) and string.format('%04d', num) or '') .. suffix

		end

		return type .. routeKey -- Return the sort key for this route, composed of the type and zero-padded route number.

	end

end



function termini(args)

	-- This function determines if this is a beltway or not, and displays the termini columns appropriately.

	local beltway = args"beltway" -- Text in this parameter will span both termini columns.

	local terminus_a = args"terminus_a" or '—' -- Southern or western terminus

	local terminus_b = args"terminus_b" or '—' -- Northern or eastern terminus

	

	if beltway then

		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 dates(established, decommissioned, routeState, args)

	-- This function displays the date columns.

	

	

	if args.gazette == 'yes' then

		local established = args.established or "—"

		local established_ref = args.established_ref or ''

		

		return "|align=center|" .. established .. established_ref

	else

		local established_ref = args.established_ref or '' -- Reference for date established

		local decommissioned_ref = args.decommissioned_ref or '' -- Reference for date decommissioned

		return "|align=center|" .. formed(routeState, established, args.circa_established) ..

		       established_ref .. "||align=center|" .. removed(routeState, decommissioned, args.circa_decommissioned) ..

		       decommissioned_ref

	end

end



--- Return output for the length columns for a given route, with the appropriate conversions.

local function length(args)

	local km = args"length_km" or '' -- Length in kilometers

    local mi = args"length_mi" or '' -- Length in miles

    local ref = args"length_ref"  or ''



    if mi == '' and km == '' then

        return format("|align=right|—||align=right|—")

	elseif mi ~= '0' and km == '' then

		return format("|align=right|") .. mi .. ref .. format("||align=right|") .. frame:expandTemplate{ title = 'convert', args = { mi, "mi", "km", disp = "output number only"}}

	else

		return format("|align=right|") .. km .. ref .. format("||align=right|") .. frame:expandTemplate{ title = 'convert', args = { km, "km", "mi", disp = "output number only"}}

	end

end



function localname(args)

	-- This function generates a "Local names" cell if necessary

	local enabled = args1 or ''

	local localName = args"local" or ''

	if mw.text.trim(enabled) == "local" then

		return "|" .. localName

	else

		return ''

	end

end



function notes(notes)

	-- This function generates a "Notes" cell if necessary.

	if notes == 'none' then

		return '| ' --create empty cell

	elseif notes then

		return '|' .. notes --display notes in cell

	else

		return '' --create no cell

	end

end



function gap(args)

	local text = args.text or "''Number not designated''"

	

	if notes then

		return '|align=center colspan=7|' .. text --display notes in cell

	else

		return '|align=center colspan=6|' .. text --display notes in cell

	end

end



function route(args)

	-- This function displays the shield and link.

	local format = mw.ustring.format	

	local parserModule = require "Module:Road data/parser"

	local parser = parserModule.parser

	

	local noshield = args.noshield

	local bannerFile = parser(args, 'banner')

	local banner

	if not noshield and bannerFile and bannerFile ~= '' then

		local widthCode = parser(args, 'width') or 'square'

		if widthCode == 'square' then

			banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

		elseif widthCode == 'expand' then

			local route = args.route

			if #route >= 3 then

				banner = format("[[File:No image.svg|3px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|3px|link=|alt=]]", bannerFile)

			else

				banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

			end

		elseif widthCode == 'wide' then

			banner = format("[[File:No image.svg|3px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|3px|link=|alt=]]", bannerFile)

		elseif widthCode == 'MOSupp' then

			local route = args.route

			if #route >= 2 then

				banner = format("[[File:No image.svg|3px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|3px|link=|alt=]]", bannerFile)

			else

				banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

			end

		elseif widthCode == 'US1926' then

			banner = format("[[File:%s|25px|link=|alt=]][[File:No image.svg|1px|link=|alt=]]", bannerFile)

		elseif args.state == 'CA' then

			local route = args.route

			local type = args.type

			if type == 'US-Bus' then

				if #route >= 3 then

					banner = format("[[File:No image.svg|2px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|2px|link=|alt=]]", bannerFile)

				else

					banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

				end

			elseif type == 'CA-Bus' or type == 'SR-Bus' then

				if #route >= 3 then

					banner = format("[[File:No image.svg|1px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|2px|link=|alt=]]", bannerFile)

				else

					banner = format("[[File:%s|24px|link=|alt=]]", bannerFile)

				end

			end

		end

		banner = banner .. '<br>'

	else

		banner = ''

	end



	local shield

	if not noshield then

		local shieldFile, second = parser(args, 'shieldlist') or parser(args, 'shield') or ''

		if shieldFile == nil or shieldFile == '' then

			shield = ''

		elseif type(shieldFile) == 'table' then

			shieldFile, second = shieldFile1], shieldFile2

		end

		if second and type(second) == 'string' then

			local shield1 = format("[[File:%s|x25px|alt=|link=]]", shieldFile)

			local shield2 = format("[[File:%s|x25px|alt=|link=]]", second)

			shield = shield1 .. shield2

		elseif shield == '' then

			shield = ''

		else

			shield = shieldFile and format("[[File:%s|x25px|alt=|link=]]", shieldFile) or ''

		end

	else

		shield = ''

	end

	

	local linkTarget = (not args.nolink) and parser(args, 'link')

	local abbr = parser(args, 'abbr')

	local link

	if linkTarget then

		link = format("[[%s|%s]]", linkTarget, abbr)

	else

		link = abbr

	end

	if not link then error("Type not in database: " .. args.type) end

	local sortkey = sortkey(args)

	local sortedLink = format("<span data-sort-value=\"%s&#32;!\">%s</span>", sortkey, link)

	local route = banner .. shield .. ' ' .. sortedLink

	return '!scope="row" class="nowrap"|' .. route

end



function p.row(frame)

	local args = getArgs(frame) -- Gather passed arguments into easy-to-use table

	

	local established = args.established

	local decommissioned = args.decommissioned

	local routeState = getRouteState(established, decommissioned)

	local anchor = args.anchor or sortkey(args)

	local rowdef = routeState.row .. string.format(' id="%s"', anchor)

	local route = route(args)

	local length = length(args)

	local termini = termini(args)

	local localname = localname(args)

	local dates = dates(established, decommissioned, routeState, args)

	local notesArg = args.notes

	local notes = notes(notesArg)

	

	local row = {rowdef, route, length, termini, localname, dates, notes}

	return table.concat(row, '\n')

end



function p.gap(frame)

	local args = getArgs(frame) -- Gather passed arguments into easy-to-use table



	local routeState = getRouteState(established, decommissioned)

	local anchor = args.anchor or sortkey(args)

	local rowdef = routeState.row .. string.format(' id="%s"', anchor)

	local route = route(args)

	local gap = gap(args)

	

	local row = {rowdef, route, gap}

	return table.concat(row, '\n')

end



return p
Permanently protected module
From Wikipedia, the free encyclopedia


local p = { } -- Package to be exported

local getArgs = require('Module:Arguments').getArgs -- Import module function to work with passed arguments

local lang = mw.getContentLanguage() -- Retrieve built-in locale for date formatting

local format = mw.ustring.format -- String formatting function

local frame = mw.getCurrentFrame()



local routeStates = { } -- Table with route statuses.

--[[ The following tables include the following entries:

row: The start of the row, for this particular type (color)

established: The string to be output in the "Formed" column. For future routes, "proposed" is displayed here. Otherwise, display the year passed in the established parameter.

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 = "|-", removed = "current"} -- Data for current routes

routeStates.future = {row = '|- style="background-color:#ffdead;" title="Future route"', established = "proposed", removed = "—"} -- Data for future routes

routeStates.former = {row = '|- style="background-color:#d3d3d3;" title="Former route"'} -- Data for former routes

routeStates.formeroverride = {row = '|- style="background-color:#d3d3d3;" title="Former route"', removed = "—"} -- Data for routes marked as former by override

routeStates.unknown = {row = "|-", removed = "—"} -- Data for route with unknown status



function getRouteState(established, decommissioned)

	--[[ 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.

	]]--

	if decommissioned == 'yes' then --If the decommissioned property just says "yes", then mark it as a former route and display default data.

		return routeStates.formeroverride

	elseif decommissioned then -- If the route is decommissioned, then it must be a former route.

		return routeStates.former

	elseif not established then -- Without the establishment date, there is not enough information to determine the status of the route.

		return routeStates.unknown

	elseif established == 'proposed' then -- If the "established date" is the string 'proposed', 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 dtsYearCore(date, circa)

	-- A limited replacement for {{dts}}. 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 not 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', content=dtsStr, attrs=spanParams}) -- This generates the HTML code necessary for the hidden sort key.

	if circa == 'yes' then -- If the date is tagged as circa,

		return dtsSpan .. "<abbr title=\"circa\">c.</abbr><span style=\"white-space:nowrap;\">&thinsp;" .. year .. "</span>" -- Add the circa abbreviation to the display. Derived from {{circa}}

	else -- Otherwise,

		return dtsSpan .. year -- Return the hidden sort key concatenated with the year for this date.

	end

end



function dtsYear(date, circa)

	local success, result = pcall(dtsYearCore, date, circa)

	if success then

		return result

	else

		return string.format('%s<span class="error">Error: Invalid date "%s".</span>', circa and '<abbr title="circa">c.</abbr>&thinsp;' or '', date)

	end

end



function removed(routeState, decommissioned, circa)

	-- This function returns the proper value for the removed column.

	return routeState.removed or dtsYear(decommissioned, circa) -- Returns the removed attribute of the provided routeState table or, if empty, the dtsYear-formatted decommissioned date.

end



function formed(routeState, established, circa)

	-- This function returns the proper value for the formed column.

	return routeState.established or dtsYear(established, circa) or "—" -- Returns 'proposed' if the route is proposed, the dtsYear-formatted established date if one was provided, or an em-dash.

end



function sortkey(args)

	-- 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.)

	local key = args.sortkey

	local type = args.type

	local route = args.route or ''

	if key then -- If a sort key already exists:

		return key -- Simply return it.

	else -- Otherwise:

		local routeKey

		local routeNum = tonumber(route)

		if routeNum then

			routeKey = string.format('%04d', route) -- This invocation is equivalent to the {{0000expr}} template. It zero-pads the given route number up to 4 digits.

		else

			local num, suffix = string.match(route, "(%d*)(.+)")

			routeKey = (tonumber(num) and string.format('%04d', num) or '') .. suffix

		end

		return type .. routeKey -- Return the sort key for this route, composed of the type and zero-padded route number.

	end

end



function termini(args)

	-- This function determines if this is a beltway or not, and displays the termini columns appropriately.

	local beltway = args"beltway" -- Text in this parameter will span both termini columns.

	local terminus_a = args"terminus_a" or '—' -- Southern or western terminus

	local terminus_b = args"terminus_b" or '—' -- Northern or eastern terminus

	

	if beltway then

		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 dates(established, decommissioned, routeState, args)

	-- This function displays the date columns.

	

	

	if args.gazette == 'yes' then

		local established = args.established or "—"

		local established_ref = args.established_ref or ''

		

		return "|align=center|" .. established .. established_ref

	else

		local established_ref = args.established_ref or '' -- Reference for date established

		local decommissioned_ref = args.decommissioned_ref or '' -- Reference for date decommissioned

		return "|align=center|" .. formed(routeState, established, args.circa_established) ..

		       established_ref .. "||align=center|" .. removed(routeState, decommissioned, args.circa_decommissioned) ..

		       decommissioned_ref

	end

end



--- Return output for the length columns for a given route, with the appropriate conversions.

local function length(args)

	local km = args"length_km" or '' -- Length in kilometers

    local mi = args"length_mi" or '' -- Length in miles

    local ref = args"length_ref"  or ''



    if mi == '' and km == '' then

        return format("|align=right|—||align=right|—")

	elseif mi ~= '0' and km == '' then

		return format("|align=right|") .. mi .. ref .. format("||align=right|") .. frame:expandTemplate{ title = 'convert', args = { mi, "mi", "km", disp = "output number only"}}

	else

		return format("|align=right|") .. km .. ref .. format("||align=right|") .. frame:expandTemplate{ title = 'convert', args = { km, "km", "mi", disp = "output number only"}}

	end

end



function localname(args)

	-- This function generates a "Local names" cell if necessary

	local enabled = args1 or ''

	local localName = args"local" or ''

	if mw.text.trim(enabled) == "local" then

		return "|" .. localName

	else

		return ''

	end

end



function notes(notes)

	-- This function generates a "Notes" cell if necessary.

	if notes == 'none' then

		return '| ' --create empty cell

	elseif notes then

		return '|' .. notes --display notes in cell

	else

		return '' --create no cell

	end

end



function gap(args)

	local text = args.text or "''Number not designated''"

	

	if notes then

		return '|align=center colspan=7|' .. text --display notes in cell

	else

		return '|align=center colspan=6|' .. text --display notes in cell

	end

end



function route(args)

	-- This function displays the shield and link.

	local format = mw.ustring.format	

	local parserModule = require "Module:Road data/parser"

	local parser = parserModule.parser

	

	local noshield = args.noshield

	local bannerFile = parser(args, 'banner')

	local banner

	if not noshield and bannerFile and bannerFile ~= '' then

		local widthCode = parser(args, 'width') or 'square'

		if widthCode == 'square' then

			banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

		elseif widthCode == 'expand' then

			local route = args.route

			if #route >= 3 then

				banner = format("[[File:No image.svg|3px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|3px|link=|alt=]]", bannerFile)

			else

				banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

			end

		elseif widthCode == 'wide' then

			banner = format("[[File:No image.svg|3px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|3px|link=|alt=]]", bannerFile)

		elseif widthCode == 'MOSupp' then

			local route = args.route

			if #route >= 2 then

				banner = format("[[File:No image.svg|3px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|3px|link=|alt=]]", bannerFile)

			else

				banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

			end

		elseif widthCode == 'US1926' then

			banner = format("[[File:%s|25px|link=|alt=]][[File:No image.svg|1px|link=|alt=]]", bannerFile)

		elseif args.state == 'CA' then

			local route = args.route

			local type = args.type

			if type == 'US-Bus' then

				if #route >= 3 then

					banner = format("[[File:No image.svg|2px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|2px|link=|alt=]]", bannerFile)

				else

					banner = format("[[File:%s|25px|link=|alt=]]", bannerFile)

				end

			elseif type == 'CA-Bus' or type == 'SR-Bus' then

				if #route >= 3 then

					banner = format("[[File:No image.svg|1px|link=|alt=]][[File:%s|25px|link=|alt=]][[File:No image.svg|2px|link=|alt=]]", bannerFile)

				else

					banner = format("[[File:%s|24px|link=|alt=]]", bannerFile)

				end

			end

		end

		banner = banner .. '<br>'

	else

		banner = ''

	end



	local shield

	if not noshield then

		local shieldFile, second = parser(args, 'shieldlist') or parser(args, 'shield') or ''

		if shieldFile == nil or shieldFile == '' then

			shield = ''

		elseif type(shieldFile) == 'table' then

			shieldFile, second = shieldFile1], shieldFile2

		end

		if second and type(second) == 'string' then

			local shield1 = format("[[File:%s|x25px|alt=|link=]]", shieldFile)

			local shield2 = format("[[File:%s|x25px|alt=|link=]]", second)

			shield = shield1 .. shield2

		elseif shield == '' then

			shield = ''

		else

			shield = shieldFile and format("[[File:%s|x25px|alt=|link=]]", shieldFile) or ''

		end

	else

		shield = ''

	end

	

	local linkTarget = (not args.nolink) and parser(args, 'link')

	local abbr = parser(args, 'abbr')

	local link

	if linkTarget then

		link = format("[[%s|%s]]", linkTarget, abbr)

	else

		link = abbr

	end

	if not link then error("Type not in database: " .. args.type) end

	local sortkey = sortkey(args)

	local sortedLink = format("<span data-sort-value=\"%s&#32;!\">%s</span>", sortkey, link)

	local route = banner .. shield .. ' ' .. sortedLink

	return '!scope="row" class="nowrap"|' .. route

end



function p.row(frame)

	local args = getArgs(frame) -- Gather passed arguments into easy-to-use table

	

	local established = args.established

	local decommissioned = args.decommissioned

	local routeState = getRouteState(established, decommissioned)

	local anchor = args.anchor or sortkey(args)

	local rowdef = routeState.row .. string.format(' id="%s"', anchor)

	local route = route(args)

	local length = length(args)

	local termini = termini(args)

	local localname = localname(args)

	local dates = dates(established, decommissioned, routeState, args)

	local notesArg = args.notes

	local notes = notes(notesArg)

	

	local row = {rowdef, route, length, termini, localname, dates, notes}

	return table.concat(row, '\n')

end



function p.gap(frame)

	local args = getArgs(frame) -- Gather passed arguments into easy-to-use table



	local routeState = getRouteState(established, decommissioned)

	local anchor = args.anchor or sortkey(args)

	local rowdef = routeState.row .. string.format(' id="%s"', anchor)

	local route = route(args)

	local gap = gap(args)

	

	local row = {rowdef, route, gap}

	return table.concat(row, '\n')

end



return p

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook