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 entradas separando (pies y pulgadas), (millas y yardas), (millas y cadenas), (toneladas largas y centenas) o (toneladas cortas y centenas) 
-- 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'')
-- Admite tríos de datos en el campo [1], separados por una pareja de los caracteres anteriores
-- Admite separador " " o "-" en el campo [1] cuando el parámetro [op=n] (no opera la expresión)
-- 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)
   zz = {} --Matriz con la unidad [1] cortada en bloques (separadas por blancos)

   ib =0   --número de elementos de la matriz en la que se almacene el corte entre blancos
   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

   IZ =0   --Número de elementos guardados en la matriz zz
   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 NO3 Y NO4 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 es fraccional
   SALIDA="" --Valor que devuelve la rutina 

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]

--Limpieza previa salvo, que op=n
 if frame.args["op"]~="n" then
 --Sustitución de guiones largos (char(8722)) por guiones normales (-) en FFRR[1]
   FFRR[1]=FFRR[1]:gsub(mw.ustring.char(8722), "-") 
 --Reordenación de valores para el caso del campo [1] doble o triple:
   dobleuno (FFRR[1]) 
 end

--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

--Reordenación de valores para el caso de que la precisión aparezca en el campo [3] y el campo 4 esté vacío (se permuta con el [4])
   if (tonumber(FFRR[3])~= nil and FFRR[4]=="") then 
      FFRR[3],FFRR[4]=FFRR[4],FFRR[3]
   end

--CASO DE FORMATO DEL CAMPO 1 INDEFINIDO CON op=n (sin operar)
 if frame.args["op"]=="n" then 
    divideuno (FFRR[1])
    IZ=ib
   --Casos correctos e incorrectos de divideuno:
   K1=tonumber(quitacoma(fraccion(FFRR[1])))
   K3=tonumber(quitacoma(fraccion(FFRR[3])))
      
   if ((IZ==1 and K1==nil) or (IZ==2 and (K1==nil or K3==nil)) or IZ>2) then             
       -- Casos incorrectos (se calculan aquí):
       -- Tratamiento previo de separadores:
       FFRR[1]=frame.args[1]
       FFRR[1]=" "..FFRR[1].." "
       FFRR[1]=FFRR[1]:gsub("; "," ; ") --sustituir cada "; " por un " ; "
       FFRR[1]=FFRR[1]:gsub(", "," , ") --sustituir cada ", " por un " , "
       FFRR[1]=FFRR[1]:gsub(": "," : ") --sustituir cada ": " por un " : "
       FFRR[1]=FFRR[1]:gsub("/"," / ")  --sustituir cada "/" por un " / "
       FFRR[1]=FFRR[1]:gsub(" ","   ")  --sustituir cada " " por un "   "

       --Separación en bloques
       cortarblanco (FFRR[1], zz)
       SALIDA=""
       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]
       for i=1,ib do                  
           K1=tonumber(quitacoma(zz[i]))
           if K1==nil then
              SALIDA=SALIDA..zz[i].." "
           else
              FFRR[1]=quitacoma(zz[i])               
              SALIDA=SALIDA..UNIDAD1(frame)..UNIDAD2(frame).." "
           end
       end
       -- Tratamiento posterior de separadores:
       SALIDA=trim1(SALIDA)
       SALIDA=SALIDA:gsub(" ;",";") --sustituir cada " ;" por un ";"
       SALIDA=SALIDA:gsub(" ,",",") --sustituir cada " ," por un ","
       SALIDA=SALIDA:gsub(" :",":") --sustituir cada " :" por un ":"
       SALIDA=SALIDA:gsub(" / ","/")  --sustituir cada " / " por un "/"
       SALIDA=SALIDA:gsub("  "," ")  --sustituir cada "  " por un " "
       SALIDA=SALIDA:gsub("  "," ")  --sustituir cada "  " por un " "
   else
       --Casos correctos (pasan desde aquí a la rutina general)
       SALIDA=""
       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]
       divideuno (FFRR[1])
   end 
 end


if SALIDA=="" then
  --Lectura de los campos 2, 3 y 4 para determinar el tipo de entrada:
    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

  --Cálculo de K3 para ver si es un número; en caso afirmativo; IU=1
    if tonumber(uu[1])~=nil then IU=1 end
   
  -- Caso de varias salidas declaradas y una sola entrada:   
    if (IU > 1 and tonumber(FFRR[1])~= nil) 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 entrada doble con mi[2] + ch[4]:  
    elseif (K2=="mi" and K4=="ch") 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 entrada doble con mi[2] + yd[4]:  
    elseif (K2=="mi" and K4=="yd") 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 entrada doble con LT[2] + Lcwt[4]:  
    elseif (K2=="LT" and K4=="Lcwt") 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 entrada doble con ST[2] + Scwt[4]:  
    elseif (K2=="ST" and K4=="Scwt") 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 o triples de entrada (y de salida):
    elseif (K2=="-" or K2=="and" or K2=="to" or K2=="to(-)" or K2=="hasta" or K2=="y" or K2=="x" or K2=="X" or K2=="by" or K2=="por" or K2=="a" or K2==";" or K2=="/") 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=="to(-)" or K2=="a" or K2=="hasta") then KSALIDA=" a " end
     if K2==";" then KSALIDA="; " end
     if K2=="/" then KSALIDA="/" end
     KSALIDA1=KSALIDA
     if (KD ~= "" and KD ~= nil) then KSALIDA1="" end
     SALIDA=SALIDA..KSALIDA1

     --Caso con entrada triple
     if FFRR[7]~= nil then
        I1=7; I2=4; CASOUD="NO" 
        SALIDA=SALIDA..UNIDAD1(frame)..KSALIDA1
     end

     I1=3; I2=4; CASOUD=""
     SALIDA=SALIDA..UNIDAD1(frame)
    
   --Cálculo de IU, para detectar si hay varias unidades de salida declaradas:
    cortarblanco (FFRR[5], uu);IU=ib

   --Bucle con las llamadas a UNIDAD2
     for i=1,IU do
        if i>1 then SALIDA=SALIDA.." " end
        II=i
        I1=1; I2=4; I3=5; I4=6; CASOUD="NO1"
        SALIDA=SALIDA..UNIDAD2(frame)
        SALIDA=SALIDA..KSALIDA

        --Caso con entrada triple
        if FFRR[7]~= nil then
           I1=7; I2=4; I3=5; I4=6; CASOUD="NO4"
           SALIDA=SALIDA..UNIDAD2(frame)..KSALIDA1
        end

        I1=3; I2=4; I3=5; I4=6; CASOUD="NO2"
        SALIDA=SALIDA..UNIDAD2(frame)
     end

-- Caso normal:
    else
  --Llamada a las funciones locales UNIDAD1 y UNIDAD2
    SALIDA= UNIDAD1(frame)..UNIDAD2(frame)  
    end
 end
end

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=="/" or kdisp=="br" or kdisp=="table") 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" or kdisp=="table") then kunidad1=""; CASOUD=""; end  
        -- Llamada a formatnum:     
           kmed=frame:expandTemplate{ title = "es:formatnum", args = {kmed} }
           kmed=kmed:gsub("-","−") --sustituir cada "-" (corto) por un "−" (largo)
        -- Caso de fracción:
           if kunidad1~="" then kunidad1=" "..kunidad1.." " end
           if FRAC~= "" then
              kunidad1=FRAC..kunidad1
           else
              kunidad1=kmed..kunidad1
           end
        -- Caso ftin y table:
           if (FFRR[2]=="ft" and FFRR[4]=="in" and kdisp=="table") then
              if I1==1 then kunidad1=kmed.."'"  end
              if I1==3 then kunidad1=" "..kmed..string.char(34) end
           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 and FFRR[2]=="ft") then
        kmed= kmed + (tonumber(quitacoma(fraccion(FFRR[3]))))/12
     end

   --Caso de entrada en (mi + ch):
     if (I3== 5 and FFRR[2]=="mi" and FFRR=="ch") then
        kmed= kmed + (tonumber(quitacoma(fraccion(FFRR[3]))))/80
     end

   --Caso de entrada en (mi + yd):
     if (I3== 5 and FFRR[2]=="mi" and FFRR[4]=="yd") then
        kmed= kmed + (tonumber(quitacoma(fraccion(FFRR[3]))))/1760
     end

   --Caso de entrada en (LT + Lcwt):
     if (I3== 5 and FFRR[2]=="LT" and FFRR[4]=="Lcwt") then
        kmed= kmed + (tonumber(quitacoma(fraccion(FFRR[3]))))/20
     end

   --Caso de entrada en (ST + Scwt):
     if (I3== 5 and FFRR[2]=="ST" and FFRR[4]=="Scwt") then
        kmed= kmed + (tonumber(quitacoma(fraccion(FFRR[3]))))/20
     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=="br" then kapert="<br />(" end
     if kdisp=="table" then kapert="||" end
     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 de una tabla:
        if kdisp=="table"  then kunidad1="" 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} }
              kmedz=kmedz:gsub("-","−") --sustituir cada "-" (corto) por un "−" (largo)
       end
       local kcierre=""
       if (kdisp==nil or kdisp=="" or kdisp=="br") then kcierre=")" end
       if kdisp=="table" 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  CASOUD=="NO4" then kcierre=""; kapert="";kunidad1="" end

       if (kdisp=="#" or kdisp=="numero") then 
           kunidad1=kmedz
       else
           if kunidad1 ~= "" then
              kunidad1=kapert..kmedz.."&nbsp;"..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

     --CONVERSIÓN 1 (origen a base):
     medicion= (medicion + CTE0) * kk0 
    
     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
           kkz=1/kkz 
        end
     end

     --CONVERSIÓN 2 (base a destino):
     medicion= medicion/kkz - CTEZ 
 
   return medicion 
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("+"," ")

   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 
   --Se controla que entero, numerador y denominador sean números correctos:
   if (tonumber(numerador) ~= nil and tonumber(denominador) ~= nil and tonumber(entero) ~= nil) 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 (caso habitual, con separador):
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" or letra==";") 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) 
   -- Caso doble 
   if ib==3 then
      if (ww[2]=="-" or ww[2]=="a" or ww[2]=="x" or ww[2]=="y" or ww[2]==";" or ww[2]=="/") 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
   -- Caso triple
   if ib==5 then
      if ((ww[2]=="-" or ww[2]=="a" or ww[2]=="x" or ww[2]=="y" or ww[2]==";" or ww[2]=="/") and (ww[2]==ww[4])) then
        FFRR[6]=FFRR[4]
        FFRR[5]=FFRR[3]
        FFRR[4]=FFRR[2]
        FFRR[1]=ww[1]
        FFRR[2]=ww[2]
        FFRR[3]=ww[5]
        FFRR[7]=ww[3]
      end
   end

  return
end

--Función para subdividir el campo 1 si es doble (caso sin separador o separador /) cuando op=n::
function divideuno(s)
   local ww = {}
   local l=string.len(s)
   local cadena=trim1(s)
   local cadena1=""
   local i=0
   local contador=0
   local letra=""

   -- Se separan los sumandos y se cambian comas por puntos
   for i=1,l do
       letra=string.sub (cadena, i, i)
       if (letra=="-" or letra=="+") then
              letra=" "..letra 
       end
       if letra=="," then letra="." end
       if letra=="/" then letra=" " end
       cadena1=cadena1..letra
   end 

   -- Se corta la cadena
   cortarblanco (cadena1, ww) 
   
   -- Se analiza si la cadena1 tiene dos campos
   -- Se reasignan los campos de FFRR
   cortarblanco (cadena1, ww) 
   if ib==2 then
        FFRR[6]=FFRR[4]
        FFRR[5]=FFRR[3]
        FFRR[4]=FFRR[2]
        FFRR[1]=ww[1]
        FFRR[2]="/"
        FFRR[3]=ww[2]
   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