Ir para o conteúdo

Módulo:Check isxn

De Wiki TokuDrive

--[[

Este código é derivado do código de validação ISXN no Módulo:Citação/CS1. Ele permite validar ISBN, ISMN, e ISSN sem ter que invocar uma predefinição de citação.

]]

local p = {}


--[[--------------------------< E R R _ M S G _ S U P L _ T >--------------------------------------------------

Mensagem de erro suplementar para check_isbn(); adaptado de uma tabela nomeada simelhante de Módulo:Citação/CS1/Configuração

]]

local err_msg_supl_t = { ['char'] = 'caractere inválido', ['check'] = 'soma de verificação', ['form'] = 'forma inválida', ['group'] = 'id do grupo inválido', ['length'] = 'comprimento', ['prefix'] = 'prefixo inválido', }


--[[--------------------------< IS _ V A L I D _ I S X N >-----------------------------------------------------

O código validador ISBN-10 e ISSN calcula a soma de verificação em todos os dígitos isbn/issn, incluindo o dígito de verificação. ISBN-13 é verificado em check_isbn(). Se o número for válido, o resultado será 0. Antes de chamar esta função, issbn/issn deve ser verificado quanto ao comprimento e sem travessões, espaços e outros caracteres não isxn.

]]

local function is_valid_isxn (isxn_str, len) local temp = 0; isxn_str = { isxn_str:byte(1, len) }; -- cria uma tabela de valores de bytes '0' → 0x30 .. '9' → 0x39, 'X' → 0x58 len = len+1; -- ajuste para ser um contador de loop for i, v in ipairs( isxn_str ) do -- faz um loop por todos os bytes e calcular a soma de verificação if v == string.byte( "X" ) then -- se o dígito de verificação é X (compara o valor de byte de 'X' que é 0x58) temp = temp + 10*( len - i ); -- representa o 10 decimal else temp = temp + tonumber( string.char(v) )*(len-i); end end return temp % 11 == 0; -- retorna verdadeiro de o resultado do cálculo é zero end


--[[--------------------------< IS _ V A L I D _ I S X N _ 1 3 >----------------------------------------------

O código validador ISBN-13 e ISMN calcula a soma de verificação em todos os 13 dígitos isbn/ismn, incluindo o dígito de verificação. Se o número for válido, o resultado será 0. Antes de chamar esta função, isbn-13/ismn deve ser verificado quanto ao comprimento e sem travessões, espaços e outros caracteres diferentes de isxn-13.

]]

local function is_valid_isxn_13 (isxn_str) local temp=0;

isxn_str = { isxn_str:byte(1, 13) }; -- cria uma tabela com os valores de bytes '0' → 0x30 .. '9' → 0x39 for i, v in ipairs( isxn_str ) do temp = temp + (3 - 2*(i % 2)) * tonumber( string.char(v) ); -- multiplica índices ímpares por 1, pares por 3 e soma; incluindo o dígito de verificação end return temp % 10 == 0; -- soma modulo 10 é zero quando a isbn-13/ismn está correta end


--[[--------------------------< C H E C K _ I S B N >------------------------------------------------------------

Determina se uma ISBN é válida.

]]

local function check_isbn (isbn_str, frame) local function return_result (check, err_type) -- função local para renderizar os vários retornos de erro if not check then -- <check> é falso quando há um erro local template = ((frame.args.template_name and ~= frame.args.template_name) and frame.args.template_name) or nil; -- pega o nome da predefinição if not template then return ' a chamada da predefinição requer o parâmetro template_name'; end

local out_t = {''}; -- abre o span da mensagem de erro table.insert (out_t, ' Erro de parâmetro em {{[[Predefinição:'); -- abre a marcação para 'predefinição'; abre a ligação para o domínio predefinição table.insert (out_t, template); -- ligação para o nome da predefinição table.insert (out_t, '|'); -- pipe table.insert (out_t, template); -- etiqueta da ligação table.insert (out_t, ']]}}: '); -- fecha ligação; fecha a marcação 'predefinição' table.insert (out_t, err_type); -- tipo do erro da isbn table.insert (out_t, '') -- fecha o span da mensagem de erro if 0 == mw.title.getCurrentTitle().namespace then -- categoriza apenas se a predefinição é utilizada no domínio principal local category = table.concat ({}); table.insert (out_t, category); end return table.concat (out_t); -- cria uma grande string e finaliza end return ; -- se não há erros, retorna uma string vazia end

if nil ~= isbn_str:match ('[^%s-0-9X]') then return return_result (false, err_msg_supl_t.char); -- erro se isbn_str contiver qualquer coisa além de dígitos, hifens ou X maiúsculo end

local id = isbn_str:gsub ('[%s-]', ); -- remove hifens e espaços em branco

local len = id:len();

if len ~= 10 and len ~= 13 then return return_result (false, err_msg_supl_t.length); -- erro se o comprimento for incorreto end

if len == 10 then if id:match ('^%d*X?$') == nil then -- erro se isbn_str contiver 'X' em qualquer lugar que não seja no último dígito return return_result (false, err_msg_supl_t.form); end if id:find ('^63[01]') then -- 630xxxxxxx e 631xxxxxxx (aparentemente) não são IDs de grupo isbn válidos, mas são usados pela Amazon como identificadores numéricos (asin) return return_result (false, err_msg_supl_t.group); -- erro se isbn-10 começa com 630/1 end return return_result (is_valid_isxn (id, 10), err_msg_supl_t.check); -- aprova se isbn-10 for numericamente válido (soma de verificação) else if id:match ('^%d+$') == nil then return return_result (false, err_msg_supl_t.char); -- erro se ISBN-13 não for apenas dígitos end if id:match ('^97[89]%d*$') == nil then return return_result (false, err_msg_supl_t.prefix); -- erro se ISBN-13 não começar com 978 ou 979 end if id:match ('^9790') then return return_result (false, err_msg_supl_t.group); -- o grupo identificador '0' é resercado para ISMN end return return_result (is_valid_isxn_13 (id), err_msg_supl_t.check); -- aprova se isbn-10 for numericamente válido (soma de verificação) end end


--[[--------------------------< C H E C K _ I S M N >------------------------------------------------------------

Determina se uma sequência ISMN é válida. Semelhante ao isbn-13, o ismn tem 13 dígitos começando com 979-0-... e usa os mesmos cálculos de dígitos de verificação. Consulte http://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf seção 2, páginas 9–12.

]]

local function check_ismn (id, error_string) local text; local valid_ismn = true;

id=id:gsub( "[%s-–]", "" ); -- retira espaços, hífens e travessões do ismn

if 13 ~= id:len() or id:match( "^9790%d*$" ) == nil then -- ismn deve conter 13 dígitos e começar com 9790 valid_ismn = false; else valid_ismn=is_valid_isxn_13 (id); -- valida ismn end

return valid_ismn and or error_string end


--[[--------------------------< I S S N >----------------------------------------------------------------------

Valida e formata um issn. Este código corrige o caso em que um editor incluiu um ISSN na citação, mas separou os dois grupos de quatro dígitos com um espaço. Quando essa condição ocorre, a ligação resultante fica assim:

|issn=0819 4327 gera: 4327 0819 4327 -- não poda haver espações numa ligação externa

Este código agora evita isso inserindo um hífen no ponto médio do issn. Ele também valida o comprimento do issn e garante que o dígito de verificação esteja de acordo com o valor calculado. Comprimento incorreto (8 dígitos), caracteres diferentes de 0-9 e X ou incompatibilidade de dígito de verificação/valor calculado causarão uma mensagem de erro de verificação issn.

]]

local function check_issn(id, error_string) local issn_copy = id; -- salva uma cópia da issn não alterada; usa esta versão para exibir se a issn não for válida local text; local valid_issn = true;

if not id:match ('^%d%d%d%d%-%d%d%d[%dX]$') then return error_string; end

id=id:gsub( "[%s-–]", "" ); -- retirar espaços, hífens e travessões do issn

if 8 ~= id:len() or nil == id:match( "^%d*X?$" ) then -- valida o issn: 8 digitos de comprimento, contendo apenas 0-9 ou X nã última posição valid_issn=false; -- comprimento errado ou caractere impróprio else valid_issn=is_valid_isxn(id, 8); -- valida issn end

return valid_issn and or error_string end



< E N T R Y P O I N T S >--------------------------------------------------====

function p.check_isbn(frame) return check_isbn(frame.args[1] or frame:getParent().args[1], frame) end

function p.check_ismn(frame) return check_ismn(frame.args[1] or frame:getParent().args[1], frame.args['error'] or frame:getParent().args['error'] or 'error') end

function p.check_issn(frame) return check_issn(frame.args[1] or frame:getParent().args[1], frame.args['error'] or frame:getParent().args['error'] or 'error') end

return p