มอดูล:Adjacent stations

Documentation icon คู่มือการใช้งานมอดูล

This module implements {{Adjacent stations}}, {{Rail icon}}, {{Rail color box}}, {{Line link}}, {{Station link}} and {{Rail color}}. Please see those templates' pages for documentation on how to use those templates. (Instructions for the convert function of this module are in the {{Adjacent stations}} documentation.)

The aforementioned templates rely on data stored in subpages for this module (list). For example, {{Rail icon|MRT}} generates using Module:Adjacent stations/MRT.

It is possible to create and edit data by following existing examples, but having some knowledge of Lua helps prevent mistakes. If you have programmed or used Lua before, you may like to skip the next subsection.


Hierarchy and list of parameters

  1. The first layer of the table is data for the entire system, as well as output options.
  2. Under the system table is the list of lines.
  3. The third layer is data for a given line.
  4. Each line can have 'types'. This can be either types of services or branches of the line.
  5. The fifth layer is data for a given type.

If not specified, all keys and values are strings.

Main layer (1)

ParameterTypeUsed in {{Adjacent stations}}Description
["lang"]Stringใช่ค่าเริ่มต้นสำหรับภาษาไทยคือ "th-TH"
["system title"]Stringใช่Text in the middle cell of the header.
["system icon"]Stringใช่Image used in the middle cell of the {{Adjacent stations}} header and by {{Rail icon}}.
["system icon format"]Stringไม่Icon type, used by {{Rail icon}}. If specified and not "image", the value is passed to the function that implements {{Rail color box}}.
["system color"]Stringไม่RGB hex triplet (three or six characters, like "BE2D2C" or "039"). Can be called by using only one parameter in {{Rail color}}.
["header stop noun"]Stringใช่The noun after 'preceding' and 'following' in the left and right header cells. Default value is "station".
["name format"]Stringไม่CSS for the header of {{Infobox station}} and anything else using the style function with |1=header. Values can be strings or nested tables, with the first level being for the line (whatever's in |style2= of {{Infobox station}}). The second level is currently unused. The first entry in a nested table with no key (i.e. with key 1) is the default.
["header background color"]Stringไม่RGB hex triplet for {{Infobox station}} subheaders and anything else using the style function with |1=subheader. By default, it is a light gray. Values can be strings or nested tables, like those for "name format".
["header text color"]Stringไม่RGB hex triplet for {{Infobox station}} subheaders and anything else using the style function with |1=subheader. By default, it is calculated based on the header background color. Values can be strings or nested tables, like those for ["name format"].
["station format"]Table or stringใช่Table containing station format strings. The first entry without a specified key (i.e. with the key being the number 1) is the default, and all other entries must have keys corresponding to the input. Format strings without wikilink brackets are converted to links, with the input (usually the station name) used as the displayed text. Tables can be nested within this table to indicate options based on the line and line type passed to this template.

%1, %2 and %3 can be used in all strings regardless of the level of nesting to be replaced respectively by the station input, the line input (after alias replacement) and the type input (after alias replacement).

["lines"]Tableใช่Data table containing line tables.
["aliases"]Tableใช่Table containing aliases (as table keys) for lines (as values). All keys are lowercase, as the input is treated as case-insensitive by being lower-cased.

Station format table (2)

ParameterTypeUsed in {{Adjacent stations}}Description
[1]Stringใช่Default format.
["non-default station name"]String or tableใช่Format for a non-default station, or line-specific format table.

Line-specific format table (3)

ParameterTypeUsed in {{Adjacent stations}}Description
[1]Stringใช่Default format.
["line name"]String or tableใช่Format for a non-default station, or type-specific format table.

Type-specific format table (4)

ParameterTypeUsed in {{Adjacent stations}}Description
[1]Stringใช่Default format.
["type name"]Stringใช่Format for a non-default station.

Line table (3)

A virtual line named ["_default"] can be added to set default values for all lines. Currently, this is available for three parameters.

ParameterTypeUsed in {{Adjacent stations}}Description
["title"]Stringใช่The text displayed in the middle cell, typically a link to the line's article. If not specified, then the data in ["_default"] is used (%1 in the default value is replaced by the input after alias replacement).
["short name"]Stringไม่Abbreviated line name used by {{Rail color box}} and {{Short line link}}.
["icon"]Stringไม่Image used by {{Rail icon}}. If not specified, then the data in ["_default"] is used (%1 in the default value is replaced by the input after alias replacement).
["icon format"]Stringไม่Icon type used by {{Rail icon}}. If specified and not "image", the value is passed to the function that implements {{Rail color box}}.
["color"]Stringใช่RGB hex triplet. Lines fall back to the ["_default"] colour (if any) or the system's colour if they themselves do not have one; types fall back to the line's colour (if any), to the ["_default"] colour (if any) or to the system's colour. This colour is used in the second and fourth columns of {{Adjacent stations}}, and by {{Rail color box}} and {{Rail icon}} as the emphasised colour. By default, if a type and its line both have a colour, then the line's colour will be treated as the background colour (see next section) for the line name in the middle cell. This can be turned off by setting the type's background colour to "" or "transparent".
["background color"]Stringใช่RGB hex triplet (three or six characters). This colour is optional and is only displayed behind the line name in the middle cell. The module adds transparency so that all text displayed over the background is legible.
["border color"]Stringไม่RGB hex triplet used by {{Rail color box}}.
["text color"]Stringไม่RGB hex triplet used by {{Rail color box}}.
["left terminus"]Stringใช่The station which is usually the left terminus of the line. If there are multiple stations by default, the value should be a table containing numbered values (e.g. ["left terminus"] = {"Chesham", "Amersham"}). The key ["via"] in that table can be used to append 'via' and the value's station link.
["right terminus"]Stringใช่The station which is usually the right terminus of the line; behaves like ["left terminus"].
["note-mid"]Stringใช่Default small text below line and type names. Overridden by |note-mid= in transclusion.
["circular"]Booleanใช่If the value is true then the termini will display without 'toward'/'towards'. May be overridden by type.
["oneway-left"]Booleanใช่If the value is true then 'One-way operation' will display instead of the left terminus.
["oneway-right"]Booleanใช่Right counterpart of oneway-left.
["types"]Tableใช่Table containing the line type tables.

Type table (5)

ParameterTypeUsed in {{Adjacent stations}}Description
["title"]Stringใช่The name of the line type. In {{Adjacent stations}}, this is displayed as normal-sized text below the line name in the middle cell; in {{Rail color box}}, for some options this is displayed after the line name, separated from it by a spaced en dash (this is also used for the nonstop text). To avoid displaying a type name, set this to "".
["short name"]Stringไม่Abbreviated line name used by {{Rail color box}} and {{Short line link}}.
["icon"]Stringไม่Image used by {{Rail icon}}.
["icon format"]Stringไม่Icon type used by {{Rail icon}}. If specified and not "image", the value is passed to the function that implements {{Rail color box}}.
["color"]Stringใช่RGB hex triplet. Lines fall back to the ["_default"] colour (if any) or the system's colour if they themselves do not have one; types fall back to the line's colour (if any), to the ["_default"] colour (if any) or to the system's colour. This colour is used in the second and fourth columns of {{Adjacent stations}}, and by {{Rail color box}} and {{Rail icon}} as the emphasised colour. By default, if a type and its line both have a colour, then the line's colour will be treated as the background colour (see next section) for the line name in the middle cell. This can be turned off by setting the type's background colour to "" or "transparent".
["background color"]Stringใช่RGB hex triplet (three or six characters). This colour is optional and is only displayed behind the line name in the middle cell. The module adds transparency so that all text displayed over the background is legible.
["border color"]Stringไม่RGB hex triplet used by {{Rail color box}}.
["text color"]Stringไม่RGB hex triplet used by {{Rail color box}}.
["left terminus"]Stringใช่The station which is usually the left terminus of the line. Overrides line terminus. If there are multiple stations by default, the value should be a table containing numbered values (e.g. ["left terminus"] = {"Chesham", "Amersham"}). The key ["via"] in that table can be used to append 'via' and the value's station link.
["right terminus"]Stringใช่The station which is usually the right terminus of the line; behaves like ["left terminus"].
["note-mid"]Stringใช่Default small text below line and type names. Overridden by |note-mid= in transclusion.
["circular"]Booleanใช่If the value is true then the termini will display without 'toward'/'towards'.

require('strict')local p = {}local lang = 'th-TH'local i18n = require("Module:Adjacent stations/i18n")local function getData(system, verify)if verify thenlocal title = mw.title.new('Module:Adjacent stations/' .. system -- .. '/sandbox')if not (title and title.exists) then return nil endendreturn require('Module:Adjacent stations/' .. system -- .. '/sandbox')endlocal function getLine(data, lineN)if lineN thenif data['aliases'] thenlineN = data['aliases'][mw.ustring.lower(lineN)] or lineNendlocal default = data['lines']['_default'] or {}local line = data['lines'][lineN] or {}for k, v in pairs(default) doif v then line[k] = line[k] or v endendline['title'] = line['title'] and mw.ustring.gsub(line['title'], '%%1', lineN)return line, lineNendendlocal function getColor(data, system, line, Type, frame)if system thenif line then return frame:expandTemplate{ title = system .. ' color', args = {line, ['branch'] = Type} } endreturn frame:expandTemplate{ title = system .. ' color' }elseline = (getLine(data, line))local default = data['lines']['_default']if line or default thendefault = default or {}if not line then line = mw.clone(default) endlocal color = line['color'] or line['background color'] or default['color'] or default['background color'] or data['system color']local Type_value = Type and line['types'] and (line['types'][Type] and line['types'][Type]['color'])if Type_value then color = Type_value endreturn colorendreturn (default and (default['color'] or default['background color']) or data['system color'] or '')endendlocal lineN, typeNlocal function somethingMissing(name, key, formats)local formatKeys = {}for k in pairs(formats) dotable.insert(formatKeys, k)endreturn name .. ' was "' .. key .. '" but neither an entry for it nor a default was found. Choices were: ' .. table.concat(formatKeys, ', ')endlocal function getStation(station, _Format)if type(_Format) == 'table' thenlocal lineNformats = _Format_Format = lineNformats[lineN] or lineNformats[1]if not _Format thenerror(somethingMissing('lineN', lineN, lineNformats))elseif type(_Format) == 'table' thenlocal typeNformats = _Format_Format = typeNformats[typeN] or typeNformats[1]if not _Format thenerror(somethingMissing('typeN', typeN, typeNformats))endendendif typeN then _Format = mw.ustring.gsub(_Format, '%%3', typeN) endif lineN then _Format = mw.ustring.gsub(_Format, '%%2', lineN) endreturn (mw.ustring.match(_Format, '%[%[.+%]%]')) and (mw.ustring.gsub(_Format, '%%1', station)) or table.concat({'[[', mw.ustring.gsub(_Format, '%%1', station), '|', station, ']]'})endlocal function getTerminusText(var, Format)local function subst(var1, var2)-- var1 is the terminus or table of termini; var2 is the key for the table of terminireturn type(var1) == 'string' and getStation(var1, (Format[var1] or Format[1]))or type(var1) == 'table' and #var1 > 0 and getStation(var1[var2], (Format[var1[var2]] or Format[1]))or ''endif Format thenif type(var) == 'string' thenreturn subst(var)elseif type(var) == 'table' and #var > 0 thenlocal t = {subst(var, 1)}for i = 2, #var - 1 dot[i] = i18n[lang]['comma'](subst(var, i))endif #var > 1 then t[#var] = i18n[lang]['or'](subst(var, #var)) endif var['via'] thenif i18n[lang]['via-first'] thentable.insert(t, 1, i18n[lang]['via'](subst(var, 'via')))elsetable.insert(t, i18n[lang]['via'](subst(var, 'via')))endendreturn table.concat(t)elsereturn ''endelsereturn var or ''endendfunction p._main(_args) -- Arguments are processed here instead of the main functionlocal yesno = require('Module:Yesno')local trimq = require('Module:Trim quotes')._trimlocal boolean = {['oneway-left'] = true,['oneway-right'] = true,['reverse'] = true,['reverse-left'] = true,['reverse-right'] = true}local args = {} -- Processed argumentslocal index = {} -- A list of addresses corresponding to number suffixes in the argumentsfor k, v in pairs(_args) do -- Maps each raw argument to processed arguments by string matching_args[k] = v:match('^%s*(.-)%s*$')if _args[k] and _args[k] ~= '' thenlocal a = mw.ustring.match(k, '^(.*%D)%d+$') or k -- The parameter; address 1 can be omittedlocal b = tonumber(mw.ustring.match(k, '^.*%D(%d+)$')) or 1 -- The address for a given argument; address 1 can be omittedif boolean[a] thenv = yesno(v)endif not args[b] thenargs[b] = {[a] = v}table.insert(index, b)elseif args[b][a] thenreturn error(i18n[lang]['error_duplicate'](a .. b))elseargs[b][a] = vendendendtable.sort(index)local function small(s, italic)return italic and '<div class="isA">' .. s .. '</div>'or '<div class="smA">' .. s .. '</div>'endlocal style = { -- Style for each cell type['header cell'] = 'class="hcA"|',['header midcell'] = 'colspan="3" class="hmA"|',['body cell'] = 'class="bcA"|',['body banner'] = 'class="bbA" style="color:inherit;background-color:#',}local function rgb(var)if var:len() == 3 thenreturn {tonumber(var:sub(1, 1), 16) * 17, tonumber(var:sub(2, 2), 16) * 17, tonumber(var:sub(2, 2), 16) * 17}elseif var:len() == 6 thenreturn {tonumber(var:sub(1, 2), 16), tonumber(var:sub(3, 4), 16), tonumber(var:sub(5, 6), 16)}endreturn {}endlocal data = {} -- A table of data modules for each addresslocal noclearclass = (((_args.noclear or '') ~= '') and ' adjacent-stations-noclear' or '')local wikitable = {'{| class="wikitable adjacent-stations' .. noclearclass .. '"'}for i, v in ipairs(index) do-- If an address has a system argument, indexes the data moduledata[v] = args[v]['system'] and getData(args[v]['system'])-- If an address has no system, the row uses data from the previous addressor data[index[i - 1]]or (args[v]['header'] and getData(args[index[i+1]]['system']))or error(i18n[lang]['error_unknown'](args[v]['system']))local lang = data[v]['lang'] or langif args[v]['system'] and not args[v]['hide-system'] then -- Header rowlocal stop_noun = data[v]['header stop noun'] or i18n[lang]['stop_noun']table.insert(wikitable, table.concat({'\n|-','\n! scope="col" ', style['header cell'], i18n[lang]['preceding'](stop_noun),'\n! scope="col" ', style['header midcell'], (data[v]['system icon'] and data[v]['system icon'] .. ' ' or ''), (data[v]['system title'] or ('[['.. args[v]['system'] ..']]')),'\n! scope="col" ', style['header cell'], i18n[lang]['following'](stop_noun)}))table.insert(wikitable, '')table.insert(wikitable, '')table.insert(wikitable, '')endif args[v]['header'] then -- Subheadertable.insert(wikitable, '\n|-\n!colspan="5" class="hmA"|'.. args[v]['header'])table.insert(wikitable, '')table.insert(wikitable, '')table.insert(wikitable, '')endif args[v]['line'] or args[v]['left'] or args[v]['right'] or args[v]['nonstop'] thenif not args[v]['line'] and i > 1 and not args[v]['system'] thenargs[v]['line'] = args[index[i - 1]]['line']endlineN = args[v]['line'] or '_default'typeN = args[v]['type']if data[v]['aliases'] thenlineN = data[v]['aliases'][mw.ustring.lower(lineN)] or lineNif typeN then typeN = data[v]['aliases'][mw.ustring.lower(typeN)] or typeN endend-- get the line tablelocal line = data[v]['lines'] and (mw.clone(data[v]['lines'][lineN]) or error(i18n[lang]['error_unknown'](args[v]['line']))) or error(i18n[lang]['error_line'])local default = data[v]['lines']['_default'] or {}line['title'] = line['title'] or default['title']line['title'] = mw.ustring.gsub(line['title'], '%%1', lineN)-- cell across row for non-stop serviceif args[v]['nonstop'] thentable.insert(wikitable,table.concat({'\n|-\n|colspan="5" ',style['body cell'],((args[v]['nonstop'] == 'former') and i18n[lang]['nonstop_past'] or i18n[lang]['nonstop_present'])(p._box({data = data[v], line = lineN, Type = typeN, inline = 'yes'}))}))table.insert(wikitable, '')table.insert(wikitable, '')table.insert(wikitable, '')elselocal Format = data[v]['station format'] or i18n[lang]['error_format']local color, color_2, background_color, circularlocal Type = line['types'] and line['types'][typeN] -- get the line type tableif Type thenif Type['color'] then-- line color is used as background if there is no background color in the line type tablebackground_color = Type['background color'] or line['color']color = Type['color']color_2 = Type['color2'] or colorelsebackground_color = Type['background color'] or line['background color']color = line['color'] or default['color'] or ''color_2 = line['color2'] or colorendif Type['circular'] then-- Type may override the circular status of the linecircular = Type['circular']endelsebackground_color = line['background color']color = line['color'] or default['color'] or ''color_2 = line['color2'] or colorcircular = line['circular']end-- Alternate termini can be specified based on typelocal sideCell = {true, true}for i, b in ipairs({'left', 'right'}) doif not args[v][b] then -- If no station is given on one side, the station is assumed to be the terminus on that sidelocal _through = args[v]['through-' .. b] or args[v]['through']local _through_data = getLine(data[v], _through)if _through_data then _through = _through_data['title'] or _through endsideCell[i] = _through and "''" .. i18n[lang]['through'](trimq(_through)) .. "''"or "''" .. trimq((args[v]['reverse-' .. b]or args[v]['reverse']) and i18n[lang]['reverse']or i18n[lang]['terminus']) .. "''"elselocal terminusTlocal terminusN = Type and Type[b .. ' terminus'] or line[b .. ' terminus']-- If the terminus table has more than one numbered key or has the via key then the table shows only the default termini, since terminusN[2] cannot be used and terminusN[via] is reservedif type(terminusN) == 'string' or (type(terminusN) == 'table' and (terminusN[2] or terminusN['via'])) thenif args[v]['to-' .. b] thenterminusT = args[v]['to-' .. b]local _or = mw.ustring.match(terminusT, i18n[lang]['or-format'])if _or thenterminusT = mw.ustring.gsub(terminusT, i18n[lang]['or-format'], '\127_OR_\127')terminusT = mw.ustring.gsub(terminusT, i18n[lang]['comma-format'], '\127_OR_\127')endlocal _via = (mw.ustring.match(terminusT, i18n[lang]['via-format']))if _via thenterminusT = mw.ustring.gsub(terminusT, i18n[lang]['via-format'], '')terminusT = mw.text.split(terminusT, '\127_OR_\127')terminusT['via'] = _viaelseif _or thenterminusT = mw.text.split(terminusT, '\127_OR_\127')endelseterminusT = terminusNendelseif type(terminusN) == 'table' thenterminusT = terminusN[args[v]['to-' .. b]] or terminusN[args[v]['to']] or terminusN[1]endlocal mainText = args[v]['note-' .. b] and getTerminusText(args[v][b], Format) .. small(args[v]['note-' .. b]) or getTerminusText(args[v][b], Format)local subText = (args[v]['oneway-' .. b] or line['oneway-' .. b]) and i18n[lang]['oneway']or args[v][b] == terminusT and i18n[lang]['terminus']or circular and terminusTor i18n[lang]['towards'](getTerminusText(terminusT, Format))subText = small(subText, true)sideCell[i] = mainText .. subTextendendtable.insert(wikitable, '\n|-')table.insert(wikitable, '\n|' .. style['body cell'] .. sideCell[1])table.insert(wikitable, table.concat({'\n|', style['body banner'], color, '"|','\n|', (background_color and 'class="bcA" style="background-color:rgba(' .. table.concat(rgb(background_color), ',') .. ',.2)"|' or style['body cell']), line['title'],-- Type; table key 'types' in subpages (datatype table, with strings as keys). If table does not exist then the input is displayed as the text(typeN and '<div>' .. (Type and Type['title'] or typeN) .. '</div>' or ''),-- Note-mid; table key 'note-mid' in subpages. Overridden by user input((args[v]['note-mid'] and small(args[v]['note-mid'])) or (Type and Type['note-mid'] and small(Type['note-mid'])) or (line['note-mid'] and small(line['note-mid'])) or ''),-- Transfer; uses system's station link table(args[v]['transfer'] and small('เชื่อมต่อที่ ' .. getTerminusText(args[v]['transfer'], Format), true) or ''),'\n|', style['body banner'], color_2, '"|'}))table.insert(wikitable, '\n|' .. style['body cell'] .. sideCell[2])endendif args[v]['note-row'] then -- Noteif args[v]['note-row']:match('^%s*<tr') or args[v]['note-row']:match('^%s*%|%-') thentable.insert(wikitable, '\n' .. args[v]['note-row'])elsetable.insert(wikitable, '\n|-\n|colspan="5" ' .. style['body cell'] .. args[v]['note-row'])endtable.insert(wikitable, '')table.insert(wikitable, '')table.insert(wikitable, '')endendlocal function combine(t, n)if t[n + 4] ~= '' and t[n + 4] == t[n] thent[n + 4] = '' -- The cell in the next row is deletedlocal rowspan = 2while t[n + rowspan * 4] == t[n] dot[n + rowspan * 4] = ''rowspan = rowspan + 1endt[n] = mw.ustring.gsub(t[n], '\n|class="', '\n|rowspan="' .. rowspan .. '" class="')endendlocal M = #wikitablefor i = 3, M, 4 do combine(wikitable, i) endfor i = 4, M, 4 do combine(wikitable, i) endfor i = 5, M, 4 do combine(wikitable, i) endtable.insert(wikitable, '\n|}')return table.concat(wikitable)endlocal getArgs = require('Module:Arguments').getArgslocal function makeInvokeFunction(funcName)-- makes a function that can be returned from #invoke, using-- [[Module:Arguments]]return function (frame)local args = getArgs(frame, {parentOnly = true})return p[funcName](args, frame)endendp.main = makeInvokeFunction('_main')function p._color(args, frame)local data = args.dataif args[1] or data thendata = data or getData(args[1], true)if not data then return getColor(nil, args[1], args[2], args[3], frame) endreturn getColor(data, nil, args[2], args[3])endendp.color = makeInvokeFunction('_color')function p._box(args, frame)local system = args[1] or args.systemlineN = args[2] or args.lineif not (system or lineN) then return '' endlocal line, Type, line_datalocal inline = args[3] or args.inlinetypeN = args.typelocal data = args.dataif system or data thendata = data or getData(system, true)local colorif data thenlocal default = data['lines']['_default'] or {}line, lineN = getLine(data, lineN)if typeN thentypeN = data['aliases'] and data['aliases'][mw.ustring.lower(typeN)] or typeNType = line['types'] and line['types'][typeN] and line['types'][typeN]['title'] or typeNendcolor = getColor(data, nil, lineN, typeN)if inline ~= 'box' thenline_data = line or error(i18n[lang]['error_unknown'](lineN))line = line_data['title'] or default['title'] or error(i18n[lang]['error_missing']('title'))line = mw.ustring.gsub(line, '%%1', lineN)endelsecolor = getColor(nil, system, lineN, typeN, frame)if inline ~= 'box' thenline = frame:expandTemplate{ title = system .. ' lines', args = {lineN, ['branch'] = typeN} }if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) endendType = typeNendlocal resultif Type and Type ~= '' and inline ~= 'box' thenif line == '' thenline = Typeelseresult = ' – ' .. Typeendendif args.note then result = (result or '') .. ' ' .. args.note endresult = result or ''if not inline then -- [[Template:Legend]]result = '<div class="legend" style="page-break-inside:avoid;break-inside:avoid-column"><span class="legend-color" style="display:inline-block;min-width:1.25em;height:1.25em;line-height:1.25;margin:1px 0;border:1px solid black;background-color:#' .. color .. '"> </span> ' .. line .. result .. '</div>'elseif inline == 'yes' thenresult = '<span style="background-color:#' .. color .. ';border:1px solid #000">    </span>&nbsp;' .. line .. resultelseif inline == 'box' thenresult = '<span style="background-color:#' .. color .. ';border:1px solid #000">    </span>' .. resultelseif inline == 'link' thenlocal link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')if link thenresult = '[[' .. link .. '|<span style="background-color:#' .. color .. ';border:1px solid #000">    </span>]]' .. resultelseresult = '<span style="background-color:#' .. color .. ';border:1px solid #000">    </span>' .. resultendelseif inline == 'square' thenresult = '<span style="color:#' .. color .. ';line-height:initial">■</span>&nbsp;' .. line .. resultelseif inline == 'lsquare' thenlocal link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')if link thenresult = '[[' .. link .. '|<span style="color:#' .. color .. ';line-height:initial">■</span>]]'elseresult = '<span style="color:#' .. color .. ';line-height:initial">■</span>'endelseif inline == 'dot' thenresult = '<span style="color:#' .. color .. ';line-height:initial">●</span> ' .. line .. resultelseif inline == 'ldot' thenlocal link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')if link thenresult = '[[' .. link .. '|<span style="color:#' .. color .. ';line-height:initial">●</span>]]'elseresult = '<span style="color:#' .. color .. ';line-height:initial">●</span>'endelseif inline == 'small' thenresult = '<span style="background-color:#' .. color .. '"> </span>' .. ' ' .. line .. resultelselocal yesno = require("Module:Yesno")local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')local border_color, text_colorlocal color_box = data['color box format'] or data['rail box format'] or {}if line_data thenif line_data['types'] and line_data['types'][typeN] thenlocal Type_data = line_data['types'][typeN]border_color = Type_data['border color'] or line_data['border color'] or colortext_color = Type_data['text color'] or line_data['text color']if color_box == 'title' and not args[4] thenlineN = Type_data['short name'] or line_data['short name'] or require('Module:Delink')._delink{line}elselineN = Type_data['short name'] or line_data['short name'] or lineNendelseborder_color = line_data['border color'] or colortext_color = line_data['text color']if color_box == 'title' and not args[4] thenlineN = line_data['short name'] or require('Module:Delink')._delink{line}elselineN = line_data['short name'] or lineNendendelseborder_color = colorendtext_color = text_color and '#' .. text_color or require('Module:Color contrast')._greatercontrast{color}local bold = ';font-weight:bold'if (yesno(args.bold) == false) then bold = '' endif inline == 'route' then -- [[Template:RouteBox]]if link thenresult = '<span style="background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'elseresult = '<span style="background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'endelseif inline == 'croute' then -- [[Template:Bahnlinie]]if link thenresult = '<span style="background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'elseresult = '<span style="background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'endelseif inline == 'xroute' then -- [[Template:Bahnlinie]]if link thenresult = '<span style="border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em">[[' .. link .. '|<span style="color:#' .. color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'elseresult = '<span style="border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em;color:#' .. color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'endelseif inline == 'broute' thenif link thenresult = '<span style="background-color:#' .. color .. ';border:.075em solid #000;padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'elseresult = '<span style="background-color:#' .. color .. ';border:.075em solid #000;padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'endelse -- [[Template:Legend]] (fallback; duplication to simplify logic)result = '<div class="legend" style="page-break-inside:avoid;break-inside:avoid-column"><span class="legend-color" style="display:inline-block;min-width:1.25em;height:1.25em;line-height:1.25;margin:1px 0;border:1px solid black;background-color:#' .. color .. '"> </span> ' .. line .. result .. '</div>'endendresult = mw.ustring.gsub(result, ':%s*#transparent', ':transparent')return resultendendp.box = makeInvokeFunction('_box')function p._icon(args, frame)local system = args[1] or args.systemlocal data = args.dataif not system and not data thenreturnenddata = data or getData(system)local line, line_name = getLine(data, args[2] or args.line)local iconlocal icon_formatif line thenlocal line_type = args[3] or args.typeif line_type thenline_type = data.aliases and  data.aliases[mw.ustring.lower(line_type)] or line_typeline_type = line.types and line.types[line_type] -- If there's no type table or entry for this type, then it can't have its own iconicon_format = line_type['icon format'] or data['type icon format']if line_type.icon thenicon = line_type.iconendendif not icon thenicon = line.iconend-- Only if there is no icon use the icon_format.if not icon and not icon_format thenicon_format = line['icon format'] or data['line icon format']endlocal default = data.lines._default or {}if icon and string.find(icon, "%%1") and default and default.icon thenicon = mw.ustring.gsub(default.icon, '%%1', line_name)endendif not icon thenicon = data['system icon']endif not icon_format thenicon_format = data['system icon format']endif icon_format thenif icon_format ~= 'image' thenicon = p._box({data = data, [2] = (args[2] or args.line), [3] = icon_format, type = (args[3] or args.type), bold = args.bold, link = args.link}, frame)if args.name thenif line and line.title thenreturn icon .. " " .. line.titleendreturn icon .. " " .. data["system title"]endendendlocal size = args.sizeif size thenif mw.ustring.match(size, '%d$') thensize = '|' .. size .. 'px'elsesize = '|' .. sizeend-- Upright values are to be disabled until there is use of upright scaling in subpages; doesn't seem to work anyway as of 2018-08-10local regex = {'|%s*%d*x?%d+px%s*([%]|])', -- '|%s*upright=%d+%.?%d*%s*([%]|])', '|%s*upright%s*([%]|])'}if mw.ustring.match(icon, regex[1]) thenicon = mw.ustring.gsub(icon, regex[1], size .. '%1')--elseif mw.ustring.match(icon, regex[2]) then--icon = gsub(icon, regex[2], size .. '%1')--elseif mw.ustring.match(icon, regex[3]) then--icon = gsub(icon, regex[3], size .. '%1')elseicon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1' .. size .. '%2')endendlocal link = args.linkif link thenif mw.ustring.match(icon, '|%s*link=[^%]|]*[%]|]') thenicon = mw.ustring.gsub(icon, '|%s*link=[^%]|]*([%]|])', '|link=' .. link .. '%1')elseicon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1|link=' .. link .. '%2')endendlocal alt = args.alt or linkif alt thenif mw.ustring.match(icon, '|%s*alt=[^%]|]*[%]|]') thenicon = mw.ustring.gsub(icon, '|%s*alt=[^%]|]*([%]|])', '|alt=' .. alt .. '%1')elseicon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1|alt=' .. alt .. '%2')endendif args.name thenif line and line.title thenreturn icon .. " " .. line.titleendreturn icon .. " " .. data["system title"]endreturn iconendp.icon = makeInvokeFunction('_icon')function p._line(args, frame)local system = args[1] or args.systemlocal line = args[2] or args.lineif not line then return '' endlocal Type = args[3] or args.typelocal data = args.dataif system or data thendata = data or getData(system, true)if data thenline = (getLine(data, line)) or error(i18n[lang]['error_unknown'](line))if Type thenType = data['aliases'] and data['aliases'][mw.ustring.lower(Type)] or TypeType = line['types'] and line['types'][Type] and line['types'][Type]['title'] or Typeendline = line['title'] or error(i18n[lang]['error_missing']('title'))elseline = frame:expandTemplate{ title = system .. ' lines', args = {line, ['branch'] = Type} }if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) endendif Type and Type ~= '' thenif line == '' thenline = Typeelseline = line .. ' – ' .. Typeendendreturn lineendendp.line = makeInvokeFunction('_line')function p._shortline(args, frame)local system = args[1] or args.systemlineN = args[2] or args.lineif not (system or lineN) then return '' endlocal line, Type, line_datatypeN = args.typelocal data = args.dataif system or data thendata = data or getData(system, true)if data thenlocal default = data['lines']['_default'] or {}line, lineN = getLine(data, lineN)if typeN thentypeN = data['aliases'] and data['aliases'][mw.ustring.lower(typeN)] or typeNType = line['types'] and line['types'][typeN] and line['types'][typeN]['title'] or typeNendline_data = line or error(i18n[lang]['error_unknown'](lineN))line = line_data['title'] or default['title'] or error(i18n[lang]['error_missing']('title'))line = mw.ustring.gsub(line, '%%1', lineN)elseline = frame:expandTemplate{ title = system .. ' lines', args = {lineN, ['branch'] = typeN} }if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) endType = typeNendlocal resultif Type and Type ~= '' thenif line == '' thenline = Typeelseresult = ' – ' .. Typeendendif args.note then result = (result or '') .. ' ' .. args.note endresult = result or ''local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')if line_data thenif line_data['types'] and line_data['types'][typeN] thenlocal Type_data = line_data['types'][typeN]lineN = Type_data['short name'] or line_data['short name'] or lineNelselineN = line_data['short name'] or lineNendendif link thenresult = '[[' .. link .. '|' .. lineN .. ']]'elseresult = lineNendresult = mw.ustring.gsub(result, ':%s*#transparent', ':transparent')return resultendendp.shortline = makeInvokeFunction('_shortline')function p._station(args, frame)local system = args[1] or args.systemlocal station = args[2] or args.stationif not station then return '' endlineN = args[3] or args.linetypeN = args[4] or args.typelocal data = args.dataif system or data thendata = data or getData(system, true)if data thenlocal _Format = data['station format'][station] or data['station format'][1]if _Format thenif data['aliases'] thenif lineN thenlineN = data['aliases'][mw.ustring.lower(lineN)] or lineNendif typeN thentypeN = data['aliases'][mw.ustring.lower(typeN)] or typeNendendstation = getStation(station, _Format)elsestation = station or ''endelsestation = frame:expandTemplate{ title = system .. ' stations', args = {['station'] = station, ['line'] = lineN, ['branch'] = typeN} }endreturn stationendendp.station = makeInvokeFunction('_station')function p._terminusTable(args, frame)local system = args[1] or args.systemlineN = args[2] or args.linelocal side = mw.ustring.sub(mw.ustring.lower(args[3] or args.side or ''), 1, 1)typeN = args.typelocal prefix = (side == 'r') and 'right' or 'left'local data = args.dataif system or data thendata = data or getData(system, true)endif data thenlocal line = getLine(data, lineN) or error(i18n[lang]['error_unknown'](lineN))if typeN and data and data['aliases'] then typeN = data['aliases'][mw.ustring.lower(typeN)] or typeN endlocal Type = line['types'] and line['types'][typeN]local circularif Type thenif Type['circular'] then-- Type may override the circular status of the linecircular = Type['circular']endelsecircular = line['circular']endreturn Type and Type[prefix .. ' terminus'] or line[prefix .. ' terminus'], data['station format'] or i18n[lang]['error_format'], circularelselocal terminus = frame:expandTemplate{ title = 'S-line/' .. system .. ' ' .. prefix .. '/' .. lineN }return mw.ustring.gsub(terminus, '{{{type}}}', typeN)endendfunction p._terminus(args, frame)local var, Format, circular = p._terminusTable(args, frame)return circular and var or getTerminusText(var, Format)endp.terminus = makeInvokeFunction('_terminus')function p._style(args, frame)local style = args[1] or args.stylelocal system = args[2] or args.systemlocal line = args[3] or args.linelocal station = args[4] or args.stationlocal result = {}local data = args.datalocal default = 'background-color:#efefef' -- Default background color for {{Infobox station}}if system or data thendata = data or getData(system, true)endif data thenlocal function getValue(var)if type(var) == 'table' thenvar = var[line] or var[1]if type(var) == 'table' thenvar = var[station] or var[1]endendif var ~= '' then return var endendif style == 'header' thenlocal tmp = data['name format'] and getValue(data['name format'])if tmp then table.insert(result, tmp) endelseif style == 'subheader' thenlocal tmp = data['header background color'] and getValue(data['header background color'])if tmp thentable.insert(result, 'background-color:#' .. tmp)local color = data['header text color'] and getValue(data['header text color'])if color thentable.insert(result, 'color:#' .. color)elselocal greatercontrast = require('Module:Color contrast')._greatercontrastif greatercontrast{tmp} == '#FFFFFF' then table.insert(result, 'color:#FFFFFF') endendelsetable.insert(result, default)local color = data['header text color'] and getValue(data['header text color'])if color then table.insert(result, 'color:#' .. color) endendendresult = table.concat(result, ';')elseif system thenlocal title = 'Template:' .. system .. ' style'local titleObj = mw.title.new(title)if titleObj and titleObj.exists thenlocal tmpif style == 'header' thentmp = frame:expandTemplate{ title = title, args = {'name_format', line, station} }if tmp ~= '' then table.insert(result, tmp) endelseif style == 'subheader' thentmp = frame:expandTemplate{ title = title, args = {'thbgcolor', line, station} }if tmp ~= '' thentable.insert(result, 'background-color:#' .. tmp)local color = frame:expandTemplate{ title = title, args = {'thcolor', line, station} }if color ~= '' thentable.insert(result, 'color:#' .. color)elselocal ratio = require('Module:Color contrast')._ratioif ratio{tmp, '222222'} < 4.5 then table.insert(result, 'color:#FFFFFF') end -- 222222 is the default text color in Vectorendelsetable.insert(result, default)tmp = frame:expandTemplate{ title = title, args = {'thcolor', line, station} }if tmp ~= '' thentable.insert(result, 'color:#' .. tmp)endendendresult = table.concat(result, ';')elseif style == 'subheader' thenresult = defaultelseresult = ''endendelseif style == 'subheader' thenresult = defaultelseresult = ''endendreturn resultendfunction p.style(frame)local args = getArgs(frame, {frameOnly = true})return p._style(args, frame)endfunction p.convert(frame)local args = frame.argslocal code = mw.text.split(mw.ustring.gsub(args[1], '^%s*{{(.*)}}%s*$', '%1'), '%s*}}%s*{{%s*')local systemlocal group = tonumber(args.offset or 0) or 0local firstgroup = group + 1local delete = {['s-rail'] = true,['s-rail-next'] = true,['s-rail-national'] = true,['s-start'] = true,['s-rail-start'] = true,['start'] = true,['s-end'] = true,['end'] = true}local order = {'line', 'left', 'right', 'to-left', 'to-right','oneway-left', 'oneway-right', 'through-left', 'through-right','reverse', 'reverse-left', 'reverse-right','note-left', 'note-mid', 'note-right', 'transfer'-- circular: use module subpage-- state: not implemented}local replace = {['previous'] = 'left',['next'] = 'right',['type'] = 'to-left',['type2'] = 'to-right',['branch'] = 'type',['note'] = 'note-left',['notemid'] = 'note-mid',['note2'] = 'note-right',['oneway1'] = 'oneway-left',['oneway2'] = 'oneway-right',['through1'] = 'through-left',['through2'] = 'through-right'}local remove_rows = {}local data = {}local noclear = falsefor i, v in ipairs(code) docode[i] = mw.ustring.gsub(code[i], '\n', ' ')local template = mw.ustring.lower(mw.text.trim(mw.ustring.match(code[i], '^[^|]+')))code[i] = mw.ustring.match(code[i], '(|.+)$')if (mw.ustring.match(code[i] or '', 'noclear%s*=%s*[a-z]')) thennoclear = trueendif template == 's-line' thendata[i] = {}local this_system = mw.text.trim(mw.ustring.match(code[i], '|%s*system%s*=([^|]+)'))code[i] = mw.text.split(code[i], '%s*|%s*')for m, n in ipairs(code[i]) dolocal tmp = mw.text.split(n, '%s*=%s*')if tmp[3] thentmp[2] = mw.ustring.gsub(n, '^.-%s*=', '')endtmp[1] = replace[tmp[1]] or tmp[1]if tmp[2] then-- checks for matching bracketslocal curly = select(2, mw.ustring.gsub(tmp[2], "{", ""))-select(2, mw.ustring.gsub(tmp[2], "}", ""))local square = select(2, mw.ustring.gsub(tmp[2], "%[", ""))-select(2, mw.ustring.gsub(tmp[2], "%]", ""))if not (curly == 0 and square == 0) thenlocal count = mw.clone(m)+1while not (curly == 0 and square == 0) dotmp[2] = tmp[2]..'|'..code[i][count]curly = curly+select(2, mw.ustring.gsub(code[i][count], "{", ""))-select(2, mw.ustring.gsub(code[i][count], "}", ""))square = square+select(2, mw.ustring.gsub(code[i][count], "%[", ""))-select(2, mw.ustring.gsub(code[i][count], "%]", ""))code[i][count] = ''count = count+1endenddata[i][tmp[1]] = tmp[2]endendif (this_system ~= system) or (not system) thensystem = this_systemdata[i]['system'] = systemelsedata[i]['system'] = nilendlocal last = data[i-1] or data[i-2] or data[i-3]if last thenfor r, s in pairs({['hide1'] = {'left', 'to-left', 'note-left', 'oneway-left'},['hide2'] = {'right', 'to-right', 'note-right', 'oneway-right'},['hidemid'] = {'type', 'note-mid'}}) doif data[i][r] thenfor m, n in ipairs(s) doif not data[i][n] thendata[i][n] = last[n]endendendendendcode[i] = {}local X = '|'local Y = (i+group)..'='if data[i]['system'] thentable.insert(code[i], '|system')table.insert(code[i], Y)table.insert(code[i], data[i]['system'])table.insert(code[i], '\n')endfor m, n in ipairs(order) doif data[i][n] thentable.insert(code[i], X)table.insert(code[i], n)table.insert(code[i], Y)table.insert(code[i], data[i][n])endendcode[i] = table.concat(code[i])elseif template == 's-note' thencode[i] = mw.ustring.gsub(code[i], '|%s*text%s*=', '|header'..i+group..'=')code[i] = mw.ustring.gsub(code[i], '|%s*wide%s*=[^|]*', '')elseif template == 's-text' thencode[i] = mw.ustring.gsub(code[i], '|%s*text%s*=', '|note-row'..i+group..'=')elseif delete[template] thencode[i] = ''table.insert(remove_rows, 1, i) -- at the start, so that the rows are deleted in reverse ordergroup = group-1endendfor i, v in ipairs(remove_rows) dotable.remove(code, v)endcode = table.concat(code, '\n')local t = {'{{Adjacent stations' .. (noclear and '|noclear=y\n' or ''), '\n}}'}system = mw.ustring.match(code, '|system(%d*)=')code = mw.ustring.gsub(code, '\n\n+', '\n')if tonumber(system) > firstgroup then-- If s-line isn't the first template then the system will have to be moved to the topsystem = mw.ustring.match(code, '|system%d*=([^|]*[^|\n])')code = mw.ustring.gsub(code, '|system%d*=[^|]*', '')code = '\n|system'..firstgroup..'='..system..codeelseif not mw.ustring.match(code, '^[^{%[]*|[^=|]+2=') then-- If there's only one parameter group then there's no need to have line breakscode = mw.ustring.gsub(code, '\n', '')code = mw.ustring.gsub(code, '(|[^=|]+)1=', '%1=')t[2] = '}}'if not mw.ustring.match(code, '[%[{]') thencode = mw.ustring.gsub(code, '|[^=|]*=$', '')code = mw.ustring.gsub(code, '|[^=|]*$', '')endendif not mw.ustring.match(code, '[%[{]') thencode = mw.ustring.gsub(code, '|[^=|]*=|', '|')code = mw.ustring.gsub(code, '|[^=|]*|', '|')code = mw.ustring.gsub(code, '|[^=|]*=\n', '\n')code = mw.ustring.gsub(code, '|[^=|]*\n', '\n')endreturn t[1]..code..t[2]endreturn p
🔥 Top keywords: พระวรวงศ์เธอ พระองค์เจ้าเฉลิมศึกยุคลหน้าหลักพระสุนทรโวหาร (ภู่)องค์การกระจายเสียงและแพร่ภาพสาธารณะแห่งประเทศไทยพิเศษ:ค้นหาพระบาทสมเด็จพระวชิรเกล้าเจ้าอยู่หัวพระเจ้าวรวงศ์เธอ พระองค์เจ้าเฉลิมพลฑิฆัมพรอสมทวอลเลย์บอลหญิงเนชันส์ลีก 2024สไปร์ท (แร็ปเปอร์)ฟุตบอลชิงแชมป์แห่งชาติยุโรปฟุตบอลชิงแชมป์แห่งชาติยุโรป 2024พุ่มพวง ดวงจันทร์ดวงใจเทวพรหม (ละครโทรทัศน์)อีดิลอัฎฮาสมเด็จพระเจ้าบรมวงศ์เธอ เจ้าฟ้ายุคลทิฆัมพร กรมหลวงลพบุรีราเมศวร์ดอกเตอร์ไคลแมกซ์ ปุจฉาพาเสียวราชวงศ์จักรีลำดับโปเจียมแห่งราชอาณาจักรไทยรายชื่อตัวละครในพระอภัยมณีหม่อมเจ้านวพรรษ์ ยุคลทุติยจุลจอมเกล้าวิเศษพระเจ้าวรวงศ์เธอ พระองค์เจ้าภาณุพันธุ์ยุคลพระอภัยมณีหม่อมเจ้ามงคลเฉลิม ยุคลหม่อมเจ้าฑิฆัมพร ยุคลพระบาทสมเด็จพระจุลจอมเกล้าเจ้าอยู่หัวพระบาทสมเด็จพระมหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตรหลานม่าอริยสัจ 4ตารางธาตุนิราศภูเขาทองรายชื่อเครื่องดนตรีเฌอมาวีร์ สุวรรณภาณุโชคประเทศไทยอาณาจักรอยุธยาปิติ ภิรมย์ภักดีวอลเลย์บอลวอลเลย์บอลหญิงทีมชาติไทย