Module:Citation/CS1/Utilities

The educational technology and digital learning wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Citation/CS1/Utilities/doc

  1 local u = {}
  2 
  3 local z = {
  4 	error_categories = {};														-- for categorizing citations that contain errors
  5 	error_ids = {};
  6 	message_tail = {};
  7 	maintenance_cats = {};														-- for categorizing citations that aren't erroneous per se, but could use a little work
  8 	properties_cats = {};														-- for categorizing citations based on certain properties, language of source for instance
  9 };
 10 
 11 
 12 --[[--------------------------< F O R W A R D   D E C L A R A T I O N S >--------------------------------------
 13 ]]
 14 
 15 local cfg;																		-- table of tables imported from slected Module:Citation/CS1/Configuration
 16 
 17 
 18 --[[--------------------------< I S _ S E T >------------------------------------------------------------------
 19 
 20 Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.
 21 This function is global because it is called from both this module and from Date validation
 22 
 23 ]]
 24 local function is_set( var )
 25 	return not (var == nil or var == '');
 26 end
 27 
 28 
 29 --[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
 30 
 31 Whether needle is in haystack
 32 
 33 ]]
 34 
 35 local function in_array( needle, haystack )
 36 	if needle == nil then
 37 		return false;
 38 	end
 39 	for n,v in ipairs( haystack ) do
 40 		if v == needle then
 41 			return n;
 42 		end
 43 	end
 44 	return false;
 45 end
 46 
 47 
 48 --[[--------------------------< S U B S T I T U T E >----------------------------------------------------------
 49 
 50 Populates numbered arguments in a message string using an argument table.
 51 
 52 ]]
 53 
 54 local function substitute( msg, args )
 55 	return args and mw.message.newRawMessage( msg, args ):plain() or msg;
 56 end
 57 
 58 
 59 --[[--------------------------< E R R O R _ C O M M E N T >----------------------------------------------------
 60 
 61 Wraps error messages with css markup according to the state of hidden.
 62 
 63 ]]
 64 local function error_comment( content, hidden )
 65 	return substitute( hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content );
 66 end
 67 
 68 
 69 --[[--------------------------< S E T _ E R R O R >--------------------------------------------------------------
 70 
 71 Sets an error condition and returns the appropriate error message.  The actual placement of the error message in the output is
 72 the responsibility of the calling function.
 73 
 74 ]]
 75 local function set_error( error_id, arguments, raw, prefix, suffix )
 76 	local error_state = cfg.error_conditions[ error_id ];
 77 	
 78 	prefix = prefix or "";
 79 	suffix = suffix or "";
 80 	
 81 	if error_state == nil then
 82 		error( cfg.messages['undefined_error'] );
 83 	elseif is_set( error_state.category ) then
 84 		table.insert( z.error_categories, error_state.category );
 85 	end
 86 	
 87 	local message = substitute( error_state.message, arguments );
 88 	
 89 	message = message .. " ([[" .. cfg.messages['help page link'] .. 
 90 		"#" .. error_state.anchor .. "|" ..
 91 		cfg.messages['help page label'] .. "]])";
 92 	
 93 	z.error_ids[ error_id ] = true;
 94 	if in_array( error_id, { 'bare_url_missing_title', 'trans_missing_title' } )
 95 			and z.error_ids['citation_missing_title'] then
 96 		return '', false;
 97 	end
 98 	
 99 	message = table.concat({ prefix, message, suffix });
100 	
101 	if raw == true then
102 		return message, error_state.hidden;
103 	end		
104 		
105 	return error_comment( message, error_state.hidden );
106 end
107 
108 
109 --[[-------------------------< I S _ A L I A S _ U S E D >-----------------------------------------------------
110 
111 This function is used by select_one() to determine if one of a list of alias parameters is in the argument list
112 provided by the template.
113 
114 Input:
115 	args – pointer to the arguments table from calling template
116 	alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration
117 	index – for enumerated parameters, identifies which one
118 	enumerated – true/false flag used choose how enumerated aliases are examined
119 	value – value associated with an alias that has previously been selected; nil if not yet selected
120 	selected – the alias that has previously been selected; nil if not yet selected
121 	error_list – list of aliases that are duplicates of the alias already selected
122 
123 Returns:
124 	value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected
125 	selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected
126 
127 ]]
128 
129 local function is_alias_used (args, alias, index, enumerated, value, selected, error_list)
130 	if enumerated then															-- is this a test for an enumerated parameters?
131 		alias = alias:gsub ('#', index);										-- replace '#' with the value in index
132 	else
133 		alias = alias:gsub ('#', '');											-- remove '#' if it exists
134 	end
135 
136 	if is_set(args[alias]) then													-- alias is in the template's argument list
137 		if value ~= nil and selected ~= alias then								-- if we have already selected one of the aliases
138 			local skip;
139 			for _, v in ipairs(error_list) do									-- spin through the error list to see if we've added this alias
140 				if v == alias then
141 					skip = true;
142 					break;														-- has been added so stop looking 
143 				end
144 			end
145 			if not skip then													-- has not been added so
146 				table.insert( error_list, alias );								-- add error alias to the error list
147 			end
148 		else
149 			value = args[alias];												-- not yet selected an alias, so select this one
150 			selected = alias;
151 		end
152 	end
153 	return value, selected;														-- return newly selected alias, or previously selected alias
154 end
155 
156 
157 --[[--------------------------< A D D _ M A I N T _ C A T >------------------------------------------------------
158 
159 Adds a category to z.maintenance_cats using names from the configuration file with additional text if any.
160 To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maintenance_cats.
161 
162 ]]
163 
164 local added_maint_cats = {}														-- list of maintenance categories that have been added to z.maintenance_cats
165 local function add_maint_cat (key, arguments)
166 	if not added_maint_cats [key] then
167 		added_maint_cats [key] = true;											-- note that we've added this category
168 		table.insert( z.maintenance_cats, substitute (cfg.maint_cats [key], arguments));	-- make name then add to table
169 	end
170 end
171 
172 
173 --[[--------------------------< S A F E _ F O R _ I T A L I C S >----------------------------------------------
174 
175 Protects a string that will be wrapped in wiki italic markup '' ... ''
176 
177 Note: We cannot use <i> for italics, as the expected behavior for italics specified by ''...'' in the title is that
178 they will be inverted (i.e. unitalicized) in the resulting references.  In addition, <i> and '' tend to interact
179 poorly under Mediawiki's HTML tidy.
180 
181 ]]
182 
183 local function safe_for_italics( str )
184 	if not is_set(str) then
185 		return str;
186 	else
187 		if str:sub(1,1) == "'" then str = "<span />" .. str; end
188 		if str:sub(-1,-1) == "'" then str = str .. "<span />"; end
189 		
190 		-- Remove newlines as they break italics.
191 		return str:gsub( '\n', ' ' );
192 	end
193 end
194 
195 
196 --[[--------------------------< W R A P _ S T Y L E >----------------------------------------------------------
197 
198 Applies styling to various parameters.  Supplied string is wrapped using a message_list configuration taking one
199 argument; protects italic styled parameters.  Additional text taken from citation_config.presentation - the reason
200 this function is similar to but separate from wrap_msg().
201 
202 ]]
203 
204 local function wrap_style (key, str)
205 	if not is_set( str ) then
206 		return "";
207 	elseif in_array( key, { 'italic-title', 'trans-italic-title' } ) then
208 		str = safe_for_italics( str );
209 	end
210 
211 	return substitute( cfg.presentation[key], {str} );
212 end
213 
214 
215 --[[--------------------------< S E L E C T _ O N E >----------------------------------------------------------
216 
217 Chooses one matching parameter from a list of parameters to consider.  The list of parameters to consider is just
218 names.  For parameters that may be enumerated, the position of the numerator in the parameter name is identified
219 by the '#' so |author-last1= and |author1-last= are represented as 'author-last#' and 'author#-last'.
220 
221 Because enumerated parameter |<param>1= is an alias of |<param>= we must test for both possibilities.
222 
223 
224 Generates an error if more than one match is present.
225 
226 ]]
227 
228 local function select_one( args, aliases_list, error_condition, index )
229 	local value = nil;															-- the value assigned to the selected parameter
230 	local selected = '';														-- the name of the parameter we have chosen
231 	local error_list = {};
232 
233 	if index ~= nil then index = tostring(index); end
234 
235 	for _, alias in ipairs( aliases_list ) do									-- for each alias in the aliases list
236 		if alias:match ('#') then												-- if this alias can be enumerated
237 			if '1' == index then												-- when index is 1 test for enumerated and non-enumerated aliases
238 				value, selected = is_alias_used (args, alias, index, false, value, selected, error_list);	-- first test for non-enumerated alias
239 			end
240 			value, selected = is_alias_used (args, alias, index, true, value, selected, error_list);		-- test for enumerated alias
241 		else
242 			value, selected = is_alias_used (args, alias, index, false, value, selected, error_list);		--test for non-enumerated alias
243 		end
244 	end
245 
246 	if #error_list > 0 and 'none' ~= error_condition then						-- for cases where this code is used outside of extract_names()
247 		local error_str = "";
248 		for _, k in ipairs( error_list ) do
249 			if error_str ~= "" then error_str = error_str .. cfg.messages['parameter-separator'] end
250 			error_str = error_str .. wrap_style ('parameter', k);
251 		end
252 		if #error_list > 1 then
253 			error_str = error_str .. cfg.messages['parameter-final-separator'];
254 		else
255 			error_str = error_str .. cfg.messages['parameter-pair-separator'];
256 		end
257 		error_str = error_str .. wrap_style ('parameter', selected);
258 		table.insert( z.message_tail, { set_error( error_condition, {error_str}, true ) } );
259 	end
260 	
261 	return value, selected;
262 end
263 
264 
265 --[=[-------------------------< R E M O V E _ W I K I _ L I N K >----------------------------------------------
266 
267 Gets the display text from a wikilink like [[A|B]] or [[B]] gives B
268 
269 ]=]
270 
271 local function remove_wiki_link (str)
272 	return (str:gsub( "%[%[([^%[%]]*)%]%]", function(l)
273 		return l:gsub( "^[^|]*|(.*)$", "%1" ):gsub("^%s*(.-)%s*$", "%1");
274 	end));
275 end
276 
277 
278 --[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
279 
280 Sets local cfg table to same (live or sandbox) as that used by the other modules.
281 
282 ]]
283 
284 local function set_selected_modules (cfg_table_ptr)
285 	cfg = cfg_table_ptr;
286 end
287 
288 
289 
290 return {																		-- return exported functions and tables
291 	is_set = is_set,
292 	in_array = in_array,
293 	substitute = substitute,
294 	error_comment = error_comment,
295 	set_error = set_error,
296 	select_one = select_one,
297 	add_maint_cat = add_maint_cat,
298 	wrap_style = wrap_style;
299 	safe_for_italics = safe_for_italics;
300 	remove_wiki_link = remove_wiki_link;
301 	set_selected_modules = set_selected_modules;
302 	z = z,
303 	}