Module:RecetaDeck

local p = {} local html = {} local debug_text = ''

-- FUNCTION: Debug local function debug(...) for i,v in ipairs(arg) do       debug_text = debug_text .. (v or "nil") end end

local function debugline(...) for i,v in ipairs(arg) do       debug_text = debug_text .. (v or "nil") end debug_text = debug_text .. "\n" end

-- FUNCION: Convierte el texto en negrilla formato wikitexto local function b(s) return "'''" .. s .. "'''" end

-- FUNCION: Convierte el texto en cursiva formato wikitexto local function i(s) return "''" .. s .. "''" end

-- FUNCION: Convierte el nombre ingresado (valor del parámetro) en ID function p.normalize (cardname) -- Convierte en minúsculas cardname = string.lower(cardname) -- Retira las tildes de las letras mayúsculas cardname = string.gsub(cardname, 'Á', 'a') cardname = string.gsub(cardname, 'Ä', 'a') cardname = string.gsub(cardname, 'Â', 'a') cardname = string.gsub(cardname, 'É', 'e') cardname = string.gsub(cardname, 'Ë', 'e') cardname = string.gsub(cardname, 'Í', 'i') cardname = string.gsub(cardname, 'Ï', 'i') cardname = string.gsub(cardname, 'Ó', 'o') cardname = string.gsub(cardname, 'Ö', 'o') cardname = string.gsub(cardname, 'Ú', 'u') cardname = string.gsub(cardname, 'Ü', 'u') -- Retira las tildes de las letras minúsculas cardname = string.gsub(cardname, 'á', 'a') cardname = string.gsub(cardname, 'ä', 'a') cardname = string.gsub(cardname, 'â', 'a') cardname = string.gsub(cardname, 'é', 'e') cardname = string.gsub(cardname, 'ë', 'e') cardname = string.gsub(cardname, 'í', 'i') cardname = string.gsub(cardname, 'ï', 'i') cardname = string.gsub(cardname, 'ó', 'o') cardname = string.gsub(cardname, 'ö', 'o') cardname = string.gsub(cardname, 'ú', 'u') cardname = string.gsub(cardname, 'ü', 'u') -- Retira los símbolos conflictivos (% = escape) cardname = string.upper(cardname) cardname = string.gsub(cardname, ' ', '') cardname = string.gsub(cardname, '"', )   cardname = string.gsub(cardname, "'", )    cardname = string.gsub(cardname, ',', )    cardname = string.gsub(cardname, '%.', )    cardname = string.gsub(cardname, '%-', )    cardname = string.gsub(cardname, '¡', )    cardname = string.gsub(cardname, '!', )    cardname = string.gsub(cardname, '¿', )    cardname = string.gsub(cardname, '%?', )    cardname = string.gsub(cardname, ':', )    cardname = string.gsub(cardname, 'º', )    cardname = string.gsub(cardname, '/', )    cardname = string.gsub(cardname, '#', )    cardname = string.gsub(cardname, '&', 'Y')    cardname = string.gsub(cardname, '“', )    cardname = string.gsub(cardname, '”', )    cardname = string.gsub(cardname, '’', )    cardname = string.gsub(cardname, '%–', )    cardname = string.gsub(cardname, 'ñ', 'Ñ')    cardname = string.gsub(cardname, '·', ) cardname = string.gsub(cardname, '☆', '') cardname = string.gsub(cardname, 'ß', 'B') return cardname end

-- Se usa en getCardsData para obtener la letra inicial -- del id de una carta function p.selectLetter(idcard) -- Extrae la primera letra local letter = string.sub(idcard, 0, 1) -- Convierte la primera letra en número (ASCII) local char_n = string.byte(letter) -- Compara si la letra pertenece al alfabeto (A-Z) if char_n > 64 and char_n < 91 then return letter else -- Si no, devuelve un 7 para hacer referencia al Module RdDatos7 -- que es en donde se almacenan estas cartas return '7' end end

-- FUNCION: Obtiene todos los datos de las cartas encontradas. -- PARAMETROS: Recibe como parámetro un arreglo con IDs de cartas -- ordenados alfabéticamente y sin repetir function p.getCardsData(sortcardnames) -- Almacena los datos que serán devueltos local temp = {} -- Almacena la lista de restricción (OCG, prohibidas y semi/limitadas) local RdRestriccion = require('Module:RestriccionCarta') -- Almacena temporalmente el Module requerido según la letra local RdDatos = {} -- Lleva la cuenta de la letra actual de búsqueda local RdLetter = '' -- Recorre el arreglo recibido como parámetro -- Nota: utiliza el valor (id) como índice para el arreglo for i, idcard in ipairs(sortcardnames) do       -- Extrae la letra inicial del id        local Letter = p.selectLetter(idcard) -- Si la letra inicial es distinta de la actual, carga un nuevo Module if RdLetter ~= Letter then -- Reemplaza la letra actual de búsqueda RdLetter = Letter -- Carga el Module de la letra actual RdDatos = require('Module:RdDatos' .. RdLetter) end -- Reserva un espacio en el arreglo temporal usando -- el id de la carta (valor del parámetro) como índice temp[idcard] = {} -- Revisa si la carta está registrada if RdDatos[idcard] ~= nil then -- Si está registrada, extrae los datos local data = RdDatos[idcard] -- Parámetros comunes para todas las cartas temp[idcard]['nombre'] = data[1] temp[idcard]['ingles'] = data[2] temp[idcard]['carta'] = data[3] temp[idcard]['atributo'] = data[4] temp[idcard]['tipo'] = data[5] -- Parámetros válidos solo para cartas de monstruo if data[4] ~= 'mágica' and data[4] ~= 'trampa' then -- Los monstruos de enlace no poseen nivel ni defensa if data[3] ~= 'monstruo de enlace' then -- Parametros para todos los monstruos -- que no sean de enlace temp[idcard]['nivel'] = data[6] temp[idcard]['ataque'] = data[7] temp[idcard]['defensa'] = data[8] temp[idcard]['codigo'] = data[9] else -- Sólo monstruos de enlace temp[idcard]['ataque'] = data[6] temp[idcard]['codigo'] = data[7] end else -- Registra el código de cartas mágicas y de trampa temp[idcard]['codigo'] = data[6] end -- Los índices de restricción solo están en español (data[1]) -- Utiliza el nombre en español para obtener el id           local restriccion = RdRestriccion[p.normalize(data[1])] if restriccion ~= nil then -- Arreglo para convertir los números en palabras (0='ocg') local str_restriccion = {'ocg', 'prohibida', 'limitada', 'semilimitada'} -- Añade un campo restricción a las cartas que la tengan -- En formato palabra para facilitar la visualización de iconos temp[idcard]['restriccion'] = str_restriccion[restriccion] end end end -- Devuelve un arreglo con todos los datos de las cartas return temp end

-- FUNCION PRINCIPAL: Recorre la lista de cartas ingresadas function p.decks(frame) -- VARIABLES LOCALES local sortcardnames = {} -- cartas ordenadas local allcardnames = {} -- valores ingresados (YGOPro) local cardnames = {} -- almacena los id para evitar repetidos -- contadores de cartas para cada deck local main_n = 0 -- contador maindeck local extra_n = 0 local side_n = 0 -- almacenan los id de las cartas (normalizados) local maindeck = {} local extradeck = {} local sidedeck = {} local edeck = {} local edeck_n = 0 -- Almacena el resultado en una variable de texto local text = '' -- Recorre los nombres de las cartas ingresadas (name=value) for name, value in pairs(frame.args) do       -- Si el parámetro no tiene valor (name=''), el parámetro no se procesa if value ~= '' then -- Normaliza los parámetros (D1 => d1) local index = string.lower(name) -- Extraer la primera letra para llevar la cuenta local letter = string.sub(index, 0, 1) -- Convierte el nombre de carta en ID mediante función local id_card = p.normalize(value) -- Recorre el Deck Principal if letter == 'd' then maindeck[index] = {} maindeck[index]['id'] = id_card maindeck[index]['notfound'] = value main_n = main_n + 1 -- contador else if letter == 'e' then -- Recorre con el Deck Extra extradeck[index] = {} extradeck[index]['id'] = id_card extradeck[index]['notfound'] = value extra_n = extra_n + 1 -- contador else if letter == 's' then -- Recorre el Side Deck sidedeck[index] = {} sidedeck[index]['id'] = id_card sidedeck[index]['notfound'] = value side_n = side_n + 1 --contador end end end -- Almacena el id solo si no ha sido almacenado previamente (omite repetidos) if cardnames[id_card] == nil then cardnames[id_card] = {} -- Almacena el ID en una tabla para ordenar table.insert(sortcardnames, id_card) end -- Almacena todos los valores de los parámetros de los tres decks -- (incluye repetidos) table.insert(allcardnames, value) end end -- Ordena las tablas table.sort(sortcardnames) table.sort(allcardnames) -- Reemplaza la tabla IDs con los datos de las cartas existentes -- (está ordenada alfabéticamente para facilitar la búsqueda de datos   -- y sin repetidos para evitar consultas innecesarias). cardnames = p.getCardsData(sortcardnames) local lista = html.partialList(main_n, maindeck, extra_n, extradeck, side_n, sidedeck, cardnames, allcardnames) local ygopro = html.partialYgopro(main_n, maindeck, extra_n, extradeck, side_n, sidedeck, cardnames, allcardnames) local vista = html.partialView(main_n, maindeck, extra_n, extradeck, side_n, sidedeck, cardnames, allcardnames) return frame:preprocess(   	vista .. '\n'    	.. ' '    	.. ygopro    	.. ' '    ) --debug('\n\n-- end --') --return debug_text end

-- Normaliza el nombre de una carta en el nombre de archivo de imagen -- siguiendo las mismas convenciones que la wiki principal function p.convnombreimagen(filename) -- Convierte a minúsculas filename = string.lower(filename) -- Retira las tildes filename = string.gsub(filename, 'Á', 'á') filename = string.gsub(filename, 'Ä', 'ä') filename = string.gsub(filename, 'Â', 'â') filename = string.gsub(filename, 'É', 'é') filename = string.gsub(filename, 'Ë', 'ë') filename = string.gsub(filename, 'Í', 'í') filename = string.gsub(filename, 'Ï', 'ï') filename = string.gsub(filename, 'Ó', 'ó') filename = string.gsub(filename, 'Ö', 'ö') filename = string.gsub(filename, 'Ú', 'ú') filename = string.gsub(filename, 'Ü', 'ü') -- Retira los símbolos conflictivos filename = string.gsub(filename, '/', '-') filename = string.gsub(filename, '&#39;', '') filename = string.gsub(filename, '\, ) filename = string.gsub(filename, '"', )   filename = string.gsub(filename, '&quot;', )    filename = string.gsub(filename, '&#34;', )    filename = string.gsub(filename, '?', )    filename = string.gsub(filename, '&#3f;', '')    return filename end

-- FUNCION CARDVIEW -- Convierte los datos en una imagen para la pestaña "Vista Principal" function html.cardview (cardname, notfound) local text = '' if cardname.carta ~= nil then local tmb_image = 'Thumb3 ' .. string.lower(cardname.carta) .. ' '       if cardname.atributo == 'mágica' or cardname.atributo == 'trampa' then tmb_image = tmb_image .. cardname.tipo else tmb_image = tmb_image .. cardname.atributo end local tmb_class = 'tmbfoto' local tmb_size = '40x40' if cardname.carta == 'monstruo de enlace' then tmb_class = tmb_class .. 'enlace' tmb_size = '42x42' end if cardname.carta == 'monstruo de péndulo' or cardname.carta == 'monstruo de péndulo normal' or cardname.carta == 'monstruo de péndulo xyz' or cardname.carta == 'monstruo de péndulo cantante' or cardname.carta == 'monstruo de péndulo cantante normal' or cardname.carta == 'monstruo de péndulo de sincronía' or cardname.carta == 'monstruo de péndulo de fusión' then tmb_class = tmb_class .. 'pendulum' tmb_size = '48x36' end local tmb_filename = p.convnombreimagen(cardname.nombre) text = text .. ' '            .. '' .. ''           .. ' '        -- Restriccion if cardname.restriccion ~= nil then local restfilename = '' if cardname.restriccion == 'ocg' then restfilename = 'icono ocg' else restfilename = 'Nuevo icono restricción ' .. cardname.restriccion end text = text .. ' '        end else text = text .. ' '        -- Evita que esta página se categorice como "Thumb desconocido" text = text ..        if (mw.title.getCurrentTitle.subjectNsText ~= 'Module') then            text = text .. 'Categoría:Thumb desconocido'        end        text = text ..  end return text end

-- FUNCION CARDVIEW -- Convierte los datos de carta en una fila para la pestaña "Lista de cartas" function html.cardline (cardname, notfound, counter) local text = '' if cardname.nombre ~= nil then text = '[[image:icono ' .. string.lower(cardname.carta)       if counter == 2 then            text = text .. ' x2'        elseif counter > 2 then            text = text .. ' x3'        end        text = text .. '.gif]]' .. b('x' .. counter) .. ' ' .. ' ' .. '' .. b(cardname.nombre) .. ' ' ..' \n' text = text .. i('(' .. cardname.ingles .. ')') .. ' ' .. '\n' text = text .. ''       text = text .. ''       if cardname.atributo ~= 'mágica' and cardname.atributo ~= 'trampa' and cardname.carta ~= 'monstruo de enlace' then if cardname.carta == 'monstruo xyz' then text = text .. ' ' .. cardname.nivel else text = text .. ' ' .. cardname.nivel end text = text .. ' ' text = text .. ' ' .. cardname.ataque if cardname.carta ~= 'monstruo de enlace' then text = text .. ' ' .. cardname.defensa end else if cardname.carta == 'monstruo de enlace' then text = text .. ' ' text = text .. ' ' .. cardname.ataque end end text = text .. ' '       if cardname.restriccion ~= nil then local restfilename = '' if cardname.restriccion == 'ocg' then restfilename = 'icono ocg' else restfilename = 'Nuevo icono restricción ' .. cardname.restriccion end text = text .. '  ' end text = text .. '  \n' else text = ' ' .. b('x' .. counter) .. ' ' .. i(notfound) .. ' \n' .. i('(carta no registrada)') .. '  \n' end return text end

-- FUNCION: Vista principal function html.vista(letter, deck_n, deck, cardnames) local title = '' local bgcolor = {} if letter == 'd' then title = 'DECK PRINCIPAL' bgcolor = {'#e98b14', '#de6f03', '#e98911', '#eab97f'} else if letter == 'e' then title = 'DECK EXTRA' bgcolor = {'#0099d2', '#0292c7', '#0099d2', '#74c3e2'} else title = 'SIDE DECK' bgcolor = {'#8db71b', '#72aa01', '#92b920', '#b8cf75'} end end local text = '' text = text .. " \n" text = text .. "" .. b(title) .. " " .. b(deck_n) .. " "    text = text .. '' if deck[letter .. '1'] ~= nil then local i = 1 while deck[letter .. i] ~= nil do           local card = deck[letter .. i]           local cardname = cardnames[card.id] text = text .. '<div class="carta_thumb">' text = text .. html.cardview(cardname, card.notfound) text = text .. '<div class="num_tag">' .. string.upper(letter) .. i .. ' '            i = i + 1 end else text = text .. ' -- Sin cartas -- \n' end text = text .. ' \n' return text end

-- FUNCION: Lista de cartas function html.lista(letter, deck, cardnames) local NOMBRE_DECK = '' local titulos = {} local contadores = {} contadores[1] = 0 contadores[2] = 0 contadores[3] = 0 contadores[4] = 0 contadores[5] = 0 local grupos = {} grupos[1] = '' -- Desconocidas grupos[2] = '' -- Monstruos / Fusiones grupos[3] = '' -- Mágicas / Sincronías grupos[4] = '' -- Trampas / Xyz grupos[5] = '' -- Enlaces local text = '' if letter == 'e' then titulos = {'Cartas desconocidas', 'Fusiones', 'Sincronías', 'Xyz', 'Enlaces'} NOMBRE_DECK = 'Deck Extra' else titulos = {'Cartas desconocidas', 'Monstruos', 'Mágicas', 'Trampas', ''} if letter == 'd' then NOMBRE_DECK = 'Deck Principal' else NOMBRE_DECK = 'Side Deck' end end if deck[letter .. '1'] ~= nil then local i = 1 local lastcard = nil local lastnotfound = nil local lastcount = 1 local card = nil local salir = 0 while salir == 0 do           local continuar = 0 if deck[letter .. i] == nil then salir = 1 continuar = 1 else card = deck[letter .. i]               if card.id == lastcard then lastcount = lastcount + 1 else continuar = 1 end end if continuar == 1 then if lastcard ~= nil then local cardname = cardnames[lastcard] local index_grupo = 1 if letter == 'e' then if cardname.carta == 'monstruo de sincronía' or cardname.carta == 'monstruo de sincronía cantante' or cardname.carta == 'monstruo péndulo de sincronía' then index_grupo = 3 elseif cardname.carta == 'monstruo xyz' or cardname.carta == 'monstruo péndulo xyz' then index_grupo = 4 elseif cardname.carta == 'monstruo de enlace' then index_grupo = 5 elseif cardname.nombre ~= nil then index_grupo = 2 end else if cardname.atributo == 'mágica' then index_grupo = 3 elseif cardname.atributo == 'trampa' then index_grupo = 4 elseif cardname.nombre ~= nil then index_grupo = 2 end end grupos[index_grupo] = grupos[index_grupo] .. html.cardline(cardname, lastnotfound, lastcount) contadores[index_grupo] = contadores[index_grupo] + lastcount end lastcard = card.id               lastnotfound = card.notfound lastcount = 1 end i = i + 1 end local count_deck = contadores[1] + contadores[2] + contadores[3] + contadores[4] + contadores[5] text = text .. ' ' .. NOMBRE_DECK .. ' (' .. count_deck .. ') \n' text = text .. '<ul>' -- Imprime todos los grupos no vacíos local i = 0 for i=1,5 do           if grupos[i] ~= '' then grupos[i] = ' ' .. titulos[i] .. ' (' .. contadores[i] .. ') \n' .. grupos[i] text = text .. grupos[i] end end else text = text .. ' ' .. NOMBRE_DECK .. ' \n' text = text .. '<ul>' text = text .. '' .. i('-- Sin cartas --') .. '</li>' end text = text .. '</ul>'

return text end

-- FUNCION: YGOPro function html.ygopro(maindeck, extradeck, sidedeck, cardnames, allcardnames) -- Variable local local text = '' local ydk_text = '<pre id="data-ydk">\n' ydk_text = ydk_text .. '#created by ...\n' -- YGOPro: Deck Principal ydk_text = ydk_text .. '#main\n' if maindeck['d1'] ~= nil then local i = 1 local maincard = nil while maindeck['d' .. i] ~= nil do           maincard = maindeck['d' .. i]           local cardname = cardnames[maincard.id] if cardname.codigo ~= nil then ydk_text = ydk_text .. cardname.codigo .. '\n' end i = i + 1 end end -- YGOPro: Deck Extra ydk_text = ydk_text .. '#extra\n' if extradeck['e1'] ~= nil then local i = 1 local maincard = nil while extradeck['e' .. i] ~= nil do           maincard = extradeck['e' .. i]           local cardname = cardnames[maincard.id] if cardname.codigo ~= nil then ydk_text = ydk_text .. cardname.codigo .. '\n' end i = i + 1 end end -- YGOPro: Side Deck ydk_text = ydk_text .. '!side\n' if sidedeck['s1'] ~= nil then local i = 1 local maincard = nil while sidedeck['s' .. i] ~= nil do           maincard = sidedeck['s' .. i]           local cardname = cardnames[maincard.id] if cardname.codigo ~= nil then ydk_text = ydk_text .. cardname.codigo .. '\n' end i = i + 1 end end

ydk_text = ydk_text .. ' \n' -- YGOPro: Verificar cartas local text3 = '' local last_id = nil local lastcardname = nil local lastcount = 0 local card = nil local salir = 0 local i = 1 local valid_counter = 0

while salir == 0 do       debugline("-- while: ", i)        local continuar = 0 local n = allcardnames[i] local current_id = nil if n ~= nil then current_id = p.normalize(n) if last_id == current_id then debugline("-- incrementar contador") lastcount = lastcount + 1 else debugline("-- imprimir carta") continuar = 1 end else -- Última carta debugline("-- imprimir última carta") salir = 1 continuar = 1 end if continuar == 1 then if last_id ~= nil then debugline(" -- IMPRIMIENDO CARTA: ", last_id ," --") local cardname = cardnames[last_id] if cardname.nombre ~= nil then if cardname.codigo ~= nil then -- Carta con código válido valid_counter = valid_counter + 1 if cardname.restriccion == 'prohibida' then debugline(" -- prohibida") text3 = text3 .. " " .. "La carta " .. b(cardname.nombre) .. " se encuentra prohibida.</li>" elseif lastcount > 3 then debugline(" -- excede copias") text3 = text3 .. " " .. "La carta " .. b(cardname.nombre) .. " excede el número de copias para un deck.</li>" elseif lastcount > 2 and cardname.restriccion == 'semilimitada' then debugline(" -- semilimitada, excede copias") text3 = text3 .. " " .. "La carta " .. b(cardname.nombre) .. " está semi-limitada y excede el número de copias.</li>" elseif lastcount > 1 and cardname.restriccion == 'limitada' then debugline(" -- limitada, excede copias") text3 = text3 .. " " .. "La carta " .. b(cardname.nombre) .. " está limitada y excede el número de copias.</li>" end else -- Carta sin código válido debugline(" -- carta sin código") text3 = text3 .. " " .. "La carta " .. b(cardname.nombre) .. " no posee código y fue excluída.</li>" end else -- La carta aún no ha sido registrada if lastcardname ~= nil then debugline(" -- carta no registrada") text3 = text3 .. " " .. "La carta " .. b(lastcardname) .. " no se encuentra registrada</li>" end end --lastcount = 1 else debugline(" -- last_id vacío") end lastcardname = n           last_id = current_id lastcount = 1 end i = i + 1 debugline("-- valid_counter: ", valid_counter) debugline("-- last_count: ", lastcount) end -- Imprime resultado if text3 ~= '' then text = text .. " ATENCION: Se han detectado los siguientes problemas: \n<ul>\n" .. text3 .. "</ul>\n" else if valid_counter > 0 then text = text .. "<p style='color:#088A08'> No se han detectado problemas. Todas las cartas se encuentran registradas correctamente. \n" end end if valid_counter == 0 then text = text .. " <p style='color:red'> No se ha registrado ninguna carta válida. La lista se encuentra vacía. \n" else text = text .. ydk_text text = text .. ' '   end debugline("\n\n\n RESULTADO: ", text3, "\n")

return text end

function html.partialView (main_n, maindeck, extra_n, extradeck, side_n, sidedeck, cardnames) local text = '' -- Deck Principal text = text .. html.vista('d', main_n, maindeck, cardnames) -- Deck Extra text = text .. html.vista('e', extra_n, extradeck, cardnames) -- Side Deck text = text .. html.vista('s', side_n, sidedeck, cardnames) -- Footer text = text .. ' \n' text = text .. '\n' text = text .. ' \n' text = text .. '  \n' return text end

function html.partialList (main_n, maindeck, extra_n, extradeck, side_n, sidedeck, cardnames) local text = '' text = text .. '<div class="decklist_sections">\n' -- Lista de cartas: Deck Principal text = text .. html.lista('d', maindeck, cardnames) -- Lista de cartas: Deck Extra text = text .. html.lista('e', extradeck, cardnames) -- Lista de cartas: Side Deck text = text .. html.lista('s', sidedeck, cardnames) -- Footer text = text .. ' \n' return text end

-- FUNCION: Convierte todos los parámetros en wikitexto function html.partialYgopro (main_n, maindeck, extra_n, extradeck, side_n, sidedeck, cardnames, allcardnames) local text = '' -- YGOPro -- -- YGOPro: Intro text = text .. ' '   text = text .. ' \n' text = text .. ' Esta receta se visualiza en formato compatible con YGOPRO. '       .. 'Puedes hacer click en el botón "Descargar el deck", o puedes copiar el texto en un editor ' .. 'y guardarlo con la extensión ".ydk" para cargarlo en el juego. \n' text = text .. html.ygopro(maindeck, extradeck, sidedeck, cardnames, allcardnames)

return text end

return p