Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Routelist row/sandbox 2
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} -- Package to be exported -- Change to "" upon deployment. local moduleSuffix = "" local lang = mw.getContentLanguage() -- Built-in locale for date formatting local format = mw.ustring.format -- String formatting function local insert = table.insert local concat = table.concat local util = require("Module:Road data/util") local frame = mw.getCurrentFrame() local parserModuleName = "Module:Road data/parser" .. moduleSuffix local statenameModuleName = "Module:Jct/statename" .. moduleSuffix -- TODO transition local concat = table.concat local insert = table.insert local format = mw.ustring.format local trim = mw.text.trim local parserModule = require(parserModuleName) local parser = parserModule.parser -- Shields local defaultShieldSize = 28 local function addContextBanner(args, name, suffix, bannerSpec) local bannerModule = 'Module:Road data/banners/' .. string.upper(args.country) local shieldfield = name .. 'shield' local shield = parser(args, shieldfield) if shield == nil then -- This route type does not define shield. -- Find shield in the default banner table. shield = parser(args, 'shield', name, bannerModule) if shield and shield ~= '' then if suffix == nil then suffix = parser(args, 'shield', 'suffix', bannerModule) end if suffix and suffix ~= '' then shield = shield .. " " .. suffix end shield = shield .. ".svg" end end if shield and shield ~= '' then local shieldSize = defaultShieldSize -- Add banner plate. insert(bannerSpec, {shield, shieldSize}) end end local function bannerSpec(banner, bannerSize, bannerSuffix, route) local banners = {} if type(banner) == "table" then local bannerSizeIsNotTable = type(bannerSize) ~= "table" for i,filename in ipairs(banner) do local bannersize = bannerSizeIsNotTable and bannerSize or bannerSize[i] or defaultShieldSize insert(banners, {filename, bannersize}) end elseif banner ~= '' then insert(banners, {banner, bannerSize}) end return banners end local function shieldSpec(args, mainShield, shieldList) local shieldSpec = {} local shield if not shield then shield = parser(args, 'shieldlist') or parser(args, 'shield') or '' end if shield == '' then return shieldSpec end local orientation = parser(args, 'orientation') local function size(args) if orientation == "upright" then return defaultShieldSize else return "x" .. defaultShieldSize end end local shieldsize = size(args) local banner = parser(args, 'banner') or {} local bannersize = defaultShieldSize local bannersuffix = parser(args, 'bannersuffix') local bannerIsNotTable = type(banner) ~= "table" local bannersizeIsNotTable = type(bannersize) ~= "table" local bannersuffixIsNotTable = type(bannersuffix) ~= "table" if type(shield) == "table" then for i,filename in ipairs(shield) do local size = shieldsize[i] or shieldsize if size == "" then size = nil end -- banner.all describes banners that apply to all multiple shields. local shieldBanner = bannerIsNotTable and banner or (banner[i] or banner.all or {}) -- Banner size is default if the corresponding entry -- in bannerSize table is not set. local shieldBannerSize = bannersizeIsNotTable and bannersize or (bannersize[i] or bannersize.all or defaultShieldSize) local shieldBannerSuffix = bannersuffix and (bannersuffixIsNotTable and bannersuffix or bannersuffix[i]) insert(shieldSpec, { shield = {filename, size}, banners = bannerSpec(shieldBanner, shieldBannerSize, shieldBannerSuffix, route) }) end elseif shield ~= '' then if shieldsize == "" then shieldsize = nil end insert(shieldSpec, { shield = {shield, shieldsize}, banners = bannerSpec(banner, bannersize, bannersuffix, route) }) end return shieldSpec end local missingShields local shieldExistsCache = {} local function render(shieldEntry, scale, showLink) local shield = shieldEntry.shield local banners = shieldEntry.banners local size if shield[2] then local width, height = mw.ustring.match(shield[2], "(%d*)x?(%d*)") width = tonumber(width) height = tonumber(height) local sizeparts = {} if width then insert(sizeparts, format("%d", width * scale)) end if height then insert(sizeparts, format("x%d", height * scale)) end size = concat(sizeparts) else size = format("%s%d", landscape and "x" or "", defaultShieldSize * scale) end local shieldCode = format("[[File:%s|%spx|link=|alt=]]", shield[1], size) if not banners[1] then return shieldCode end for _,banner in ipairs(banners) do shieldCode = format("[[File:%s|%spx|link=|alt=]]<br>%s", banner[1], defaultShieldSize, shieldCode) end return '<span style="display: inline-block; vertical-align: baseline; line-height: 0; text-align: center;">' .. shieldCode .. '</span>' end function p.shield(args, scale, showLink, mainShield, shieldList) missingShields = {} scale = scale or 1 local rendered = {} for _,entry in ipairs(shieldSpec(args, mainShield, shieldList)) do insert(rendered, render(entry, scale, showLink)) end return concat(rendered), missingShields end -- Links/abbreviations function p.link(args) local nolink = args.nolink local abbr = parser(args, 'abbr') if nolink then return abbr else local link = parser(args, 'link') if not link or link == '' then return abbr else return format("[[%s|%s]]", link, abbr) end end end local function stateName(args) -- TODO transition local data = mw.loadData(statenameModuleName) local abbr = args.state or args.province local countryData = data[args.country] return countryData and countryData[abbr] end -------------------------- --[[- @type status @field #string row: The start of the row, for this particular type (color) @field #string 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. @field #string 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. ]] --[[- Route statuses. @list <#status> ]] local routeStatuses = { -- current routes current = { row = "|-", removed = "current" }, -- future routes future = { row = '|- style="background-color:#ffdead;" title="Future route"', established = "proposed", removed = "β" }, -- former routes former = { row = '|- style="background-color:#d3d3d3;" title="Former route"' }, -- routes marked as former by override -- deprecated formeroverride = { row = '|- style="background-color:#d3d3d3;" title="Former route"', removed = "β" }, -- route with unknown status unknown = { row = "|-", removed = "β" } } --[[- Return the route status. @param #string established `established` argument passed to the module @param #string decommissioned `decommissioned` argument passed to the module @return #status the status of the route. ]] local function getRouteStatus(established, decommissioned) if decommissioned == 'yes' then -- a former route with no decommission information return routeStatuses.formeroverride elseif decommissioned then -- If the route is decommissioned, then it must be a former route. return routeStatuses.former elseif not established then -- Without the establishment date, there is not enough information -- to determine the status of the route. return routeStatuses.unknown elseif established == 'proposed' then -- a future route return routeStatuses.future else -- a current route return routeStatuses.current end end --[[- A limited replacement for {{dts}}. Derive the sort key from a given date. @param #string date @param #string circa "yes" if `date` is tagged as circa @return #string true the hidden sort key, along with the year of the original date @return #boolean false if the sort key cannot be derived ]] local function dtsYearCore(date) local year = lang:formatDate('Y', date) -- year for this date if year == date then -- If the provided date is just the year, -- tack on January 1 for the sort key to work right. date = date .. "-01-01" end local month = lang:formatDate('m', date) -- month for this date local day = lang:formatDate('d', date) -- day for this date -- Create and store the formatted hidden sort key. -- The year must be five digits, per convention. local dtsStr = format("%05d-%02d-%02d", year, month, day) -- Return the hidden sort key and the year for this date. return {dtsStr, year} end local function dtsYear(date, circa) local success, result = pcall(dtsYearCore, date) if not success then result = { "00001-01-01", util.err(format('Invalid date "%s".', date)) } end -- Generate the HTML code necessary for the hidden sort key. local dtsStyle = format("style=\"white-space:nowrap;\" data-sort-value=\"%s\"", result[1]) local year = result[2] if circa == 'yes' then -- If the date is tagged as circa, -- add the circa abbreviation to the display. Derived from {{circa}}. year = "<span style=\"white-space:nowrap;\"><abbr title=\"circa\">c.</abbr> " .. year .. "</span>" end return dtsStyle, year end --- Return formatting and output for a date column. local function date(text, date, circa, ref) -- Returns the text if specified, or the dtsYear-formatted date, and an em-dash. local style, output if text then output = text elseif date then style, output = dtsYear(date, circa) else output = "β" end return format("|align=center %s|%s%s", style or "", output, ref) end --- Return output for the date columns for a given route. local function dates(established, decommissioned, routeStatus, args) local established_ref = args.established_ref or '' -- Reference for date established local decommissioned_ref = args.decommissioned_ref or '' -- Reference for date decommissioned return format("%s\n%s", date(routeStatus.established, established, args.circa_established, established_ref), date(routeStatus.removed, decommissioned, args.circa_decommissioned, decommissioned_ref)) end --- Return output for the termini columns for a given route. local function termini(args) local beltway = args["beltway"] if beltway then -- The given route is a beltway. -- `beltway` text will span both termini columns. return "|colspan=2 align=center|" .. beltway else local terminus_a = args["terminus_a"] or 'β' -- Southern or western terminus local terminus_b = args["terminus_b"] or 'β' -- Northern or eastern terminus -- Fill in the termini columns return '|' .. terminus_a .. '||' .. terminus_b 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("|") .. frame:expandTemplate{ title = 'convert', args = { mi, "mi", "km", disp = "table"}} else return format("|") .. frame:expandTemplate{ title = 'convert', args = { km, "km", "mi", disp = "table"}} end end --- Generate a "Local names" cell if necessary. local function localname(args) local enabled = args[1] or '' if enabled == "local" then local localName = args["local"] or '' return "|" .. localName else return '' end end --- Generate a "Notes" cell if necessary. local function notes(notes) if notes == 'none' then return '| ' --create empty cell elseif notes then return '|' .. notes --display notes in cell else return '' --create no cell end end --- Derive the sort key from a given route. local function sortkey(abbr) -- Split `abbr` into three possibly empty parts, with number in the middle. local prefix, num, suffix = mw.ustring.match(abbr, "([^0-9]*)(%d*)(.*)") -- If `abbr` does not contain a number, the entry appears at the bottom. num = tonumber(num) num = type(num) == "number" and format("%04d", num) or "" -- The sort key is `abbr`, but with route number zero-padded to 4 digits -- and prefix moved to the end. return mw.text.trim( mw.ustring.gsub(format("%s%s %s", num, suffix, prefix), " ", " "), "- ") end local function route(args, shieldSize) local link, abbr = p.link(args) -- Use the sort key if already specified. local sortkey = args.sortkey or sortkey(abbr or "") local shield = p.shield(args) if shield == nil or args.noshield then return format('!scope="row" class="nowrap" data-sort-value="%s"|%s', sortkey, link) else return format('!scope="row" class="nowrap" data-sort-value="%s"|%s %s', sortkey, shield, link) end end --- Derive the anchor from a given route. local function anchor(routeType, routeNo) -- Split `routeNo` into three possibly empty parts, with number in the middle. local prefix, num, suffix = mw.ustring.match(routeNo, "([^0-9]*)(%d*)(.*)") -- Zero-pad route number to 4 digits if `routeNo` does contain a number. num = tonumber(num) num = type(num) == "number" and format("%04d", num) or "" -- The anchor is the concatenation of `type` and zero-padded `routeNo`. return format("%s%s%s%s", routeType, prefix, num, suffix) end function p._row(args) local established = args.established local decommissioned = args.decommissioned local routeStatus = getRouteStatus(established, decommissioned) local anchor = args.anchor or anchor(args.type, args.route) local rowdef = format('%s id="%s"', routeStatus.row, anchor) local route = route(args) local length = length(args) local termini = termini(args) local localname = localname(args) local dates = dates(established, decommissioned, routeStatus, args) local notes = notes(args.notes) local row = {rowdef, route, length, termini, localname, dates, notes} return concat(row, '\n') end function p.row(frame) -- Import module function to work with passed arguments local getArgs = require('Module:Arguments').getArgs local args = getArgs(frame) -- Gather passed arguments into easy-to-use table return p._row(args); end return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Routelist row/sandbox 2/doc
(
edit
)