Module:Jctint
Appearance
![]() | This Lua module is used on 15,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 format = mw.ustring.format -- Local version of string formatting function
local HtmlBuilder = require "Module:HtmlBuilder" -- Import module to build HTML code
local getArgs = require('Module:Arguments').getArgs -- Import module function to work with passed arguments
local types = mw.loadData("Module:Road data/RJL types") -- Import type-based data for colors and tooltips
local row -- HtmlBuilder object for the generated row
local jspan -- Junction span argument is stored here for efficiency
local color -- Color specified by any supplied type
local title -- Tooltip specified by any supplied type
local function conversion(unit, unitdef)
-- This function converts the distance specified in unit from the unit specified in unitdef to the other supported unit
local primary = unit and tonumber(unit) or -1 -- If unit is nil, primary will be -1. If unit is a non-numeric string, primary will be nil. Otherwise, primary will be the string as a number.
if not primary then -- If primary is nil (unit was non-numeric), 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
local category = format("[[Category:Jctint template using non-numeric parameter values|# %s]]", pagename) -- Create category string
return category .. unit -- Return category concatenated with supplied unit
elseif primary == -1 then -- If primary is -1 (unit is nil), simply return nil
return nil
end
local math = require "Module:Math" -- Import math module
local precision = math._precision -- Function to determine a numeric string's precision
local round = math._precision_format -- Function to display a number rounded to a given number of digits
local converted -- Distance converted into the secondary unit
if unitdef == 'mi' then -- If the primary unit is miles
converted = primary * 1.609344 -- Convert into kilometers
else -- Otherwise
converted = primary / 1.609344 -- Convert into miles
end
local prec = precision(unit) -- Retrieve precision of supplied distance
if prec < 0 then prec = 0 end -- Precision must be at least 0
return round(converted, prec) -- Return the converted distance rounded to the same number of digits as the supplied distance
end
local function locations(args)
local unitary = args.unitary
if unitary then
local tag = row.tag('td').attr('colspan', 3).wikitext(unitary)
local align = args.unitary_align or 'left'
tag.css('text-align', align)
else
local areas = {village = "Village", city = "City", town = "Town", community = "Community", CDP = "Community", hamlet = "Hamlet", ["unorganized territory"] = "Unorganized Territory"}
local notPrimaryTopic = args.primary_topic == 'no'
-- Regions
local regionSpan = args.regionspan
local region = args.region
if regionSpan then
local regionCell = row.tag('td').attr('rowspan', regionSpan)
local regionSpecial = args.region_special or ('[[' .. region .. ']]')
regionCell.wikitext(regionSpecial)
end
-- Independent Cities
local indepCity = args.indep_city
local indepCitySpecial = args.indep_city_special
local sub1note = args.sub1_note
local sub2span = args.sub2span or 1
if indepCity or indepCitySpecial then
local indepCityCell = row.tag('td').attr('colspan', 2).attr('rowspan', sub2span)
local align = args.indep_city_align or 'left'
indepCityCell.css('text-align', align)
if indepCitySpecial then
indepCityCell.wikitext(indepCitySpecial)
elseif notPrimaryTopic then
local text = format('[[Independent city|City]] of [[%s, %s|%s]]', indepCity, region, indepCity)
indepCityCell.wikitext(text)
else
local text = format('[[Independent city|City]] of [[%s]]', indepCity)
indepCityCell.wikitext(text)
end
if sub1note then
indepCityCell.tag('br', {selfClosing = true})
indepCityCell.tag('small').wikitext(sub1note)
end
end
-- First-level Subdivisions
local sub1 = args.sub1
local sub1Special = args.sub1_special
local sub1name = args.sub1name
if sub1 or sub1Special then
local sub1span = args.sub1span or 1
local sub1Cell = row.tag('td').attr('rowspan', sub1span)
if sub1Special then
sub1Cell.wikitext(sub1Special)
elseif notPrimaryTopic then
local text = format('[[%s %s, %s|%s]]', sub1, sub1name, region, sub1)
sub1Cell.wikitext(text)
else
local text = '[[' .. sub1
if sub1name then
text = text .. format(' %s|%s', sub1name, sub1)
end
sub1Cell.wikitext(text .. ']]')
end
if sub1note then
sub1Cell.tag('br', {selfClosing = true})
sub1Cell.tag('small').wikitext(sub1note)
end
end
-- Second-level Subdivisions
local sub2 = args.sub2
local sub2Special = args.sub2_special
if (sub2 == 'none') or (sub2 == ' ') then
row.tag('td').wikitext(" ")
elseif sub2Special then
row.tag('td').attr('rowspan', sub2span).wikitext(sub2Special)
elseif sub2 then
local sub2Cell = row.tag('td').attr('rowspan', sub2span)
if not notPrimaryTopic then
sub2Cell.wikitext('[[' .. sub2 .. ']]')
else
local text = {'[[', sub2}
local area = args.area
local insert = table.insert
if area then
insert(text, format(' (%s)', area))
end
insert(text, ", ")
local sub1dab = args.sub1dab
if sub1dab then
insert(text, format('%s %s, ', sub1dab, sub1name))
end
insert(text, region .. '|')
if area then
local linktext = areas[area]
insert(text, linktext .. ' of ')
end
insert(text, sub2 .. ']]')
sub2Cell.wikitext(table.concat(text))
end
end
end
end
function units(args)
local alt_unit = args.altunit
if alt_unit then
local tag = row.tag('th').attr('scope', 'row').css('text-align', 'right')
local span = args.auspan or jspan or 1
tag.attr('rowspan', span)
tag.attr('title', title)
tag.wikitext(alt_unit)
else
local unit = args.unit
if unit ~= 'none' then
local primary = row.tag('th').attr('scope', 'row').css('text-align', 'right')
local span = args.uspan or jspan or 1
primary.attr('rowspan', span)
primary.attr('title', title)
local secondary = row.tag('td').css('text-align', 'right').css('background-color', '#f2f2f2').attr('rowspan', span)
secondary.attr('title', title)
local unitdef = args.unitdef
primary.wikitext(unit)
secondary.wikitext(conversion(unit, unitdef))
local unit2 = args.unit2
if unit2 then
local line = args.line
if line then
primary.tag('hr', {selfClosing = true})
secondary.tag('hr', {selfClosing = true})
else
primary.wikitext('–').tag('br', {selfClosing = true})
secondary.wikitext('–').tag('br', {selfClosing = true})
end
primary.wikitext(unit2)
secondary.wikitext(conversion(unit2, unitdef))
end
local unit_ref = args.unit_ref
if unit_ref then primary.wikitext(unit_ref) end
end
end
end
function place(args)
-- This function generates a cell for places, such as bridges and rest areas
local tag = row.tag('td').css('text-align', 'center') -- Create cell and center-align its future contents
local pspan = args.pspan or jspan or 1 -- Determine row span ("pspan" = "place span"), using global row span argument jspan and 1 as backups, in that order
tag.attr('rowspan', pspan) -- Apply row span to cell
local colspan -- Create local variable to store column span
local exit = args[1] -- Whether this table has exit numbers, both old and current exit numbers, or neither
local named = args[2] -- Whether this table includes named junctions
if exit == 'exit' then -- Calculate column span
if named == 'name' then
colspan = 4
else
colspan = 3
end
elseif exit == 'old' then
if named == 'name' then
colspan = 5
else
colspan = 4
end
else
colspan = 2
end
tag.attr('colspan', colspan) -- Apply column span to cell
tag.attr('title', title).css('background-color', color) -- Apply any type-derived coloring and tooltip
tag.wikitext(args.place) -- Store the place in the cell
end
function exits(args)
-- This function generates table cells for exit and named junction data
local exit = args[1] -- Is either 'exit', 'old', or nil
local named = args[2] -- Is either 'name' or nil
if exit == 'old' then -- Add old exit number cell
local oldTag = row.tag('td').css('text-align', 'center').css('background-color', '#d3d3d3').attr('title', 'Former exit number') -- Create cell and properly style it
local ospan = args.ospan or jspan or 1 -- Determine row span ("ospan" = "old span"), using global row span argument jspan and 1 as backups, in that order
oldTag.attr('rowspan', ospan).wikitext(args.old) -- Apply row span and add old exit number
end
if exit == 'exit' or exit == 'old' then -- If either is true, add current exit number cell
local exitTag = row.tag('td').css('text-align', 'center') -- Create cell and center-align its contents
local espan = args.espan or jspan or 1 -- Determine row span ("espan" = "exit span"), using global row span argument jspan and 1 as backups, in that order
exitTag.attr('rowspan', espan) -- Apply row span to cell
exitTag.attr('title', title).css('background-color', color) -- Apply any type-derived coloring and tooltip
exitTag.wikitext(args.exit) -- Store the exit number in the cell
end
if named == 'name' then -- This junction list has a junction name column, so a cell must be produced
local nameTag = row.tag('td') -- Create a cell for the junction name
local namespan = args.namespan or jspan or 1 -- Determine row span, using global row span argument jspan and 1 as backups, in that order
nameTag.attr('rowspan', namespan) -- Apply row span to cell
nameTag.attr('title', title).css('background-color', color) -- Apply any type-derived coloring and tooltip
nameTag.wikitext(args.name) -- Store the junction name in the cell
end
end
function destinations(args)
-- This function creates the cells for destinations and notes
local destTag = row.tag('td') -- Create destination cell
local rcspan = args.rcspan or 1 -- Determine column span ("rcspan" = "road column span"), using 1 as a default
destTag.attr('colspan', rcspan) -- Apply column span to cell
local rspan = args.rspan or jspan or 1 -- Determine row span ("rspan" = "road span"), using global row span argument jspan and 1 as backups, in that order
destTag.attr('rowspan', rspan) -- Apply row span to cell
destTag.attr('title', title).css('background-color', color) -- Apply any type-derived coloring and tooltip
destTag.wikitext(args.road) -- Store the supplied cell contents
local notes = args.notes -- Contents of the notes cell
if notes ~= 'none' then -- If the contents equal the string 'none', then no cell will be produced. Otherwise...
local notesTag = row.tag('td') -- Create notes cell
local nspan = args.nspan or jspan or 1 -- Determine row span ("nspan" = "notes span"), using global row span argument jspan and 1 as backups, in that order
notesTag.attr('rowspan', nspan) -- Apply row span to cell
notesTag.attr('title', title).css('background-color', color) -- Apply any type-derived coloring and tooltip
notesTag.wikitext(notes) -- Store the notes in the cell
end
end
function p._jctint(args)
-- This function creates the table row and calls other functions to popluate it.
-- This function is accessible from other Lua modules
jspan = args.jspan -- Junction span (backup for row span that is applicable to all columns)
local type = args.type -- {{{type}}} argument to determine color and tooltips
if type then -- If a type was passed
local typeData = types[type] -- Retrieve the type data
color = typeData.color -- Store the color globally
title = typeData.jctint -- Store the tooltip globally
end
local root = HtmlBuilder.create() -- Create the root HtmlBuilder object
row = root.tag('tr').css('text-align', 'left') -- Create the table row and store it globally
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 and notes
end
return tostring(root) -- Return the HTML code in the HtmlBuilder object as a string
end
function p.jctint(frame)
-- Entry function for {{jctint/core}}
local args = getArgs(frame) -- Gather passed arguments into easy-to-use table
return p._jctint(args) -- Simply call another function with those arguments to actually create the row
end
return p -- Return package