Module:Jctco
Jump to navigation
Jump to search
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}
local roadDataModule = require('Module:Road data')
local format = mw.ustring.format
local frame = mw.getCurrentFrame()
local getArgs = require('Module:Arguments').getArgs
local function country(args)
local state = args.state or args.province or args.department
local country
local countryModule = mw.loadData("Module:Road data/countrymask")
local country = args.country or countryModule[state] or nil
return country
end
local function state(args)
local state = args.state or args.province
local country = country(args)
if country == 'FRA' then
return ''
else
return frame:expandTemplate ({title='Country name', args = { country .. "-" .. state}})
end
end
local function sub1name(args)
local country = country(args)
local state = state(args)
local sub1name
if args.department then
sub1name = ''
elseif args.borough then
sub1name = "Borough"
elseif args.municipality then
if state == 'Québec' then
sub1name = "Regional County Municipality"
else
sub1name = "Municipality"
end
elseif args.parish then
sub1name = "Parish"
elseif args.district then
sub1name = "District"
else
sub1name = "County"
end
return sub1name
end
local function category(args)
local country = country(args)
local state = state(args)
local sub1name = sub1name(args)
local sub1 = args.department or args.borough or args.municipality or args.parish or args.district or args.county -- add more as needed
if sub1 then
if country == 'FRA' then
return format('[[Category:%s]]', sub1)
else
return format('[[Category:%s %s, %s]]', sub1, sub1name, state)
end
else
return nil
end
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 = state(args)
if region or args.region_special then
-- Row span for region; must be specified to display a region cell.
local regionSpan = args.regionspan or args.sspan
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("[[w:%s|%s]]", region, 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.county_note -- check existence later
-- Row span for the last location column, default to `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('[[w:%s|%s]]', indepCity, indepCity)
elseif region then
-- Specialize independent city to the region.
cityLink = format('[[w:%s, %s|%s]]', indepCity, region, indepCity)
end
if cityLink then
indepCityText = "[[w: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', jspan) -- 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
local country = country(args)
local state = state(args)
local sub1 = args.department or args.borough or args.municipality or args.parish or args.district or args.county -- add more as needed
-- Name of the type of subdivision, e.g., "County" and "Parish"
local sub1name = sub1name(args)
local sub1Text -- Value for first-level subdivision column.
if args.sub1_special then
sub1Text = args.special -- Overrides `sub1` argument.
elseif sub1 then
if country == 'BLZ' then
-- Add type (if specified) to wikilink for first-level subdivision.
local sub1Link = format("%s %s", sub1, sub1name)
sub1Text = format('[[w:%s|%s]]', sub1Link, sub1)
elseif country == 'FRA' then
sub1Text = format('[[w:%s|%s]]', sub1, 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('[[w:%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
end
--- Creates a cell for places, such as bridges and rest areas.
local function place(args)
local place = "No major intersections"
local colspan = 5 -- 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
local indepCity = args.indep_city
-- Adjust column span
if exit == "old" then colspan = colspan + 2
elseif exit == "exit" then colspan = colspan + 1
elseif indepCity 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
end
---
-- Returns a row in the junction list.
-- Accessible from other Lua modules
function p._jctco(args)
local country = country(args)
jspan = args.jspan or 1 -- Global row span for all columns; defaults to 1
if country == nil then
return nil
else
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
place(args) -- Create cell for place
category(args) -- Create location category
-- Return the HTML code in the mw.html object as a string, plus any error messages
return tostring(root) .. table.concat(errorMsg)
end
end
--- Entry function for {{jctco/core}}
function p.jctco(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._jctco(args)
end
return p -- Return package