Module:Sandbox/BrownHairedGirl/IrelandByCountyCatNav4

	-- each title consists of 3 parts
	--    * prefix
	--    * county name
	--    * suffix
	-- e.g. "Foo in County Mayo"
	--    * prefix = "Foo in "
	--    * county name = "County Mayo"
	--    * suffix = ""
	-- e.g. "County Sligo-related lists"
	--    * prefix = ""
	--    * county name = "County Sligo"
	--    * suffix = "-related lists"

local debugging = false
local debugmsg = "   "
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local p = {}

local TwentySixCounties = {
	'Carlow',
	'Cavan',
	'Clare',
	'Cork',
	'Donegal',
	'Dublin',
	'Galway',
	'Kerry',
	'Kildare',
	'Kilkenny',
	'Laois',
	'Leitrim',
	'Limerick',
	'Longford',
	'Louth',
	'Mayo',
	'Meath',
	'Monaghan',
	'Offaly',
	'Roscommon',
	'Sligo',
	'Tipperary',
	'Waterford',
	'Westmeath',
	'Wexford',
	'Wicklow'
}

local SixCounties = {
	'Antrim',
	'Armagh',
	'Down',
	'Fermanagh',
	'Londonderry',
	'Tyrone'
}

local New_counties = {
	'Dún Laoghaire–Rathdown',
	'Fingal',
	'South Dublin (county)'
}

local Traditional32Counties = {
	'Antrim',
	'Armagh',
	'Carlow',
	'Cavan',
	'Clare',
	'Cork',
	'Donegal',
	'Down',
	'Dublin',
	'Fermanagh',
	'Galway',
	'Kerry',
	'Kildare',
	'Kilkenny',
	'Laois',
	'Leitrim',
	'Limerick',
	'Londonderry',
	'Longford',
	'Louth',
	'Mayo',
	'Meath',
	'Monaghan',
	'Offaly',
	'Roscommon',
	'Sligo',
	'Tipperary',
	'Tyrone',
	'Waterford',
	'Westmeath',
	'Wexford',
	'Wicklow'
}

local GAACounties = {
	'Antrim',
	'Armagh',
	'Carlow',
	'Cavan',
	'Clare',
	'Cork',
	'Donegal',
	'Derry',
	'Down',
	'Dublin',
	'Fermanagh',
	'Galway',
	'Kerry',
	'Kildare',
	'Kilkenny',
	'Laois',
	'Leitrim',
	'Limerick',
	'Longford',
	'Louth',
	'Mayo',
	'Meath',
	'Monaghan',
	'Offaly',
	'Roscommon',
	'Sligo',
	'Tipperary',
	'Tyrone',
	'Waterford',
	'Westmeath',
	'Wexford',
	'Wicklow'
}


function makeTable()
	local i, myCounty
	local myTable = '<table class="infobox" style="margin-left:auto; margin-right:auto; font-size: 90%; clear:left; float:left; width:auto;">\n'
	myTable = myTable .. '<tr>\n'
--	myTable = myTable .. '<td colspan="2" style="text-align:center; background-color:#f3f3f3"></td>\n'
	myTable = myTable .. '</tr>\n'
	myTable = myTable .. '<td style="text-align:right; font-weight: bold;">' .. 'Republic of Ireland</td>\n'
	myTable = myTable .. '<td style="text-align:left;"><div class="hlist">\n'
	for i, myCounty in ipairs(TwentySixCounties) do
		myCatName = makeCatName("County " .. myCounty, title_prefix, title_suffix, title_nocountyword)
		myTable = myTable .. "* " .. makeCatLink(myCatName, myCounty) .. "\n"
		local j, nuCounty
		if (myCounty == "Dublin") then
			for j, nuCounty in ipairs(New_counties) do
				myCatName = makeCatName(nuCounty, title_prefix, title_suffix, true)
				myTable = myTable .. "** " .. makeCatLink(myCatName, nuCounty) .. "\n"
			end
			myCatName = makeCatName("Dublin (city)", title_prefix, title_suffix, title_nocountyword)
			myTable = myTable .. "** " .. makeCatLink(myCatName, "City") .. "\n"
		end
	end

	myTable = myTable .. "</div></td></tr>"
	myTable = myTable .. '<tr style="margin:1.5em; background-color:#f3f3f3">\n'
	myTable = myTable .. '<td style="text-align:right;  font-weight: bold;">' .. 'Northern&nbsp;Ireland</td>\n'
	myTable = myTable .. '<td style="text-align:left;"> <div class="hlist">\n'
	for i, myCounty in ipairs(SixCounties) do
		myCatName = makeCatName("County " .. myCounty, title_prefix, title_suffix, title_nocountyword)
		myTable = myTable .. "* " .. makeCatLink(myCatName, myCounty) .. "\n"
	end
	myTable = myTable .. "</div></td></tr></table>\n"
	return myTable
end


function makeCatLink(catname, disp)
	local displaytext
	if (disp ~= "") and (disp ~= nil) then
		-- use 'disp' parameter, but strip any trailing disambiguator
		displaytext = mw.ustring.gsub(disp, "%s+%(.+$", "");
	else
		displaytext = catname
	end
	local link = "[[:Category:" .. catname .. "|" .. displaytext .. "]]"
	local fmtlink
	local linktitle = mw.title.new( catname, "Category" )
	if (linktitle.exists) then
		fmtlink = link
	else
		fmtlink = "<span style=\"color:#888\">" .. displaytext .. "</span>"
	end

	return fmtlink
end

function makeCatName(countyname, prefix, suffix, nocounty)
	local this_cat_name = '';
	this_cat_name = this_cat_name .. prefix
	this_cat_name = this_cat_name .. countyname
	this_cat_name = this_cat_name .. suffix
	return this_cat_name
end


-- Does the pagename include a bare county name? (i.e. without the prefix "County ")
-- This would be one line in regex, but Lua pattern matching is cruder, so
-- we need several passes to ensure that any match is of a complete word
function findBareCountyNameInPagename(pn, countylist, description)
	local i, testCounty
	debugLog(2, "trying bare_county name [" .. pn .."] in county set: " .. description)
	for i, testCounty in ipairs(countylist) do
		debugLog(3, "testing new_county: ["  .. testCounty .. "]")
		local testCountyEncoded = mw.ustring.gsub(testCounty, "([%W])", "%%%1")
		-- for efficiency, the first test is a simple match as a a screening test
		-- if the bare county name is nowhere in the pagename, then no need for
		if (mw.ustring.match(pn, testCountyEncoded)) then
			debugLog(4, "simple match success")
			debugLog(4, "match at start, followed by separator? ")
			if mw.ustring.match(pn, "^" .. testCountyEncoded .. "[^%w]") then
				debugLog(nil, "Yes")
				return testCounty
			else
				debugLog(nil, "No")
			end
			debugLog(4, "match at end, preceded by separator? ")
			if mw.ustring.match(pn, "[^%w]" .. testCountyEncoded .. "$") then
				debugLog(nil, "Yes")
				return testCounty
			else
				debugLog(nil, "No")
			end
			debugLog(4, "match anywhere, preceded and followed by separator? ")
			if mw.ustring.match(pn, "[^%w]" .. testCountyEncoded .. "[^%w]") then
				debugLog(nil, "Yes")
				return testCounty
			else
				debugLog(nil, "No")
			end
		else
			debugLog(4, "simple match fail")
		end
	end
	return nil
end

-- check whether a given county name is in a particular set
function isCountyInSet(s, countySet)
	local thisCounty = mw.ustring.gsub(s, "^County +", "")
	local aValidCounty
	for i, aValidCounty in ipairs(countySet) do
		if mw.ustring.match(thisCounty, "^" .. aValidCounty .. "$") then
			return true
		end
	end
	return false
end


function parsePagename(pn)
	debugLog(1, "parsePagename: [" .. pn .. "]")
	debugLog(2, "simple parse")
	match_prefix, match_county, match_suffix = mw.ustring.match(pn, "^(.*)(County%s+%a+)(.*)$")
	if not(match_county == nil or match_county == '') then
		debugLog(3, "County Foo = [" .. match_county .. "]")
		-- we have a "County Foo" ... but is it one of the 32 counties?
		debugLog(3, "is [" .. match_county .. "] one of the 32 counties?")
		if isCountyInSet(match_county, Traditional32Counties) then
			debugLog(nil, "Yes")
		else
			debugLog(nil, "No")
			return false
		end
	else -- simple 
		debugLog(3, "No match_'County Foo'")
		local new_county = findBareCountyNameInPagename(pn, New_counties, "New_counties")
		if new_county == nil then
			debugLog(3, "no match in new counties")
			return false
		end
		debugLog(3, "found new county: [" .. new_county .. "]")
		local testCountyEncoded = mw.ustring.gsub(new_county, "([%W])", "%%%1")
		match_prefix, match_county, match_suffix = mw.ustring.match(pn, "^(.*)(" .. testCountyEncoded .. ")(.*)$")
	end
	title_prefix = match_prefix
	title_suffix = match_suffix
	debugLog(2, "parse successful")
	debugLog(3, "match_prefix = [" .. match_prefix .. "]")
	debugLog(3, "match_county = [" .. match_county .. "]")
	debugLog(3, "match_suffix = [" .. match_suffix .. "]")
	return true
end

function publishDebugLog()
	if not debugging then
		return ""
	end
	return "==Debugging ==\n\n" .. debugmsg .. "\n== Output ==\n"
end


-- debugLog builds a log which can be output if debuging is enabled
-- each log entry is given a level, so that the output is not simply a flat list
-- a debug msg may be appended to the previous msg by setting the level to nil
function debugLog(level, msg)

	if (debugmsg == nil) then
		debugmsg = ""
	end

	if (level ~= nil) then
		-- not appending, so make a new line
		debugmsg = debugmsg .. "\n"
		-- then add the level
		if (level == 1) then
			debugmsg = debugmsg .. "# "
		elseif  (level == 2) then
			debugmsg = debugmsg .. "#* "
		elseif  (level == 3) then
			debugmsg = debugmsg .. "#*# "
		elseif  (level == 4) then
			debugmsg = debugmsg .. "#*#* "
		end
	end
	debugmsg = debugmsg .. " " .. msg
	return true
end


function argValueFunc(value)
	if (value == nil) then
		value = '' -- nil value = blank
	end
	value = mw.ustring.gsub(value, "^%s+$", "") -- only whitespace, so replace with ''
	return value
end

		
function p.main(frame)
-- getArgs
-- In all cases, convert to blank (i.e. '')
--   * a nil value
--   * a value consisting only of whitespace

	if (frame.args['debug'] ~= nil) then
		if	yesno(frame.args['debug'], false) then
			debugLog(1, "debug=Yes")
			debugging = true
		end
	end

	local myArgs = {}
	local x
	debugLog(1, "frame.args")
	for x = 1, 9 do
		-- debugLog(2, "frame.args[" .. tostring(x) .. "] = [" .. frame.args[x] .. "]")
	end
	
	debugLog(1, "myArgs")
	for x = 1, 9 do
		myArgs[x] = argValueFunc(frame.args[x])
		debugLog(2, "myArgs[" .. tostring(x) .. "] = [" .. myArgs[x] .. "]")
	end

	-- now set the key variables
	title_prefix = myArgs[1]
	title_suffix = myArgs[2]
	title_nocountyword = false

	debugLog(1, "set main variables")
	debugLog(2, "title_prefix = [" .. title_prefix .. "]")
	debugLog(2, "title_suffix = [" .. title_suffix .. "]")

	debugLog(1, "check named parameters")
	if yesno(myArgs['nocountyword'], false) then
		debugLog(2, "nocountyword=Yes")
		title_nocountyword = true
	end

	-- get the page title
	thispage = mw.title.getCurrentTitle()
	thispagename = thispage.text;
	
	debugLog(1, "mw.title.getCurrentTitle()")
	debugLog(2, "thispage.text = [" .. thispage.text .."]")
	debugLog(2, "thispage.namespace = [" .. thispage.namespace .."]")
	debugLog(2, "thispage.nsText = [" .. thispage.nsText .."]")
	debugLog(2, "is it a cat? using (thispage:inNamespace(14)): ")
	if not (thispage:inNamespace(14)) then
		debugLog(nil, "No, this is not a category")
		debugLog(1, "Not a category, so no output")
		return publishDebugLog()
	end
	debugLog(nil, "Yes, this is a category")

	if not parsePagename(thispagename) then
		-- some error parsing the title, so don't proceed to output
		return publishDebugLog()
	end
	
	debugLog(1, "all parse done")
	debugLog(2, "title_prefix = [" .. title_prefix .. "]")
	debugLog(2, "title_suffix = [" .. title_suffix .. "]")

	return publishDebugLog() .. makeTable()

end

return p