Module:Infobox school tracking
local p = {}
 
 function p.tracking(frame)
     local function isblank( val ) 
         return (val == nil) or val:match('^[%s]*$')
     end
     local function trim(s)
 		return s:match('^%s*(.-)%s*$')
 	end
     local function isnotblank(s)
 		return s and trim(s) ~= ''
 	end
     local cats = ''
     local args = frame:getParent().args
     local unknown_parameters = {}
     local duplicate_parameters = {}
     local count = 0
 
 	if args['Campuses'] then 
     	table.insert(unknown_parameters, 'Campuses = use campuses instead')
     end
     if args['Classes offered'] then 
     	table.insert(unknown_parameters, 'Classes offered = use classes_offered instead')
     end
     if args['Graduates'] then 
     	table.insert(unknown_parameters, 'Graduates = use graduates instead')
     end
 	if args['Hours_in_Day'] then 
     	table.insert(unknown_parameters, 'Hours_in_Day = use hours_in_day instead')
     end
     if args['International_Students'] then 
     	table.insert(unknown_parameters, 'International_Students = use international_students instead')
     end
     if args['Location'] then 
     	table.insert(unknown_parameters, 'Location = use location instead')
     end
     if args['Opened'] then 
     	table.insert(unknown_parameters, 'Opened = use opened instead')
     end
     if args['National_ranking'] then 
     	table.insert(unknown_parameters, 'National_ranking = use national_ranking instead')
     end
     if args['Number'] then 
     	table.insert(unknown_parameters, 'Number = use number instead')
     end
     if args['Principal'] then 
     	table.insert(unknown_parameters, 'Principal = use principal instead')
     end
     if args['Region'] then 
     	table.insert(unknown_parameters, 'Region = use region instead')
     end
     if args['Students'] then 
     	table.insert(unknown_parameters, 'Students = use students instead')
     end
     if args['System'] then 
     	table.insert(unknown_parameters, 'System = use system instead')
     end
     if args['Years'] then 
     	table.insert(unknown_parameters, 'Years = use years instead')
     end
     if args['approx'] then 
     	table.insert(unknown_parameters, 'approx = add c. before any approximate dates')
     end
     if args['c_approx'] then 
     	table.insert(unknown_parameters, 'c_approx = add c. before any approximate dates')
     end
     if args['motto_pl'] then 
     	table.insert(unknown_parameters, 'motto_pl = use mottoes instead')
     end
     if args['founder_pl'] then 
     	table.insert(unknown_parameters, 'founder_pl = use founders instead')
     end
     if args['specialist_pl'] then 
     	table.insert(unknown_parameters, 'specialist_pl = use specialists instead')
     end
     if args['year'] then 
     	table.insert(unknown_parameters, 'year = use ACT_year or SAT_year or graduates_year instead')
     end
     if args['main feeder schools'] then 
     	table.insert(unknown_parameters, 'main feeder schools = use feeder_schools instead')
     end
     if isnotblank(args['fundingtype']) and isnotblank(args['type']) then
 		table.insert(duplicate_parameters, 'fundingtype = type')
 	end
 	if isnotblank(args['religious_affiliation']) and isnotblank(args['religion']) then
 		table.insert(duplicate_parameters, 'religious_affiliation = religion')
 	end
 	if isnotblank(args['head_name']) and isnotblank(args['head_label']) then
 		table.insert(duplicate_parameters, 'head_name = head_label')
 	end
 	if isnotblank(args['employees']) and isnotblank(args['num_employ']) then
 		table.insert(duplicate_parameters, 'employees = num_employ')
 	end
 	if isnotblank(args['enrolment']) and isnotblank(args['enrollment']) then
 		table.insert(duplicate_parameters, 'enrolment = enrollment')
 	end
 	if isnotblank(args['enrolment_as_of']) and isnotblank(args['enrollment_as_of']) then
 		table.insert(duplicate_parameters, 'enrolment_as_of = enrollment_as_of')
 	end
     count = 0
 	if isnotblank(args['address']) then count = count + 1 end
 	if isnotblank(args['street']) then count = count + 1 end
 	if isnotblank(args['streetaddress']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'address = street = streetaddress')
 	end
 	count = 0
 	if isnotblank(args['city']) then count = count + 1 end
 	if isnotblank(args['town']) then count = count + 1 end
 	if isnotblank(args['city/town']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'city = town = city/town')
 	end
 	count = 0
 	if isnotblank(args['postcode']) then count = count + 1 end
 	if isnotblank(args['postalcode']) then count = count + 1 end
 	if isnotblank(args['zipcode']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'postcode = postalcode = zipcode')
 	end
 	count = 0
 	if isnotblank(args['educational_authority']) then count = count + 1 end
 	if isnotblank(args['educational authority']) then count = count + 1 end
 	if isnotblank(args['authority']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'educational_authority = educational authority = authority')
 	end
 	count = 0
 	if isnotblank(args['school_number']) then count = count + 1 end
 	if isnotblank(args['schoolnumber']) then count = count + 1 end
 	if isnotblank(args['number']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'school_number = schoolnumber = number')
 	end
 	count = 0
 	if isnotblank(args['staff']) then count = count + 1 end
 	if isnotblank(args['number_of_staff']) then count = count + 1 end
 	if isnotblank(args['number of staff']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'staff = number_of_staff = number of staff')
 	end
 	count = 0
 	if isnotblank(args['lower_age']) then count = count + 1 end
 	if isnotblank(args['age_range']) then count = count + 1 end
 	if isnotblank(args['age range']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'lower_age = age_range = age range')
 	end
 	count = 0
 	if isnotblank(args['pupils']) then count = count + 1 end
 	if isnotblank(args['number_of_pupils']) then count = count + 1 end
 	if isnotblank(args['number of pupils']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'pupils = number_of_pupils = number of pupils')
 	end
 	count = 0
 	if isnotblank(args['average_class_size']) then count = count + 1 end
 	if isnotblank(args['avg_class_size']) then count = count + 1 end
 	if isnotblank(args['class']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'average_class_size = avg_class_size = class')
 	end	
 	count = 0
 	if isnotblank(args['colours']) then count = count + 1 end
 	if isnotblank(args['colors']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'colours = colors')
 	end	
 	count = 0
 	if isnotblank(args['schoolcolours']) then count = count + 1 end
 	if isnotblank(args['schoolcolors']) then count = count + 1 end
 	if isnotblank(args['school_colours']) then count = count + 1 end
 	if isnotblank(args['school_colors']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'schoolcolours = schoolcolors = school_colours = school_colors')
 	end	
 	count = 0
 	if isnotblank(args['feeders']) then count = count + 1 end
 	if isnotblank(args['feeder_schools']) then count = count + 1 end
 	if isnotblank(args['main feeder schools']) then count = count + 1 end
 	if count &gt; 1 then
 		table.insert(duplicate_parameters, 'feeders = feeder_schools = main feeder schools')
 	end
 	if isnotblank(frame.args['nocat']) then
 		cats = ''
 	end
 	warnmsg = {}
 	if #unknown_parameters &gt; 0 then
 		for i, v in ipairs( unknown_parameters ) do
 			local t = mw.text.split(v, '=')
 			table.insert(warnmsg, 'Unknown parameter &lt;code&gt;' .. t[1] .. '&lt;/code&gt; ' .. t[2])
 			cats = cats .. '[[Category:Pages using infobox school with deprecated parameters|' .. t[1] .. ']]'
 		end
 	end
 	if #duplicate_parameters &gt; 0 then
 		for i, v in ipairs( duplicate_parameters ) do
 			local t = mw.text.split(v, '=')
 			table.insert(warnmsg, 'Using more than one of the following parameters: &lt;code&gt;' ..
 				table.concat(t, '&lt;/code&gt;, &lt;code&gt;') .. '&lt;/code&gt;')
 			cats = cats .. '[[Category:Pages using infobox school with deprecated parameters|' .. t[1] .. ']]'
 		end
 	end
 	if #warnmsg &gt; 0 then
 		if frame:preprocess( &quot;{{REVISIONID}}&quot; ) == &quot;&quot; then
 			cats = '&lt;div class=&quot;hatnote&quot; style=&quot;color:red&quot;&gt;&lt;strong&gt;Infobox school warning:&lt;/strong&gt; ' .. table.concat(warnmsg, '&lt;br&gt;') .. '&lt;/div&gt;' .. cats
 		end
 	end
     return cats
 end