Ir al contenido

Diferencia entre revisiones de «Módulo:ConvertirAux»

De Wikipedia, la enciclopedia libre
Contenido eliminado Contenido añadido
Sin resumen de edición
Sin resumen de edición
Línea 393: Línea 393:
cadena=cadena:gsub("+"," ")
cadena=cadena:gsub("+"," ")
--Sustituir cada "−" (largo) por un "-" (corto)
--Sustituir cada "−" (largo) por un "-" (corto)
cadena=cadena:gsub("−","%1-")
cadena=cadena:gsub("−","%-")





Revisión del 19:32 9 abr 2020

Este módulo no tiene página de documentación[crear]
-- Módulo diseñado para ampliar las funcionalidades de la plantilla convertir, admitiendo la mayor parte de las entradas de la función convert en inglés 
-- Admite no declarar la segunda unidad (conversiones con variable por defecto)
-- Admite salida en pies y pulgadas; y en yardas, pies y pulgadas
-- Admite varias unidades de destino simultáneamente
-- Admite entrada en pies y pulgadas separados
-- Admite un intervalo de entrada, que se convierte en un intervalo de salida 
-- (pueden escribirse ambos en el campo [1], separados por uno de los cuatro caracteres siguientes: (''x'' ''y'' ''-'' ó ''a'') 
-- Además:
-- --La plantilla Convertir/ud permite definir nuevas unidades de forma más sencilla y compacta; incluyendo las relaciones numéricas entre ellas

local ConvertirAux = {}
 --Declaración de variables globales
   FFRR = {} --Matriz en la que se vuelcan los datos del frame
   vv = {} --Matriz de los 7 parámetros de unidad leídos de Convert/ud (separados por !)
   uu = {} --Matriz de las unidades de salida múltiples en [3] (separadas por blancos)
   ib =0   --número de elementos de la matriz uu
   ff0 = {} --Matriz con los elementos de la fórmula de conversión de la unidad origen
   ffz = {} --Matriz con los elementos de la fórmula de conversión de la unidad destino
   ii0 =0 --número de elementos de la matriz ff0
   iiz =0 --número de elementos de la matriz ffz

   IU =0   --número de unidades de salida
   I1 =1   --Posición inicial del valor a leer [1]
   I2 =2   --Posición inicial del valor a leer [2]
   I3 =3   --Posición inicial del valor a leer [3]
   I4 =4   --Posición inicial del valor a leer [4]
   II =1   --Controla el bucle de IU cuando hay varias unidades de salida (I3 múltiple)
   CASOUD="" --NO0 NO1 NO2 Y NO3 para quitar los paréntesis de cola y cabeza y los separadores en su caso
   FORMULA0="" --Conversión de la unidad de origen  guardada en Convertir/ud (campos 6 y 7)
   FORMULAZ="" --Conversión de la unidad de destino guardada en Convertir/ud (campos 6 y 7)
   FRAC="" --Indica si la medida se ha introducido con una expresión fraccional

function ConvertirAux.CONVTOT(frame)
  --Volcado del frame
    FFRR[1]=frame.args[1]
    FFRR[2]=frame.args[2]
    FFRR[3]=frame.args[3]
    FFRR[4]=frame.args[4]
    FFRR[5]=frame.args[5]
    FFRR[6]=frame.args[6]

 --Reordenación de valores para el caso del campo [1] doble:
   dobleuno (FFRR[1])

 --Reordenación de valores para el caso de que la precisión aparezca en el campo [5] (se permuta con el [6])
   if tonumber(FFRR[5])~= nil then 
      FFRR[5],FFRR[6]=FFRR[6],FFRR[5]
   end

  --Lectura de los campos 2, 3 y 4 para determinar tipo de entrada:
    local SALIDA=""
    local K2= FFRR[2]
    local K3= FFRR[3]
    local K4= FFRR[4]
    local KD= frame.args["disp"]
    local KSALIDA=""
    local KSALIDA1=""
    IU=1
  --Cálculo de IU, para detectar si hay varias unidades de salida declaradas:
    if (K3 ~= "" and K3 ~= nil) then cortarblanco (K3, uu);IU=ib ;end

  -- Caso de varias salidas declaradas:   
    if IU > 1 then
      local KSALIDA="; "  
      --Llamada a la funcion local UNIDAD1
      SALIDA= UNIDAD1(frame)
      --Bucle con las llamadas a UNIDAD2
      for i=1,IU do
          II=i
          CASOUD="NO3" 
          if II==1 then CASOUD="NO0" end
          if II==IU then CASOUD="NO2";KSALIDA="" end
          SALIDA=SALIDA..UNIDAD2(frame)..KSALIDA
      end
    else

  -- Caso entrada doble con ft[2] + in[4]:  
    if (K2=="ft" and K4=="in") then
     I1=1; I2=2
     SALIDA=UNIDAD1(frame)
     I1=3; I2=4;
     SALIDA=SALIDA..UNIDAD1(frame)
     I1=1; I2=2; I3=5; I4=6;
     SALIDA=SALIDA..UNIDAD2(frame)
 
 -- Caso con intervalos dobles de entrada (y de salida):
    elseif (K2=="-" or K2=="and" or K2=="to" or K2=="hasta" or K2=="y" or K2=="x" or K2=="X" or K2=="by" or K2=="por" or K2=="a") then
     I1=1; I2=4; CASOUD="NO"
     SALIDA=UNIDAD1(frame)
     KSALIDA=""
     if K2=="-" then KSALIDA="-" end
     if (K2=="and" or K2=="y") then KSALIDA=" y " end
     if (K2=="x" or K2=="X") then KSALIDA=" x " end
     if (K2=="by" or K2=="por") then KSALIDA=" por " end
     if (K2=="to" or K2=="a" or K2=="hasta") then KSALIDA=" a " end
     KSALIDA1=KSALIDA
     if (KD ~= "" and KD ~= nil) then KSALIDA1="" end
     SALIDA=SALIDA..KSALIDA1
     I1=3; I2=4; CASOUD=""
     SALIDA=SALIDA..UNIDAD1(frame)
     I1=1; I2=4; I3=5; I4=6; CASOUD="NO1"
     SALIDA=SALIDA..UNIDAD2(frame)
     SALIDA=SALIDA..KSALIDA
     I1=3; I2=4; I3=5; I4=6; CASOUD="NO2"
     SALIDA=SALIDA..UNIDAD2(frame)
 -- Caso normal:
    else
  --Llamada a las funciones locales UNIDAD1 y UNIDAD2
    SALIDA= UNIDAD1(frame)..UNIDAD2(frame)  
    end
 end 

 --Sustituir cada "-" (corto) por un "−" (largo)
   SALIDA=SALIDA:gsub("-","−")

 return SALIDA
end


function UNIDAD1(frame)
   --Función que representa la primera unidad:
   --Variables
     local kunidadA=""
     local kunidadB=""
     local kunidad1=""
   --Carga de variables desde frame
     local kmed= tonumber(quitacoma(fraccion(FFRR[I1]))) --para evitar problemas si el decimal de entrada se pone con coma
     local kuni0= FFRR[I2]
     local kdisp= frame.args["disp"]
     local klk= frame.args["lk"]
     local ksing= frame.args["sing"]
     local kabr= tonumber(frame.args["abr"])
     local kabbr=frame.args["abbr"]
   -- Llamada a Convertir/ud:
     local kuni=frame:expandTemplate{ title = "es:Convertir/ud", args = {kuni0} }
      
   -- Ver casos:
      -- Si disp está activado, no se representa:
      if (kdisp== nil or kdisp== "" or kdisp=="/") then
         cortar(kuni) --Cortar kuni
         kunidadB=vv[3]
         -- Singular si sing es distinto de "" y de nil:
           if (ksing ~= nil and ksing ~= "") then
              kunidadB=vv[2]
           else 
           -- Singular además si la unidad es igual a 1
              if kmed==1 then kunidadB=vv[2] end
           -- Singular además si la medida es una fracción
              if FRAC~= "" then kunidadB="de "..vv[2] end
           end
         -- Si está abreviado, se pone la abreviatura:
            if kabr== 1 or kabr==3 then kunidadB=vv[4] end
            if kabbr=="on"  then kunidadB=vv[4] end
         -- Linkado activado o no:
           if (klk ~= nil and klk ~= "" and klk~="off" and klk ~= "2") then
              kunidad1="[["..vv[1].."|"..kunidadB.."]]"
           else
              kunidad1=kunidadB 
           end
        -- Casos en que se quita la denominación de la unidad:
           if CASOUD=="NO" then kunidad1=""; CASOUD=""; end
        -- Llamada a formatnum:     
           kmed=frame:expandTemplate{ title = "es:formatnum", args = {kmed} }
        -- Caso de fracción:
           if kunidad1~="" then kunidad1=" "..kunidad1.." " end
           if FRAC~= "" then
              kunidad1=FRAC..kunidad1
           else
              kunidad1=kmed..kunidad1
           end
      end
    return kunidad1
end

function UNIDAD2(frame)
   --Función que representa la segunda unidad:
   --Variables
     local kunidadA=""
     local kunidadB=""
     local kunidad1=""
   --Carga de variables desde frame
     local kmed= tonumber(quitacoma(fraccion(FFRR[I1])))
     local kuni0= FFRR[I2]
     local kuniz= FFRR[I3]
     local kprec= FFRR[I4]
     if kprec ~= nil then kprec= tonumber(kprec) end

   --Caso de varias unidades de salida declaradas:
     if IU >1 then kuniz=uu[II] end
     
   --Caso de entrada en (ft + in):
     if I3== 5 then
        kmed= kmed + (tonumber(quitacoma(fraccion(FFRR[3]))))/12
     end
     if kprec==nil then kprec=1 end
     local klk= frame.args["lk"]
     local ksing= frame.args["sing"]
     local kabr= tonumber(frame.args["abr"])
     local kabbr=frame.args["abbr"]
     local kdisp=frame.args["disp"]
  -- Búsqueda de la unidad por defecto si kuniz no se ha declarado:
     if (kuniz=="" or kuniz==nil) then
     -- Llamada a Convertir/ud:
        local kuni=frame:expandTemplate{ title = "es:Convertir/ud", args = {kuni0} }   
        cortar(kuni) --Cortar kuni
        kuniz=vv[5]
     end
  -- Conversión y cálculo de unidades:
     local base0="" --Unidad de referencia del origen
     local basez="" --Unidad de referencia del destino
     --Unidad 0:
     cortar(frame:expandTemplate{ title = "es:Convertir/ud", args = {kuni0} })
     FORMULA0=vv [6]; base0=vv [7]
     --Unidad Z:
     cortar(frame:expandTemplate{ title = "es:Convertir/ud", args = {kuniz} })
     FORMULAZ=vv [6]; basez=vv [7]
     if base0 ~= basez then kuniz = "UNIDADES INCOMPATIBLES" end
     kmedz= calcular (kmed, FORMULA0, FORMULAZ)
     
  -- Llamada a Convertir/ud:
     local kuni=frame:expandTemplate{ title = "es:Convertir/ud", args = {kuniz} }

   -- Ver casos:
     --Según disp=
     local kapert=""
     if (kdisp==nil or kdisp=="") then kapert="(" end
     if kdisp=="/" then kapert="/" end
     if kdisp=="2[" then kapert="[" end
    --Se quita la apertura en la segunda llamada del caso 2-2:
     if (CASOUD=="NO2" or CASOUD=="NO3") then kapert="" end

     cortar(kuni) --Cortar kuni
     kunidadB=vv[3]
     -- Singular si sing es distinto de "" y de nil:
       if (ksing ~= nil and ksing ~= "") then
          kunidadB=vv[2]
       else 
       -- Singular además si la unidad es igual a 1
          if kmed==1 then kunidadB=vv[2] end
       end
     -- Si está abreviado, se pone la abreviatura:
        if (kabr== 2 or kabr== 3 or kabr== nil) then kunidadB=vv[4] end
        if kabbr=="on"  then kunidadB=vv[4] end
     -- Linkado activado o no:
       if (klk ~= nil and klk ~= "" and klk ~= "1") then
          kunidad1="[["..vv[1].."|"..kunidadB.."]]"
       else
          kunidad1=kunidadB 
       end
    -- Caso especial de ftin:
       if kuniz== "ftin" then
           -- Llamada a ftin:
              kmedz=frame:expandTemplate{ title = "es:ftin", args = {kmedz} }
              kunidad1=""
       elseif kuniz== "ydftin" then
    -- Caso especial de ydftin:
           -- Llamada a ydftin:
              kmedz=frame:expandTemplate{ title = "es:ydftin", args = {kmedz} }
              kunidad1=""    
       else 
           -- Llamada a decimales:
              kmedz=frame:expandTemplate{ title = "es:Decimales", args = {kmedz, kprec} }
           -- Llamada a formatnum:     
              kmedz=frame:expandTemplate{ title = "es:formatnum", args = {kmedz} }
       end
       local kcierre=""
       if (kdisp==nil or kdisp=="") then kcierre=")" end
       if kdisp=="2[" then kcierre="]" end
     --Se quitan el cierre y la unidad en la primera llamada del caso 2-2:
       if (CASOUD=="NO0" or CASOUD=="NO1" or CASOUD=="NO3") then kcierre="" end
       if  CASOUD=="NO1" then kunidad1="" end

       if (kdisp=="#" or kdisp=="numero") then 
           kunidad1=kmedz
       else
           if kunidad1 ~= "" then
              kunidad1=kapert..kmedz.." "..kunidad1..kcierre
           else
              kunidad1=kapert..kmedz..kcierre
           end
       end
    CASOUD=""
    return kunidad1
end

-- Función para cortar una cadena con siete argumentos separados por ! procedente de la plantilla Convertir/ud
function cortar (s)
   --Variables del bucle, y recortado del letrero, que se almacena en la matriz vv[]
   local indice=7
   local l=0
   local cadena=""
   local i=0
   local name
   --Preparación del letrero para recortarlo (trim y una barra de propina al final)
   name= trim1(s)
   name=name.."!"
   --Bucle de recortado
   for i=1,indice do
      l= string.find(name, '!')
      cadena=string.sub (name, 1, l-1)
      name=string.sub (name,l+1)
      vv[i]=trim1(cadena)
   end
end

-- Función para cortar una cadena con un número variable de argumentos separados por blancos 
function cortarblanco (s, ss)
   --Variables del bucle, y recortado del letrero, que se almacena en la matriz ss[]
   --local ss = {} 
   local indice=0 
   local cadena=s
   local letra0=" "
   local letra1=" " 
   while letra1 ~= "" do
         letra1 = string.sub (cadena, 1, 1)
         if (letra1 ~= " " and letra0 == " ") then indice=indice+1; ss[indice]="";end
         if letra1 ~= " " then ss[indice]=ss[indice]..letra1; end
         letra0=letra1
         cadena=string.sub (cadena, 2)
   end
   ib=indice
end

-- Función para operar la conversión de medida -> origen -> destino a partir de FORMULA0  y FORMULAZ
function calcular (kmed, FORMULA0, FORMULAZ)
   -- Contempla el caso de las temperaturas, en las que en la conversión se utilizan dos constantes (campo [2] = "+" o "-")
   -- Contempla el caso de los consumos, donde hay unidades inversas (campo [2] = "/")  
   local kk0=1
   local kkz=1
   local CTE0=0
   local CTEZ=0
   local medicion=tonumber (kmed)

   --Cortar las fórmulas y guardarlas
     cortarblanco (FORMULA0, ff0)
     ii0=ib
     cortarblanco (FORMULAZ, ffz)
     iiz=ib
    --Poner constantes en orden:
     kk0=tonumber(ff0[1])
     if ii0==3 then
        CTE0=tonumber(ff0[3])
        if ff0[2]=="-" then CTE0=CTE0*-1; end
        if ff0[2]=="/" then 
           medicion= 1/medicion
           CTE0=0
        end
     end
     kkz=tonumber(ffz[1])
     if iiz==3 then
        CTEZ=tonumber(ffz[3])
        if ffz[2]=="-" then CTEZ=CTEZ*-1; end
        if ffz[2]=="/" then 
           medicion= 1/medicion
           CTEZ=0
        end
     end
   return ((medicion + CTE0) * kk0) /kkz - CTEZ
end

-- Función para cambiar coma por punto, y quitar puntos sobrantes (en caso de notación 5.255,4). Empieza por detrás, y también quita blancos intercalados
function quitacoma (s)
   local l=string.len(s)
   local cadena=""
   local i=0
   local letra=""
   local ultima=0
   for i=l,1,-1 do
       letra=string.sub (s, i, i)
       if letra==" " then letra="" end
       if (ultima==1 and letra==".") then letra="" end
       if (ultima==0 and letra==",") then letra="."; ultima=1; end
       cadena=letra..cadena
   end 
   s=cadena
   return s
end


-- Función para convertir el dato de entrada de fracción (2 3/5 por ejemplo) a un solo número
function fraccion (s)
   local ww = {}
   local l=string.len(s)
   local cadena=s
   local i=0
   local letra=""
   local entero="0"
   local numerador=""
   local denominador=""
   local n=1

   --Sustituir cada "+" por un blanco
    cadena=cadena:gsub("+"," ")
   --Sustituir cada "−" (largo) por un "-" (corto)
    cadena=cadena:gsub("−","%-")


   cortarblanco (cadena, ww) -- Se analiza si la cadena tiene un campo (n/m) o dos campos(a b/c)
   if ib==2 then
      entero=ww[1]
      cadena=ww[2]
   end

   for i=1,l,1 do
       letra=string.sub (cadena, 1, 1)
       if letra=="/" then
          n=2 
       else
          if n==1 then 
             numerador=numerador..letra
          else
             denominador=denominador..letra
          end       
       end
       cadena=string.sub (cadena, 2)
   end 
   
   if denominador ~= "" then
      cadena=tostring(tonumber(entero)+(tonumber(numerador)/tonumber(denominador)))
      FRAC=s
   else
      cadena=s
      FRAC="" 
   end
   s=cadena
   return s
end


--Función para subdividir el campo 1 si es doble:
function dobleuno(s)
   local ww = {}
   local l=string.len(s)
   local cadena=trim1(s)
   local cadena1=""
   local i=0
   local contador=0
   local letra=""

   for i=1,l do
       letra=string.sub (cadena, i, i)
       if (letra=="-" or letra=="a" or letra=="x" or letra=="y") then
           if (i>1 and contador==0) then
              contador=1
              letra=" "..letra.." " 
           end  
       end
       cadena1=cadena1..letra
   end 
   
   -- Se analiza si la cadena1 tiene tres campos y un separador correcto
   -- Se reasignan los campos de FFRR
   cortarblanco (cadena1, ww) 
   if ib==3 then
      if (ww[2]=="-" or ww[2]=="a" or ww[2]=="x" or ww[2]=="y") then
        FFRR[6]=FFRR[4]
        FFRR[5]=FFRR[3]
        FFRR[4]=FFRR[2]
        FFRR[1]=ww[1]
        FFRR[2]=ww[2]
        FFRR[3]=ww[3]
      end
   end
  return
end

--Función milagrosa que quita blancos (detrás y delante)
function trim1(s)
   return (s:gsub("^%s*(.-)%s*$", "%1"))
end

return ConvertirAux