Module:track gauge/sandbox

-- This module implements the {{Track gauge}} template.

-- Data is in Module:Track gauge/data

local p = {}

local gaugeDataAll = nil

local dataPageName = 'Module:Track gauge/data/sandbox' -- set /data/sandbox here to test data/sandbox

-----------------------------------------------------------------------------------

-- prepareArgs -- Normalise Arguments coming from an #invoke or from a module

-----------------------------------------------------------------------------------

local function prepareArgs(frame)

local origArgs

if frame == mw.getCurrentFrame() then

origArgs = frame:getParent().args

for k, v in pairs(frame.args) do

origArgs = frame.args

break

end

else

origArgs = frame

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

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, '⁄', '/')

return a

end

-----------------------------------------------------------------------------------

-- debugReturnArgs -- Debug function.

-----------------------------------------------------------------------------------

function p.debugReturnArgs(frame)

local args = prepareArgs(frame)

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('%s', s)

end

-----------------------------------------------------------------------------------

-- frac -- A slimmed-down version of the {{frac}} template (a nowrap is to be added with the unit)

-----------------------------------------------------------------------------------

local function frac(whole, num, den)

-- normally would do the TemplateStyles expansion here, but instead we do

-- it at the callsite because of :phab:T200704

return mw.ustring.format(

'%s%s%s',

whole and (whole .. '+') 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 %s', ft, ftlink))

end

local inches = tgEntry['in']

local num = tgEntry.num

local den = tgEntry.den

local has_fraction = num and den

if inches and not num and not den then

table.insert(ret, inches)

elseif has_fraction 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, ' '))

else

gaugeSize = table.concat(ret, ' ')

end

-- we have do this here to work around phab:T200704

local templatestyles

if has_fraction then

templatestyles = mw.getCurrentFrame():extensionTag{

name = 'templatestyles', args = { src = 'Fraction/styles.css' }

}

else

templatestyles = ''

end

if measurementToLink == 'imp' and tgEntry.pagename ~= nil then

return mw.ustring.format(

'%s%s',

templatestyles,

tgEntry.pagename,

gaugeSize

)

else

return templatestyles .. gaugeSize

end

end

-----------------------------------------------------------------------------------

-- formatMet -- Formats metric measurements into a single formatted text element. Public for autodocument

-----------------------------------------------------------------------------------

function p.formatMet(tgEntry, measurementToLink, setNowrap, addUnitlink, removeComma)

local m = tgEntry.m

local gaugeSize

if m then

local mUnit = addUnitlink and measurementToLink ~= 'met' and 'm' or 'm'

gaugeSize = mw.ustring.format('%s %s', m, mUnit)

else

local mm = tgEntry.mm

mm = tonumber(mm)

if mm then

mm = mw.getContentLanguage():formatNum(mm)

if removeComma then

mm = string.gsub( mm, ",", "" )

end

end

local mmUnit = addUnitlink and measurementToLink ~= 'met' and 'mm' or 'mm'

gaugeSize = mw.ustring.format('%s %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, '')

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

end

return table.concat(retAlt, '')

end

-----------------------------------------------------------------------------------

-- main -- The basic module

-----------------------------------------------------------------------------------

function p.main(frame)

-- 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(frame)

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 = require('Module:If preview')._warning({

'Track gauge ' ..

input ..

' not in List of defined track gauges (talk).'

})

if title:inNamespaces(0, 14) then -- mainspace and category space

errorTail = errorTail .. "Category:Articles using Template:Track gauge with unrecognized input"

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 comma = args.comma 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

-- String the text elements together (compose the return table)

local ret = {}

-- nowrap opening tag

if nowrap == 'all' or nowrap == 'on' then

table.insert(ret, '')

end

-- First measure

if first == 'met' then

table.insert(ret,

p.formatMet(tgEntry, measurementToLink, setNowrapElement, unitlink == 'on', comma == 'off'))

else

table.insert(ret,

p.formatImp(tgEntry, measurementToLink, setNowrapElement, unitlink == 'on', comma == 'off'))

end

-- The joint and the second measure

if disp ~= '1' then

local joinText = ''

local closeDisp = ''

if disp == 's' or disp == '/' then

joinText = ' / ' --spaces

elseif disp == 'br' then

joinText = '
('

closeDisp = ')'

elseif disp == '[' or disp == '[]' then

joinText = ' ['

closeDisp = ']'

elseif disp ~= '' then -- Is anytext

joinText = ' ' .. args['rawDisp'] .. ' '

else

joinText = ' ('

closeDisp = ')'

end

table.insert(ret, joinText)

if first ~= 'met' then

table.insert(ret,

p.formatMet(tgEntry, measurementToLink, setNowrapElement, unitlink == 'on', comma == 'off'))

else

table.insert(ret,

p.formatImp(tgEntry, measurementToLink, setNowrapElement, unitlink == 'on'))

end

table.insert(ret, closeDisp) -- Could be ''

end

if nowrap == 'on' then -- Closing tag

table.insert(ret, '')

end

-- Alternative name

if args.al == 'on' or args.allk == 'on' then

local setNowrapAltname = (nowrap == '' or nowrap == 'on') -- Logic applied to prevent nested nowrap tags

table.insert(ret, formatAltName(tgEntry, args.al == 'on', args.allk == 'on', disp, setNowrapAltname, args.engvar))

end

-- Closing nowrap tag

if nowrap == 'all' then

table.insert(ret, '')

end

-- Category mentionings (maintenance)

if args.addcat or '' == 'no' then

-- No categorization

elseif title:inNamespaces(0) then

-- switched off per Wikipedia:Categories_for_discussion/Log/2016_December_6#Category:Articles_that_mention_a_specific_track_gauge

-- 2016-12-19

-- table.insert(ret, p.catMentions(tgEntry))

end

-- Now sting the table together

return table.concat(ret, '')

end

return p

--20161219: maintenance categorisation switched off per CfD

--20170602: fix bug, show name when al=on

--20180708: show preview warning when gauge is not in list

--20190124: with disp=/ (slash) value separator: surround by spaces

--20210304: add option comma=off (mm only)