Module:Track gauge

-- 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 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, '&frasl;', '/')	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 1/undefined 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 &frasl; %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 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 .. ""		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 else 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 Categories_for_discussion/Log/2016_December_6 -- 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)