<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.cultopedia.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ACS1_identifiers</id>
	<title>Module:CS1 identifiers - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.cultopedia.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ACS1_identifiers"/>
	<link rel="alternate" type="text/html" href="https://www.cultopedia.org/index.php?title=Module:CS1_identifiers&amp;action=history"/>
	<updated>2026-04-05T21:59:27Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.5</generator>
	<entry>
		<id>https://www.cultopedia.org/index.php?title=Module:CS1_identifiers&amp;diff=218&amp;oldid=prev</id>
		<title>imported&gt;Trappist the monk at 14:15, 3 August 2025</title>
		<link rel="alternate" type="text/html" href="https://www.cultopedia.org/index.php?title=Module:CS1_identifiers&amp;diff=218&amp;oldid=prev"/>
		<updated>2025-08-03T14:15:05Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require (&amp;#039;strict&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
local get_args = require (&amp;#039;Module:Arguments&amp;#039;).getArgs;&lt;br /&gt;
local identifiers = require (&amp;#039;Module:Citation/CS1/Identifiers&amp;#039;);&lt;br /&gt;
local utilities = require (&amp;#039;Module:Citation/CS1/Utilities&amp;#039;);&lt;br /&gt;
	local has_accept_as_written = utilities.has_accept_as_written;				-- import functions from Module:Citation/CS1/Utilities&lt;br /&gt;
	local is_set = utilities.is_set;&lt;br /&gt;
	local make_wikilink = utilities.make_wikilink;&lt;br /&gt;
	local set_message = utilities.set_message;&lt;br /&gt;
	local substitute = utilities.substitute;&lt;br /&gt;
&lt;br /&gt;
local cfg = mw.loadData (&amp;#039;Module:Citation/CS1/Configuration&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
utilities.set_selected_modules (cfg);											-- so that functions in Utilities can see the selected cfg tables&lt;br /&gt;
identifiers.set_selected_modules (cfg, utilities);								-- so that functions in Identifiers can see the selected cfg tables and selected Utilities module&lt;br /&gt;
&lt;br /&gt;
local Frame;																	-- local copy of &amp;lt;frame&amp;gt; from main(); nil else&lt;br /&gt;
local this_page = mw.title.getCurrentTitle();									-- used to limit categorization to certain namepsaces&lt;br /&gt;
&lt;br /&gt;
local no_cat;																	-- used to limit categorization to certain namespaces&lt;br /&gt;
if cfg.uncategorized_namespaces[this_page.namespace] then						-- is this page&amp;#039;s namespace id one of the uncategorized namespace ids?&lt;br /&gt;
	no_cat = true;																-- set no_cat; this page will not be categorized&lt;br /&gt;
end&lt;br /&gt;
for _, v in ipairs (cfg.uncategorized_subpages) do								-- cycle through page name patterns&lt;br /&gt;
	if this_page.text:match (v) then											-- test page name against each pattern&lt;br /&gt;
		no_cat = true;															-- set no_cat; this page will not be categorized&lt;br /&gt;
		break;																	-- bail out if one is found&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E R R _ M E S S A G E _ C O N V E R T &amp;gt;----------------------------------------&lt;br /&gt;
&lt;br /&gt;
converts cs1|2 error message to a message suitable for this module.&lt;br /&gt;
&lt;br /&gt;
converted error messages do not name a parameter as is done in cs1|2.  The help link links to the template page&lt;br /&gt;
not to a help-namespace page.  The prefix is rewritten to name the offending template; not a cs1|2 template.&lt;br /&gt;
&lt;br /&gt;
adds template specific category.&lt;br /&gt;
&lt;br /&gt;
done this way because the identifier functions in Module:Citation/CS1/Identifiers create properly formatted&lt;br /&gt;
messages with correct html for styling.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function err_message_convert (message_prefix, message, _template, no_cat)&lt;br /&gt;
	message = message:gsub (&amp;#039;&amp;amp;#124;([^=]+)=&amp;#039;, &amp;#039;%1&amp;#039;);							-- remove parameter pipe and assignment operator&lt;br /&gt;
	message = message:gsub (&amp;#039;Help:CS1 errors#[^%]]+&amp;#039;, substitute (&amp;#039;Template:$1|help&amp;#039;, _template));	-- rewrite help text&lt;br /&gt;
	message = message:gsub (&amp;#039;(%b&amp;lt;&amp;gt;)&amp;#039;, substitute (&amp;#039;$1$2: &amp;#039;, {&amp;#039;%1&amp;#039;, message_prefix}), 1);	-- %1 is the opening span tag; insert &amp;lt;message_prefix&amp;gt;&lt;br /&gt;
	local category = no_cat and &amp;#039;&amp;#039; or substitute (&amp;#039;[[Category:Pages with $1 errors]]&amp;#039;, _template:upper());	-- limited to certain namespaces &lt;br /&gt;
	return substitute (&amp;#039;$1$2&amp;#039;, {message, category});							-- make a big string and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; M A I N T _ M E S S A G E _ C O N V E R T &amp;gt;------------------------------------&lt;br /&gt;
&lt;br /&gt;
converts cs1|2 maintenance message to a message suitable for this module.&lt;br /&gt;
&lt;br /&gt;
converted maintenance messages have a prefix suitable for the rendered template.  The &amp;#039;link&amp;#039; text links to the&lt;br /&gt;
an appropriate maintenance category&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function maint_message_convert (message_prefix, message_raw, _template, no_cat)&lt;br /&gt;
	message_raw = message_raw:gsub (&amp;#039;CS1 maint: &amp;#039;, &amp;#039;&amp;#039;);							-- strip cs1-specific prefix from cat name&lt;br /&gt;
	local message = substitute (&amp;#039;$1: $2&amp;#039;, {message_prefix, message_raw});		-- add the template prefix&lt;br /&gt;
	message = substitute (&amp;#039;$1$2 ($3)&amp;#039;, {&lt;br /&gt;
		message,&lt;br /&gt;
		no_cat and &amp;#039;&amp;#039; or substitute (cfg.messages[&amp;#039;cat wikilink&amp;#039;], message_raw),-- the category link; limited to certain namespaces&lt;br /&gt;
		substitute (cfg.messages[&amp;#039;:cat wikilink&amp;#039;], message_raw)}				-- links to the maint cat, just as cs1|2 links to its maint cats&lt;br /&gt;
		);&lt;br /&gt;
	return substitute (cfg.presentation[&amp;#039;hidden-maint&amp;#039;], message);				-- the maint message text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; P A R A M S _ G E T &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
extract enumerated parameters from &amp;lt;args_t&amp;gt; where the enumerator is &amp;lt;i&amp;gt;.  enumerator is always the last character&lt;br /&gt;
of the parameter name (doi-broken-date1 not doi1-broken-date)&lt;br /&gt;
&lt;br /&gt;
special case the enumerator is 1: prefer non-enumerated parameters&lt;br /&gt;
&lt;br /&gt;
returns a table of same-enumerator parameters (without enumerator) &lt;br /&gt;
&lt;br /&gt;
note: &amp;lt;i&amp;gt; is a number&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function params_get (args_t, i)&lt;br /&gt;
--mw.logObject (args_t, &amp;#039;args_t&amp;#039;)&lt;br /&gt;
	local params_t = {};														-- selected parameters go in this table&lt;br /&gt;
	if 1 == i then																-- special case when enumerator (&amp;lt;i&amp;gt;) is 1&lt;br /&gt;
		for k, v in pairs (args_t) do											-- for each parameter&lt;br /&gt;
			if &amp;#039;number&amp;#039; == type (k) then										-- if this is a positional parameter&lt;br /&gt;
				if 1 == k then													-- and its the first positional parameter&lt;br /&gt;
					params_t[1] = v;											-- save it&lt;br /&gt;
				end&lt;br /&gt;
			else																-- here for named parameters&lt;br /&gt;
				local enum = k:match (&amp;#039;%d+$&amp;#039;);									-- extract the enumerator from the parameter&amp;#039;s name; nil else&lt;br /&gt;
				if (not enum) or (1 == tonumber (enum)) then					-- when not enumerated or when enumerator is 1&lt;br /&gt;
					k = k:gsub (&amp;#039;%d+$&amp;#039;, &amp;#039;&amp;#039;);									-- remove the enumerator from parameter name&lt;br /&gt;
					params_t[k] = v;											-- and save this parameter&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for k, v in pairs (args_t) do											-- for each parameter&lt;br /&gt;
			if &amp;#039;number&amp;#039; == type (k) then										-- if this is a positional parameter&lt;br /&gt;
				if i == k then													-- and is the desired positional parameter&lt;br /&gt;
					params_t[1] = v;											-- save it (as index number 1; not as index &amp;lt;i&amp;gt;)&lt;br /&gt;
				end&lt;br /&gt;
			else																-- here for named parameters&lt;br /&gt;
				local enum = k:match (&amp;#039;%d+$&amp;#039;);									-- extract the parameter&amp;#039;s enumerator; nil else&lt;br /&gt;
				if enum and (i == tonumber (enum)) then							-- when enumerated and the enumerator is same as requested&lt;br /&gt;
					k = k:gsub (&amp;#039;%d+$&amp;#039;, &amp;#039;&amp;#039;);									-- remove the enumerator from parameter name&lt;br /&gt;
					params_t[k] = v;											-- and save this parameter&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
--mw.logObject (params_t, &amp;#039;params_t&amp;#039;)&lt;br /&gt;
	return params_t;															-- and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; R E N D E R _ F I N A L &amp;gt;------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
this function applies cs1|2 template style sheet to a rendered identifier or error message&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function render_final (output)&lt;br /&gt;
	if not Frame then															-- not set when this module called from another module&lt;br /&gt;
		Frame = mw.getCurrentFrame();											-- get the calling module&amp;#039;s frame so that we can call extensionTag()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return substitute (&amp;#039;$1$2&amp;#039;, {&lt;br /&gt;
		Frame:extensionTag (&amp;#039;templatestyles&amp;#039;, &amp;#039;&amp;#039;, {src=&amp;#039;Module:Citation/CS1/styles.css&amp;#039;}),	-- apply templatestyles&lt;br /&gt;
		output																	-- to the rendered identifier or error message&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; _ M A I N &amp;gt;--------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
entry point when called from another module; example:&lt;br /&gt;
	local rendered_identifier = require (&amp;#039;Module:CS1 identifiers&amp;#039;)._main ({&amp;#039;10.4231/sommat&amp;#039;, _template = &amp;#039;doi&amp;#039;, [&amp;#039;doi-access&amp;#039;] = &amp;#039;free&amp;#039;, [&amp;#039;doi-broken-date&amp;#039;] = &amp;#039;June 2025&amp;#039;});&lt;br /&gt;
&lt;br /&gt;
supported identifier templates are:&lt;br /&gt;
	{{arxiv}}	{{asin}}	{{bibcode}}	{{biorxiv}}		{{citeseerx}}	{{doi}}&lt;br /&gt;
	{{hdl}}		{{isbn}}	{{ismn}}	{{issn}}		{{jfm}}			{{jstor}}&lt;br /&gt;
	{{medrxiv}}	{{mr}}		{{oclc}}	{{ol}}			{{osti}}		{{pmc}}&lt;br /&gt;
	{{pmid}}	{{sbn}}		{{ssrn}}	{{s2cid}}		{{zbl}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;args_t&amp;gt; is a table of all parameters needed to properly render the identifier&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function _main (args_t)&lt;br /&gt;
	local ID_list_t = {};														-- sequence table of rendered identifiers&lt;br /&gt;
	local ID_list_coins_t = {};													-- table of identifiers and their values from args; key is same as cfg.id_handlers&amp;#039;s key; COinS not supported in this module&lt;br /&gt;
	local template_name = args_t._template;&lt;br /&gt;
	local message_prefix;&lt;br /&gt;
&lt;br /&gt;
	if not (template_name and cfg.id_handlers[template_name:upper()]) then&lt;br /&gt;
		error (&amp;#039;|_template= requires valid value&amp;#039;);								-- a message for template writers; not seen by users&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	template_name = template_name:lower();										-- force lower case&lt;br /&gt;
	message_prefix = substitute (&amp;#039;&amp;lt;code class=&amp;quot;cs1-code&amp;quot;&amp;gt;&amp;amp;#x7B;{[[Template:$1|$1]]}}&amp;lt;/code&amp;gt;&amp;#039;, template_name);&lt;br /&gt;
&lt;br /&gt;
	local rendered_id;															-- a single rendered id worked on here&lt;br /&gt;
	local rendered_ids_t = {};													-- individual rendered ids go here&lt;br /&gt;
	&lt;br /&gt;
	local i = 1;																-- initialize the indexer for the repeat loop&lt;br /&gt;
	repeat																		-- loop until no &lt;br /&gt;
		local params_t = params_get (args_t, i);								-- get the parameters associated with enumerator &amp;lt;i&amp;gt;&lt;br /&gt;
		params_t[template_name] = params_t[1] or params_t[&amp;#039;id&amp;#039;];				-- assign value from {{{1}}} or |id= to |&amp;lt;identifier&amp;gt;=&lt;br /&gt;
		params_t._template = nil;												-- unset as no longer needed&lt;br /&gt;
		if not params_t[template_name] then										-- in case params_t[1] and params_t.id are nil&lt;br /&gt;
			params_t[template_name] = &amp;#039;&amp;#039;;										-- set &amp;lt;id&amp;gt; to empty string&lt;br /&gt;
			return render_final (												-- make an error message and done&lt;br /&gt;
				substitute (&amp;#039;&amp;lt;span class=&amp;quot;cs1-visible-error citation-comment&amp;quot;&amp;gt;$1: required identifier missing ($2)&amp;lt;/span&amp;gt;$3&amp;#039;, {&lt;br /&gt;
					message_prefix,&lt;br /&gt;
					substitute (&amp;#039;[[Template:$1|help]]&amp;#039;, template_name),&lt;br /&gt;
					no_cat and &amp;#039;&amp;#039; or substitute (&amp;#039;[[Category:Pages with $1 errors]]&amp;#039;, template_name:upper())&lt;br /&gt;
					}));&lt;br /&gt;
		end&lt;br /&gt;
		params_t[i] = nil;														-- unset these as no longer needed&lt;br /&gt;
		params_t.id = nil;&lt;br /&gt;
&lt;br /&gt;
		local DoiBroken = params_t[&amp;#039;doi-broken-date&amp;#039;];							-- {{doi}} only&lt;br /&gt;
		local Embargo = params_t[&amp;#039;pmc-embargo-date&amp;#039;];							-- {{pmc}} only&lt;br /&gt;
		local Class = params_t[&amp;#039;class&amp;#039;];										-- {{arxiv}} only&lt;br /&gt;
		local AsinTLD = params_t[&amp;#039;asin-tld&amp;#039;];									-- {{asin}} only&lt;br /&gt;
&lt;br /&gt;
		ID_list_t, ID_list_coins_t = identifiers.identifier_lists_get (params_t, {DoiBroken = DoiBroken, Embargo = Embargo, Class = Class, ASINTLD = AsinTLD}, {});	-- {} is a placeholder for unused ID_support{}&lt;br /&gt;
		rendered_id = ID_list_t[1];&lt;br /&gt;
&lt;br /&gt;
		if utilities.z.error_msgs_t[1] then										-- only one error message considered&lt;br /&gt;
			rendered_id = substitute (&amp;#039;$1 $2&amp;#039;, {&lt;br /&gt;
				rendered_id,&lt;br /&gt;
				err_message_convert (message_prefix, utilities.z.error_msgs_t[1], template_name, no_cat),&lt;br /&gt;
				});&lt;br /&gt;
			&lt;br /&gt;
		elseif utilities.z.maint_cats_t[1] then									-- only one maint message considered per rendering&lt;br /&gt;
			rendered_id = substitute (&amp;#039;$1 $2&amp;#039;, {&lt;br /&gt;
				rendered_id,&lt;br /&gt;
				maint_message_convert (message_prefix, utilities.z.maint_cats_t[1], template_name, no_cat),&lt;br /&gt;
				});&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		utilities.z.error_msgs_t = {};											-- reset these&lt;br /&gt;
		utilities.z.maint_cats_t = {};&lt;br /&gt;
		&lt;br /&gt;
		if (1 ~= i) or ((1 == i) and (&amp;#039;yes&amp;#039; == args_t.plainlink)) then			-- no label for 2nd... identifiers; when |plainlink=yes then no label for first identifier; &lt;br /&gt;
			local separator = cfg.id_handlers[template_name:upper()].separator;	-- get the identifier label separator&lt;br /&gt;
			rendered_id = rendered_id:gsub (&amp;#039;^%[%[.-|.-%]%]&amp;#039;, &amp;#039;&amp;#039;);				-- strip cs1-supplied label&lt;br /&gt;
			rendered_id = rendered_id:gsub (&amp;#039;^&amp;#039; .. separator, &amp;#039;&amp;#039;);				-- and strip the label separator&lt;br /&gt;
		elseif 1 == i then														-- here for first identifier; |plainlink= not set&lt;br /&gt;
			if &amp;#039;no&amp;#039; == args_t.link then											-- |link=no then do not link identifier label&lt;br /&gt;
				rendered_id = rendered_id:gsub (&amp;#039;^%[%[.-|(.-)%]%]&amp;#039;, &amp;#039;%1&amp;#039;);		-- strip wikilink markup from cs1-supplied label&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		table.insert (rendered_ids_t, rendered_id);								-- save the rendered identifier&lt;br /&gt;
		&lt;br /&gt;
		i = i + 1;																-- bump the indexer&lt;br /&gt;
		until not (args_t[i] or args_t[&amp;#039;id&amp;#039; .. i]);								-- end of repeat loop&lt;br /&gt;
&lt;br /&gt;
	local list_separator = &amp;#039;, &amp;#039;;												-- identifier separator for a list of identifiers&lt;br /&gt;
	local leadout = args_t.leadout and mw.ustring.gsub (args_t.leadout, &amp;#039;^(%a.*)&amp;#039;, &amp;#039; %1 &amp;#039;) or nil;	-- insert leading space if first character is a letter; add trailing space&lt;br /&gt;
&lt;br /&gt;
	if leadout then																-- extra text goes between last two identifiers in the list&lt;br /&gt;
		return render_final (mw.text.listToText (rendered_ids_t, list_separator, leadout));	-- make a list, add templatestyles, and done&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return render_final (table.concat (rendered_ids_t, list_separator));		-- make a list, add templatestyles, and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; M A I N &amp;gt;----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
entry point from an invoke&lt;br /&gt;
&lt;br /&gt;
	{{#invoke:CS1 identifiers|main|_template=&amp;lt;identifier name&amp;gt;}}&lt;br /&gt;
	&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function main (frame)&lt;br /&gt;
	Frame = frame;																-- make a copy for rendering final output&lt;br /&gt;
	local args_t = get_args (frame);											-- extract the arguments&lt;br /&gt;
&lt;br /&gt;
	return _main (args_t);														-- render the identifier and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E X P O R T S &amp;gt;----------------------------------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	main = main,																-- entry point from an invoke (in a template usually)&lt;br /&gt;
	&lt;br /&gt;
	_main = _main																-- entry point when called from another module&lt;br /&gt;
	}&lt;/div&gt;</summary>
		<author><name>imported&gt;Trappist the monk</name></author>
	</entry>
</feed>