Diferencia entre revisiones de «Módulo:ConvertirAux»
Apariencia
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("−","% |
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