<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://themidnight.wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ACheck_isxn</id>
	<title>Module:Check isxn - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://themidnight.wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ACheck_isxn"/>
	<link rel="alternate" type="text/html" href="https://themidnight.wiki/index.php?title=Module:Check_isxn&amp;action=history"/>
	<updated>2026-04-03T17:48:29Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://themidnight.wiki/index.php?title=Module:Check_isxn&amp;diff=11990&amp;oldid=prev</id>
		<title>Timothy: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://themidnight.wiki/index.php?title=Module:Check_isxn&amp;diff=11990&amp;oldid=prev"/>
		<updated>2024-01-30T15:46:35Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:46, 30 January 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Timothy</name></author>
	</entry>
	<entry>
		<id>https://themidnight.wiki/index.php?title=Module:Check_isxn&amp;diff=11989&amp;oldid=prev</id>
		<title>wikipedia&gt;Trappist the monk: sync from sandbox;</title>
		<link rel="alternate" type="text/html" href="https://themidnight.wiki/index.php?title=Module:Check_isxn&amp;diff=11989&amp;oldid=prev"/>
		<updated>2022-11-03T23:27:58Z</updated>

		<summary type="html">&lt;p&gt;sync from sandbox;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
This code is derived from the ISXN validation code at Module:Citation/CS1.  It allows validating ISBN,&lt;br /&gt;
ISMN, and ISSN without invoking a citation template.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E R R _ M S G _ S U P L _ T &amp;gt;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
error message supplements for check_isbn(); adapted from a similarly named table at Module:Citation/CS1/Configuration&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local err_msg_supl_t = {&lt;br /&gt;
	[&amp;#039;char&amp;#039;] = &amp;#039;invalid character&amp;#039;,&lt;br /&gt;
	[&amp;#039;check&amp;#039;] = &amp;#039;checksum&amp;#039;,&lt;br /&gt;
	[&amp;#039;form&amp;#039;] = &amp;#039;invalid form&amp;#039;,&lt;br /&gt;
	[&amp;#039;group&amp;#039;] = &amp;#039;invalid group id&amp;#039;,&lt;br /&gt;
	[&amp;#039;length&amp;#039;] = &amp;#039;length&amp;#039;,&lt;br /&gt;
	[&amp;#039;prefix&amp;#039;] = &amp;#039;invalid prefix&amp;#039;,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; IS _ V A L I D _ I S X N &amp;gt;-----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ISBN-10 and ISSN validator code calculates checksum across all isbn/issn digits including the check digit. ISBN-13 is checked in check_isbn().&lt;br /&gt;
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,&lt;br /&gt;
spaces and other non-isxn characters.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_isxn (isxn_str, len)&lt;br /&gt;
	local temp = 0;&lt;br /&gt;
	isxn_str = { isxn_str:byte(1, len) };	-- make a table of byte values &amp;#039;0&amp;#039; → 0x30 .. &amp;#039;9&amp;#039;  → 0x39, &amp;#039;X&amp;#039; → 0x58&lt;br /&gt;
	len = len+1;							-- adjust to be a loop counter&lt;br /&gt;
	for i, v in ipairs( isxn_str ) do		-- loop through all of the bytes and calculate the checksum&lt;br /&gt;
		if v == string.byte( &amp;quot;X&amp;quot; ) then		-- if checkdigit is X (compares the byte value of &amp;#039;X&amp;#039; which is 0x58)&lt;br /&gt;
			temp = temp + 10*( len - i );	-- it represents 10 decimal&lt;br /&gt;
		else&lt;br /&gt;
			temp = temp + tonumber( string.char(v) )*(len-i);&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return temp % 11 == 0;					-- returns true if calculation result is zero&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; IS _ V A L I D _ I S X N  _ 1 3 &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
ISBN-13 and ISMN validator code calculates checksum across all 13 isbn/ismn digits including the check digit.&lt;br /&gt;
If the number is valid, the result will be 0. Before calling this function, isbn-13/ismn must be checked for length&lt;br /&gt;
and stripped of dashes, spaces and other non-isxn-13 characters.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_isxn_13 (isxn_str)&lt;br /&gt;
	local temp=0;&lt;br /&gt;
	&lt;br /&gt;
	isxn_str = { isxn_str:byte(1, 13) };										-- make a table of byte values &amp;#039;0&amp;#039; → 0x30 .. &amp;#039;9&amp;#039;  → 0x39&lt;br /&gt;
	for i, v in ipairs( isxn_str ) do&lt;br /&gt;
		temp = temp + (3 - 2*(i % 2)) * tonumber( string.char(v) );				-- multiply odd index digits by 1, even index digits by 3 and sum; includes check digit&lt;br /&gt;
	end&lt;br /&gt;
	return temp % 10 == 0;														-- sum modulo 10 is zero when isbn-13/ismn is correct&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C H E C K _ I S B N &amp;gt;------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Determines whether an ISBN string is valid.  Implements an ISBN validity check for {{ISBN}}, {{ISBNT}}, {{SBN}}, and&lt;br /&gt;
{{Format ISBN}}.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function check_isbn (isbn_str, frame)&lt;br /&gt;
	local function return_result (check, err_type)								-- local function to render the various error returns&lt;br /&gt;
		if not check then														-- &amp;lt;check&amp;gt; false when there is an error&lt;br /&gt;
			local template = ((frame.args.template_name and &amp;#039;&amp;#039; ~= frame.args.template_name) and frame.args.template_name) or nil;	-- get template name&lt;br /&gt;
			if not template then&lt;br /&gt;
				return &amp;#039;&amp;lt;span class=&amp;quot;error&amp;quot; style=&amp;quot;font-size:100%&amp;quot;&amp;gt;&amp;amp;nbsp;calling template requires template_name parameter&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local out_t = {&amp;#039;&amp;lt;span class=&amp;quot;error&amp;quot; style=&amp;quot;font-size:100%&amp;quot;&amp;gt;&amp;#039;};		-- open the error message span&lt;br /&gt;
			table.insert (out_t, &amp;#039;&amp;amp;nbsp;Parameter error in {{[[Template:&amp;#039;);		-- open &amp;#039;template&amp;#039; markup; open wikilink with Template namespace&lt;br /&gt;
			table.insert (out_t, template);										-- template name wikilink&lt;br /&gt;
			table.insert (out_t, &amp;#039;|&amp;#039;);											-- its pipe&lt;br /&gt;
			table.insert (out_t, template);										-- wikilink label&lt;br /&gt;
			table.insert (out_t, &amp;#039;]]}}:&amp;amp;nbsp;&amp;#039;);								-- close wikilink; close &amp;#039;template&amp;#039; markup&lt;br /&gt;
			table.insert (out_t, err_type);										-- type of isbn error&lt;br /&gt;
			table.insert (out_t, &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;)										-- close the error message span&lt;br /&gt;
			if 0 == mw.title.getCurrentTitle().namespace then					-- categorize only when this template is used in mainspace&lt;br /&gt;
				local category = table.concat ({&amp;#039;[[Category:Pages with ISBN errors]]&amp;#039;});&lt;br /&gt;
				table.insert (out_t, category);&lt;br /&gt;
			end&lt;br /&gt;
			return table.concat (out_t);										-- make a big string and done&lt;br /&gt;
		end&lt;br /&gt;
	return &amp;#039;&amp;#039;;																	-- no error, return an empty string&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if nil ~= isbn_str:match (&amp;#039;[^%s-0-9X]&amp;#039;) then&lt;br /&gt;
		return return_result (false, err_msg_supl_t.char);						-- fail if isbn_str contains anything but digits, hyphens, or the uppercase X&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local id = isbn_str:gsub (&amp;#039;[%s-]&amp;#039;, &amp;#039;&amp;#039;);										-- remove hyphens and whitespace&lt;br /&gt;
&lt;br /&gt;
	local len = id:len();&lt;br /&gt;
 &lt;br /&gt;
	if len ~= 10 and len ~= 13 then&lt;br /&gt;
		return return_result (false, err_msg_supl_t.length);					-- fail if incorrect length&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if len == 10 then&lt;br /&gt;
		if id:match (&amp;#039;^%d*X?$&amp;#039;) == nil then										-- fail if isbn_str has &amp;#039;X&amp;#039; anywhere but last position&lt;br /&gt;
			return return_result (false, err_msg_supl_t.form);									&lt;br /&gt;
		end&lt;br /&gt;
		if id:find (&amp;#039;^63[01]&amp;#039;) then												-- 630xxxxxxx and 631xxxxxxx are (apparently) not valid isbn group ids but are used by amazon as numeric identifiers (asin)&lt;br /&gt;
			return return_result (false, err_msg_supl_t.group);					-- fail if isbn-10 begins with 630/1&lt;br /&gt;
		end&lt;br /&gt;
		return return_result (is_valid_isxn (id, 10), err_msg_supl_t.check);	-- pass if isbn-10 is numerically valid (checksum)&lt;br /&gt;
	else&lt;br /&gt;
		if id:match (&amp;#039;^%d+$&amp;#039;) == nil then&lt;br /&gt;
			return return_result (false, err_msg_supl_t.char);					-- fail if ISBN-13 is not all digits&lt;br /&gt;
		end&lt;br /&gt;
		if id:match (&amp;#039;^97[89]%d*$&amp;#039;) == nil then&lt;br /&gt;
			return return_result (false, err_msg_supl_t.prefix);				-- fail when ISBN-13 does not begin with 978 or 979&lt;br /&gt;
		end&lt;br /&gt;
		if id:match (&amp;#039;^9790&amp;#039;) then&lt;br /&gt;
			return return_result (false, err_msg_supl_t.group);					-- group identifier &amp;#039;0&amp;#039; is reserved to ISMN&lt;br /&gt;
		end&lt;br /&gt;
		return return_result (is_valid_isxn_13 (id), err_msg_supl_t.check);		-- pass if isbn-10 is numerically valid (checksum)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C H E C K _ I S M N &amp;gt;------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Determines whether an ISMN string is valid.  Similar to isbn-13, ismn is 13 digits begining 979-0-... and uses the&lt;br /&gt;
same check digit calculations.  See http://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf&lt;br /&gt;
section 2, pages 9–12.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function check_ismn (id, error_string)&lt;br /&gt;
	local text;&lt;br /&gt;
	local valid_ismn = true;&lt;br /&gt;
&lt;br /&gt;
	id=id:gsub( &amp;quot;[%s-–]&amp;quot;, &amp;quot;&amp;quot; );													-- strip spaces, hyphens, and endashes from the ismn&lt;br /&gt;
&lt;br /&gt;
	if 13 ~= id:len() or id:match( &amp;quot;^9790%d*$&amp;quot; ) == nil then					-- ismn must be 13 digits and begin 9790&lt;br /&gt;
		valid_ismn = false;&lt;br /&gt;
	else&lt;br /&gt;
		valid_ismn=is_valid_isxn_13 (id);										-- validate ismn&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return valid_ismn and &amp;#039;&amp;#039; or error_string&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S S N &amp;gt;----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Validate and format an issn.  This code fixes the case where an editor has included an ISSN in the citation but has separated the two groups of four&lt;br /&gt;
digits with a space.  When that condition occurred, the resulting link looked like this:&lt;br /&gt;
&lt;br /&gt;
	|issn=0819 4327 gives: [http://www.worldcat.org/issn/0819 4327 0819 4327]  -- can&amp;#039;t have spaces in an external link&lt;br /&gt;
	&lt;br /&gt;
This code now prevents that by inserting a hyphen at the issn midpoint.  It also validates the issn for length and makes sure that the checkdigit agrees&lt;br /&gt;
with the calculated value.  Incorrect length (8 digits), characters other than 0-9 and X, or checkdigit / calculated value mismatch will all cause a check issn&lt;br /&gt;
error message.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function check_issn(id, error_string)&lt;br /&gt;
	local issn_copy = id;		-- save a copy of unadulterated issn; use this version for display if issn does not validate&lt;br /&gt;
	local text;&lt;br /&gt;
	local valid_issn = true;&lt;br /&gt;
&lt;br /&gt;
	if not id:match (&amp;#039;^%d%d%d%d%-%d%d%d[%dX]$&amp;#039;) then&lt;br /&gt;
		return error_string;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	id=id:gsub( &amp;quot;[%s-–]&amp;quot;, &amp;quot;&amp;quot; );									-- strip spaces, hyphens, and endashes from the issn&lt;br /&gt;
&lt;br /&gt;
	if 8 ~= id:len() or nil == id:match( &amp;quot;^%d*X?$&amp;quot; ) then		-- validate the issn: 8 digits long, containing only 0-9 or X in the last position&lt;br /&gt;
		valid_issn=false;										-- wrong length or improper character&lt;br /&gt;
	else&lt;br /&gt;
		valid_issn=is_valid_isxn(id, 8);						-- validate issn&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return valid_issn and &amp;#039;&amp;#039; or error_string&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
------------------------------&amp;lt; E N T R Y   P O I N T S &amp;gt;--------------------------------------------------====&lt;br /&gt;
&lt;br /&gt;
function p.check_isbn(frame)&lt;br /&gt;
	return check_isbn(frame.args[1] or frame:getParent().args[1], frame)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.check_ismn(frame)&lt;br /&gt;
	return check_ismn(frame.args[1] or frame:getParent().args[1], frame.args[&amp;#039;error&amp;#039;] or frame:getParent().args[&amp;#039;error&amp;#039;] or &amp;#039;error&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.check_issn(frame)&lt;br /&gt;
	return check_issn(frame.args[1] or frame:getParent().args[1], frame.args[&amp;#039;error&amp;#039;] or frame:getParent().args[&amp;#039;error&amp;#039;] or &amp;#039;error&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>wikipedia&gt;Trappist the monk</name></author>
	</entry>
</feed>