请输入您要查询的百科知识:

 

词条 Module:Jctint/core/sandbox
释义

local p = {} -- Package to be exported

-- Change to "" upon deployment.

local moduleSuffix = "/sandbox"

local parserModuleName = "Module:Road data/parser" .. moduleSuffix

-- Local version of string formatting function

local format = mw.ustring.format

-- Store functions in a local variable to avoid expensive table lookups.

local concat = table.concat

local insert = table.insert

-- Road data functions

local roadDataModule = require("Module:Road data")

-- Road data utility functions

local util = require("Module:Road data/util")

-- mw.html object for the generated row

local row

-- Default row span for all columns (`jspan` = "junction span")

local jspan

-- Error types

local errorTypes = {

convert = {cat = "Category:Jctint template using non-numeric parameter values", prefix = "#"},

type = {cat = "Category:Jctint template with invalid type"}

}

-- Error messages to be added to the output

local errors = {}

-- 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 lengths = util.convertLengths({[unitdef] = unit})

if lengths.error then -- An error occurred during conversion.

errors.convert = lengths.error

end

return lengths

end

--- Prepare wikitext for a given location cell.

local function locnSub(args, config, subType)

local locns = {warnings = {}}

local origParam

local group

local subTypeConfig = config[subType .. "_params"] or {subType}

if args[subType .. "_special"] then

locns[subType] = args[subType .. "_special"]

return locns

end

local paramPrefix = subTypeConfig[#subTypeConfig]

if paramPrefix and args[paramPrefix .. "_special"] then

locns[subType] = args[paramPrefix .. "_special"]

return locns

end

-- Find parameter.

for _,p in ipairs(subTypeConfig) do

if args[p] then

origParam = p

group = false

break

elseif args[p .. 1] then

origParam = p

group = true

break

end

end

if origParam then

local subParts = {}

-- Retrieve wikilinks for subdivisions.

local num = 1

local paramSuffix = group and num or ""

while num == 1 or group and args[origParam .. paramSuffix] do

local param = origParam

local saved = {}

saved[param] = args[param] or false

args[param] = args[origParam .. paramSuffix]

if subType == "sub1" then

-- Handle sub1area

local sub1area_param = config.sub1area_param or "sub1area"

saved.sub1area = args.sub1area or false

args.sub1area = args[sub1area_param .. paramSuffix]

elseif subType == "sub2" then

-- Handle sub1dab and sub2area

local sub1dab_param = config.sub1dab_param or "sub1dab"

saved.sub1dab = args.sub1dab or false

args.sub1dab = args[sub1dab_param .. paramSuffix] or args[sub1dab_param]

local sub2area_param = config.sub2area_param or "sub2area"

saved.sub2area = args.sub2area or false

args.sub2area = args[sub2area_param .. paramSuffix]

end

while config[param] and config[param].alias do

-- Resolve alias and save parameters.

for key,value in pairs(config[param].alias) do

if key == "param" then

saved[value] = args[value] or false

args[value] = args[param]

param = value

else

saved[key] = args[key] or false

args[key] = value

end

end

end

local subTypeCall = roadDataModule.locations(args, "jctint", group)

insert(subParts, subTypeCall[subType])

util.addAll(locns.warnings, subTypeCall.warnings, true)

-- Restore parameters.

for key,value in pairs(saved) do

args[key] = value or nil

end

num = num + 1

paramSuffix = group and num or ""

end

if group then

if #subParts > 1 then

-- Construct wikitext for multiple subs.

local textParts = {}

insert(textParts, subParts[1])

for i = 2, #subParts do

insert(textParts, "–")

if i % 2 ~= 0 then

-- Odd subs after first begin a new line.

insert(textParts, "
")

end

insert(textParts, subParts[i])

end

local groupSuffix = args[origParam .. "_group"] or config[origParam] and config[origParam].group

if groupSuffix then

insert(textParts,

format("%s%s", #subParts % 2 == 0 and "
" or " ", groupSuffix))

end

if #subParts == 2 then

local borderSuffix = config.bordersuffix or "border"

if borderSuffix ~= "" then

insert(textParts, " " .. borderSuffix)

end

elseif #subParts == 3 then

insert(textParts, " tripoint")

elseif #subParts == 4 then

insert(textParts, " quadripoint")

else

insert(textParts, " multipoint")

end

locns[subType] = concat(textParts)

else

locns.warnings.group = "Singleton list for " .. origParam

end

else

locns[subType] = concat(subParts)

end

end

return locns

end

--- Prepare wikitext for location cells.

local function locns(args)

local parserModule = require(parserModuleName)

local config = parserModule.parser(args, "jctrow", " config ") or {}

local locns = {warnings = {}}

local regionCall = roadDataModule.locations(args, "jctint")

locns.region = regionCall.region

util.addAll(locns.warnings, regionCall.warnings, true)

local indepCityCall = locnSub(args, config, "indep_city")

locns.indep_city = indepCityCall.indep_city

util.addAll(locns.warnings, indepCityCall.warnings, true)

if locns.indep_city then return locns end

local sub1Call = locnSub(args, config, "sub1")

locns.sub1 = sub1Call.sub1

util.addAll(locns.warnings, sub1Call.warnings, true)

local sub2Call = locnSub(args, config, "sub2")

locns.sub2 = sub2Call.sub2

util.addAll(locns.warnings, sub2Call.warnings, true)

return locns

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

-- Prepare text for location cells.

local locns = locns(args)

-- Create cells for regular location columns.

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

end

-- 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 = locns.indep_city -- Value to span both subdivision columns.

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 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 sub1Text = locns.sub1 -- Value for first-level subdivision column.

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

sub1Cell:tag('small'):wikitext(sub1note)

end

end

-- Second-level subdivision, e.g., city and town

local sub2Text = locns.sub2 -- Value for second-level subdivision column.

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

local secondary = row:tag('th'):attr('scope', 'row') -- Create the secondary unit cell.

:css('text-align', 'right')

:attr('rowspan', uspan)

:wikitext(lengths[lengths.comp]) -- Store the secondary distance in the cell.

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

-- Add the converted second distance to the secondary distance cell.

secondary:wikitext(lengths2[lengths2.comp])

end

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

end

end

-- Spec for formatting cell background colors and tooltip based on types

local typesSpec = {}

--- Apply any type-derived coloring and tooltip to the given cell.

local function applyTypeStyle(cell, multiple)

cell:attr('title', typesSpec.title)

:css('background', multiple and typesSpec.colors or typesSpec.color)

if multiple and typesSpec.minWidth then

-- minimum cell width to make enough room for all colors

cell:css('min-width', format('%dpx', typesSpec.minWidth))

end

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, true)

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

local oldExits = {}

if args.old then insert(oldExits, args.old) end

local num = 0

repeat

num = num + 1

local key = "old" .. num

if args[key] then insert(oldExits, args[key]) end

until num > 1 and args[key] == nil

-- Row span (`ospan` = "old span")

local ospan = args.ospan or jspan

local oldExitCell = row:tag('td') -- Create old exit number cell

:css('text-align', 'center')

:css('background-color', '#d3d3d3')

:attr('title', 'Former exit number')

:attr('rowspan', ospan)

if #oldExits > 2 then

-- Create a collapsible table for many old exit numbers.

local numOldExits = #oldExits

local tbl = oldExitCell:tag("table")

:attr("class", "collapsible collapsed")

:css("margin", "auto")

:css("border-collapse", "collapse")

tbl:tag("th"):attr("scope", "col")

local ul = tbl:tag("tr"):tag("td"):tag("div")

:attr("class", "plainlist")

:tag("ul")

:css("text-align", "center")

for num,oldExit in ipairs(oldExits) do

if num < numOldExits then

ul:tag("li"):wikitext(oldExit)

end

end

-- Most recent number is always shown below the table.

oldExitCell:wikitext(oldExits[numOldExits])

else

-- Create an hlist for few old exit numbers.

local ul = oldExitCell:tag("div")

:attr("class", "hlist")

:tag("ul")

:css("text-align", "center")

for _,oldExit in ipairs(oldExits) do

ul:tag("li"):wikitext(oldExit)

end

end

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, true)

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

local types = mw.text.split(argType, ",")

table.sort(types, function(a, b) return a > b end)

-- Type-based data for colors and tooltips

local definedTypes = mw.loadData("Module:Road data/RJL types")

local colors = {}

local titles = {}

for _,type in ipairs(types) do

local typeSpec = definedTypes[string.lower(type)] -- Retrieve the type spec

if typeSpec then

insert(colors, typeSpec.color)

insert(titles, 1, typeSpec.jctint)

title = typeSpec.jctint -- Store the tooltip globally

else

errors.type = util.err("Invalid type: " .. argType)

end

end

local colorWidth = 36

local colorSpec = {}

local lastColor

local colorCount = 0

for _,color in ipairs(colors) do

if lastColor then

insert(colorSpec, format("%s %dpx", lastColor, colorCount * colorWidth))

end

insert(colorSpec, format("%s %dpx", color, colorCount * colorWidth))

lastColor = color

colorCount = colorCount + 1

end

if colorCount > 1 then

typesSpec.colors = format("linear-gradient(-90deg, %s);", concat(colorSpec, ", "))

typesSpec.minWidth = (colorCount - 1) * colorWidth

end

typesSpec.color = lastColor

typesSpec.title = concat(titles, ", ")

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

-- Prepare error messages.

local errorMsg = {}

for key,msg in pairs(errors) do

-- Add the transcluding page to an error tracking category.

local prefix = errorTypes[key].prefix and errorTypes[key].prefix .. " " or ""

insert(errorMsg, format("%s%s%%page%%", msg, errorTypes[key].cat, prefix))

end

if #errorMsg > 0 then

local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page's title

-- Add error cell

local msg = mw.ustring.gsub(concat(errorMsg, " "), "%%page%%", page)

row:tag("td"):wikitext(msg)

end

-- Return the HTML code in the mw.html object as a string

return tostring(root)

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

随便看

 

开放百科全书收录14589846条英语、德语、日语等多语种百科知识,基本涵盖了大多数领域的百科知识,是一部内容自由、开放的电子版国际百科全书。

 

Copyright © 2023 OENC.NET All Rights Reserved
京ICP备2021023879号 更新时间:2024/9/20 13:34:41