Module:Settlement short description
--generates auto short description for use in infobox settlement
 local p = {}
 p.categories = &quot;&quot;
 local plain = require('Module:Plain text')._main
 local getArgs = require('Module:Arguments').getArgs
 local tableTools = require ('Module:TableTools')
 
 function p.reverseTable (init)
 	init[1], init[3] = init[3], init[1]
 	return init
 end
 
 function p.assign (args, argname, num)
 	local val
 	local var = {}
 	for i = 0,num do
 		--handle initial &quot;subdivision_foo&quot; without number
 		if i == 0 then
 			val = &quot;&quot;
 		else
 			val = tostring(i)
 		end
 		var[i+1] = p.validate(plain(args[argname..val]))
 	end
 	return var
 end
 
 --Display short description using {{short description}}
 function p.shortdesc(text, frame)
 	return frame:expandTemplate{title = 'Short description', args = {text, 'noreplace'}}
 end
 
 function p.category (cattype)
 	local category = string.format('[[Category:Pages using infobox settlement with bad %s]]', cattype)
 	if category then p.categories = p.categories..category end --categorize
 end
 
 --sanity and other checks
 function p.validate (parameter, cat)
 	if not parameter then return nil end
 	parameter = parameter:gsub('%b()', '') --remove things in brackets as extraneous information
 			   :gsub('%s+', ' ') --fix possible extra spaces from previous cleanup
 			   :gsub('^%s+', '') --trim spaces from beginning
 			   :gsub('%s+$', '') --trim spaces from end
 	if parameter:match(&quot;[,;]&quot;) or not parameter:match(&quot;%a&quot;) then --must have some letters, ignore if multiple types/subdivisions
 		if cat then p.category (cat) end
 		return nil
 	end
 	if (parameter == &quot;&quot;) then return nil end
 	return parameter
 end
 
 --removes redundancy like &quot;England, United Kingdom&quot; and fixes issues like &quot;Foo in United States&quot; (to &quot;Foo in the United States&quot;)
 --also used in Module:Type in location
 function p.cleanupLoc (location)
 	if location == &quot;&quot; then return nil end
 	local replacements = {
 		[&quot;England, United Kingdom&quot;] =  &quot;England&quot;,
 		[&quot;Scotland, United Kingdom&quot;] =  &quot;Scotland&quot;,
 		[&quot;Wales, United Kingdom&quot;] =  &quot;Wales&quot;,
 		[&quot;New York City, New York, United States&quot;] =  &quot;New York City&quot;,
 		[&quot;^United States$&quot;] = &quot;the United States&quot;,
 		[&quot;London, United Kingdom&quot;] = &quot;London, England&quot;
 	}
 	for i, v in pairs(replacements) do 
 		location = location:gsub(i, v) --series of replacements
 	end
 	return location
 end
 
 function p.main(frame)
 	local categories = &quot;&quot;
 	local subdivision_types = {}
 	local subdivision_names = {}
 	local args = getArgs (frame, {parentOnly = true})
 	local settlement_type = p.validate(plain(args.settlement_type or args.type), &quot;settlement type&quot;) or &quot;Place&quot;
 	local short_description = plain(args.short_description)
 	subdivision_types = p.assign(args, &quot;subdivision_type&quot;, 2)
 	subdivision_names = p.assign(args, &quot;subdivision_name&quot;, 2)
 	
 	if short_description then
 		if (short_description == 'no') then
 			return
 		else
 			local language = mw.language.getContentLanguage()
 			return p.shortdesc(language:ucfirst(short_description), frame)
 		end
 	end
 	
 	if not(subdivision_names[3] and
 		(string.find(settlement_type, '[nN]eighbo[u]?rhood') or string.find(settlement_type, '[sS]uburb'))) then
 		subdivision_names[3] = nil --display the third subdivision_type only if suburb or neighborhood
 	end
 	
 	--if say &quot;Voivodeship&quot; is found within the subdivision_type, then specially handle
 	--by adding Voivodeship to the end if not already present
 	for x, y in ipairs (subdivision_types) do
 		local special_types = {
 			&quot;Voivodeship&quot;
 		}
 		for i, j in ipairs(special_types) do
 			if subdivision_names[x] and string.find(y, j, 1, true)
 				and not string.find(subdivision_names[x], j, 1, true) then
 				subdivision_names[x] = subdivision_names[x]..&quot; &quot;..j
 			end
 		end
 	end
 	
 	for x, y in ipairs (subdivision_names) do
 		if y then
 			if string.find(settlement_type, y, 1, true) then --if the subdivision is found within the settlement type
 				subdivision_names[x] = nil --don't display redundancy
 				p.category (&quot;settlement type&quot;)
 			end
 			if y == mw.title.getCurrentTitle().text then --if the title is the same as one of the subdivision_names
 				subdivision_names[x] = nil --don't display redundancy
 			end
 		end
 	end
 
 	local location = table.concat(tableTools.compressSparseArray(p.reverseTable(subdivision_names)), ', ')
 	
 	location = p.cleanupLoc (location)
 	
 	if location then location =  &quot; in &quot; .. location else location = &quot;&quot; end
 	
 	local language = mw.language.getContentLanguage()
 	return p.shortdesc(language:ucfirst(settlement_type..location), frame)..p.categories
 end