Documentation for this module may be created at ሞድዩል:Identifiers/doc

local p = {}

--[[
ISBN-10 and ISSN validator code calculates checksum across all isbn/issn digits including the check digit. ISBN-13 is checked in checkisbn().
If the number is valid the result will be 0. Before calling this function, issbn/issn must be checked for length and stripped of dashes,
spaces and other non-isxn characters.
]]
-- Function taken from en:Module:Citation/CS1

function p.isValidISXN (isxn_str, len)
	local temp = 0;
	isxn_str = { isxn_str:byte(1, len) };	-- make a table of bytes
	len = len+1;							-- adjust to be a loop counter
	for i, v in ipairs( isxn_str ) do		-- loop through all of the bytes and calculate the checksum
		if v == string.byte( "X" ) then		-- if checkdigit is X
			temp = temp + 10*( len - i );	-- it represents 10 decimal
		else
			temp = temp + tonumber( string.char(v) )*(len-i);
		end
	end
	return temp % 11 == 0;					-- returns true if calculation result is zero
end

-- Adaptation of the checkisbn function from en:Module:Citation/CS1
function p.isValidISBN(isbn)
	-- The isbn only contains numbers, hyphens, blank spaces, and the check
	-- digit X.
	
	if not isbn or isbn:match("[^%s-0-9X]")  then
		return false
	end
	
	-- Remove hyphens and whitespace
	
	isbn = isbn:gsub( "-", "" ):gsub( " ", "" )
	local length = isbn:len()
 
	if length == 10 then
		-- The X can only go at the end.
		if not isbn:match( "^%d*X?$" ) then
			return false
		end
		return p.isValidISXN(isbn, 10);
	elseif length == 13 then -- isbn13
		local temp = 0;
		-- Must start with 978 or 979
		if not isbn:match( "^97[89]%d*$" ) then 
			return false
		end
		
		-- Check the check digit
		isbn = { isbn:byte(1, length) };
		for i, v in ipairs( isbn ) do
			temp = temp + (3 - 2*(i % 2)) * tonumber( string.char(v) );
		end
		return temp % 10 == 0;
	else
		return false
	end
	
end

-- Function that returns a link to the ISBN if it is correct and if not (for example if
-- it is already linked) it returns it without further ado.
-- By default, the literal ISBN is not included in front.

function p.linkISBN(isbn, options)
    if p.isValidISBN(isbn) then
        return '[[Special:BookSources/' .. isbn .. '|' .. isbn .. ']]'
    else
    	return isbn
    end
end

function p.linkOCLC(oclc, options)
    if tonumber(oclc) then
        return '[http://www.worldcat.org/oclc/' .. oclc .. ' ' .. oclc .. ']'
    else
    	return oclc
    end
end

return p