Uso

Por ahora, {{#invoke:Convierte:convierte| ... mismos parámetros que para {{Convertir}} ... }}




require('Módulo:No globals')

local tablas = {
   {  -- Tabla 1. Longitud
      -- unidad base: m

      -- los prefijos estándar
      ym     = { 1e-24, "yoctómetro", "yoctómetros" },
      zm     = { 1e-21, "zeptómetro", "zeptómetros" },
      am     = { 1e-18, "attómetro",  "attómetros"  },
      fm     = { 1e-15, "femtómetro", "femtómetros", "fermi", "fermis" },
      pm     = { 1e-12, "picómetro",  "picómetros"  },
      nm     = { 1e-9,  "nanómetro",  "nanómetros"  },
      ["µm"] = { 1e-6,  "micrómetro", "micrómetros", "micrón", "micra", "micrones", "micras" },
      mm     = { 0.001, "milímetro",  "milímetros"  },
      cm     = { 0.01,  "centímetro", "centímetros" },
      dm     = { 0.1,   "decímetro",  "decímetros"  },
      m      = { 1,     "metro",      "metros"      },
      dam    = { 10,    "decámetro",  "decámetros",  "Dm" },
      hm     = { 100,   "hectómetro", "hectómetros", "Hm" },
      km     = { 1000,  "kilómetro",  "kilómetros",  "Km" },
      Mm     = { 1e6,   "megámetro",  "megámetros" },
      Gm     = { 1e9,   "gigámetro",  "gigámetros" },
      Tm     = { 1e12,  "terámetro",  "terámetros" },
      Pt     = { 1e15,  "petámetro",  "petámetros" },
      Em     = { 1e18,  "exámetro",   "exámetros"  },
      Zm     = { 1e21,  "zettametro", "zettametros" },
      Ym     = { 1e24,  "yottametro", "yottametros" },

      -- otros
      mam    = { 10000, "miriámetro", "miriámetros", "mil" },
      ["Å"]  = { 1e-10, "ångström", "ångströms", "angstrom" },
      xu     = { 1e-13, "unidad x", "unidades x" },
      ua     = { 149597870700, "unidad astronómica", "unidades astronómicas", "UA", "au", "AU" },
      ly     = { 9460730472580800, "año luz", "años luz", "al", "l.y.", "a.l.";
                 ua = 63241.077 },
      pc     = { 3.085677581e16, "pársec", "pársecs", "parsec";
                 ly = 3.261563777, ua = 206264.806247096 },
      -- unidades inglesas
      ["in"] = { 0.0254, "pulgada", "pulgadas" },
      ft     = { 0.3048, "pie",     "pies";  enlace = "Pie (unidad)" },
      yd     = { 0.9144, "yarda",   "yardas"   },
      mi     = { 1609.344, "milla", "millas"   },
      M      = { 1852, "milla náutica", "millas náuticas", "NM", "nmi" },
   },
   {  -- Tabla 2. Área
      -- unidad base: m²

      -- ''algunos'' prefijos estándar
      ["mm²"] = { 1e-6, "milímetro cuadrado",  "milímetros cuadrados", "mm2" },
      ["cm²"] = { 1e-4, "centímetro cuadrado", "centímetros cuadrados", "cm2" },
      ["m²"]  = { 1,    "metro cuadrado",      "metros cuadrados", "m2" },
      ["km²"] = { 1e6,  "kilómetro cuadrado",  "kilómetros cuadrados", "km2" },
      
      -- otros
      ca      = { 1,     "centiárea", "centiáreas" },
      a       = { 100,   "área",      "áreas";  enlace = "Área (unidad de superficie)" },
      ha      = { 10000, "hectárea",  "hectáreas" },

      -- inglesas
      ["in²"] = { 0.00064516,   "pulgada cuadrada", "pulgadas cuadradas", "sqin", "in2" },
      ["ft²"] = { 0.09290304,   "pie cuadrado", "pies cuadrados", "sqft", "pie²", "ft2", "pie2" },
      ["yd²"] = { 0.83612736,   "yarda cuadrada", "yardas cuadradas", "sqyd", "yarda²", "yd2" },
      acre    = { 4046.8564224, "acre", "acres" },
      ["mi²"] = { 2589988.110336, "milla cuadrada", "millas cuadradas", "sqmi", "milla²", "mi2" },
   },
   {  -- Tabla 3. Volumen
      -- unidad base: m³

      ["mm³"] = { 1e-9,  "milímetro cúbico",  "milímetros cúbicos", "mm3" },
      ["cm³"] = { 1e-6,  "centímetro cúbico", "centímetros cúbicos", "cc", "cm3" },
      ["m³"]  = { 1,     "metro cúbico",      "metros cúbicos", "m3" },

      -- litros
      ["µl"]  = { 1e-9,  "microlitro", "microlitros", "µL" },
      ml      = { 1e-6,  "mililitro",  "mililitros",  "mL" },
      cl      = { 1e-5,  "centilitro", "centilitros", "cL" },
      dl      = { 1e-4,  "decilitro",  "decilitros",  "dL" },
      l       = { 0.001, "litro",      "litros", "L" },
      hl      = { 0.1,   "hectolitro", "hectolitros", "hL" },

      -- inglesas
      gal     = { 0.003785411784, "galón", "galones", "usgal" },
   },
   {  -- Tabla 4. Masa
      -- unidad base: kg

      pg     = { 1e-15, "picogramo", "picogramos" },
      ng     = { 1e-12, "nanogramo", "nanogramos" },
      ["µg"] = { 1e-9,  "microgramo", "microgramos" },
      mg     = { 1e-6,  "miligramo", "miligramos" },
      g      = { 0.001, "gramo",     "gramos" },
      dag    = { 0.01,  "decagramo", "decagramos", "dkg" },
      kg     = { 1,     "kilogramo", "kilogramos", "kilo", "kilos" },

      -- toneladas
      t      = { 1000, "tonelada", "toneladas", "T", "Tn", "tn" },
      --kt     = { 1e6,  "kilotonelada", "kilotoneladas" },
      Mt     = { 1e9, "megatonelada", "megatoneladas" },

      -- otros
      ["@"]  = { 11.5, "arroba", "arrobas";  enlace = "Arroba (unidad de masa)" },

      -- inglesas
      oz     = { 0.028349523125, "onza",      "onzas";  enlace = "Onza (unidad de masa)" },
      ozt    = { 0.0311034768,   "onza troy", "onzas troy" },
      lb     = { 0.45359237,     "libra",     "libras";  enlace = "Libra (unidad de masa)" },
      st     = { 6.35029318,     "stone",     "stones", "st." },
   },
   {  -- Tabla 5. Velocidad
      -- unidad básica: km/h
      
      ["m/s"]  = { 3.6, "metro por segundo", "metros por segundo" },
      ["km/h"] = { 1,   "kilómetro por hora", "kilómetros por hora", "kph" },

      -- otras, inglesas
      ["mi/h"] = { 1.609344, "milla por hora", "millas por hora", "mph" },
      ["kn"]   = { 1.852,    "nudo", "nudos", "kt", "kts";  enlace = "Nudo (unidad)" },
      ["ft/s"] = { 1.09728,  "pie por segundo", "pies por segundo", "pie/s" },
   },
   {  -- Tabla 6. Fuerza
      -- unidad básica: N
      N   = { 1, "newton", "newtons";  enlace = "Newton (unidad)" },
      kN  = { 1000, "kilonewton", "kilonewtons" },
      MN  = { 1e6,  "meganewton", "meganewtons" },

      dyn = { 1e-5, "dina", "dinas";  enlace = "Dina (unidad de medida)" },
      kp  = { 9.80665, "kilopondio", "kilopondios", "kgf" },

      lbf = { 4.448222, "libra (fuerza)", "libras (fuerza)";  enlace = "Libra (unidad de fuerza)" },
   },
}

-- aplanamos la tabla para agilizar el acceso
local unidades = {}

local agrega = function (k, v)
   local duplicada = unidades[k]
   if duplicada and duplicada ~= v then error("se redefine la unidad " .. k) end
   unidades[k] = v
end

do
   for _, t in ipairs(tablas) do
      local tipo = {}
      for k, v in pairs(t) do
         local entrada = {
            tipo = tipo,
            simbolo = k,
            factor = v[1], singular = v[2], plural = v[3],
            enlace = v.enlace or v[2],
            conv = {}
         }
         for dest, factor in pairs(v) do
            if type(dest) == "string" and dest ~= "enlace" then
               entrada.conv[dest] = factor
            end
         end
         agrega(k, entrada)
         for i = 2, #v do
            agrega(string.gsub(v[i], " ", ""), entrada)
         end
      end
   end
end

tablas = nil  agrega = nil

-- agregamos las conversiones directas inversas
for de, entrada in pairs(unidades) do
   for a, factor in pairs(entrada.conv) do
      if type(factor) == "number" and not unidades[a].conv[de] then
         unidades[a].conv[de] = 1/factor
      end
   end
end

local function getunidad (s)
   local u = unidades[string.gsub(s, " ", "")]
   if not u then error("unidad desconocida: " .. s) end
   return u
end

local function convierte2 (n, de, a)
   local ude = getunidad(de)
   local ua  = getunidad(a)
   if ude.tipo ~= ua.tipo then
      error("unidades incompatibles: " .. de .. " y " .. a)
   end
   local n2
   local factor = ude.conv[ua.simbolo]
   if factor then
      if type(factor) == "function" then
         n2 = factor(n)
      else
         n2 = n * factor
      end
   else
      factor = ude.factor/ua.factor
      n2 = n * factor
   end

   return n, ude, n2, ua
end

local function convierte1 (n, de, a, opciones)
   local n1, u1, n2, u2 = convierte2(n, de, a)
      
   if opciones.precision then
      n2 = math.floor(n2 * 10^opciones.precision + 0.5) / 10^opciones.precision
   end

   return n1, u1, n2, u2
end

local parametros = {
   abrev = { "abbr", "abrev" },
   enlace = { "lk", "enlace" },
   mostrar = { "disp", "mostrar" },
}

local function esteoambos (este, s)
   if not s then return false end
   if string.match(s, "^" .. este) or string.match(s, "^on") or string.match(s, "^ambos") then
      return true
   end
   return false
end

local function formatea (lado, num, u, lang, opciones)
   local result = lang:formatNum(num)
   local m = opciones.mostrar or ""
   local sololado2 = string.match(m, "2")
   if sololado2 and lado == "1" then return "" end
   if lado == "2" and (string.match(m, "#") or string.match(m, "número")) then
      return result
   end
   result = result .. " "
   local lk = esteoambos(lado, opciones.enlace)
   if lk then result = result .. "[[" .. lang:ucfirst(u.enlace) .. "|" end
   if esteoambos(lado, opciones.abrev) then
      result = result .. u.simbolo
   elseif num == 1 then
      result = result .. u.singular
   else
      result = result .. u.plural
   end
   if lk then result = result .. "]]" end

   if lado == "2" then
      if string.match(m, "%[") or string.match(m, "brackets") then
         result = "[" .. result .. "]"
         if not sololado2 then result = " " .. result end
      elseif not sololado2 then
         if string.match(m, "/") or string.match(m, "slash") then
            result = "/" .. result
         else
            result = " (" .. result .. ")"
         end
      end
   end
   return result
end

local function convierte (frame)
   local n = tonumber((string.gsub(frame.args[1], ",", ".")))
   local de = frame.args[2]
   local a  = frame.args[3]
   local opciones = { precision = frame.args[4] }
   for nombreparam, paramalias in pairs(parametros) do
      for _, p in ipairs(paramalias) do
         local valor = frame.args[p]
         if valor then opciones[nombreparam] = valor end
      end
   end
   local n1, u1, n2, u2 = convierte1(n, de, a, opciones)
   local lang = mw.language.getContentLanguage()
   local izq = formatea("1", n1, u1, lang, opciones)
   local der = formatea("2", n2, u2, lang, opciones)

   return izq .. der
end

return { convierte = convierte }

-- mw = {
--    language = {
--       getContentLanguage = function ()
--          return {
--             uc = function (self, s) return s end,
--             ucfirst = function (self, s) return s end,
--             formatNum = function (self, n) return tostring(n) end
--          }
--       end
--    }
-- }

-- print(convierte{ args = { "32", "m", "pie", "0" } })
-- print(convierte{ args = { "1250", "sqft", "m²", "1", lk = "on", abbr = "1" }})
-- print(convierte{ args = { "1250", "ha", "m²", "1", lk = "on", abbr = "1" }})
-- print(convierte{ args = { "1250", "lb", "oz", "1", lk = "on", }})
-- print(convierte{ args = { "10", "au", "pc" }})