<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.americanmusicclub.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ACitation%2FCS1%2FUtilities</id>
	<title>Module:Citation/CS1/Utilities - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.americanmusicclub.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ACitation%2FCS1%2FUtilities"/>
	<link rel="alternate" type="text/html" href="https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;action=history"/>
	<updated>2026-04-04T14:47:59Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;diff=28107&amp;oldid=prev</id>
		<title>Amc-admin: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;diff=28107&amp;oldid=prev"/>
		<updated>2017-12-19T23:01:37Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local u = {}&lt;br /&gt;
&lt;br /&gt;
local z = {&lt;br /&gt;
	error_categories = {};														-- for categorizing citations that contain errors&lt;br /&gt;
	error_ids = {};&lt;br /&gt;
	message_tail = {};&lt;br /&gt;
	maintenance_cats = {};														-- for categorizing citations that aren&amp;#039;t erroneous per se, but could use a little work&lt;br /&gt;
	properties_cats = {};														-- for categorizing citations based on certain properties, language of source for instance&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; F O R W A R D   D E C L A R A T I O N S &amp;gt;--------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local cfg;																		-- table of tables imported from selected Module:Citation/CS1/Configuration&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ S E T &amp;gt;------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Returns true if argument is set; false otherwise. Argument is &amp;#039;set&amp;#039; when it exists (not nil) or when it is not an empty string.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_set( var )&lt;br /&gt;
	return not (var == nil or var == &amp;#039;&amp;#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I N _ A R R A Y &amp;gt;--------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Whether needle is in haystack&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function in_array( needle, haystack )&lt;br /&gt;
	if needle == nil then&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	for n,v in ipairs( haystack ) do&lt;br /&gt;
		if v == needle then&lt;br /&gt;
			return n;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S U B S T I T U T E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Populates numbered arguments in a message string using an argument table.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function substitute( msg, args )&lt;br /&gt;
	return args and mw.message.newRawMessage( msg, args ):plain() or msg;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E R R O R _ C O M M E N T &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Wraps error messages with css markup according to the state of hidden.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function error_comment( content, hidden )&lt;br /&gt;
	return substitute( hidden and cfg.presentation[&amp;#039;hidden-error&amp;#039;] or cfg.presentation[&amp;#039;visible-error&amp;#039;], content );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; M A K E _ W I K I L I N K &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Makes a wikilink; when bot link and display text is provided, returns a wikilink in the form [[L|D]]; if only&lt;br /&gt;
link is provided, returns a wikilink in the form [[L]]; if neither are provided or link is omitted, returns an&lt;br /&gt;
empty string.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function make_wikilink (link, display)&lt;br /&gt;
	if is_set (link) then&lt;br /&gt;
		if is_set (display) then&lt;br /&gt;
			return table.concat ({&amp;#039;[[&amp;#039;, link, &amp;#039;|&amp;#039;, display, &amp;#039;]]&amp;#039;});&lt;br /&gt;
		else&lt;br /&gt;
			return table.concat ({&amp;#039;[[&amp;#039;, link, &amp;#039;]]&amp;#039;});&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;#039;&amp;#039;;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E T _ E R R O R &amp;gt;--------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Sets an error condition and returns the appropriate error message.  The actual placement of the error message in the output is&lt;br /&gt;
the responsibility of the calling function.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function set_error( error_id, arguments, raw, prefix, suffix )&lt;br /&gt;
	local error_state = cfg.error_conditions[ error_id ];&lt;br /&gt;
	&lt;br /&gt;
	prefix = prefix or &amp;quot;&amp;quot;;&lt;br /&gt;
	suffix = suffix or &amp;quot;&amp;quot;;&lt;br /&gt;
	&lt;br /&gt;
	if error_state == nil then&lt;br /&gt;
		error( cfg.messages[&amp;#039;undefined_error&amp;#039;] );								-- because missing error handler in Module:Citation/CS1/Configuration&lt;br /&gt;
	elseif is_set( error_state.category ) then&lt;br /&gt;
		table.insert( z.error_categories, error_state.category );&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local message = substitute( error_state.message, arguments );&lt;br /&gt;
&lt;br /&gt;
	message = table.concat (&lt;br /&gt;
		{&lt;br /&gt;
		message,&lt;br /&gt;
		&amp;#039; (&amp;#039;,&lt;br /&gt;
		make_wikilink (&lt;br /&gt;
			table.concat (&lt;br /&gt;
				{&lt;br /&gt;
				cfg.messages[&amp;#039;help page link&amp;#039;],&lt;br /&gt;
				&amp;#039;#&amp;#039;,&lt;br /&gt;
				error_state.anchor&lt;br /&gt;
				}),&lt;br /&gt;
			cfg.messages[&amp;#039;help page label&amp;#039;]),&lt;br /&gt;
		&amp;#039;)&amp;#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
--	message = table.concat ({message, &amp;#039; (&amp;#039;, substitute (cfg.presentation[&amp;#039;wikilink&amp;#039;], &lt;br /&gt;
--		{cfg.messages[&amp;#039;help page link&amp;#039;] .. &amp;#039;#&amp;#039; .. error_state.anchor, cfg.messages[&amp;#039;help page label&amp;#039;]}), &amp;#039;)&amp;#039;});&lt;br /&gt;
--	message = message .. &amp;quot; ([[&amp;quot; .. cfg.messages[&amp;#039;help page link&amp;#039;] .. &lt;br /&gt;
--		&amp;quot;#&amp;quot; .. error_state.anchor .. &amp;quot;|&amp;quot; ..&lt;br /&gt;
--		cfg.messages[&amp;#039;help page label&amp;#039;] .. &amp;quot;]])&amp;quot;;&lt;br /&gt;
	&lt;br /&gt;
	z.error_ids[ error_id ] = true;&lt;br /&gt;
	if in_array( error_id, { &amp;#039;bare_url_missing_title&amp;#039;, &amp;#039;trans_missing_title&amp;#039; } )&lt;br /&gt;
			and z.error_ids[&amp;#039;citation_missing_title&amp;#039;] then&lt;br /&gt;
		return &amp;#039;&amp;#039;, false;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	message = table.concat({ prefix, message, suffix });&lt;br /&gt;
	&lt;br /&gt;
	if raw == true then&lt;br /&gt;
		return message, error_state.hidden;&lt;br /&gt;
	end		&lt;br /&gt;
		&lt;br /&gt;
	return error_comment( message, error_state.hidden );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[-------------------------&amp;lt; I S _ A L I A S _ U S E D &amp;gt;-----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This function is used by select_one() to determine if one of a list of alias parameters is in the argument list&lt;br /&gt;
provided by the template.&lt;br /&gt;
&lt;br /&gt;
Input:&lt;br /&gt;
	args – pointer to the arguments table from calling template&lt;br /&gt;
	alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration&lt;br /&gt;
	index – for enumerated parameters, identifies which one&lt;br /&gt;
	enumerated – true/false flag used choose how enumerated aliases are examined&lt;br /&gt;
	value – value associated with an alias that has previously been selected; nil if not yet selected&lt;br /&gt;
	selected – the alias that has previously been selected; nil if not yet selected&lt;br /&gt;
	error_list – list of aliases that are duplicates of the alias already selected&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
	value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected&lt;br /&gt;
	selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_alias_used (args, alias, index, enumerated, value, selected, error_list)&lt;br /&gt;
	if enumerated then															-- is this a test for an enumerated parameters?&lt;br /&gt;
		alias = alias:gsub (&amp;#039;#&amp;#039;, index);										-- replace &amp;#039;#&amp;#039; with the value in index&lt;br /&gt;
	else&lt;br /&gt;
		alias = alias:gsub (&amp;#039;#&amp;#039;, &amp;#039;&amp;#039;);											-- remove &amp;#039;#&amp;#039; if it exists&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if is_set(args[alias]) then													-- alias is in the template&amp;#039;s argument list&lt;br /&gt;
		if value ~= nil and selected ~= alias then								-- if we have already selected one of the aliases&lt;br /&gt;
			local skip;&lt;br /&gt;
			for _, v in ipairs(error_list) do									-- spin through the error list to see if we&amp;#039;ve added this alias&lt;br /&gt;
				if v == alias then&lt;br /&gt;
					skip = true;&lt;br /&gt;
					break;														-- has been added so stop looking &lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if not skip then													-- has not been added so&lt;br /&gt;
				table.insert( error_list, alias );								-- add error alias to the error list&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			value = args[alias];												-- not yet selected an alias, so select this one&lt;br /&gt;
			selected = alias;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return value, selected;														-- return newly selected alias, or previously selected alias&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; A D D _ M A I N T _ C A T &amp;gt;------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Adds a category to z.maintenance_cats using names from the configuration file with additional text if any.&lt;br /&gt;
To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maintenance_cats.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local added_maint_cats = {}														-- list of maintenance categories that have been added to z.maintenance_cats&lt;br /&gt;
local function add_maint_cat (key, arguments)&lt;br /&gt;
	if not added_maint_cats [key] then&lt;br /&gt;
		added_maint_cats [key] = true;											-- note that we&amp;#039;ve added this category&lt;br /&gt;
		table.insert( z.maintenance_cats, substitute (cfg.maint_cats [key], arguments));	-- make name then add to table&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S A F E _ F O R _ I T A L I C S &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Protects a string that will be wrapped in wiki italic markup &amp;#039;&amp;#039; ... &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Note: We cannot use &amp;lt;i&amp;gt; for italics, as the expected behavior for italics specified by &amp;#039;&amp;#039;...&amp;#039;&amp;#039; in the title is that&lt;br /&gt;
they will be inverted (i.e. unitalicized) in the resulting references.  In addition, &amp;lt;i&amp;gt; and &amp;#039;&amp;#039; tend to interact&lt;br /&gt;
poorly under Mediawiki&amp;#039;s HTML tidy.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function safe_for_italics( str )&lt;br /&gt;
	if not is_set(str) then&lt;br /&gt;
		return str;&lt;br /&gt;
	else&lt;br /&gt;
		if str:sub(1,1) == &amp;quot;&amp;#039;&amp;quot; then str = &amp;quot;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;quot; .. str; end&lt;br /&gt;
		if str:sub(-1,-1) == &amp;quot;&amp;#039;&amp;quot; then str = str .. &amp;quot;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;quot;; end&lt;br /&gt;
		&lt;br /&gt;
		-- Remove newlines as they break italics.&lt;br /&gt;
		return str:gsub( &amp;#039;\n&amp;#039;, &amp;#039; &amp;#039; );&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; W R A P _ S T Y L E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Applies styling to various parameters.  Supplied string is wrapped using a message_list configuration taking one&lt;br /&gt;
argument; protects italic styled parameters.  Additional text taken from citation_config.presentation - the reason&lt;br /&gt;
this function is similar to but separate from wrap_msg().&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function wrap_style (key, str)&lt;br /&gt;
	if not is_set( str ) then&lt;br /&gt;
		return &amp;quot;&amp;quot;;&lt;br /&gt;
	elseif in_array( key, { &amp;#039;italic-title&amp;#039;, &amp;#039;trans-italic-title&amp;#039; } ) then&lt;br /&gt;
		str = safe_for_italics( str );&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return substitute( cfg.presentation[key], {str} );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E L E C T _ O N E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Chooses one matching parameter from a list of parameters to consider.  The list of parameters to consider is just&lt;br /&gt;
names.  For parameters that may be enumerated, the position of the numerator in the parameter name is identified&lt;br /&gt;
by the &amp;#039;#&amp;#039; so |author-last1= and |author1-last= are represented as &amp;#039;author-last#&amp;#039; and &amp;#039;author#-last&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Because enumerated parameter |&amp;lt;param&amp;gt;1= is an alias of |&amp;lt;param&amp;gt;= we must test for both possibilities.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generates an error if more than one match is present.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function select_one( args, aliases_list, error_condition, index )&lt;br /&gt;
	local value = nil;															-- the value assigned to the selected parameter&lt;br /&gt;
	local selected = &amp;#039;&amp;#039;;														-- the name of the parameter we have chosen&lt;br /&gt;
	local error_list = {};&lt;br /&gt;
&lt;br /&gt;
	if index ~= nil then index = tostring(index); end&lt;br /&gt;
&lt;br /&gt;
	for _, alias in ipairs( aliases_list ) do									-- for each alias in the aliases list&lt;br /&gt;
		if alias:match (&amp;#039;#&amp;#039;) then												-- if this alias can be enumerated&lt;br /&gt;
			if &amp;#039;1&amp;#039; == index then												-- when index is 1 test for enumerated and non-enumerated aliases&lt;br /&gt;
				value, selected = is_alias_used (args, alias, index, false, value, selected, error_list);	-- first test for non-enumerated alias&lt;br /&gt;
			end&lt;br /&gt;
			value, selected = is_alias_used (args, alias, index, true, value, selected, error_list);		-- test for enumerated alias&lt;br /&gt;
		else&lt;br /&gt;
			value, selected = is_alias_used (args, alias, index, false, value, selected, error_list);		--test for non-enumerated alias&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if #error_list &amp;gt; 0 and &amp;#039;none&amp;#039; ~= error_condition then						-- for cases where this code is used outside of extract_names()&lt;br /&gt;
		local error_str = &amp;quot;&amp;quot;;&lt;br /&gt;
		for _, k in ipairs( error_list ) do&lt;br /&gt;
			if error_str ~= &amp;quot;&amp;quot; then error_str = error_str .. cfg.messages[&amp;#039;parameter-separator&amp;#039;] end&lt;br /&gt;
			error_str = error_str .. wrap_style (&amp;#039;parameter&amp;#039;, k);&lt;br /&gt;
		end&lt;br /&gt;
		if #error_list &amp;gt; 1 then&lt;br /&gt;
			error_str = error_str .. cfg.messages[&amp;#039;parameter-final-separator&amp;#039;];&lt;br /&gt;
		else&lt;br /&gt;
			error_str = error_str .. cfg.messages[&amp;#039;parameter-pair-separator&amp;#039;];&lt;br /&gt;
		end&lt;br /&gt;
		error_str = error_str .. wrap_style (&amp;#039;parameter&amp;#039;, selected);&lt;br /&gt;
		table.insert( z.message_tail, { set_error( error_condition, {error_str}, true ) } );&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return value, selected;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; R E M O V E _ W I K I _ L I N K &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Gets the display text from a wikilink like [[A|B]] or [[B]] gives B&lt;br /&gt;
&lt;br /&gt;
The str:gsub() returns either A|B froma [[A|B]] or B from [[B]] or B from B (no wikilink markup).&lt;br /&gt;
&lt;br /&gt;
In l(), l:gsub() removes the link and pipe (if they exist); the second :gsub() trims white space from the label&lt;br /&gt;
if str was wrapped in wikilink markup.  Presumably, this is because without wikimarkup in str, there is no match&lt;br /&gt;
in the initial gsub, the replacement function l() doesn&amp;#039;t get called.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function remove_wiki_link (str)&lt;br /&gt;
	return (str:gsub( &amp;quot;%[%[([^%[%]]*)%]%]&amp;quot;, function(l)&lt;br /&gt;
		return l:gsub( &amp;quot;^[^|]*|(.*)$&amp;quot;, &amp;quot;%1&amp;quot; ):gsub(&amp;quot;^%s*(.-)%s*$&amp;quot;, &amp;quot;%1&amp;quot;);&lt;br /&gt;
	end));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; I S _ W I K I L I N K &amp;gt;--------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Determines if str is a wikilink, extracts, and returns the the wikilink type, link text, and display text parts.&lt;br /&gt;
If str is a complex wikilink ([[L|D]]):&lt;br /&gt;
	returns wl_type 2 and D and L from [[L|D]];&lt;br /&gt;
if str is a simple wikilink ([[D]])&lt;br /&gt;
	returns wl_type 1 and D from [[D]] and L as empty string;&lt;br /&gt;
if not a wikilink:&lt;br /&gt;
	returns wl_type 0, str as D, and L as empty string.&lt;br /&gt;
&lt;br /&gt;
trims leading and trailing white space and pipes from L and D ([[L|]] and [[|D]] are accepted by MediaWiki and&lt;br /&gt;
treated like [[D]]; while [[|D|]] is not accepted by MediaWiki, here, we accept it and return D without the pipes).&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function is_wikilink (str)&lt;br /&gt;
	local D, L&lt;br /&gt;
	local wl_type = 2;															-- assume that str is a complex wikilink [[L|D]]&lt;br /&gt;
&lt;br /&gt;
	L, D = str:match (&amp;#039;%[%[([^|]+)|([^%]]+)%]%]&amp;#039;);								-- get L and D from [[L|D]] &lt;br /&gt;
&lt;br /&gt;
	if not is_set (D) then														-- if no separate link&lt;br /&gt;
		D = str:match (&amp;#039;%[%[([^%]]*)|*%]%]&amp;#039;);									-- get D from [[D]]&lt;br /&gt;
		wl_type = 1; &lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if not is_set (D) then														-- no wikilink markup&lt;br /&gt;
		D = str;																-- return the string as D&lt;br /&gt;
		wl_type = 0;															-- but say that it is not a wikilink&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	D = mw.text.trim (D, &amp;#039;%s|&amp;#039;);												-- trim white space and pipe characters &lt;br /&gt;
	L = L and mw.text.trim (L, &amp;#039;%s|&amp;#039;);&lt;br /&gt;
	&lt;br /&gt;
	return wl_type, D, L or &amp;#039;&amp;#039;;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E T _ S E L E C T E D _ M O D U L E S &amp;gt;--------------------------------------&lt;br /&gt;
&lt;br /&gt;
Sets local cfg table to same (live or sandbox) as that used by the other modules.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function set_selected_modules (cfg_table_ptr)&lt;br /&gt;
	cfg = cfg_table_ptr;&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return {																		-- return exported functions and tables&lt;br /&gt;
	is_set = is_set,&lt;br /&gt;
	in_array = in_array,&lt;br /&gt;
	substitute = substitute,&lt;br /&gt;
	error_comment = error_comment,&lt;br /&gt;
	set_error = set_error,&lt;br /&gt;
	select_one = select_one,&lt;br /&gt;
	add_maint_cat = add_maint_cat,&lt;br /&gt;
	wrap_style = wrap_style,&lt;br /&gt;
	safe_for_italics = safe_for_italics,&lt;br /&gt;
	remove_wiki_link = remove_wiki_link,&lt;br /&gt;
	is_wikilink = is_wikilink,&lt;br /&gt;
	make_wikilink = make_wikilink,&lt;br /&gt;
	set_selected_modules = set_selected_modules,&lt;br /&gt;
	z = z,&lt;br /&gt;
	}&lt;/div&gt;</summary>
		<author><name>Amc-admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;diff=8885&amp;oldid=prev</id>
		<title>Amc-admin: 18 revisions imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;diff=8885&amp;oldid=prev"/>
		<updated>2016-11-19T04:30:07Z</updated>

		<summary type="html">&lt;p&gt;18 revisions 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 04:30, 19 November 2016&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>Amc-admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;diff=5309&amp;oldid=prev</id>
		<title>Amc-admin: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.americanmusicclub.com/index.php?title=Module:Citation/CS1/Utilities&amp;diff=5309&amp;oldid=prev"/>
		<updated>2016-11-19T00:53:35Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local u = {}&lt;br /&gt;
&lt;br /&gt;
local z = {&lt;br /&gt;
	error_categories = {};														-- for categorizing citations that contain errors&lt;br /&gt;
	error_ids = {};&lt;br /&gt;
	message_tail = {};&lt;br /&gt;
	maintenance_cats = {};														-- for categorizing citations that aren&amp;#039;t erroneous per se, but could use a little work&lt;br /&gt;
	properties_cats = {};														-- for categorizing citations based on certain properties, language of source for instance&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; F O R W A R D   D E C L A R A T I O N S &amp;gt;--------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local cfg;																		-- table of tables imported from slected Module:Citation/CS1/Configuration&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ S E T &amp;gt;------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Returns true if argument is set; false otherwise. Argument is &amp;#039;set&amp;#039; when it exists (not nil) or when it is not an empty string.&lt;br /&gt;
This function is global because it is called from both this module and from Date validation&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
local function is_set( var )&lt;br /&gt;
	return not (var == nil or var == &amp;#039;&amp;#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I N _ A R R A Y &amp;gt;--------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Whether needle is in haystack&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function in_array( needle, haystack )&lt;br /&gt;
	if needle == nil then&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	for n,v in ipairs( haystack ) do&lt;br /&gt;
		if v == needle then&lt;br /&gt;
			return n;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S U B S T I T U T E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Populates numbered arguments in a message string using an argument table.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function substitute( msg, args )&lt;br /&gt;
	return args and mw.message.newRawMessage( msg, args ):plain() or msg;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E R R O R _ C O M M E N T &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Wraps error messages with css markup according to the state of hidden.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
local function error_comment( content, hidden )&lt;br /&gt;
	return substitute( hidden and cfg.presentation[&amp;#039;hidden-error&amp;#039;] or cfg.presentation[&amp;#039;visible-error&amp;#039;], content );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E T _ E R R O R &amp;gt;--------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Sets an error condition and returns the appropriate error message.  The actual placement of the error message in the output is&lt;br /&gt;
the responsibility of the calling function.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
local function set_error( error_id, arguments, raw, prefix, suffix )&lt;br /&gt;
	local error_state = cfg.error_conditions[ error_id ];&lt;br /&gt;
	&lt;br /&gt;
	prefix = prefix or &amp;quot;&amp;quot;;&lt;br /&gt;
	suffix = suffix or &amp;quot;&amp;quot;;&lt;br /&gt;
	&lt;br /&gt;
	if error_state == nil then&lt;br /&gt;
		error( cfg.messages[&amp;#039;undefined_error&amp;#039;] );&lt;br /&gt;
	elseif is_set( error_state.category ) then&lt;br /&gt;
		table.insert( z.error_categories, error_state.category );&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local message = substitute( error_state.message, arguments );&lt;br /&gt;
	&lt;br /&gt;
	message = message .. &amp;quot; ([[&amp;quot; .. cfg.messages[&amp;#039;help page link&amp;#039;] .. &lt;br /&gt;
		&amp;quot;#&amp;quot; .. error_state.anchor .. &amp;quot;|&amp;quot; ..&lt;br /&gt;
		cfg.messages[&amp;#039;help page label&amp;#039;] .. &amp;quot;]])&amp;quot;;&lt;br /&gt;
	&lt;br /&gt;
	z.error_ids[ error_id ] = true;&lt;br /&gt;
	if in_array( error_id, { &amp;#039;bare_url_missing_title&amp;#039;, &amp;#039;trans_missing_title&amp;#039; } )&lt;br /&gt;
			and z.error_ids[&amp;#039;citation_missing_title&amp;#039;] then&lt;br /&gt;
		return &amp;#039;&amp;#039;, false;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	message = table.concat({ prefix, message, suffix });&lt;br /&gt;
	&lt;br /&gt;
	if raw == true then&lt;br /&gt;
		return message, error_state.hidden;&lt;br /&gt;
	end		&lt;br /&gt;
		&lt;br /&gt;
	return error_comment( message, error_state.hidden );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[-------------------------&amp;lt; I S _ A L I A S _ U S E D &amp;gt;-----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This function is used by select_one() to determine if one of a list of alias parameters is in the argument list&lt;br /&gt;
provided by the template.&lt;br /&gt;
&lt;br /&gt;
Input:&lt;br /&gt;
	args – pointer to the arguments table from calling template&lt;br /&gt;
	alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration&lt;br /&gt;
	index – for enumerated parameters, identifies which one&lt;br /&gt;
	enumerated – true/false flag used choose how enumerated aliases are examined&lt;br /&gt;
	value – value associated with an alias that has previously been selected; nil if not yet selected&lt;br /&gt;
	selected – the alias that has previously been selected; nil if not yet selected&lt;br /&gt;
	error_list – list of aliases that are duplicates of the alias already selected&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
	value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected&lt;br /&gt;
	selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_alias_used (args, alias, index, enumerated, value, selected, error_list)&lt;br /&gt;
	if enumerated then															-- is this a test for an enumerated parameters?&lt;br /&gt;
		alias = alias:gsub (&amp;#039;#&amp;#039;, index);										-- replace &amp;#039;#&amp;#039; with the value in index&lt;br /&gt;
	else&lt;br /&gt;
		alias = alias:gsub (&amp;#039;#&amp;#039;, &amp;#039;&amp;#039;);											-- remove &amp;#039;#&amp;#039; if it exists&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if is_set(args[alias]) then													-- alias is in the template&amp;#039;s argument list&lt;br /&gt;
		if value ~= nil and selected ~= alias then								-- if we have already selected one of the aliases&lt;br /&gt;
			local skip;&lt;br /&gt;
			for _, v in ipairs(error_list) do									-- spin through the error list to see if we&amp;#039;ve added this alias&lt;br /&gt;
				if v == alias then&lt;br /&gt;
					skip = true;&lt;br /&gt;
					break;														-- has been added so stop looking &lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if not skip then													-- has not been added so&lt;br /&gt;
				table.insert( error_list, alias );								-- add error alias to the error list&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			value = args[alias];												-- not yet selected an alias, so select this one&lt;br /&gt;
			selected = alias;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return value, selected;														-- return newly selected alias, or previously selected alias&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; A D D _ M A I N T _ C A T &amp;gt;------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Adds a category to z.maintenance_cats using names from the configuration file with additional text if any.&lt;br /&gt;
To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maintenance_cats.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local added_maint_cats = {}														-- list of maintenance categories that have been added to z.maintenance_cats&lt;br /&gt;
local function add_maint_cat (key, arguments)&lt;br /&gt;
	if not added_maint_cats [key] then&lt;br /&gt;
		added_maint_cats [key] = true;											-- note that we&amp;#039;ve added this category&lt;br /&gt;
		table.insert( z.maintenance_cats, substitute (cfg.maint_cats [key], arguments));	-- make name then add to table&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S A F E _ F O R _ I T A L I C S &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Protects a string that will be wrapped in wiki italic markup &amp;#039;&amp;#039; ... &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Note: We cannot use &amp;lt;i&amp;gt; for italics, as the expected behavior for italics specified by &amp;#039;&amp;#039;...&amp;#039;&amp;#039; in the title is that&lt;br /&gt;
they will be inverted (i.e. unitalicized) in the resulting references.  In addition, &amp;lt;i&amp;gt; and &amp;#039;&amp;#039; tend to interact&lt;br /&gt;
poorly under Mediawiki&amp;#039;s HTML tidy.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function safe_for_italics( str )&lt;br /&gt;
	if not is_set(str) then&lt;br /&gt;
		return str;&lt;br /&gt;
	else&lt;br /&gt;
		if str:sub(1,1) == &amp;quot;&amp;#039;&amp;quot; then str = &amp;quot;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;quot; .. str; end&lt;br /&gt;
		if str:sub(-1,-1) == &amp;quot;&amp;#039;&amp;quot; then str = str .. &amp;quot;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;quot;; end&lt;br /&gt;
		&lt;br /&gt;
		-- Remove newlines as they break italics.&lt;br /&gt;
		return str:gsub( &amp;#039;\n&amp;#039;, &amp;#039; &amp;#039; );&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; W R A P _ S T Y L E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Applies styling to various parameters.  Supplied string is wrapped using a message_list configuration taking one&lt;br /&gt;
argument; protects italic styled parameters.  Additional text taken from citation_config.presentation - the reason&lt;br /&gt;
this function is similar to but separate from wrap_msg().&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function wrap_style (key, str)&lt;br /&gt;
	if not is_set( str ) then&lt;br /&gt;
		return &amp;quot;&amp;quot;;&lt;br /&gt;
	elseif in_array( key, { &amp;#039;italic-title&amp;#039;, &amp;#039;trans-italic-title&amp;#039; } ) then&lt;br /&gt;
		str = safe_for_italics( str );&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return substitute( cfg.presentation[key], {str} );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E L E C T _ O N E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Chooses one matching parameter from a list of parameters to consider.  The list of parameters to consider is just&lt;br /&gt;
names.  For parameters that may be enumerated, the position of the numerator in the parameter name is identified&lt;br /&gt;
by the &amp;#039;#&amp;#039; so |author-last1= and |author1-last= are represented as &amp;#039;author-last#&amp;#039; and &amp;#039;author#-last&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Because enumerated parameter |&amp;lt;param&amp;gt;1= is an alias of |&amp;lt;param&amp;gt;= we must test for both possibilities.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generates an error if more than one match is present.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function select_one( args, aliases_list, error_condition, index )&lt;br /&gt;
	local value = nil;															-- the value assigned to the selected parameter&lt;br /&gt;
	local selected = &amp;#039;&amp;#039;;														-- the name of the parameter we have chosen&lt;br /&gt;
	local error_list = {};&lt;br /&gt;
&lt;br /&gt;
	if index ~= nil then index = tostring(index); end&lt;br /&gt;
&lt;br /&gt;
	for _, alias in ipairs( aliases_list ) do									-- for each alias in the aliases list&lt;br /&gt;
		if alias:match (&amp;#039;#&amp;#039;) then												-- if this alias can be enumerated&lt;br /&gt;
			if &amp;#039;1&amp;#039; == index then												-- when index is 1 test for enumerated and non-enumerated aliases&lt;br /&gt;
				value, selected = is_alias_used (args, alias, index, false, value, selected, error_list);	-- first test for non-enumerated alias&lt;br /&gt;
			end&lt;br /&gt;
			value, selected = is_alias_used (args, alias, index, true, value, selected, error_list);		-- test for enumerated alias&lt;br /&gt;
		else&lt;br /&gt;
			value, selected = is_alias_used (args, alias, index, false, value, selected, error_list);		--test for non-enumerated alias&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if #error_list &amp;gt; 0 and &amp;#039;none&amp;#039; ~= error_condition then						-- for cases where this code is used outside of extract_names()&lt;br /&gt;
		local error_str = &amp;quot;&amp;quot;;&lt;br /&gt;
		for _, k in ipairs( error_list ) do&lt;br /&gt;
			if error_str ~= &amp;quot;&amp;quot; then error_str = error_str .. cfg.messages[&amp;#039;parameter-separator&amp;#039;] end&lt;br /&gt;
			error_str = error_str .. wrap_style (&amp;#039;parameter&amp;#039;, k);&lt;br /&gt;
		end&lt;br /&gt;
		if #error_list &amp;gt; 1 then&lt;br /&gt;
			error_str = error_str .. cfg.messages[&amp;#039;parameter-final-separator&amp;#039;];&lt;br /&gt;
		else&lt;br /&gt;
			error_str = error_str .. cfg.messages[&amp;#039;parameter-pair-separator&amp;#039;];&lt;br /&gt;
		end&lt;br /&gt;
		error_str = error_str .. wrap_style (&amp;#039;parameter&amp;#039;, selected);&lt;br /&gt;
		table.insert( z.message_tail, { set_error( error_condition, {error_str}, true ) } );&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return value, selected;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; R E M O V E _ W I K I _ L I N K &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Gets the display text from a wikilink like [[A|B]] or [[B]] gives B&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function remove_wiki_link (str)&lt;br /&gt;
	return (str:gsub( &amp;quot;%[%[([^%[%]]*)%]%]&amp;quot;, function(l)&lt;br /&gt;
		return l:gsub( &amp;quot;^[^|]*|(.*)$&amp;quot;, &amp;quot;%1&amp;quot; ):gsub(&amp;quot;^%s*(.-)%s*$&amp;quot;, &amp;quot;%1&amp;quot;);&lt;br /&gt;
	end));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S E T _ S E L E C T E D _ M O D U L E S &amp;gt;--------------------------------------&lt;br /&gt;
&lt;br /&gt;
Sets local cfg table to same (live or sandbox) as that used by the other modules.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function set_selected_modules (cfg_table_ptr)&lt;br /&gt;
	cfg = cfg_table_ptr;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return {																		-- return exported functions and tables&lt;br /&gt;
	is_set = is_set,&lt;br /&gt;
	in_array = in_array,&lt;br /&gt;
	substitute = substitute,&lt;br /&gt;
	error_comment = error_comment,&lt;br /&gt;
	set_error = set_error,&lt;br /&gt;
	select_one = select_one,&lt;br /&gt;
	add_maint_cat = add_maint_cat,&lt;br /&gt;
	wrap_style = wrap_style;&lt;br /&gt;
	safe_for_italics = safe_for_italics;&lt;br /&gt;
	remove_wiki_link = remove_wiki_link;&lt;br /&gt;
	set_selected_modules = set_selected_modules;&lt;br /&gt;
	z = z,&lt;br /&gt;
	}&lt;/div&gt;</summary>
		<author><name>Amc-admin</name></author>
	</entry>
</feed>