<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.roatpkz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ACategory_handler</id>
	<title>Module:Category handler - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.roatpkz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ACategory_handler"/>
	<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Category_handler&amp;action=history"/>
	<updated>2026-04-28T12:58:38Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.roatpkz.com/index.php?title=Module:Category_handler&amp;diff=298&amp;oldid=prev</id>
		<title>Hefner: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Category_handler&amp;diff=298&amp;oldid=prev"/>
		<updated>2024-03-23T19:30:07Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:30, 23 March 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Hefner</name></author>
	</entry>
	<entry>
		<id>https://wiki.roatpkz.com/index.php?title=Module:Category_handler&amp;diff=297&amp;oldid=prev</id>
		<title>Armadyl Godsword&gt;Shayani: Protected &quot;Module:Category handler&quot;: High use module/template: considering the main template invoking it is also autoconf protected ([Edit=Only allow autoconfirmed users] (indefinite) [Move=Only allow autoconfirmed users] (indefinite))</title>
		<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Category_handler&amp;diff=297&amp;oldid=prev"/>
		<updated>2022-04-26T10:30:51Z</updated>

		<summary type="html">&lt;p&gt;Protected &amp;quot;&lt;a href=&quot;/Module:Category_handler&quot; title=&quot;Module:Category handler&quot;&gt;Module:Category handler&lt;/a&gt;&amp;quot;: High use module/template: considering the main template invoking it is also autoconf protected ([Edit=Only allow autoconfirmed users] (indefinite) [Move=Only allow autoconfirmed users] (indefinite))&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[=[ &amp;lt;pre&amp;gt;&lt;br /&gt;
-- Implements [Template:Ctg]&lt;br /&gt;
-- Sorts pages into a category more appropriately than pagename alone&lt;br /&gt;
-- Default and custom rules are outlined at [[Template:Category handler/doc]]&lt;br /&gt;
--]=]&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local ucf = require(&amp;#039;Module:Paramtest&amp;#039;).ucfirst&lt;br /&gt;
&lt;br /&gt;
local curpage = mw.title.getCurrentTitle()&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local ns = curpage.namespace&lt;br /&gt;
&lt;br /&gt;
	-- Just don&amp;#039;t bother unless we&amp;#039;re in content namespaces&lt;br /&gt;
	if not (ns == 0 or ns == 120 or ns == 116) then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local args = frame:getParent().args &lt;br /&gt;
	local cats = {}&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs(args) do&lt;br /&gt;
		local cat_x = {}&lt;br /&gt;
&lt;br /&gt;
		-- Replace underscores with spaces&lt;br /&gt;
		-- Condense and trim white-space; remove new lines (just in case)&lt;br /&gt;
		v = mw.text.trim(v)&lt;br /&gt;
			:gsub(&amp;#039;[_%s]+&amp;#039;,&amp;#039; &amp;#039;)&lt;br /&gt;
			:gsub(&amp;#039;\n&amp;#039;,&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		-- Snip category name now, up to the index of the first set of two colons&lt;br /&gt;
		-- If no colons, just use the whole string&lt;br /&gt;
		local cat_n = (v:match(&amp;#039;^([^:]+)::&amp;#039;) or v)&lt;br /&gt;
				:gsub(&amp;#039;[Cc]ategory:%s*&amp;#039;,&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		-- Set category name to the name just snipped&lt;br /&gt;
		cat_x.name = cat_n&lt;br /&gt;
&lt;br /&gt;
		-- Page title includes matched text&lt;br /&gt;
		-- Matched text is defined by ::ifmatches[text]&lt;br /&gt;
		-- or if empty, defaults to category name&lt;br /&gt;
		if v:find(&amp;#039;::ifmatches&amp;#039;) then&lt;br /&gt;
			-- Look for brackets used as delimiters and capture them all&lt;br /&gt;
			local match_set = v:match(&amp;#039;::ifmatches(%[[^:]+%])&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
			-- If none are found, use the pagename&lt;br /&gt;
			if not match_set then&lt;br /&gt;
				cat_x.ifmatch = {cat_n}&lt;br /&gt;
			else&lt;br /&gt;
				cat_x.ifmatch = {}&lt;br /&gt;
				-- Split match into table, delimited by brackets&lt;br /&gt;
				match_set = mw.text.split(match_set,&amp;#039;[%]%[]+&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
				-- Add to match table; only if not blank&lt;br /&gt;
				-- An empty string is created by &amp;quot;[&amp;quot; at the beginning&lt;br /&gt;
				for _, w in ipairs(match_set) do&lt;br /&gt;
					if w:find(&amp;#039;%S&amp;#039;) then&lt;br /&gt;
						table.insert(cat_x.ifmatch,w)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Iterate through and escape all metacharacters&lt;br /&gt;
			-- Prevents errors when they&amp;#039;re passed to string.match() below&lt;br /&gt;
			-- Make everything lowercase&lt;br /&gt;
			for i, w in ipairs(cat_x.ifmatch) do&lt;br /&gt;
				cat_x.ifmatch[i] = w:gsub(&lt;br /&gt;
						-- Chars: - ^ $ * ( ) + ?&lt;br /&gt;
						&amp;#039;([%-^$*()+?])&amp;#039;,&lt;br /&gt;
						&amp;#039;%%%1&amp;#039;):lower()&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Text to strip from the front of the sort&lt;br /&gt;
		-- Can be user defined with ::remove[text]&lt;br /&gt;
		-- Defaults to category name exactly&lt;br /&gt;
		-- Escape metacharacters to prevent errors when they&amp;#039;re passed to string.match() below&lt;br /&gt;
		cat_x.trim = string.gsub(&lt;br /&gt;
				v:match(&amp;#039;::remove%[%s*([^]:]+)%s*%]&amp;#039;) or&lt;br /&gt;
					cat_n,&lt;br /&gt;
					-- Chars: - ^ $ * ( ) + ?&lt;br /&gt;
					&amp;#039;([%-^$*()+?])&amp;#039;,&lt;br /&gt;
					&amp;#039;%%%1&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		-- Add category and its rules into the list&lt;br /&gt;
		table.insert(cats,cat_x)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return p._main(cats)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(cat_list)&lt;br /&gt;
	-- Pagename, exactly, in all lowercase, and escaped (used for matching)&lt;br /&gt;
	local pagename = curpage.text&lt;br /&gt;
	local pagelc = pagename:lower()&lt;br /&gt;
	local pageesc = pagelc:gsub(&lt;br /&gt;
				-- Chars: - ^ $ * ( ) + ?&lt;br /&gt;
				&amp;#039;([%-^$*()+?])&amp;#039;,&lt;br /&gt;
				&amp;#039;%%%1&amp;#039;)&lt;br /&gt;
	-- Return table&lt;br /&gt;
	local ctg = {}&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs(cat_list) do&lt;br /&gt;
		-- Category name and in lowercase&lt;br /&gt;
		local cn = v.name&lt;br /&gt;
		local cnl = cn:lower()&lt;br /&gt;
		-- Text to remove&lt;br /&gt;
		local rmv = v.trim:lower()&lt;br /&gt;
&lt;br /&gt;
		-- Little thing that checks pagename against everything in the matches table&lt;br /&gt;
		-- If there&amp;#039;s no table, keep as false (it won&amp;#039;t matter)&lt;br /&gt;
		local pagematches = false&lt;br /&gt;
		if v.ifmatch then&lt;br /&gt;
			for _, w in ipairs(v.ifmatch) do&lt;br /&gt;
				-- Look for exact match, and with faux-singular too&lt;br /&gt;
				if pagelc:find(w) or&lt;br /&gt;
				(w:find(&amp;#039;s$&amp;#039;) and &lt;br /&gt;
					pagelc:find(w:match(&amp;#039;(.*)s$&amp;#039;)))&lt;br /&gt;
				then&lt;br /&gt;
					pagematches = true&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Create a second string that counts as the singular of the text to remove&lt;br /&gt;
		-- If it works as a singular, and the page name is singular, then use it too&lt;br /&gt;
		-- Otherwise, just make it the same as rmv&lt;br /&gt;
		local rmvpl = rmv&lt;br /&gt;
		if rmv:find(&amp;#039;s$&amp;#039;) then&lt;br /&gt;
			rmvpl = rmv:match(&amp;#039;(.*)s$&amp;#039;)&lt;br /&gt;
			if pagelc:find(&amp;#039;^&amp;#039;..rmvpl) and&lt;br /&gt;
			(not pagelc:find(&amp;#039;^&amp;#039;..rmv))&lt;br /&gt;
			then&lt;br /&gt;
				-- Nothing&lt;br /&gt;
			else&lt;br /&gt;
				rmvpl = rmv&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- If v.ifmatch is not specified or&lt;br /&gt;
		-- It is and the pattern matches any part of the pagename&lt;br /&gt;
		-- Continue to add categories&lt;br /&gt;
		if (not v.ifmatch) or&lt;br /&gt;
			(v.ifmatch and pagematches)&lt;br /&gt;
		then&lt;br /&gt;
			-- If the pagename matches category name exactly&lt;br /&gt;
			-- Or either is a simple plural of the other&lt;br /&gt;
			-- Or the text to remove exactly&lt;br /&gt;
			-- Sort to front&lt;br /&gt;
			if pagelc:find(&amp;#039;^&amp;#039;..cnl..&amp;#039;$&amp;#039;) or&lt;br /&gt;
				cnl:find(&amp;#039;^&amp;#039;..pageesc..&amp;#039;s$&amp;#039;) or&lt;br /&gt;
				pagelc:find(&amp;#039;^&amp;#039;..cnl..&amp;#039;s$&amp;#039;) or&lt;br /&gt;
				pagelc:find(&amp;#039;^&amp;#039;..rmv..&amp;#039;$&amp;#039;)&lt;br /&gt;
			then&lt;br /&gt;
				table.insert(ctg,string.format(&amp;#039;[[Category:%s| ]]&amp;#039;,cn))&lt;br /&gt;
&lt;br /&gt;
			-- If the pagename begins with the category name&lt;br /&gt;
			-- Sort with beginning remove&lt;br /&gt;
			elseif pagelc:find(&amp;#039;^&amp;#039;..rmv) or &lt;br /&gt;
				pagelc:find(&amp;#039;^&amp;#039;..rmvpl)&lt;br /&gt;
			then&lt;br /&gt;
				-- Offset by an extra character if it&amp;#039;s not plural&lt;br /&gt;
				-- Or the page starts with plural&lt;br /&gt;
				if rmvpl == rmv then&lt;br /&gt;
					offset = 1&lt;br /&gt;
				else&lt;br /&gt;
					offset = 0&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				-- Unescape metacharacters for proper length&lt;br /&gt;
				local key = pagename:sub( #(rmv:gsub(&amp;#039;%%&amp;#039;,&amp;#039;&amp;#039;)) + offset )&lt;br /&gt;
&lt;br /&gt;
				key = ucf(mw.text.trim(key))&lt;br /&gt;
&lt;br /&gt;
				-- Remove punctuation from start if leftover&lt;br /&gt;
				-- Such as &amp;quot;/&amp;quot; leftover on subpages&lt;br /&gt;
				-- Or &amp;quot;(&amp;quot; for disambiguated pages&lt;br /&gt;
				if key:find(&amp;#039;^%p&amp;#039;) then&lt;br /&gt;
					key = ucf(key:sub(2))&lt;br /&gt;
				-- Just in case, remove &amp;quot;s&amp;quot; preceding punctuation&lt;br /&gt;
				elseif key:find(&amp;#039;^S%p&amp;#039;) then&lt;br /&gt;
					key = ucf(key:sub(3))&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				table.insert(ctg,string.format(&amp;#039;[[Category:%s|%s]]&amp;#039;,cn,key))&lt;br /&gt;
&lt;br /&gt;
			-- Everything else just gets the category added plainly&lt;br /&gt;
			else&lt;br /&gt;
				table.insert(ctg,string.format(&amp;#039;[[Category:%s]]&amp;#039;,cn))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(ctg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Armadyl Godsword&gt;Shayani</name></author>
	</entry>
</feed>