Module:Convert

From PS:1 Wiki Dev
Jump to navigationJump to search

Documentation for this module may be created at Module:Convert/doc

Script error: Lua error: Internal error: The interpreter exited with status 127.

local p = {}

-- Conversion factors
local conversions = {
    -- Length
    ['in'] = {factor = 2.54, to = 'cm', name = 'in'},
    ['cm'] = {factor = 1/2.54, to = 'in', name = 'cm'},
    ['ft'] = {factor = 0.3048, to = 'm', name = 'ft'},
    ['m'] = {factor = 1/0.3048, to = 'ft', name = 'm'},
    ['mi'] = {factor = 1.60934, to = 'km', name = 'mi'},
    ['km'] = {factor = 1/1.60934, to = 'mi', name = 'km'},
    
    -- Weight/Mass
    ['lb'] = {factor = 0.453592, to = 'kg', name = 'lb'},
    ['kg'] = {factor = 1/0.453592, to = 'lb', name = 'kg'},
    ['oz'] = {factor = 28.3495, to = 'g', name = 'oz'},
    ['g'] = {factor = 1/28.3495, to = 'oz', name = 'g'},
    
    -- Volume
    ['gal'] = {factor = 3.78541, to = 'L', name = 'gal'},
    ['L'] = {factor = 1/3.78541, to = 'gal', name = 'L'},
    
    -- Area
    ['sqft'] = {factor = 0.092903, to = 'm²', name = 'sq ft'},
    ['sqm'] = {factor = 1/0.092903, to = 'sq ft', name = 'm²'},
    
    -- Power
    ['hp'] = {factor = 0.745699872, to = 'kW', name = 'hp'},
    ['kW'] = {factor = 1/0.745699872, to = 'hp', name = 'kW'},
    ['W'] = {factor = 1/1000, to = 'kW', name = 'W'},
    
    -- Speed
    ['mph'] = {factor = 1.60934, to = 'km/h', name = 'mph'},
    ['kmh'] = {factor = 1/1.60934, to = 'mph', name = 'km/h'},
    
    -- Pressure
    ['psi'] = {factor = 6.89476, to = 'kPa', name = 'psi'},
    ['kPa'] = {factor = 1/6.89476, to = 'psi', name = 'kPa'}
}

-- Add commas to numbers
local function addCommas(num)
    local formatted = tostring(num)
    local k
    while true do
        formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
        if k == 0 then break end
    end
    return formatted
end

-- Round to specified precision
local function round(num, decimals)
    local mult = 10^(decimals or 0)
    return math.floor(num * mult + 0.5) / mult
end

-- Temperature conversions (special case)
local function convertTemperature(value, from, precision)
    if from == 'F' then
        local celsius = (value - 32) * 5/9
        celsius = round(celsius, precision or 1)
        return value .. ' °F (' .. addCommas(celsius) .. ' °C)'
    elseif from == 'C' then
        local fahrenheit = value * 9/5 + 32
        fahrenheit = round(fahrenheit, precision or 1)
        return value .. ' °C (' .. addCommas(fahrenheit) .. ' °F)'
    end
    return nil
end

-- Main conversion function
function p.convert(frame)
    local args = frame:getParent().args
    -- Strip commas from input
    local valueStr = args[1]
    if valueStr then
        valueStr = string.gsub(valueStr, ",", "")
    end
    local value = tonumber(valueStr)
    local unit = args[2]
    local precision = tonumber(args[3])
    
    if not value then
        return "Error: Invalid number"
    end
    
    if not unit then
        return "Error: No unit specified"
    end
    
    -- Handle temperature separately
    if unit == 'F' or unit == 'C' then
        return convertTemperature(value, unit, precision)
    end
    
    -- Look up conversion
    local conversion = conversions[unit]
    if not conversion then
        return addCommas(value) .. ' ' .. unit .. ' (conversion not supported)'
    end
    
    -- Calculate converted value
    local converted = value * conversion.factor
    
    -- Determine precision
    if not precision then
        if unit == 'in' or unit == 'cm' or unit == 'oz' or unit == 'g' then
            precision = 1
        else
            precision = 2
        end
    end
    
    converted = round(converted, precision)
    
    -- Format output
    return addCommas(value) .. ' ' .. conversion.name .. ' (' .. addCommas(converted) .. ' ' .. conversion.to .. ')'
end

return p