-- This module implements the template.
-- Data is in Module:Track gauge/data
local p = {}
local gaugeDataAll = nil
local dataPageName = 'Module:Track gauge/data' -- set /data/sandbox here
---
-- prepareArgs -- Normalise Arguments coming from an #invoke or from a module
---
local function prepareArgs
local origArgs
if == mw.getCurrentFrame then
origArgs = :getParent.args
for k, v in pairs(.args) do
origArgs = .args
break
end
else
origArgs =
end
local args = {}
-- searchAlias is the cleaned value of args[1]. args[1] is kept as rawInput for error message
local searchAlias = ''
local rawDisp
for k, v in pairs(origArgs) do
if tonumber(k) == nil then -- Named argment
if k == 'disp' then
rawDisp = v -- Keep raw disp input to pass through plain (wiki)text
args[k] = mw.ustring.lower(v)
elseif k == 'first' then
v = mw.ustring.lower(v)
if v == 'met' or v == 'metric' then
v = 'met'
elseif v == 'imp' or v == 'imperial' then
v = 'imp'
else k = 'trashparam_first' end
args[k] = v
elseif k == 'nowrap' or k == 'wrap' then -- wrap=y deprecated; reading: nowrap=off
v = mw.ustring.lower(v)
if v == '' or v == 'off' or v == 'on' or v == 'all' then
elseif v == 'inline' or (k == 'wrap' and v == 'y') then
v = 'off'
else v = '' end
args['nowrap'] = v
else
args[k] = mw.ustring.lower(v)
end
else
args[k] = v -- Keep rawInput in [1] for error message
if k == 1 then
-- Unnamed argument, the alias to be searched
-- Cleanup
searchAlias = p.normaliseAliasInput(v)
end
end
end
args['searchAlias'] = searchAlias
if rawDisp then args['rawDisp'] = rawDisp end
return args
end
---
-- normaliseAliasInput
---
function p.normaliseAliasInput(aliasIn)
local a
a = mw.ustring.lower(mw.ustring.gsub(aliasIn, '[%s%,]', ''))
a = mw.ustring.gsub(a, '&nbsp;', '')
a = mw.ustring.gsub(a, 'gauge$', '')
a = mw.ustring.gsub(a, "'", "ft")
a = mw.ustring.gsub(a, '"', 'in')
a = mw.ustring.gsub(a, '⁄', '/')
a = mw.ustring.gsub(a, '&frasl;', '/')
return a
end
---
-- debugReturnArgs -- Debug function.
---
function p.debugReturnArgs
local args = prepareArgs
local retArgs = {}
for k, a in pairs(args) do
table.insert(retArgs, k .. '=' .. a)
end
return 'Args: ' .. table.concat(retArgs, '; ')
end
---
-- getTrackGaugeEntry -- Find entry data for a single gauge (alias)
---
function p.getTrackGaugeEntry(searchAlias)
gaugeDataAll = mw.loadData(dataPageName)
if searchAlias == '' then
return nil
end
local tgEntry = nil
for i, tgEntry in ipairs(gaugeDataAll) do
for j, alias in ipairs(tgEntry.aliases) do
if alias == searchAlias then
return tgEntry
end
end
end
end
---
-- noWrap -- Add span tags to prevent a string from wrapping.
---
local function noWrap(s)
return mw.ustring.format('<span>%s</span>', s)
end
---
-- frac -- A slimmed-down version of the template (a nowrap is to be added with the unit)
---
local function frac(whole, num, den)
return mw.ustring.format(
'<span>%s%s<sup>%s</sup>&frasl;<sub>%s</sub></span>',
whole or *, whole and '<span>&nbsp;</span>' or *,
num, den)
end
---
-- catMentions -- Wikicode for "article mentions gauge" categories
---
function p.catMentions(tgEntry, sortlabel, doReturn)
local ns = 'Category:'
local cat  
if tgEntry == nil then
-- Parent, the container cat
cat = 'Articles that mention a specific track gauge'
else
cat = 'Articles that mention track gauge ' .. tgEntry.id .. ' mm'
end
-- Argument 'label' can be used to add a catsort. Catsort is not used (as of 20 May 2014)
if sortlabel ~= nil then
sortlabel = '|' .. sortlabel
else
sortlabel = ''
end
if doReturn ~= nil then
if doReturn == 'fullpagename' then
return ns .. cat
elseif doReturn == 'pagename' then -- plaintext, no namespace
return cat
elseif doReturn == 'show' then -- colontrick
return ':' .. ns .. cat .. sortlabel .. ''
else -- unknown arg value
return ns .. cat
end
else -- Returns straight categorisation (wikitext)
return * .. ns .. cat .. sortlabel .. *
end
end
---
-- formatImp -- Formats imperial units size into a single text element
---
function p.formatImp(tgEntry, measurementToLink, setNowrap, addUnitlink)
local ret = {}
local ft = tgEntry.ft
if ft then
local ftlink = addUnitlink and measurementToLink ~= 'imp' and 'ft' or 'ft'
table.insert(ret, mw.ustring.format('%s&nbsp;%s', ft, ftlink))
end
local inches = tgEntry['in']
local num = tgEntry.num
local den = tgEntry.den
if inches and not num and not den then
table.insert(ret, inches)
elseif num and den then
table.insert(ret, frac(inches, num, den))
end
if inches or num and den then
local incheslink = addUnitlink and measurementToLink ~= 'imp' and 'in' or 'in'
table.insert(ret, incheslink)
end
local gaugeSize
if setNowrap then
gaugeSize = noWrap(table.concat(ret, '&nbsp;'))
else
gaugeSize = table.concat(ret, '&nbsp;')
end
if measurementToLink == 'imp' and tgEntry.pagename ~= nil then
return mw.ustring.format('%s', tgEntry.pagename, gaugeSize)
else
return gaugeSize
end
end
---
-- formatMet -- Formats metric measurements into a single formatted text element. Public for autodocument
---
function p.formatMet(tgEntry, measurementToLink, setNowrap, addUnitlink)
local m = tgEntry.m
local gaugeSize
if m then
local mUnit = addUnitlink and measurementToLink ~= 'met' and 'm' or 'm'
gaugeSize = mw.ustring.format('%s&nbsp;%s', m, mUnit)
else
local mm = tgEntry.mm
mm = tonumber(mm)
if mm then
mm = mw.getContentLanguage:formatNum(mm)
end
local mmUnit = addUnitlink and measurementToLink ~= 'met' and 'mm' or 'mm'
gaugeSize = mw.ustring.format('%s&nbsp;%s', mm, mmUnit)
end
if setNowrap then
gaugeSize = noWrap(gaugeSize)
end
if measurementToLink == 'met' and tgEntry.pagename ~= nil then
return mw.ustring.format('%s', tgEntry.pagename, gaugeSize)
else
return gaugeSize
end
end
---
-- formatAltName
---
function formatAltName(tgEntry, addGaugeName, addGaugeNameLink, disp, setNowrap, engvar)
-- Assumed: at least one to add is true.
if tgEntry.name == nil then
-- Not checked: link does exist alone
return ''
end
local retAlt = {}
if disp == 'br' then
table.insert(retAlt, '
')
else
table.insert(retAlt, ' ')
end
if setNowrap then
table.insert(retAlt, '<span>')
end
if addGaugeNameLink then
if engvar == 'en-us' then
-- Current implementations (2016): metER for metRE (1000-met, 1009-met)
table.insert(retAlt, tgEntry.en_US_link or tgEntry.link or tgEntry.name)
else
table.insert(retAlt, tgEntry.link or tgEntry.name)
end
else -- so must be unlinked .name to add
if engvar == 'en-us' then
-- Current implementations (2016): metER for metRE (1000-met, 1009-met)
table.insert(retAlt, tgEntry.en_US_name or tgEntry.name)
else
table.insert(retAlt, tgEntry.name)
end
end
if setNowrap then --close tag
table.insert(retAlt, '</span>')
end
return table.concat(retAlt, '')
end
---
-- main -- The basic module
---
function p.main
-- In general: the tgEntry object (from TG/data) is passed to the functions, while arguments are processed here.
local title = mw.title.getCurrentTitle
local args = prepareArgs
local tgEntry = p.getTrackGaugeEntry(args.searchAlias)  
-- Categorise & preview warning when no track gauge definition was found.
if tgEntry == nil then
local input = args[1] or ''
local errorTail = ''  
if :preprocess("") == "" then
errorTail = '<div><strong>Warning:</strong> ' .. 'Track gauge ' .. (input .. ' ' or '') .. 'not in List of defined track gauges (talk).' .. ' (This message is shown only in preview.)</div>'
end  
if title:inNamespaces(0, 14) then -- mainspace and category space
errorTail = errorTail .. ""
end
return input .. errorTail
end  
-- Check and set args & tgEntry props: disp, first, nowrap, first
local disp = args.disp or ''
local first = args.first or tgEntry.def1
local unitlink = args.unitlink or ''
local nowrap = args.nowrap or ''
local setNowrapElement = (nowrap == '' or nowrap == 'off') -- To prevent nested nowrap tags
local measurementToLink
if args.lk == 'on' then
if disp == '1' then
measurementToLink = first -- Can make metric text links to the imp linked page
else
measurementToLink = tgEntry.def1 -- When first=swapped, this could link 2nd measure.
end
end