Bước tới nội dung

Mô đun:CanadaByProvinceCatNav

Bách khoa toàn thư mở Wikipedia
--[[	v01.18: fix handling of definite article (e.g. for 'the Northwest Territories')  each title consists of 3 parts    * prefix    * province name    * suffix e.g. "Foo in Quebec"    * prefix = "Foo in "    * province name = "Quebec"    * suffix = "" e.g. "Nunavut-related lists"    * prefix = ""    * province name = "Nunavut"    * suffix = "-related lists"]]-- configlocal textSize = '90%'local tableClass="toc"local evenRowStyle = "vertical-align:top; background-color:#f3f3f3;"local oddRowStyle = "vertical-align:top;"local labelStyle = "text-align:right; font-weight: bold; padding: 0.25em 0.5em 0.25em 0.5em;"local listStyle = "text-align:left; font-weight: normal; padding: 0.25em 0.5em 0.25em 0.5em;"local greyLinkColor = "#888"--[[ Note that the table styles are designed to ensure that the navbox is as wide as possible, while still leaving     enough enough space on the right for portal boxes, commons links, and GeoGroup templates.     A lot of fiddling was needed to make it work, so please test any chnages very carfully in the sandbox.]]local tableFallbackMaxWidth="auto"local tableMaxWidth="calc(100% - 25em)" -- Template:GeoGroup has width: 23em<-- local tableStyle="margin-left:0; margin-right:auto; clear:left !important; margin-top:0 !important; float:left; width:auto;"local tableStyle="margin-left:0; margin-right:auto; clear:left !important; margin-top:0 !important; width:auto;"-- Templates which are allowed to call this modulelocal callingTemplates = {	'Bản mẫu:CanadaByProvinceCatNav',}-- globals for this modulelocal debugging = falselocal debugmsg = ""local tableRowNum = 0local title_prefix = ""local title_suffix = ""local title_prefixlocal title_suffixlocal thisPageProvincelocal greyLinkCount = 0local blueLinkCount = 0local parentname = ""local templateNamelocal getArgs = require('Module:Arguments').getArgslocal yesno = require('Module:Yesno')local p = {}--[[	Plain text list of provinces and territories	* Each entry exactly as it appears in running text in categoiry titles, with any prefix (e.g. "the")	* Be sure to avoid hidden characters and duplicate spaces.  They break the pattern-matching on which this module relies]]local CanadaProvinces = {	'Alberta',	'British Columbia',	'Manitoba',	'New Brunswick',	'Newfoundland và Labrador',	'Các Lãnh thổ Tây Bắc',	'Nova Scotia',	'Nunavut',	'Ontario',	'Đảo Hoàng tử Edward',	'Quebec',	'Saskatchewan',	'Yukon'}-- If the page title matches any of these Lua patterns, treat it as a false positive local falsePositiveChecks = {	"Bắc Alberta",	"Nam Alberta",	"Thành phố Québec",	"Trung Ontario",	"Đông Ontario",	"Bắc Ontario",	"Tây Nam Ontario"}function makeTrackingCategory()	-- discount the current page, which will always be coded as a blue link, but rendered as bold un-navigable	blueLinkCount = blueLinkCount - 1	if greyLinkCount == 0 then		return "[[Category:" .. templateName .. " with no grey links]]"	end	if blueLinkCount == 0 then		return "[[Category:" .. templateName .. " with all grey links]]"	end	if  greyLinkCount <= 5 then		return "[[Category:" .. templateName .. " with fewer than 5 grey links]]"	end	if  greyLinkCount >= 10 then		return "[[Category:" .. templateName .. " with 10 or more grey links]]"	end	if  greyLinkCount > 5 then		return "[[Category:" .. templateName .. " with over 5 grey links]]"	end	return ""endfunction makeTableRow(rowLabel, provinceList)	debugLog(2, "makeTableRow, label: ")	if (rowLabel == nil) then		rowLabel = "Theo&nbsp;tỉnh bang<br />và lãnh thổ"		debugLog(nil, rowLabel)	else		rowLabel = mw.text.trim(rowLabel)		debugLog(nil, " [" .. rowLabel .. "]")	end	tableRowNum = tableRowNum + 1	local thisRow	if (tableRowNum % 2) == 0 then		debugLog(3, "Even-numbered")		thisRow = '<tr style="' .. evenRowStyle .. '">\n'	else		debugLog(3, "Odd-numbered")		thisRow = '<tr style="' .. oddRowStyle .. '">\n'	end	if not ((rowLabel == nil) or (rowLabel =="")) then		thisRow = thisRow .. '<td style="' .. labelStyle .. '">' .. rowLabel .. '</td>\n'	end	-- now begin making the row contents	thisRow = thisRow .. '<td style="' .. listStyle .. ';"><div class="hlist">\n'	local i, aProvince		debugLog(3, "Process provinceList")	for i, aProvince in ipairs(provinceList) do		debugLog(4, "No. " .. tostring(i) .. ": [" .. aProvince .. "]")		myCatName = makeCatName(aProvince, title_prefix, title_suffix)		thisRow = thisRow .. "* " .. makeCatLink(myCatName, aProvince) .. "\n"	end	thisRow = thisRow .. '</div></td>\n</tr>'	return thisRowendfunction makeTable()	debugLog(1, "makeTable")	tableRowNum = 0	local myTable = '<table class="' .. tableClass .. '"'	myTable = myTable .. ' style="' .. tableStyle .. '; font-size:' .. textSize .. '; max-width:' .. tableFallbackMaxWidth .. '; max-width:' .. tableMaxWidth ..'">\n'	myTable = myTable .. makeTableRow(nil, CanadaProvinces)	myTable = myTable .. "</table>\n"	return myTableend-- Make a piped link to a category, if it exists-- If it doesn't exist, just display the greyed the link title without linkingfunction makeCatLink(catname, disp)	local displaytext	if (disp ~= "") and (disp ~= nil) then		-- use 'disp' parameter, but strip any leading word "the"		displaytext = mw.ustring.gsub(disp, "^[tT]he%s+", "");	else		displaytext = catname	end	local fmtlink	local catPage = mw.title.new( catname, "Category" )	if (catPage.exists) then		fmtlink = "[[:Category:" .. catname .. "|" .. displaytext .. "]]"		blueLinkCount = blueLinkCount + 1	else		fmtlink = '<span style="color:' .. greyLinkColor .. '">' .. displaytext .. "</span>"		greyLinkCount = greyLinkCount + 1	end	return fmtlinkendfunction makeCatName(provinceName, prefix, suffix)	local thisCatName = prefix .. provinceName .. suffix	debugLog(5, "thisCatName = [" .. thisCatName .. "]")	--[[		Now check whether the all following conditions are true			1/ the provinceName begins with "the"			2/ the category does NOT exist if we use "the "			3/ the category does exist if we strip "the "		 If those conditions are all true, them strip "the" 	]] 	if (mw.ustring.match(provinceName, "^[tT]he ") ~= nil) then		debugLog(6, "ProvinceName begins with 'the'")		local provinceNameStripped = mw.ustring.gsub(provinceName, "^[tT]he ", "", 1)		local thisCatNameStripped = prefix .. provinceNameStripped .. suffix		debugLog(6, "thisCatNameStripped = [" .. thisCatNameStripped .. "]")		local testCatPage = mw.title.new(thisCatName, "Category" )		local testCatPageStripped = mw.title.new(thisCatNameStripped, "Category" )		if not testCatPage.exists then			debugLog(7, "[" .. testCatPage.fullText .. "] .. does not exist") 			if (testCatPageStripped.exists) then				debugLog(7, "[" .. testCatPageStripped.fullText .. "] .. DOES exist, so use that") 				return thisCatNameStripped			end		end	end	return thisCatNameendfunction patternSearchEncode(s)	return mw.ustring.gsub(s, "([%W])", "%%%1")end-- Does the pagename include a province name?function findprovinceNameInPagename(pn, provinceList, description)	local i, aProvince, testProvince	debugLog(2, "checking [" .. pn .."] for a province name in province set: " .. description)	for i, aProvince in ipairs(provinceList) do		testProvince = aProvince		debugLog(3, "testing: ["  .. testProvince .. "]")		local testProvinceEncoded = patternSearchEncode(testProvince)		-- 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		-- more precise checks		-- This check 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		debugLog(4, "simple match? ")		if (not mw.ustring.match(pn, testProvinceEncoded)) then			debugLog(nil, "Fail")		else			debugLog(nil, "Success")			-- test for false positives			local j, aFalsePositiveTest			for j, aFalsePositiveTest in ipairs(falsePositiveChecks) do				debugLog(5, "false positive test pattern '" .. aFalsePositiveTest .. "' ? ")				if (mw.ustring.match(pn, aFalsePositiveTest)) then					debugLog(nil, "Match, so fail")					return nil				end				debugLog(nil, "No match, so OK")			end			debugLog(4, "match whole name? ")			if (pn == testProvince) then				debugLog(nil, "Yes")				return testProvince			end			debugLog(nil, "No")			debugLog(4, "match at start, followed by separator? ")			if mw.ustring.match(pn, "^" .. testProvinceEncoded .. "[^%w]") then				debugLog(nil, "Yes")				return testProvince			end			debugLog(nil, "No")						debugLog(4, "match at end, preceded by separator? ")			if mw.ustring.match(pn, "[^%w]" .. testProvinceEncoded .. "$") then				debugLog(nil, "Yes")				return testProvince			end			debugLog(nil, "No")			debugLog(4, "match anywhere, preceded and followed by separator? ")			if mw.ustring.match(pn, "[^%w]" .. testProvinceEncoded .. "[^%w]") then				debugLog(nil, "Yes")				return testProvince			end			debugLog(nil, "No")		end		-- Special case: if the province name we are testing begins with a prefixed "the"		debugLog(4, "does testProvince begin with 'the' ? ")		if (mw.ustring.match(testProvince, "^[tT]he ") == nil) then			debugLog(nil, "No")		else			debugLog(nil, "Yes")		end		if (mw.ustring.match(testProvince, "^[tT]he ") ~= nil) then			local testProvinceStripped = mw.ustring.gsub(testProvince, "^[tT]he ", "", 1)			local testProvinceStrippedEncoded = patternSearchEncode(testProvinceStripped)			debugLog(4, "test pattern without leading definite article, i.e. '" .. testProvinceStrippedEncoded .. "' ? ")			if (mw.ustring.match(pn, "[^%w]" .. testProvinceStrippedEncoded .. "[^%w]")  ~= nil)			or (mw.ustring.match(pn, "^" .. testProvinceStrippedEncoded .. "[^%w]")  ~= nil)			or (mw.ustring.match(pn, "[^%w]" .. testProvinceStrippedEncoded .. "$")  ~= nil)			or (mw.ustring.match(pn, "^" .. testProvinceStrippedEncoded .. "$")  ~= nil) then				debugLog(nil, "Yes")				return testProvinceStripped			end			debugLog(nil, "No")		end	end	return nilend-- parse the pagename to find 3 parts: prefix, province name, suffixfunction parsePagename(pn)	debugLog(1, "parsePagename: [" .. pn .. "]")	local validprovinceName	validprovinceName = findprovinceNameInPagename(pn, CanadaProvinces, "provincelst")	if validprovinceName == nil then		return false	end		-- if we get here, the page name "pn" includes a validprovinceName	-- so now we need to split the string		debugLog(2, "split pagename around [" .. validprovinceName .. "]")	local validProvinceEncoded = mw.ustring.gsub(validprovinceName, "([%W])", "%%%1")	match_prefix, match_province, match_suffix = mw.ustring.match(pn, "^(.*)(" .. validProvinceEncoded .. ")(.*)$")		title_prefix = match_prefix	title_suffix = match_suffix	debugLog(2, "parse successful")	debugLog(3, "title_prefix = [" .. title_prefix .. "]")	debugLog(3, "thisPageProvince = [" .. match_province .. "]")	debugLog(3, "title_suffix = [" .. title_suffix .. "]")	return trueendfunction 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 nilfunction 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		local i		for i = 1, level do			if (i % 2) == 1 then				debugmsg = debugmsg .. "#"			else				debugmsg = debugmsg .. "*"			end		end 	end	debugmsg = debugmsg .. " " .. msg	return trueendfunction getYesNoParam(args, thisParamName, defaultVal)	local paramVal = args[thisParamName]	if paramVal == nil then		paramVal = ""	end	debugLog(2, "Evaluate yes/no parameter: [" .. thisParamName .. "] = [" .. paramVal .. "]")	debugLog(3, "default = " .. ((defaultVal and "Yes") or "No"))	debugLog(3, "Evaluate as: ")	local returnValue	if paramVal == "" then		returnValue = defaultVal	else		returnValue = yesno(args[thisParamName], defaultVal)	end	if (returnValue) then		debugLog(nil, "Yes")	else		debugLog(nil, "No")	end	return returnValueendfunction makeErrorMsg(s)	return '<p class="error">[[' .. parentname .. ']] Error: ' .. s .. '</p>\n'endfunction isValidParent(p)	local i, aParent	for i, aParent in ipairs(callingTemplates) do		if p == aParent then			return true		end	end	return falseendfunction p.main(frame)	local parent = frame:getParent()	if parent then		 parentname = parent:getTitle():gsub('/sandbox$', '')	end	if (parentname == nil) or not isValidParent(parentname) then		local errormsg = '<p class="error"> Error: ' .. parentname .. ' is not a valid wrapper for [[' .. frame:getTitle() .. ']]\n'		errormsg = errormsg .. '<br><br>Valid wrappers: '		local i, aParent		for i, aParent in ipairs(callingTemplates) do			errormsg = errormsg .. '[[' .. aParent  .. ']]'		end		errormsg = errormsg .. '</p>'		return errormsg	end	templateName = mw.ustring.gsub(parentname, "^Template:", "")		debugLog(1, "Check parameters")	debugging = getYesNoParam(frame.args, "debug", false)	-- 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 makeErrorMsg("only for use on a category page") .. 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		local trackingCatInvalid = "[[Category:" .. templateName .. " on invalid category]]"		return makeErrorMsg('the name of this category does not include a valid Candian province or territory') .. publishDebugLog() .. trackingCatInvalid	end		debugLog(1, "all parse done")	debugLog(2, "title_prefix = [" .. title_prefix .. "]")	debugLog(2, "title_suffix = [" .. title_suffix .. "]")		local myNavTable = makeTable()	debugLog(2, "blueLinkCount = [" .. blueLinkCount .. "]. &nbsp; (NB The current page is always counted as a bluelink, but will not be navigable)")	debugLog(2, "greyLinkCount = [" .. greyLinkCount .. "]")		if (blueLinkCount <= 1) then		-- This is a navbar to nowhere, so suppress display		myNavTable = ""		debugLog(1, "Zero bluelinks (other than the current page) makes this a navbox to nowhere, so do not display the navbox")	end		local myTrackingCat = makeTrackingCategory()	return publishDebugLog() .. myNavTable .. myTrackingCatendreturn p