Saltar para o conteúdo

Módulo:Convert default

Origem: Wikipédia, a enciclopédia livre.
local getArgs = require('Module:Arguments').getArgs
local TableTools = require('Module:TableTools')
local ConvertData = require('Module:Convert/data').all_units

local p = {}

function p.main(frame)
    local args = getArgs(frame, {
        frameOnly = true,
        trim = true
    })

    return p._main(frame, args)
end

function resolveUnit( unit )
    -- Resolves a unit by name to its canonical name.
    local unitData = ConvertData[unit]
    if unitData then
        if unitData["target"] then
            -- Unit alias
            return unitData["target"]
        else
            -- Not an alias
            return unit
        end
    else
        -- Not a valid unit
        return nil
    end
end

function callConvert( frame, args, input, from )
    local convertArgs = TableTools.shallowClone( args )
    -- Shift all numbered parameters up by 1.
    local i = 2
    while args[i] ~= nil do
        convertArgs[i + 1] = args[i]
        i = i + 1
    end
    
    -- Set the input value and unit
    local resolvedFrom = resolveUnit( from )
    convertArgs[1] = input
    convertArgs[2] = resolvedFrom
    
    -- Wipe custom arguments
    convertArgs["default-unit"] = nil
    convertArgs["defaultUnit"] = nil
    convertArgs["default unit"] = nil
    convertArgs["default-units"] = nil
    convertArgs["defaultUnits"] = nil
    convertArgs["default units"] = nil
    
    -- Remove duplicate units in output units (if available)
    -- Avoid doing this if there are custom display parameters set.
    if convertArgs[3] ~= nil and convertArgs["disp"] == nil then
        local outputUnits = mw.text.split( mw.text.trim( convertArgs[3] ), "%s" )
        local j = 1
        while outputUnits[j] ~= nil do
            mw.logObject(resolveUnit( outputUnits[j] ), resolvedFrom)
            if resolveUnit( outputUnits[j] ) == resolvedFrom then
                -- Duplicate unit. Remove it.
                table.remove( outputUnits, j )
                -- Do not increment; the next value will now have an index of `j`.
            else
                j = j + 1
            end
        end
        convertArgs[3] = table.concat( outputUnits, " " )
    end
    
    return frame:expandTemplate{ title = "cvt", args = convertArgs }
end

function p._main(frame, args)
    if not args[1] then
        return nil
    end
    local rawInput = mw.text.trim( args[1] )
    local defaultUnit = args["default-unit"] or args["defaultUnit"] or args["default unit"] or
        args["default-units"] or args["defaultUnits"] or args["default units"]
    
    local numSection = mw.ustring.match( rawInput, "^-?[%d,e]+" )
    if numSection == nil then
        -- Raw output (not a determinable number)
        return rawInput
    end
    
    if mw.ustring.len( rawInput ) == mw.ustring.len( mw.text.trim( numSection ) ) then
        -- There only exists a number section.
        -- Convert, and use the default unit (if defined).
        if not defaultUnit then
            return error("No default unit is set, and a unitless input was provided.")
        else
            return callConvert( frame, args, numSection, defaultUnit )
        end
    else
        -- There exists a text section.
        -- Get that section.
        local textSection = mw.text.trim(
            string.sub( rawInput, mw.ustring.len( mw.text.trim( numSection ) ) + 1 )
        )
        if resolveUnit( textSection ) ~= nil then
            return callConvert( frame, args, numSection, textSection )
        else
            -- Not a unit. Fall back to raw value.
            return rawInput
        end
    end
end

return p