Difference between pages "Module:Track gauge" and "Module:Track gauge/sandbox"
(Difference between pages)
Jump to navigation
Jump to search
m (36 revisions imported) |
m (1,000 revisions imported) |
||
| Line 1: | Line 1: | ||
| − | -- This module implements the {{ | + | -- This module implements the {{RailGauge}} template. |
| − | |||
local p = {} | local p = {} | ||
local gaugeDataAll = nil | local gaugeDataAll = nil | ||
| − | local | + | |
| + | ----------------------------------------------------------------------------------- | ||
| + | -- format_mm, to pattern '0016.5 mm' to support tablesorting and catsorting. | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function format_mm( id, suffix ) | ||
| + | return string.rep('0', 4 - (string.len(math.floor(tonumber(id))))) .. id .. | ||
| + | ' mm' .. (suffix or '') | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- anchors as target | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function anchors( gData ) | ||
| + | -- todo: distinct here or there anchors; and imp or met | ||
| + | local html = require('Module:HtmlBuilder') | ||
| + | local anchImp = '' | ||
| + | local anchMet = '' | ||
| + | local ft = '' | ||
| + | local frac = '' | ||
| + | local inch = '' | ||
| + | |||
| + | if gData == nil then | ||
| + | return '' | ||
| + | end | ||
| + | |||
| + | anchMet = gData.id .. ' mm' | ||
| + | |||
| + | if gData.ft then | ||
| + | ft = gData.ft .. ' ft' | ||
| + | end | ||
| + | if gData["in"] then | ||
| + | inch = ' ' .. gData["in"] | ||
| + | end | ||
| + | if gData.num then | ||
| + | frac = ' ' .. gData.num .. '/' .. gData.den .. ' in' | ||
| + | elseif inch ~= '' then | ||
| + | inch = inch .. ' in' | ||
| + | end | ||
| + | anchImp = ft .. inch .. frac | ||
| + | |||
| + | local buildM = html.create().tag('div').attr('id', anchMet).attr('style', 'vertical-align:top') | ||
| + | local buildI = html.create().tag('div').attr('id', anchImp).attr('style', 'vertical-align:top') | ||
| + | |||
| + | return tostring(buildM) .. tostring(buildI) | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- catMentionsSize, categorize in 'Gauge size mentioned in page' | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function catMentionsSize( mmSize, catSort, pagename, show, plaintext ) | ||
| + | local cat | ||
| + | |||
| + | -- Category page name. mmSize has format of id (like '16.5'). | ||
| + | cat = 'User:DePiep/sandbox' .. ' ' .. mmSize .. ' mm' --SANDBOX | ||
| + | if plaintext then | ||
| + | return cat | ||
| + | elseif show then | ||
| + | -- uses colon and wikilabel; no catsort | ||
| + | local label = '|DraftCat:Articles with ' .. mmSize .. ' mm' .. ' gauge' | ||
| + | cat = '[[:'.. cat .. label .. ']]' | ||
| + | else | ||
| + | if (catSort or '') ~= '' then | ||
| + | catSort = '|' .. catSort -- todo: add pagename | ||
| + | else | ||
| + | catSort = '' | ||
| + | end | ||
| + | cat = '[['.. cat .. catSort .. ']]' | ||
| + | end | ||
| + | |||
| + | return cat | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- catMentionsSizeParent, parent of all 'Cat:Gauge size mentioned x mm' | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function catMentionsSizeParent( show ) | ||
| + | local cat | ||
| + | |||
| + | -- Category page name. | ||
| + | cat = 'Category:Articles that mention a specific rail gauge' | ||
| + | if show then | ||
| + | -- uses colon and wikilabel; no catsort | ||
| + | cat = '[[:'.. cat .. '|Cat:Articles with RailGauge]]' | ||
| + | else | ||
| + | cat = '[['.. cat .. ']]' | ||
| + | end | ||
| + | |||
| + | return cat | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- prepareArgs, arguments coming from an #invoke or from a module | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function prepareArgs( frame ) | ||
| + | -- If called via #invoke, use the args passed into the invoking | ||
| + | -- template, or the args passed to #invoke if any exist. Otherwise | ||
| + | -- assume args are being passed directly in from the debug console | ||
| + | -- or from another Lua module. | ||
| + | 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 | ||
| + | |||
| + | -- Trim whitespace, make lower-case and remove blank arguments for all arguments | ||
| + | -- searchKey is the cleaned value of [1]. [1] is kept as rawInput for error message | ||
| + | local args = {} | ||
| + | args["searchKey"] = '' | ||
| + | args["rawInput"] = origArgs[1] or '' | ||
| + | |||
| + | for k, v in pairs( origArgs ) do | ||
| + | v = mw.text.trim( v ) | ||
| + | if k == 1 then | ||
| + | -- Into lowercase, remove all whitespace, commas to create the search key | ||
| + | v = mw.ustring.lower(mw.ustring.gsub( v, '[%s%,]', '' )) | ||
| + | args[ 1 ] = v | ||
| + | args["searchKey"] = v | ||
| + | else | ||
| + | args[ k ] = mw.ustring.lower( v ) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | return args | ||
| + | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- getGaugeDataSet, find dataset for a single gauge |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | local function | + | local function getGaugeDataSet( searchKey, units ) |
| − | + | if gaugeDataAll == nil then | |
| − | + | gaugeDataAll = mw.loadData( 'Module:RailGauge/data/sandbox' ) --SANDBOX | |
| − | + | end | |
| − | + | ||
| − | + | local gData = nil | |
| − | + | ||
| − | + | for i, gD in ipairs( gaugeDataAll ) do | |
| − | + | for j, alias in ipairs( gD.aliases ) do | |
| − | + | if alias == searchKey then | |
| − | + | -- A hit by alias | |
| − | + | if units then | |
| − | + | -- unit specific requested | |
| − | + | if gD.def1 == units then | |
| − | + | gData = gD | |
| − | + | end | |
| − | + | else | |
| − | + | gData = gD | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| + | end | ||
| + | if gData then break end | ||
| + | end | ||
| + | if gData then | ||
| + | break | ||
| + | elseif tonumber(searchKey) ~= nil then -- seach by id | ||
| + | --todo: preferred return metric by default, when present | ||
| + | --todo: don't break, an alias could be OK further down the line | ||
| + | if gD.id == searchKey then | ||
| + | if units ~= nil then | ||
| + | if gD.def1 == units then | ||
| + | gData = gD | ||
| + | end | ||
| + | else | ||
| + | gData = gD | ||
| + | end | ||
| + | end | ||
| + | if gData then break end | ||
| + | end | ||
| + | end | ||
| + | |||
| + | return gData | ||
| + | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- noWrap, adds span tags to prevent a string from wrapping. |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function | + | local function noWrap( s ) |
| − | + | return mw.ustring.format( '<span class="nowrap">%s</span>', s ) | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- frac, a slimmed-down version of the {{frac}} template (a nowrap to be added with the unit) | ||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | + | local function frac( whole, num, den ) | |
| + | return mw.ustring.format( | ||
| + | '<span class="frac">%s%s<sup>%s</sup>⁄<sub>%s</sub></span>', | ||
| + | whole or '', whole and '<span class="visualhide"> </span>' or '', num, den | ||
| + | ) | ||
| + | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function p. | + | -- formatImp, formats imperial measurements into a single element |
| − | + | ----------------------------------------------------------------------------------- | |
| − | + | local function formatImp( gData, ulink, articleLink, pageName ) | |
| − | + | local ret = {} | |
| − | + | local ft = gData.ft | |
| − | + | ||
| − | + | if ft then | |
| + | local ftlink = ulink and not articleLink and '[[Foot (unit)|ft]]' or 'ft' | ||
| + | table.insert( ret, mw.ustring.format( '%s %s', ft, ftlink ) ) | ||
| + | end | ||
| + | local inches = gData['in'] | ||
| + | local num = gData.num | ||
| + | local den = gData.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 = ulink and not articleLink and '[[inch|in]]' or 'in' | ||
| + | table.insert( ret, incheslink ) | ||
| + | end | ||
| + | local gaugeSize = noWrap( table.concat( ret, ' ' ) ) | ||
| + | |||
| + | if articleLink then | ||
| + | return '[[' .. pageName .. '|' .. gaugeSize .. ']]' | ||
| + | else | ||
| + | return gaugeSize | ||
| + | end | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- formatMet, formats metric measurements into a single formatted element | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function formatMet( gData, ulink, articleLink, pageName ) | ||
| + | local m = gData.m | ||
| + | local gaugeSize | ||
| + | |||
| + | if m then | ||
| + | local munit = ulink and not articleLink and '[[metre|m]]' or 'm' | ||
| + | gaugeSize = noWrap( mw.ustring.format( '%s %s', m, munit ) ) | ||
| + | else | ||
| + | local mm = gData.mm | ||
| + | mm = tonumber( mm ) | ||
| + | if mm then | ||
| + | mm = mw.getContentLanguage():formatNum( mm ) | ||
| + | end | ||
| + | local mmunit = ulink and not articleLink and '[[millimetre|mm]]' or 'mm' | ||
| + | gaugeSize = noWrap( mw.ustring.format( '%s %s', mm, mmunit ) ) | ||
| + | end | ||
| + | |||
| + | if articleLink then | ||
| + | return '[[' .. pageName .. '|' .. gaugeSize .. ']]' | ||
| + | else | ||
| + | return gaugeSize | ||
| + | end | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- compose, puts together the two metric, imperial measures into an output string. | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | local function compose( args, gData ) | ||
| + | local definition = gData.def1 | ||
| + | local pageName = gData.pagename or nil | ||
| + | local imp = formatImp( gData, args.unitlink == 'on', args.lk=='on' and definition=='imp' and pageName, pageName) | ||
| + | local met = formatMet( gData, args.unitlink == 'on', args.lk=='on' and definition=='met' and pageName, pageName) | ||
| + | local first = args.first or gData.def1 | ||
| + | |||
| + | if first == 'met' or first == 'metric' then | ||
| + | first = 'met' | ||
| + | else | ||
| + | first = 'imp' | ||
| + | end | ||
| + | local ret = {} | ||
| + | if first == 'met' then | ||
| + | table.insert( ret, met ) | ||
| + | else | ||
| + | table.insert( ret, imp ) | ||
| + | end | ||
| + | local disp = args.disp | ||
| + | if disp ~= '1' then | ||
| + | local formatText | ||
| + | if disp == 's' or disp == '/' then | ||
| + | formatText = '/​%s' | ||
| + | elseif disp == 'or' then | ||
| + | formatText = ' or %s' | ||
| + | elseif disp == '=' then | ||
| + | formatText = ' = %s' | ||
| + | else | ||
| + | formatText = ' (%s)' | ||
| + | end | ||
| + | if first == 'met' then | ||
| + | table.insert( ret, mw.ustring.format( formatText, imp ) ) | ||
| + | else | ||
| + | table.insert( ret, mw.ustring.format( formatText, met ) ) | ||
| + | end | ||
| + | end | ||
| + | ret = table.concat( ret ) | ||
| + | |||
| + | if args.wrap == 'y' then | ||
| + | return ret | ||
| + | else | ||
| + | return noWrap( ret ) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | -- main, the basic flow of the module. | ||
| + | ----------------------------------------------------------------------------------- | ||
| + | function p.main( frame ) | ||
| + | local args = nil | ||
| + | local gData = nil | ||
| + | local title = mw.title.getCurrentTitle() | ||
| + | |||
| + | args = prepareArgs( frame ) | ||
| + | -- Get the data set for this gauge from /data subpage | ||
| + | gData = getGaugeDataSet ( args.searchKey ) | ||
| + | |||
| + | -- Categorise the page if no gauge information was found. | ||
| + | if gData == nil then | ||
| + | local category = '' | ||
| + | if title:inNamespaces(0, 14) then --main=0,templ=10,cat=14--SANDBOXcolon:cat | ||
| + | category = mw.ustring.format( | ||
| + | '[[:Category:Articles with template RailGauge with unrecognized input|%s, %s]]', | ||
| + | args["rawInput"] or ' ', title.text | ||
| + | ) | ||
| + | end | ||
| + | return ( args["rawInput"] or '' ) .. category | ||
| + | end | ||
| + | |||
| + | -- Assemble the output. | ||
| + | local ret = {} | ||
| + | table.insert( ret, compose( args, gData ) ) | ||
| + | local gaugeName = gData.name | ||
| + | local gaugeLink = gData.link | ||
| + | if args.allk == 'on' and gaugeLink then | ||
| + | table.insert( ret, ' ' .. noWrap( gaugeLink ) ) | ||
| + | elseif args.al == 'on' and gaugeName then | ||
| + | table.insert( ret, ' ' .. noWrap( gaugeName ) ) | ||
| + | end | ||
| + | |||
| + | local maintCatSortDepr = gData.maintcatsort --category to be DEPRECATED, see 'Categorize all' topic (3 April 2014) | ||
| + | if maintCatSortDepr ~= nil then | ||
| + | local addMaintCat = args.addcat | ||
| + | if addMaintCat ~= 'off' and addMaintCat ~= 'no' then | ||
| + | if title.namespace == 0 or title.namespace == 14 then | ||
| + | local category = '' | ||
| + | category = mw.ustring.format( | ||
| + | '[[Category:Articles with template RailGauge that may need attention|%s, %s]]', | ||
| + | maintCatSortDepr, title.text) | ||
| + | table.insert( ret, ' ' .. category ) | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | |||
| + | return table.concat( ret ) | ||
end | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- checkData, performs various checks on the /data subpage. |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function p. | + | function p.checkData( frame ) |
| − | + | local dataPage = frame and frame.args and frame.args[1] or 'Module:RailGauge/data' | |
| − | + | local data = mw.loadData( dataPage ) | |
| − | + | local exists, dupes, dupeSort, ret = {}, {}, {}, {} | |
| − | + | ||
| − | + | -- Check for duplicate aliases. | |
| − | + | for ti, t in ipairs( data ) do | |
| − | + | for ai, alias in ipairs( t.aliases or {} ) do | |
| − | + | if not exists[ alias ] then | |
| − | + | exists[ alias ] = { ti, ai } | |
| − | + | else | |
| − | + | if not dupes[ alias ] then | |
| − | + | dupes[ alias ] = { exists[ alias ] } | |
| + | end | ||
| + | table.insert( dupes[ alias ], { ti, ai } ) | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | for alias in pairs( dupes ) do | ||
| + | table.insert( dupeSort, alias ) | ||
| + | end | ||
| + | table.sort( dupeSort ) | ||
| + | for i1, alias in ipairs( dupeSort ) do | ||
| + | local positions = {} | ||
| + | for i2, aliasKeys in ipairs( dupes[ alias ] ) do | ||
| + | local position = mw.ustring.format( 'gauge %d, alias %d (gauge id: <code>%s</code>)', aliasKeys[ 1 ], aliasKeys[ 2 ], data[ aliasKeys[ 1 ] ].id or '' ) | ||
| + | table.insert( positions, position ) | ||
| + | end | ||
| + | local aliasText = mw.ustring.format( 'Duplicate aliases "%s" detected at the following positions: %s.', alias, mw.text.listToText( positions, '; ' ) ) | ||
| + | table.insert( ret, aliasText ) | ||
| + | end | ||
| + | -- Check for numerators without denominators. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | local num = t.num | ||
| + | local den = t.den | ||
| + | if num and not den then | ||
| + | table.insert( ret, mw.ustring.format( 'Numerator "%s" with no denominator detected at gauge %d (id: <code>%s</code>).', num, ti, t.id or '' ) ) | ||
| + | elseif den and not num then | ||
| + | table.insert( ret, mw.ustring.format( 'Denominator "%s" with no numerator detected at gauge %d (id: <code>%s</code>).', den, ti, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | -- Check for gauges with no imperial or no metric measurements. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | if not ( t.ft or t['in'] or t.num or t.den ) then | ||
| + | table.insert( ret, mw.ustring.format( 'No imperial measurements found for gauge %d (id: <code>%s</code>).', ti, t.id or '' ) ) | ||
| + | end | ||
| + | if not ( t.m or t.mm ) then | ||
| + | table.insert( ret, mw.ustring.format( 'No metric measurements found for gauge %d (id: <code>%s</code>).', ti, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | -- Check for non-numeric measurements. | ||
| + | local measurements = { 'ft', 'in', 'num', 'den', 'm', 'mm' } | ||
| + | for ti, t in ipairs( data ) do | ||
| + | for mi, measurement in ipairs( measurements ) do | ||
| + | local measurementVal = t[ measurement ] | ||
| + | if measurementVal and not tonumber( measurementVal ) then | ||
| + | table.insert( ret, mw.ustring.format( 'Non-numeric <code>%s</code> measurement ("%s") found for gauge %d (id: <code>%s</code>).', measurement, measurementVal, ti, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | -- Check for gauges with no id. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | if not t.id then | ||
| + | local aliases = {} | ||
| + | for i, alias in ipairs( t.aliases ) do | ||
| + | table.insert( aliases, mw.ustring.format( '<code>%s</code>', alias ) ) | ||
| + | end | ||
| + | aliases = mw.ustring.format( ' (aliases: %s)', mw.text.listToText( aliases ) ) | ||
| + | table.insert( ret, mw.ustring.format( 'No id found for gauge %d%s.', ti, aliases or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | -- Check for gauges with no aliases. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | if type( t.aliases ) ~= 'table' then | ||
| + | table.insert( ret, mw.ustring.format( 'No aliases found for gauge %d (id: <code>%s</code>).', ti, t.id or '' ) ) | ||
| + | else | ||
| + | local isAlias = false | ||
| + | for ai, alias in ipairs( t.aliases ) do | ||
| + | isAlias = true | ||
| + | break | ||
| + | end | ||
| + | if not isAlias then | ||
| + | table.insert( ret, mw.ustring.format( 'No aliases found for gauge %d (id: <code>%s</code>).', ti, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | -- Check for named gauges with no links and gauges with links but no names. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | if t.name and not t.link then | ||
| + | table.insert( ret, mw.ustring.format( 'No link found for the named gauge "%s" at position %d (id: <code>%s</code>).', t.name, ti, t.id or '' ) ) | ||
| + | elseif t.link and not t.name then | ||
| + | table.insert( ret, mw.ustring.format( 'No name found for the gauge with link "%s" at position %d (id: <code>%s</code>).', t.link, ti, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | -- Check for invalid def1 values. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | local def1 = t.def1 | ||
| + | if def1 ~= 'imp' and def1 ~= 'met' then | ||
| + | table.insert( ret, mw.ustring.format( 'Invalid def1 value "%s" found for gauge %d (id: <code>%s</code>).', def1 or '', ti, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | -- Check for unwanted whitespace. | ||
| + | for ti, t in ipairs( data ) do | ||
| + | for tkey, tval in pairs( t ) do | ||
| + | if tkey == 'aliases' and type( tval ) == 'table' then | ||
| + | for ai, alias in ipairs( tval ) do | ||
| + | if mw.ustring.find( alias, '%s' ) then | ||
| + | table.insert( ret, mw.ustring.format( 'Unwanted whitespace detected in gauge %d alias %d ("%s", gauge id: <code>%s</code>).', ti, ai, alias, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | elseif tkey == 'name' or tkey == 'link' or tkey == 'pagename' then | ||
| + | if tval ~= mw.text.trim( tval ) then | ||
| + | table.insert( ret, mw.ustring.format( 'Unwanted whitespace detected in <code>%s</code> field of gauge %d ("%s", gauge id: <code>%s</code>).', tkey, ti, tval, t.id or '' ) ) | ||
| + | end | ||
| + | elseif mw.ustring.find( tval, '%s' ) then | ||
| + | table.insert( ret, mw.ustring.format( 'Unwanted whitespace detected in <code>%s</code> field of gauge %d ("%s", gauge id: <code>%s</code>).', tkey, ti, tval, t.id or '' ) ) | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | -- Added April 2014: alias should not double with another id (imp and mm not ambiguous) | ||
| + | local self_id = '' | ||
| + | local self_def1 = '' | ||
| + | for ti, t in ipairs( data ) do | ||
| + | self_id = t.id | ||
| + | self_def1 = t.def1 | ||
| + | for iC, aliasCheck in ipairs( t.aliases ) do | ||
| + | if tonumber( aliasCheck ) ~= nil then | ||
| + | if self_id ~= aliasCheck then | ||
| + | for iTwo, tTwo in ipairs( data ) do | ||
| + | if aliasCheck == tTwo.id then | ||
| + | table.insert( ret, mw.ustring.format( 'Input alias %s (%s) from <code>id=%s mm</code> ambiguous with gauge id=<code>%s mm</code> (%s)', aliasCheck, self_def1, self_id, tTwo.id, tTwo.def1 ) ) | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | |||
| + | -- temp check | ||
| + | if false then | ||
| + | local strC = '' | ||
| + | local self_id = '' | ||
| + | local self_def1 = '' | ||
| + | for ti, t in ipairs( data ) do | ||
| + | self_id = t.id | ||
| + | self_def1 = t.def1 | ||
| + | for iC, aliasCheck in ipairs( t.aliases ) do | ||
| + | -- strC = ' || ' .. self_id .. ' || ' .. self_def1 .. '|| ' .. aliasCheck | ||
| + | -- table.insert( ret, strC ) | ||
| + | end | ||
| + | end | ||
end | end | ||
| + | |||
| + | -- Return any errors found. | ||
| + | for i, msg in ipairs( ret ) do | ||
| + | ret[ i ] = mw.ustring.format( '<span class="error">%s</span>', msg ) | ||
| + | end | ||
| + | |||
| + | if #ret > 0 then | ||
| + | return mw.ustring.format( 'Found the following errors in %s:\n* %s', dataPage, table.concat( ret, '\n* ' ) ) | ||
| + | else | ||
| + | return mw.ustring.format( 'No errors found in %s.', dataPage ) | ||
| + | end | ||
| + | |||
| + | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- documentHeader |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | local function | + | local function documentHeader( sTitle, numberOfEntries, collapsibleState ) |
| − | + | catMparent = catMentionsSizeParent( true ) | |
| + | local sortColHeaders = '' | ||
| + | local sortClass = '' | ||
| + | |||
| + | if collapsibleState == nil then | ||
| + | collapsibleState = 'collapsible uncollapsed' --dev: autocollapse? | ||
| + | else | ||
| + | collapsibleState = 'collapsible ' .. collapsibleState | ||
end | end | ||
| + | |||
| + | if ( numberOfEntries or 0 ) > 1 then | ||
| + | sortColHeaders = '' .. | ||
| + | '\n|-' .. | ||
| + | '\n! || || || || || ||' | ||
| + | sortClass = 'sortable' | ||
| + | end | ||
| + | |||
| + | -- 7 columns | ||
| + | return '' .. | ||
| + | '\n{| class="wikitable ' .. sortClass .. ' ' .. collapsibleState .. '" ' .. | ||
| + | 'style="text-align:right; width:100%; background:#B3FFD1;" ' .. | ||
| + | '\n|+ Rail gauge' .. (sTitle or '') .. | ||
| + | '\n|- style="background:orange;" |' .. | ||
| + | '\n! Table !! 2 !! 3 !! 4 !! 5 !! 6 <br>' .. catMparent .. '!! note' .. | ||
| + | sortColHeaders | ||
| + | |||
| + | -- '\n|-' .. '\n! || || || || || ||' | ||
| + | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- documentFooter |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | local function | + | local function documentFooter() |
| − | + | return '\n|}' | |
| − | |||
| − | |||
| − | |||
end | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- DEPR documentOneGauge, create documentation for a gauge; single tablerow |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function p. | + | function p.documentOneGauge( frame ) --, gData ) |
| − | + | local args = {} | |
| − | + | ||
| + | if gData == nil then | ||
| + | args = prepareArgs( frame ) | ||
| + | gData = getGaugeDataSet ( args.searchKey ) | ||
| + | end | ||
| − | + | if gData == nil then | |
| − | + | return '' | |
| − | + | else | |
| − | + | return documentHeader() .. documentGaugeRow( gData ) .. documentFooter() | |
| − | + | end | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- DEPR documentAll, list all defined gauges |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function p. | + | function p.documentAll() |
| − | + | if gaugeDataAll == nil then | |
| − | + | gaugeDataAll = mw.loadData( 'Module:RailGauge/data/sandbox' ) --SANDBOX | |
| − | + | end | |
| − | + | local ret = {} | |
| − | + | local dDoc = '' | |
| − | + | ||
| − | + | for i, v in ipairs( gaugeDataAll ) do | |
| − | + | -- v now has gData for a single gauge | |
| − | + | dDoc = documentGaugeRow( v ) | |
| − | + | table.insert ( ret, dDoc ) | |
| − | + | if i > 12 then break end | |
| − | + | end | |
| − | + | table.sort( ret ) | |
| − | + | ||
| − | + | return documentHeader() .. table.concat( ret, ' ') .. documentFooter() | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- DEPR documentGaugeRow: create documentation row for a gauge |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function | + | function documentGaugeRow( gData ) |
| − | + | local gD1 = nil | |
| − | + | local gD2 = nil | |
| − | + | local html = require('Module:HtmlBuilder') | |
| − | + | local htmlString = '' | |
| − | + | local rowsplit = '<div style="border-top:1px solid #ddd; height:1px;"/>' | |
| − | + | ||
| − | + | if gData == nil then | |
| − | + | return '' | |
| − | + | end | |
| − | + | ||
| − | + | -- Values independent of met/imp def1: | |
| − | + | local id = gData.id | |
| − | + | local title = mw.title.getCurrentTitle() | |
| − | + | local anchors = anchors( gData ) | |
| − | + | local catSort = title.text --? | |
| − | + | local sortKey = format_mm( id ) | |
| − | + | htmlString = html.create() | |
| − | + | .tag('div').addClass('sortkey').wikitext( sortKey ) | |
| − | + | sortKey = tostring( htmlString ) | |
| − | + | ||
| − | + | local catM = catMentionsSize( id, catSort, title, true ) | |
| − | + | htmlString = html.create() | |
| + | .tag('div').css('text-align', 'left').wikitext(catM) | ||
| + | catM = tostring( htmlString ) | ||
| + | |||
| + | -- def1 | ||
| + | local def1 = {} | ||
| + | table.insert( def1, 1, gD1.def1 ) | ||
| + | |||
| + | -- pagename (link-to page) | ||
| + | local linkPage = {} | ||
| + | linkPage[1] = gD1.pagename or '' | ||
| + | linkPage['sep'] = '' | ||
| + | |||
| + | if gD2 then | ||
| + | if gD1.id ~= gD2.id then | ||
| + | devNote = gD1.id .. '<=>' .. gD2.id | ||
| + | end | ||
| + | table.insert( def1, 2, gD2.def1 ) | ||
| + | linkPage[2] = gD2.pagename or '' | ||
| + | if linkPage[1] == linkPage[2] then -- could be two blanks | ||
| + | linkPage[2] = nil -- nullify | ||
| + | else -- even when one is blank | ||
| + | --linkPage[2] = nil | ||
| + | end | ||
| + | else | ||
| + | --D1 only, could be met or imp | ||
| + | end | ||
| + | |||
| + | -- linkPage fmt | ||
| + | for i = 1, 2 do | ||
| + | if linkPage[i] and ( linkPage[i] ~= '' ) then | ||
| + | if string.len(linkPage[i]) > 25 then | ||
| + | linkPage[i] = '[[' .. linkPage[i] .. ']]' | ||
| + | else | ||
| + | local label | ||
| + | htmlString = html.create() | ||
| + | .tag('span').wikitext(linkPage[i]).addClass('nowrap') | ||
| + | label = tostring(htmlString) | ||
| + | linkPage[i] = '[[' .. linkPage[i] .. '|' .. label .. ']]' | ||
| + | end | ||
| + | htmlString = html.create() | ||
| + | .tag('div').css('text-align', 'left').wikitext(linkPage[i]) | ||
| + | linkPage[i] = tostring(htmlString) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | local measure = {} | ||
| + | measure[1] = formatMet( gD1 ) | ||
| + | measure[2] = formatImp( gD1 ) -- from gD1 both | ||
| + | if def1[1] == 'met' then | ||
| + | htmlString = html.create() | ||
| + | .tag('div').wikitext(measure[1]).css('font-weight', 'bold') | ||
| + | measure[1] = tostring(htmlString) | ||
| + | end | ||
| + | if ( def1[1] == 'imp' ) or ( def1[2] == 'imp' ) then | ||
| + | htmlString = html.create() | ||
| + | .tag('div').wikitext(measure[2]).css('font-weight', 'bold') | ||
| + | measure[2] = tostring(htmlString) | ||
| + | end | ||
| + | |||
| + | local aliases = {} | ||
| + | aliases[1] = {} | ||
| + | aliases[2] = {} | ||
| + | for i, v in ipairs( gD1.aliases ) do | ||
| + | if tonumber(v) == nil then | ||
| + | table.insert(aliases[1], v) | ||
| + | end | ||
| + | end | ||
| + | table.sort( aliases[1] ) | ||
| + | if gD2 then | ||
| + | for i, v in ipairs( gD2.aliases ) do | ||
| + | if tonumber(v) == nil then | ||
| + | table.insert(aliases[2], v) | ||
| + | end | ||
| + | end | ||
| + | table.sort( aliases[2] ) | ||
| + | aliases.sep = rowsplit | ||
| + | end | ||
| + | local aliasString = table.concat(aliases[1], '; ') .. | ||
| + | (aliases.sep or '' ) .. table.concat( aliases[2], '; ' ) | ||
| + | |||
| + | --createcat | ||
| + | local createCat = createCatMentionsSize( id ) | ||
| + | |||
| + | local row = {} | ||
| + | table.insert( row, anchors .. sortKey .. measure[1]) --1 | ||
| + | table.insert( row, sortKey .. measure[2] ) --2 | ||
| + | table.insert( row, table.concat(def1, rowsplit) ) --3 | ||
| + | table.insert( row, aliasString ) --4 | ||
| + | table.insert( row, table.concat( linkPage, rowsplit ) ) --5 | ||
| + | table.insert( row, catM ) --6 | ||
| + | table.insert( row, '[' .. createCat .. ' create]') --7 | ||
| + | |||
| + | return '' .. | ||
| + | '\n|-' .. | ||
| + | '\n| ' .. table.concat( row, ' || ' ) | ||
end | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- createCatMentionsSize, creatte and preload control |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function | + | function createCatMentionsSize( id ) |
| − | + | local catM | |
| − | + | --catMentionsSize( mmSize, catSort, pagename, show, plaintext ) | |
| − | + | catM = catMentionsSize( id, nil, nil, nil, true ) | |
| − | + | ||
| − | + | local qry = mw.uri.parseQueryString( 'action=edit&preload=Template:RailGauge/preload-categorypage-railgauge-mentionings' ) | |
| − | + | ||
| − | + | return tostring( mw.uri.fullUrl( catM, qry ) ) | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| + | |||
| + | --=================================================== | ||
| + | -- dev: INPUT TO ID | ||
| + | --=================================================== | ||
| + | local function fromInputToId( input1 ) | ||
| + | |||
| + | if gaugeDataAll == nil then | ||
| + | gaugeDataAll = mw.loadData( 'Module:RailGauge/data/sandbox' ) | ||
| + | end | ||
| + | |||
| + | local id = '' | ||
| + | local searchKey = mw.ustring.lower(mw.ustring.gsub( input1, '[%s%,]', '' )) --searchkey cleanup | ||
| + | |||
| + | for i, gD in ipairs( gaugeDataAll ) do | ||
| + | for j, alias in ipairs( gD.aliases ) do | ||
| + | if alias == searchKey then | ||
| + | id = gD["id"] | ||
| + | end | ||
| + | if id ~= '' then break end | ||
| + | end | ||
| + | if id ~= '' then break end | ||
| + | end | ||
| + | |||
| + | return id | ||
| + | end | ||
| + | |||
| + | --=================================================== | ||
| + | -- dev: ID to rowset -- idtorow SET = 3 or four entries in a row | ||
| + | --=================================================== | ||
| + | local function fromIDtoSet( id ) | ||
| + | local TableTools = require('Module:TableTools') | ||
| + | local set = {} | ||
| + | local row = {} | ||
| + | local rowsplit = '<div style="border-top:1px solid green; height:1px;"/>' | ||
| + | local html = require('Module:HtmlBuilder') | ||
| + | local htmlString = '' | ||
| + | local note = '' | ||
| + | |||
| + | note = note .. 'SET: ' .. id .. ': ' | ||
| + | |||
| + | for i, rgD in ipairs( gaugeDataAll ) do | ||
| + | if id == rgD["id"] then | ||
| + | note = note .. i .. ' HIT: ' .. id .. '='.. rgD["def1"] | ||
| + | |||
| + | if rgD["def1"] == 'met' and set[1] == nil then | ||
| + | set[1] = rgD | ||
| + | note = note .. '-metA' | ||
| + | elseif rgD["def1"] == 'imp' and set[2] == nil then | ||
| + | set[2] = rgD | ||
| + | note = note .. '-impB' | ||
| + | else | ||
| + | note = note .. 3+TableTools.size( set ) .. '-variC' | ||
| + | set[3+TableTools.size( set )] = rgD | ||
| + | end | ||
| + | set = TableTools.compressSparseArray( set ) | ||
| + | -- result: the set (table) with entries present in data, in sequence: | ||
| + | -- 1. met, 2. imp, 2, 3, 4, ... any & all second met/imp entries | ||
| + | end | ||
| + | end | ||
| + | |||
| + | note = 'SSS' .. note .. ' = ' .. #set .. 'TTT<br>' | ||
| + | ---set complete & clean | ||
| + | --= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = | ||
| + | if set[1] == nil then | ||
| + | -- row structure with colspan | ||
| + | return '' .. | ||
| + | '\n|-' .. | ||
| + | '\n| colspan=7 style="color:red; text-align:left;" |' .. | ||
| + | 'Error using [[Template:RailGauge/autodocumentation|RailGauge/autodocumentation]]:' .. | ||
| + | ' No rail gauge defined for ' .. id .. ' mm.' | ||
| + | |||
| + | end | ||
| + | |||
| + | -- Values independent of met/imp def1: | ||
| + | local title = mw.title.getCurrentTitle() | ||
| + | local anchors = anchors( set[1] ) | ||
| + | local catSort = title.text --? | ||
| + | local sortKey = format_mm( id ) | ||
| + | htmlString = html.create() | ||
| + | .tag('div').addClass('sortkey').wikitext( sortKey ) | ||
| + | sortKey = tostring( htmlString ) | ||
| + | |||
| + | local catM = catMentionsSize( id, catSort, title, true ) | ||
| + | htmlString = html.create() | ||
| + | .tag('div').css('text-align', 'left').wikitext(catM) | ||
| + | catM = tostring( htmlString ) | ||
| + | |||
| + | -- def1 | ||
| + | local def1 = {} | ||
| + | table.insert( def1, 1, set[1].def1 ) | ||
| + | |||
| + | -- pagename (link-to page) | ||
| + | local linkPage = {} | ||
| + | linkPage[1] = set[1].pagename or '' | ||
| + | linkPage['sep'] = '' | ||
| + | |||
| + | if set[2] then | ||
| + | table.insert( def1, 2, set[2].def1 ) | ||
| + | linkPage[2] = set[2].pagename or '' | ||
| + | if linkPage[1] == linkPage[2] then -- could be two blanks | ||
| + | linkPage[2] = nil -- nullify | ||
| + | else -- even when one is blank | ||
| + | --linkPage[2] = nil | ||
| + | end | ||
| + | else | ||
| + | --D1 only, could be met or imp | ||
| + | end | ||
| + | |||
| + | -- linkPage fmt | ||
| + | for i = 1, 2 do | ||
| + | if linkPage[i] and ( linkPage[i] ~= '' ) then | ||
| + | if string.len(linkPage[i]) > 25 then | ||
| + | linkPage[i] = '[[' .. linkPage[i] .. ']]' | ||
| + | else | ||
| + | local label | ||
| + | htmlString = html.create() | ||
| + | .tag('span').wikitext(linkPage[i]).addClass('nowrap') | ||
| + | label = tostring(htmlString) | ||
| + | linkPage[i] = '[[' .. linkPage[i] .. '|' .. label .. ']]' | ||
| + | end | ||
| + | htmlString = html.create() | ||
| + | .tag('div').css('text-align', 'left').wikitext(linkPage[i]) | ||
| + | linkPage[i] = tostring(htmlString) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | local measure = {} | ||
| + | measure[1] = formatMet( set[1] ) | ||
| + | measure[2] = formatImp( set[1] ) -- from gD 1 both | ||
| + | if def1[1] == 'met' then | ||
| + | htmlString = html.create() | ||
| + | .tag('div').wikitext(measure[1]).css('font-weight', 'bold') | ||
| + | measure[1] = tostring(htmlString) | ||
| + | end | ||
| + | if ( def1[1] == 'imp' ) or ( def1[2] == 'imp' ) then | ||
| + | htmlString = html.create() | ||
| + | .tag('div').wikitext(measure[2]).css('font-weight', 'bold') | ||
| + | measure[2] = tostring(htmlString) | ||
| + | end | ||
| + | |||
| + | local aliases = {} | ||
| + | aliases[1] = {} | ||
| + | aliases[2] = {} | ||
| + | for i, v in ipairs( set[1].aliases ) do | ||
| + | if tonumber(v) == nil then | ||
| + | table.insert(aliases[1], v) | ||
| + | end | ||
| + | end | ||
| + | table.sort( aliases[1] ) | ||
| + | if gD2 then | ||
| + | for i, v in ipairs( set[2].aliases ) do | ||
| + | if tonumber(v) == nil then | ||
| + | table.insert(aliases[2], v) | ||
| + | end | ||
| + | end | ||
| + | table.sort( aliases[2] ) | ||
| + | aliases.sep = rowsplit | ||
| + | end | ||
| + | local aliasString = table.concat(aliases[1], '; ') .. | ||
| + | (aliases.sep or '' ) .. table.concat( aliases[2], '; ' ) | ||
| + | |||
| + | --createcat | ||
| + | local createCat = createCatMentionsSize( id ) | ||
| + | |||
| + | table.insert( row, anchors .. sortKey .. measure[1]) --1 | ||
| + | table.insert( row, sortKey .. measure[2] ) --2 | ||
| + | table.insert( row, table.concat(def1, rowsplit) ) --3 | ||
| + | table.insert( row, aliasString ) --4 | ||
| + | table.insert( row, table.concat( linkPage, rowsplit ) ) --5 | ||
| + | table.insert( row, '6' ) --6 | ||
| + | table.insert( row, '7' ) --7 | ||
| + | --table.insert( row, catM ) --6 | ||
| + | --table.insert( row, '[' .. createCat .. ' create]') --7 | ||
| + | |||
| + | return '' .. | ||
| + | '\n|-' .. | ||
| + | '\n| ' .. table.concat( row, ' || ' ) | ||
| + | |||
| + | end | ||
| + | |||
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | -- | + | -- dev:CONTROL doc. To be: single #invoke call for all selfdoc requests (single, multiple, all) |
----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ||
| − | function p. | + | function p.documentGaugeControl( frame ) |
| − | + | ---local note = '' | |
| − | + | local args = {} | |
| − | + | local RGlist = {} | |
| − | + | ||
| + | args = prepareArgs( frame ) | ||
| + | |||
| + | if gaugeDataAll == nil then | ||
| + | gaugeDataAll = mw.loadData( 'Module:RailGauge/data/sandbox' ) | ||
| + | end | ||
| + | |||
| + | for i, RG in ipairs( gaugeDataAll ) do | ||
| + | table.insert( RGlist, tonumber( RG["id"] ) ) | ||
| + | if i >= 1 then break end | ||
| + | end | ||
| + | |||
| + | ---note = note .. '#before' .. #RGlist .. ' ' | ||
| − | + | local TableTools = require('Module:TableTools') | |
| − | + | RGlist = TableTools.removeDuplicates( RGlist ) | |
| − | + | table.sort( RGlist ) | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | ---note = note .. ' #after' .. #RGlist .. '; ' .. table.concat(RGlist, '; ') | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | local entryRow = {} | |
| − | + | table.insert( entryRow, fromIDtoSet( tostring(4321) ) ) | |
| − | + | for i, id in ipairs( RGlist ) do | |
| − | + | table.insert( entryRow, fromIDtoSet( tostring(id) ) ) | |
| − | + | end | |
| − | + | --rm dev: note | |
| − | + | return documentHeader() .. table.concat( entryRow, '' ) .. documentFooter() | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
return p | return p | ||
| − | |||
| − | |||
| − | |||
| − | |||