Module:Convert/data

From TEPwiki, Urth's Encyclopedia
Revision as of 20:19, 25 September 2012 by w>Johnuniq (data from Module:Convert; final data is around 5000 lines)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

--[[
This module contains most conversion data used by Module:Convert.
This is a separate file on the assumption that the bytecode will be cached,
and having Module:Convert "require" this should not be slow.

Three data tables follow:
    SIprefixes      prefixes like 'M' (mega, 10^6)
    units           all properties for a unit, including default output
    defaultunits    default output exceptions ('Mg' and 'g' have different defaults)

SIprefixes and defaultunits are maintained by editing this file.
However, the units table is generated by a script which reads the wikitext
for a wiki page that documents properties of units.
The wiki page is currently:
http://en.wikipedia.org/wiki/User:Johnuniq/Conversion_data

Check values at:
http://en.wikipedia.org/wiki/Template:Convert/list_of_units
http://en.wikipedia.org/wiki/Conversion_of_units
]]

local function clonetable(t)
    -- Return a shallow copy of t.
    local result = {}
    for k, v in pairs(t) do
        result[k] = v
    end
    return result
end

local function shouldbe(ucode, shouldbe)
    -- Return an error message for a unit that "should be" something else.
    -- enwiki Template:Convert outputs a much more elaborate message.
    -- LATER: Decide if "shouldbe" is useful, and what to output if it is.
    return 'ERROR: Use "' .. shouldbe .. '" (not "' .. ucode .. '") as the unit code.'
end

local SIprefixes = {
    ['Y'] = { exponent = 24, name = 'yotta' },
    ['Z'] = { exponent = 21, name = 'zetta' },
    ['E'] = { exponent = 18, name = 'exa'   },
    ['P'] = { exponent = 15, name = 'peta'  },
    ['T'] = { exponent = 12, name = 'tera'  },
    ['G'] = { exponent =  9, name = 'giga'  },
    ['M'] = { exponent =  6, name = 'mega'  },
    ['k'] = { exponent =  3, name = 'kilo'  },
    ['H'] = { exponent =  2, name = 'hecto' },  -- not an SI prefix, but allow for people typing this
    ['h'] = { exponent =  2, name = 'hecto' },
    ['da']= { exponent =  1, name = 'deca'  },
    ['D'] = { exponent =  1, name = 'deca'  },  -- not an SI prefix, but allow for people typing this
    ['d'] = { exponent = -1, name = 'deci'  },
    ['c'] = { exponent = -2, name = 'centi' },
    ['m'] = { exponent = -3, name = 'milli' },
    ['µ'] = { exponent = -6, name = 'micro' },
    ['u'] = { exponent = -6, name = 'micro' },  -- not an SI prefix, but allow for people typing this
    ['n'] = { exponent = -9, name = 'nano'  },
    ['p'] = { exponent =-12, name = 'pico'  },
    ['f'] = { exponent =-15, name = 'femto' },
    ['a'] = { exponent =-18, name = 'atto'  },
    ['z'] = { exponent =-21, name = 'zepto' },
    ['y'] = { exponent =-24, name = 'yocto' },
}

local usesubstitute = {
    -- If unit has an SI prefix, these fields may have "%s" where prefix belongs.
    'name1',
    'name1_us',
    'name2',
    'name2_us',
    'link',
}

local function set_prefixes(unit, prefixname)
    -- Insert given prefix name into the fields which require it
    -- (and which should contain '%s' to be replaced with the prefix).
    -- Pity we have to do all this work when most results are not needed,
    -- but it's cleaner to do it here rather than in final processing.
    if unit.prefixes then
        for _, name in ipairs(usesubstitute) do
            local value = unit[name]
            unit[name] = value:gsub('%%s', prefixname, 1)
        end
    end
end

-- Do not change the data in this table because it is created by running
-- a script that reads the wikitext from a wiki page (see note above).
local units = {
    lookup = function (self, unit)
        -- Return true, t where t is the unit's converter table (or false, message).
        -- Given 'unit' is a symbol (like 'g'), with an optional SI prefix (as in 'kg').
        -- If, for example, 'kg' is in this table, that entry is used; otherwise prefix is applied.
        local t = self[unit]
        if t ~= nil then
            if t.shouldbe then
                return false, shouldbe(t.shouldbe, unit)
            end
            local result = clonetable(t)
            set_prefixes(result, '')
            result.baseunit = unit
            result.prefix = ''
            return true, result
        end
        for plen = 2, 1, -1 do
            -- Check for longer prefix first ('dam' is decametre).
            local prefix = string.sub(unit, 1, plen)
            local si = SIprefixes[prefix]
            if si then
                local baseunit = unit:sub(plen+1)
                local t = self[baseunit]
                if t and t.prefixes then
                    local result = clonetable(t)
                    set_prefixes(result, si.name)
                    result.symbol = prefix .. result.symbol
                    result.sym_us = prefix .. result.sym_us
                    result.baseunit = baseunit
                    result.prefix = prefix
                    result.scale = t.scale * 10 ^ (si.exponent * t.prefixes)
                    return true, result
                end
            end
        end
        local msg = 'Unit %s is not known.[[Category:Convert unknown unit]]'
        return false, msg:format(unit)
    end,
    ["m2"] = {
    name1    = "square %smetre",
	name1_us = "square %smeter",
	name2    = "square %smetres",
	name2_us = "square %smeters",
	symbol   = "m<sup>2</sup>",
	sym_us   = "m<sup>2</sup>",
	utype    = "area",
	scale    = 1,
	offset   = 0,
	prefixes = 2,
	default  = "sqyd",
	link     = "Square %smetre",
    },
    ["a"] = {
	name1    = "%sare",
	name1_us = "%sare",
	name2    = "%sares",
	name2_us = "%sares",
	symbol   = "a",
	sym_us   = "a",
	utype    = "area",
	scale    = 100,
	offset   = 0,
	prefixes = 1,
	default  = "acre",
	link     = "Hectare#Are",
    },
    ["ha"] = {
	name1    = "hectare",
	name1_us = "hectare",
	name2    = "hectares",
	name2_us = "hectares",
	symbol   = "ha",
	sym_us   = "ha",
	utype    = "area",
	scale    = 10000,
	offset   = 0,
	default  = "acre",
	link     = "Hectare",
    },
    ["sqft"] = {
	name1    = "square foot",
	name1_us = "square foot",
	name2    = "square feet",
	name2_us = "square feet",
	symbol   = "sq ft",
	sym_us   = "sq ft",
	utype    = "area",
	scale    = 0.09290304,
	offset   = 0,
	default  = "m2",
	link     = "Square foot",
    },
    ["ft2"] = {
	name1    = "square foot",
	name1_us = "square foot",
	name2    = "square feet",
	name2_us = "square feet",
	symbol   = "sq ft",
	sym_us   = "sq ft",
	utype    = "area",
	scale    = 0.09290304,
	offset   = 0,
	default  = "m2",
	link     = "Square foot",
    },
    ["sqfoot"] = {
	name1    = "square foot",
	name1_us = "square foot",
	name2    = "square foot",
	name2_us = "square foot",
	symbol   = "sq ft",
	sym_us   = "sq ft",
	utype    = "area",
	scale    = 0.09290304,
	offset   = 0,
	default  = "m2",
	link     = "Square foot",
    },
    ["foot2"] = {
	name1    = "square foot",
	name1_us = "square foot",
	name2    = "square foot",
	name2_us = "square foot",
	symbol   = "sq ft",
	sym_us   = "sq ft",
	utype    = "area",
	scale    = 0.09290304,
	offset   = 0,
	default  = "m2",
	link     = "Square foot",
    },
    ["sqyd"] = {
	name1    = "square yard",
	name1_us = "square yard",
	name2    = "square yards",
	name2_us = "square yards",
	symbol   = "sq yd",
	sym_us   = "sq yd",
	utype    = "area",
	scale    = 0.83612736,
	offset   = 0,
	default  = "m2",
	link     = "Square yard",
    },
    ["sqin"] = {
	name1    = "square inch",
	name1_us = "square inch",
	name2    = "square inches",
	name2_us = "square inches",
	symbol   = "sq in",
	sym_us   = "sq in",
	utype    = "area",
	scale    = 0.00064516,
	offset   = 0,
	default  = "cm2",
	link     = "Square inch",
    },
    ["acre"] = {
	name1    = "acre",
	name1_us = "acre",
	name2    = "acres",
	name2_us = "acres",
	symbol   = "acre",
	sym_us   = "acre",
	utype    = "area",
	scale    = 4046.8564224,
	offset   = 0,
	default  = "ha",
	link     = "Acre",
    },
    ["m"] = {
	name1    = "%smetre",
	name1_us = "%smeter",
	name2    = "%smetres",
	name2_us = "%smeters",
	symbol   = "m",
	sym_us   = "m",
	utype    = "length",
	scale    = 1,
	offset   = 0,
	prefixes = 1,
	default  = "ft",
	link     = "%smetre",
    },
    ["mi"] = {
	name1    = "mile",
	name1_us = "mile",
	name2    = "miles",
	name2_us = "miles",
	symbol   = "mi",
	sym_us   = "mi",
	utype    = "length",
	scale    = 1609.344,
	offset   = 0,
	default  = "km",
	link     = "Mile",
    },
    ["ft"] = {
	name1    = "foot",
	name1_us = "foot",
	name2    = "feet",
	name2_us = "feet",
	symbol   = "ft",
	sym_us   = "ft",
	utype    = "length",
	scale    = 0.3048,
	offset   = 0,
	default  = "m",
	link     = "Foot (unit)",
    },
    ["foot"] = {
	name1    = "foot",
	name1_us = "foot",
	name2    = "foot",
	name2_us = "foot",
	symbol   = "ft",
	sym_us   = "ft",
	utype    = "length",
	scale    = 0.3048,
	offset   = 0,
	default  = "m",
	link     = "Foot (unit)",
    },
    ["feet"] = {
	shouldbe = "ft",
    },
    ["yd"] = {
	name1    = "yard",
	name1_us = "yard",
	name2    = "yards",
	name2_us = "yards",
	symbol   = "yd",
	sym_us   = "yd",
	utype    = "length",
	scale    = 0.3048 * 3,
	offset   = 0,
	default  = "m",
	link     = "Yard",
    },
    ["in"] = {
	name1    = "inch",
	name1_us = "inch",
	name2    = "inches",
	name2_us = "inches",
	symbol   = "in",
	sym_us   = "in",
	utype    = "length",
	scale    = 0.0254,
	offset   = 0,
	default  = "cm",
	link     = "Inch",
    },
    ["g"] = {
	name1    = "%sgram",
	name1_us = "%sgram",
	name2    = "%sgrams",
	name2_us = "%sgrams",
	symbol   = "g",
	sym_us   = "g",
	utype    = "mass",
	scale    = 0.001,
	offset   = 0,
	prefixes = 1,
	default  = "oz",
	link     = "%sgram",
    },
    ["lb"] = {
	name1    = "pound",
	name1_us = "pound",
	name2    = "pounds",
	name2_us = "pounds",
	symbol   = "lb",
	sym_us   = "lb",
	utype    = "mass",
	scale    = 0.45359237,
	offset   = 0,
	default  = "kg",
	link     = "Pound (mass)",
    },
    ["oz"] = {
	name1    = "ounce",
	name1_us = "ounce",
	name2    = "ounces",
	name2_us = "ounces",
	symbol   = "oz",
	sym_us   = "oz",
	utype    = "mass",
	scale    = 0.45359237/16,
	offset   = 0,
	default  = "g",
	link     = "Ounce",
    },
    ["ozt"] = {
	name1    = "troy ounce",
	name1_us = "troy ounce",
	name2    = "troy ounces",
	name2_us = "troy ounces",
	symbol   = "ozt",
	sym_us   = "ozt",
	utype    = "mass",
	scale    = 0.0311034768,
	offset   = 0,
	default  = "g",
	link     = "Troy ounce",
    },
    ["K"] = {
	name1    = "kelvin",
	name1_us = "kelvin",
	name2    = "kelvins",
	name2_us = "kelvins",
	symbol   = "K",
	sym_us   = "K",
	utype    = "temperature",
	scale    = 1,
	offset   = 0,
	default  = "C",
	link     = "Kelvin",
    },
    ["C"] = {
	name1    = "degree Celsius",
	name1_us = "degree Celsius",
	name2    = "degrees Celsius",
	name2_us = "degrees Celsius",
	symbol   = "°C",
	sym_us   = "°C",
	utype    = "temperature",
	scale    = 1,
	offset   = -273.15,
	default  = "F",
	link     = "Celsius",
    },
    ["°C"] = {
	name1    = "degree Celsius",
	name1_us = "degree Celsius",
	name2    = "degrees Celsius",
	name2_us = "degrees Celsius",
	symbol   = "°C",
	sym_us   = "°C",
	utype    = "temperature",
	scale    = 1,
	offset   = -273.15,
	default  = "F",
	link     = "Celsius",
    },
    ["F"] = {
	name1    = "degree Fahrenheit",
	name1_us = "degree Fahrenheit",
	name2    = "degrees Fahrenheit",
	name2_us = "degrees Fahrenheit",
	symbol   = "°F",
	sym_us   = "°F",
	utype    = "temperature",
	scale    = 5/9,
	offset   = 32-273.15*(9/5),
	default  = "C",
	link     = "Fahrenheit",
    },
    ["°F"] = {
	name1    = "degree Fahrenheit",
	name1_us = "degree Fahrenheit",
	name2    = "degrees Fahrenheit",
	name2_us = "degrees Fahrenheit",
	symbol   = "°F",
	sym_us   = "°F",
	utype    = "temperature",
	scale    = 5/9,
	offset   = 32-273.15*(9/5),
	default  = "C",
	link     = "Fahrenheit",
    },
    ["m3"] = {
	name1    = "cubic %smetre",
	name1_us = "cubic %smeter",
	name2    = "cubic %smetres",
	name2_us = "cubic %smeters",
	symbol   = "m<sup>3</sup>",
	sym_us   = "m<sup>3</sup>",
	utype    = "volume",
	scale    = 1,
	offset   = 0,
	prefixes = 3,
	default  = "cuyd",
	link     = "Cubic %smetre",
    },
    ["l"] = {
	name1    = "%slitre",
	name1_us = "%sliter",
	name2    = "%slitres",
	name2_us = "%sliters",
	symbol   = "l",
	sym_us   = "l",
	utype    = "volume",
	scale    = 0.001,
	offset   = 0,
	prefixes = 1,
	default  = "imppt",
	link     = "Litre",
    },
    ["L"] = {
	name1    = "%slitre",
	name1_us = "%sliter",
	name2    = "%slitres",
	name2_us = "%sliters",
	symbol   = "L",
	sym_us   = "L",
	utype    = "volume",
	scale    = 0.001,
	offset   = 0,
	prefixes = 1,
	default  = "imppt",
	link     = "Litre",
    },
    ["cuyd"] = {
	name1    = "cubic yard",
	name1_us = "cubic yard",
	name2    = "cubic yards",
	name2_us = "cubic yards",
	symbol   = "cu yd",
	sym_us   = "cu yd",
	utype    = "volume",
	scale    = 0.764554857984,
	offset   = 0,
	default  = "m3",
	link     = "Cubic yard",
    },
    ["USgal"] = {
	name1    = "US gallon",
	name1_us = "U.S. gallon",
	name2    = "US gallons",
	name2_us = "U.S. gallons",
	symbol   = "US gal",
	sym_us   = "U.S. gal",
	utype    = "volume",
	scale    = 0.003785411784,
	offset   = 0,
	default  = "L",
	link     = "US gallon",
    },
    ["USoz"] = {
	name1    = "US fluid ounce",
	name1_us = "U.S. fluid ounce",
	name2    = "US fluid ounces",
	name2_us = "U.S. fluid ounces",
	symbol   = "US fl oz",
	sym_us   = "U.S. fl oz",
	utype    = "volume",
	scale    = 0.003785411784/128,
	offset   = 0,
	default  = "cL",
	link     = "US fluid ounce",
    },
    ["USpt"] = {
	name1    = "U.S. pint",
	name1_us = "U.S. pint",
	name2    = "U.S. pints",
	name2_us = "U.S. pints",
	symbol   = "US pt",
	sym_us   = "US pt",
	utype    = "volume",
	scale    = 0.003785411784/8,
	offset   = 0,
	default  = "dL",
    },
    ["impgal"] = {
	name1    = "imperial gallon",
	name1_us = "imperial gallon",
	name2    = "imperial gallons",
	name2_us = "imperial gallons",
	symbol   = "imp gal",
	sym_us   = "imp gal",
	utype    = "volume",
	scale    = 0.00454609,
	offset   = 0,
	default  = "L",
	link     = "Imperial gallon",
    },
    ["impoz"] = {
	name1    = "imperial fluid ounce",
	name1_us = "imperial fluid ounce",
	name2    = "imperial fluid ounces",
	name2_us = "imperial fluid ounces",
	symbol   = "imp fl oz",
	sym_us   = "imp fl oz",
	utype    = "volume",
	scale    = 0.00454609/160,
	offset   = 0,
	default  = "cL",
	link     = "Imperial fluid ounce",
    },
    ["imppt"] = {
	name1    = "imperial pint",
	name1_us = "imperial pint",
	name2    = "imperial pints",
	name2_us = "imperial pints",
	symbol   = "imp pt",
	sym_us   = "imp pt",
	utype    = "volume",
	scale    = 0.00454609/8,
	offset   = 0,
	default  = "dL",
	link     = "Imperial pint",
    },
}

local defaultunits = {
    lookup = function (self, unit_table)
        -- Return true, s where s = name of unit's default output unit (or false, message).
        local baseunit = unit_table.baseunit
        local prefix = unit_table.prefix
        local unit = prefix .. baseunit
        local default = self[unit]
        if default ~= nil then return true, default end
        local t = units[baseunit]
        if t ~= nil then
            local default = t.default
            if default ~= nil then return true, default end
        end
        local msg = 'Unit %s has no default target conversion.[[Category:Convert unknown unit]]'
        return false, msg:format(unit)
    end,
    -- Prefixed units with a default different from that of the base unit.
    ['kg']  = 'lb',
    ['Mg']  = 'lb',
    ['Gg']  = 'lb',
    ['pm']  = 'in',
    ['nm']  = 'in',
    ['um']  = 'in',
    ['mm']  = 'in',
    ['cm']  = 'in',
    ['dm']  = 'in',
    ['dam'] = 'yd',
    ['Hm']  = 'yd',
    ['km']  = 'mi',
    ['Mm']  = 'mi',
    ['mL']  = 'impoz',
    ['cL']  = 'impoz',
    ['dL']  = 'impoz',
    ['daL'] = 'impgal',
    ['HL']  = 'impgal',
}

return {
    units = units,
    defaultunits = defaultunits,
}