Module:Jctint
| This Lua module is used on 16,000+ pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
This module implements the {{jctint/core}} template. Please see the template page for usage instructions.
Usage
From wikitext
{{#invoke:Jctint|jctint}}
From Lua
local jctintCoreModule = require("Module:Jctint")
jctintCoreModule._jctint(args)
Tracking categories
local p = {} -- Package to be exported
-- Local version of string formatting function
local format = mw.ustring.format
-- Local version of string trimming function
local trim = mw.text.trim
-- Store this function in a local variable to avoid expensive table lookups.
local insert = table.insert
-- mw.html object for the generated row
local row
-- Default row span for all columns (`jspan` = "junction span")
local jspan
-- Any error messages produced that will be added to the output
local errorMsg = {}
-- A specification for self-closing HTML tag.
local selfClosing = {selfClosing = true}
---
-- Converts the distance specified in unit from `unit` specified in `unitdef`
-- to the other supported unit.
local function convert(unit, unitdef)
if unit == nil or unitdef == nil then return {} end
-- Import module to convert length.
local util = require("Module:Road data/util")
local lengths = util.convertLengths({[unitdef] = unit})
if lengths.error then -- An error occurred during conversion.
-- Add the transcluding page to an error tracking category.
local page = mw.title.getCurrentTitle() -- Get transcluding page's title
local pagename = page.prefixedText -- Extract page's full title as string
-- Create category string
local category = format("[[Category:Jctint template using non-numeric parameter values|# %s]]", pagename)
insert(errorMsg, category) -- Add error category to error message table.
end
return lengths
end
--- Creates cells for the location columns.
local function locations(args)
-- Unitary, e.g., state line
local unitary = args.unitary -- Value to span all of the location columns
if unitary then
-- Text alignment of the cell contents, default to "left".
local align = args.unitary_align or 'left'
row:tag('td') -- Create unitary cell
:attr('colspan', 3) -- spanning three possible columns
:css('text-align', align)
:wikitext(unitary) -- Store the contents of unitary in the cell.
return
end
-- Create cells for regular location columns.
-- Region, for disambiguation and potentially for display
local region = args.region
if region or args.region_special then
-- Row span for region; must be specified to display a region cell.
local regionSpan = args.regionspan
if regionSpan then
row:tag('td') -- Create a region cell
:attr('rowspan', regionSpan)
-- Store region text in the cell.
-- `region_special` argument overrides wikilinked `region` argument.
:wikitext(args.region_special or format("[[%s]]", region))
end
end
-- Primary topic requires no specialization to supplied locations.
local primaryTopic = args.primary_topic ~= 'no'
-- Note below main text in the next column
local sub1note = args.sub1_note -- check existence later
-- Row span for the last location column, default to `jspan`
local sub2span = args.sub2span or jspan
-- Independent city
local indepCityText -- Value to span both subdivision columns.
if args.indep_city_special then
indepCityText = args.indep_city_special -- Overrides `indep_city` argument.
elseif args.indep_city then
local indepCity = args.indep_city
local cityLink -- Wikilink for independent city
if primaryTopic then
cityLink = format('[[%s]]', indepCity)
elseif region then
-- Specialize independent city to the region.
cityLink = format('[[%s, %s|%s]]', indepCity, region, indepCity)
end
if cityLink then
indepCityText = "[[Independent city|City]] of " .. cityLink
end
end
if indepCityText then -- Display independent city.
-- Text alignment of the cell contents, default to "left".
local align = args.indep_city_align or 'left'
local indepCityCell = row:tag('td') -- Create independent city cell
:attr('colspan', 2) -- spanning two columns
:attr('rowspan', sub2span) -- with the calculated row span.
:css('text-align', align)
:wikitext(indepCityText) -- Store the independent city in the cell.
if sub1note then -- A note is provided.
indepCityCell:tag('br', selfClosing) -- Add a line break to the cell.
-- Add the note to the cell, within an HTML <small> tag.
indepCityCell:tag('small'):wikitext(sub1note)
end
return
end
-- Create two cells for the first- and second-level subdivisions.
-- First-level subdivision, e.g., county
-- Name of the type of subdivision, e.g., "County" and "Parish"
local sub1name = args.sub1name -- check existence later
local sub1Text -- Value for first-level subdivision column.
if args.sub1_special then
sub1Text = args.sub1_special -- Overrides `sub1` argument.
elseif args.sub1 then
local sub1 = args.sub1
if primaryTopic then
-- Add type (if specified) to wikilink for first-level subdivision.
local sub1Link = sub1name and format("%s %s", sub1, sub1name) or sub1
sub1Text = format('[[%s|%s]]', sub1Link, sub1)
elseif region and sub1name then
-- Add type to first-level subdivision.
local sub1Typed = trim(format('%s %s', sub1, sub1name))
-- Specialize first-level subdivision, with type added, to the region.
sub1Text = format('[[%s, %s|%s]]', sub1Typed, region, sub1)
end
end
if sub1Text then -- Display first-level subdivision.
-- Row span for first-level subdivision, default to `jspan`.
local sub1span = args.sub1span or jspan
local sub1Cell = row:tag('td') -- Create first-level subdivision cell
:attr('rowspan', sub1span) -- with the calculated row span.
:wikitext(sub1Text) -- Store the first-level subdivision in the cell.
if sub1note then -- A note is provided.
sub1Cell:tag('br', selfClosing) -- Add a line break to the cell.
-- Add the note to the cell, within an HTML <small> tag.
sub1Cell:tag('small'):wikitext(sub1note)
end
end
-- Second-level subdivision, e.g., city and town
local sub2Text -- Value for second-level subdivision column.
if args.sub2_special then
sub2Text = args.sub2_special -- Overrides `sub2` argument.
elseif args.sub2 then
local sub2 = args.sub2
if sub2 == "none" or sub2 == " " then
sub2Text = "​" -- Zero-width space
elseif primaryTopic then
sub2Text = format("[[%s]]", sub2)
else
local sub2Link = {sub2}
local sub2Name = sub2
-- Type of area, e.g., city and village, as a form of disambiguation
local area = args.area
if area then
insert(sub2Link, format(' (%s)', area)) -- Add area to wikilink.
local areas = { -- table of different area types
borough = "Borough",
city = "City",
community = "Community",
CDP = "Community",
hamlet = "Hamlet",
town = "Town",
village = "Village",
["unorganized territory"] = "Unorganized Territory"
}
-- Add area name to displayed wikitext.
sub2Name = format("%s of %s", areas[area], sub2Name)
end
insert(sub2Link, ", ")
-- Some second-level subdivisions are not unique in a given region.
-- `sub1dab` is the first-level subdivision to be used for disambiguation.
local sub1dab = args.sub1dab
if sub1dab and sub1name then
insert(sub2Link, trim(format('%s %s', sub1dab, sub1name)) .. ", ")
end
if region then
insert(sub2Link, region) -- Add region to wikilink
end
sub2Text = format("[[%s|%s]]", table.concat(sub2Link), sub2Name)
end
end
if sub2Text then -- Display second-level subdivision.
row:tag('td') -- Create second-level subdivision cell
:attr('rowspan', sub2span) -- with the calculated row span.
:wikitext(sub2Text) -- Store the second-level subdivision in the cell.
end
end
--- Creates cells for the distance columns.
local function units(args)
-- Alternate units, e.g., California's postmiles.
local alt_unit = args.altunit
if alt_unit then -- Alternate units override standard units.
-- Row span (`auspan` = "alt[ernate] unit span")
local auspan = args.auspan or jspan
-- Create the alternate unit cell as a header cell for the row,
-- since it is usually unique within the table.
row:tag('th'):attr('scope', 'row')
:css('text-align', 'right')
:attr('rowspan', auspan)
:wikitext(alt_unit) -- Store the contents of alt_unit in the cell.
else
-- Convert numeric distances to a secondary unit, and display both units.
-- Distance in the primary unit, or 'none'
local unit = args.unit
-- If `unit` is "none", no cells are displayed.
if unit == "none" then return end
local unitdef = args.unitdef or "km" -- The primary unit ('mi' or 'km')
-- Convert and format the distance.
local lengths = convert(unit, unitdef)
-- Row span (`uspan` = "unit span")
local uspan = args.uspan or jspan
-- Create the primary unit cell as a header cell for the row,
-- since it is usually unique within the table.
local primary = row:tag('th'):attr('scope', 'row')
:css('text-align', 'right')
:attr('rowspan', uspan)
-- Store the primary distance and any conversion error message in the cell.
:wikitext(lengths[lengths.orig], lengths.error)
local secondary = row:tag('td') -- Create the secondary unit cell.
:css('text-align', 'right')
:css('background-color', '#eaecf0')
:attr('rowspan', uspan)
:wikitext(lengths[lengths.comp]) -- Store the secondary distance in the cell.
local unit_ref = args.unit_ref
if unit_ref then -- A reference is provided for the distance.
primary:wikitext(unit_ref) -- Add reference to the primary distance cell.
end
local unit2 = args.unit2
if unit2 then -- A second distance is provided.
local line = args.line -- A horizontal rule may be requested between the distances.
if line then
-- Add a horizontal rule to both cells.
primary:tag('hr', selfClosing)
secondary:tag('hr', selfClosing)
else
-- Add an en-dash and a line break to both cells.
primary:wikitext('–'):tag('br', selfClosing)
secondary:wikitext('–'):tag('br', selfClosing)
end
-- Convert and format the second distance.
local lengths2 = convert(unit2, unitdef)
-- Add the second distance and any conversion error message to the primary distance cell.
primary:wikitext(lengths2[lengths2.orig], lengths2.error)
-- Add the converted second distance to the secondary distance cell.
secondary:wikitext(lengths2[lengths2.comp])
end
local unit2_ref = args.unit2_ref
if unit2_ref then -- A reference is provided for the distance.
primary:wikitext(unit2_ref) -- Add reference to the primary distance cell.
end
end
end
-- Color specified by any supplied type
local color
-- Tooltip specified by any supplied type
local title
--- Apply any type-derived coloring and tooltip to the given cell.
local function applyTypeStyle(cell)
cell:attr('title', title):css('background-color', color)
end
--- Creates a cell for places, such as bridges and rest areas.
local function place(args)
local place = args.place -- Contents of the place cell
-- Do nothing if `place` is "none"
if place == "none" then return end
local colspan = 2 -- Initial column span
local exit = args[1] -- Whether this table has exit number columns
local named = args[2] -- Whether this table has named junction column
-- Adjust column span
if exit == "old" then colspan = colspan + 2
elseif exit == "exit" then colspan = colspan + 1
end
if named == "name" then colspan = colspan + 1 end
-- Row span (`pspan` = "place span")
local pspan = args.pspan or jspan
local placeCell = row:tag('td') -- Create place cell
:css('text-align', 'center')
:attr('colspan', colspan)
:attr('rowspan', pspan)
:wikitext(place) -- Store the place in the cell
applyTypeStyle(placeCell)
end
--- Creates cells for exit number and named junction columns.
local function exits(args)
local exit = args[1] -- 'exit', 'old', or nil
local named = args[2] -- 'name' or nil
if exit == 'old' then -- Add old exit number cell
-- Row span (`ospan` = "old span")
local ospan = args.ospan or jspan
row:tag('td') -- Create old exit number cell
:css('text-align', 'center')
:css('background-color', '#d3d3d3')
:attr('title', 'Former exit number')
:attr('rowspan', ospan)
:wikitext(args.old) -- Store the old exit number in the cell
end
if exit then -- "exit" or "old" is defined; add current exit number cell
-- Row span (`espan` = "exit span")
local espan = args.espan or jspan
local exitCell = row:tag('td') -- Create exit number cell
:css('text-align', 'center')
:attr('rowspan', espan)
:wikitext(args.exit) -- Store the exit number in the cell
applyTypeStyle(exitCell)
end
if named then -- Junction list has a junction name column
local namespan = args.namespan or jspan -- Row span
local nameCell = row:tag('td') -- Create junction name cell
:attr('rowspan', namespan)
:wikitext(args.name) -- Store the junction name in the cell
applyTypeStyle(nameCell)
end
end
--- Creates cell for the destinations column.
local function destinations(args)
local road = args.road -- Contents of the destinations cell
-- Do nothing if `road` is "none"
if road == "none" then return end
-- Column span (`rcspan` = "road column span"), default to 1
local rcspan = args.rcspan or 1
-- Row span (`rspan` = "road span")
local rspan = args.rspan or jspan
local destCell = row:tag('td') -- Create destination cell
:attr('colspan', rcspan)
:attr('rowspan', rspan)
:wikitext(road) -- Store the destination in the cell
applyTypeStyle(destCell)
end
--- Creates cell for the notes column.
local function notes(args)
local notes = args.notes -- Contents of the notes cell
-- Do nothing if `notes` is "none"
if notes == "none" then return end
-- Row span (`nspan` = "notes span")
local nspan = args.nspan or jspan
local notesCell = row:tag('td') -- Create notes cell
:attr('rowspan', nspan)
:wikitext(notes) -- Store the notes in the cell
applyTypeStyle(notesCell)
end
---
-- Returns a row in the junction list.
-- Accessible from other Lua modules
function p._jctint(args)
jspan = args.jspan or 1 -- Global row span for all columns; defaults to 1
-- {{{type}}} argument to determine color and tooltips
local argType = args.type
if argType then -- {{{type}}} was passed
-- Type-based data for colors and tooltips
if argType == 'mplex' then
local page = mw.title.getCurrentTitle() -- Get transcluding page's title
local pagename = page.prefixedText -- Extract page's full title as string
insert(errorMsg,
format("[[Category:Jctint template with invalid type|$ %s]]", pagename))
end
local types = mw.loadData("Module:Road data/RJL types")
local typeData = types[string.lower(argType)] -- Retrieve the type data
if typeData then
color = typeData.color -- Store the color globally
title = typeData.jctint -- Store the tooltip globally
else
-- Add error category to error message table.
local page = mw.title.getCurrentTitle() -- Get transcluding page's title
local pagename = page.prefixedText -- Extract page's full title as string
insert(errorMsg,
format("[[Category:Jctint template with invalid type|%s]]", pagename))
end
end
local root = mw.html.create() -- Create the root mw.html object to return
-- Create the table row and store it globally
row = root:tag('tr'):css('text-align', 'left')
locations(args) -- Handle location arguments
units(args) -- Handle distance arguments
if args.place then -- {{{place}}} spans all columns to the right of the distances
place(args) -- Create cell for place
else
exits(args) -- Handle exit/named junction arguments
destinations(args) -- Handle destinations
notes(args) -- Handle notes
end
-- Return the HTML code in the mw.html object as a string, plus any error messages
return tostring(root) .. table.concat(errorMsg)
end
--- Entry function for {{jctint/core}}
function p.jctint(frame)
-- Import module function to work with passed arguments
local getArgs = require('Module:Arguments').getArgs
-- Gather passed arguments into easy-to-use table
local args = getArgs(frame)
return p._jctint(args)
end
return p -- Return package
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.
- 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:
- 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.
- 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.
- 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.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.