Jump to content

Module:Track gauge

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mr. Stradivarius (talk | contribs) at 17:33, 30 July 2013 (should be feature-complete now). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}

local function removeSpaces( s )
    s = mw.ustring.gsub( s, ' ', '' )
    return s
end

local function noWrap( s )
    return mw.ustring.format( '<span class="nowrap">%s</span>', s )
end

local function frac( whole, num, den )
    return mw.ustring.format(
        '<span class="frac nowrap">%s<sup>%s%s</sup>&frasl;<sub>%s</sub></span>',
        whole or '', whole and ' ' or '', num, den
    )
end

local function formatImp( data, link )
    local ret = {}
    local ft = data.ft
    if ft then
        local ftlink = link and '[[Foot (length)|ft]]' or 'ft'
        table.insert( ret, mw.ustring.format( '%s&nbsp;%s', ft, ftlink ) )
    end
    local inches = data['in']
    local num = data.num
    local den = data.den
    if num and not den then
        error( 'Denominator not found for the inch fraction' )
    elseif den and not num then
        error( 'Nominator not found for the inch fraction' ) 
    elseif 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 = link and '[[inch|in]]' or 'in'
        table.insert( ret, incheslink )
    end
    return noWrap( table.concat( ret, '&nbsp;' ) )
end

local function formatMet( data, link )
    local m = data.m
    if m then
        local mlink = link and '[[metre|m]]' or 'm'
        return noWrap( mw.ustring.format( '%s&nbsp;%s', m, mlink ) )
    else
        local mm = data.mm
        mm = tonumber( mm )
        if not mm then
            error( 'Non-number mm value detected' )
        end
        mm = mw.getContentLanguage():formatNum( mm )
        local mmlink = link and '[[millimetre|mm]]' or 'mm'
        return noWrap( mw.ustring.format( '%s&nbsp;%s', mm, mmlink ) )
    end
end

local function compose( args, data )
    local imp = formatImp( data, args.lk == 'on' )
    local met = formatMet( data, args.lk == 'on' )
    local first = args.first or data.dflt1
    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' then
            formatText = '/&#x200b;%s'
        elseif disp == 'or' then
            formatText = ' or %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

local function _main( args )
    local gaugeData = mw.loadData( 'Module:RailGauge/data' )
    local searchKey = removeSpaces( mw.ustring.lower( args[ 1 ] or '' ) )
    local title = mw.title.getCurrentTitle()
    local data
    for i, t in ipairs( gaugeData ) do
        for j, alias in ipairs( t.aliases ) do
            if alias == searchKey then
                data = t
            end
        end
    end
    if not data then
        local category = ''
        if title.namespace == 0 then
            category = mw.ustring.format(
                '[[Category:Pages with incorrect use of RailGauge template|%s, %s]]',
                args[ 1 ] or ' ', title.text
            )
        end
        return  mw.text.trim( args[ 1 ] or '' ) .. category
    end
    local ret = {}
    table.insert( ret, compose( args, data ) )
    local gaugeName = data.name
    local gaugeLink = data.link
    if args.al == 'on' and gaugeName then
        table.insert( ret, ' ' .. gaugeName )
    elseif args.allk == 'on' and gaugeLink then
        table.insert( ret, ' ' .. gaugeLink )
    end
    if args.lk == 'on' then
        table.insert( ret, mw.ustring.format( 
            '[[Category:Pages with incorrect use of RailGauge template|U, %s]]',
            title.text
        ) )
    end
    return table.concat( ret )
end
 
function p.main( 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
    
    -- list of args:
    -- 1        sometimes upper, not always trimmed, not entirely safe to remove blanks
    -- lk       lower-case, blanks removed
    -- first    lower-case, blanks removed
    -- disp     lower-case, blanks removed
    -- wrap     lower-case, blanks removed
    -- al       lower-case, blanks removed
    -- allk     lower-case, blanks removed
    
    -- Trim whitespace, make lower-case and remove blank arguments, but leave [1] as it is.
    local args = {}
    for k, v in pairs( origArgs ) do
        if k == 1 then
            args[ 1 ] = v
        else
            v = mw.text.trim( v )
            if v ~= '' then
                args[ k ] = mw.ustring.lower( v )
            end
        end
    end
    return _main( args )
end
 
return p