This module is exports various general utility functions, which can be used by other modules.



Escapes the magic characters used in Regular Expression patterns. For example, "^$()%.[]*+-?|" becomes "%^%$%(%)%%%.%[%]%*%+%-%?%|".


format_categories(categories, lang, sort_key, sort_base, force_output)

Formats a list (table) of category names. The output is a string consisting of all categories with [[Category:...]] applied to each one, and the given sort key added. If the namespace is not the main, Appendix or Reconstruction namespaces, the output will be an empty string unless FORCE_OUTPUT is given. If no sort key is given:

  1. A default one is generated by using SORT_BASE (if given) or the current subpage name, and by removing hyphens from the beginning (so that suffixes can be sorted without a key).
  2. If a sort key is available for the given language, it is then used to create a sort key that follows the rules for that language.
  3. If the final sort key ends up being identical to PAGENAME (which is the default key used by the software), then it is omitted entirely, so that it can be used in combination with DEFAULTSORT.



This function is used by the {{categorize}}, {{catlangname}} and {{catlangcode}} templates.

local export = {}

local notneeded = {
	["und"] = true,
	["cmn"] = true,
	["ja"] = true,
	["zu"] = true,
	["nan"] = true,
	["yue"] = true,
	["ko"] = true,

local neededhassubpage = {
	["ga"] = true,
	["gv"] = true,
	["nv"] = true,
	["roa-jer"] = true,
	["fr"] = true,
	["rm"] = true,
	["prg"] = true,
	["gd"] = true,
	["twf"] = true,
	["en"] = true,
	["ro"] = true,
	["egl"] = true,
	["roa-tar"] = true,
	["gl"] = true,
	["ast"] = true,
	["br"] = true,

-- A helper function to escape magic characters in a string
-- Magic characters: ^$()%.[]*+-?
function export.pattern_escape(text)
	text = (type(text) == "table" and text.args[1] or text)
	text = mw.ustring.gsub(text, "([%^$()%%.%[%]*+%-?|])", "%%%1")
	return text

Format the categories with the appropriate sort key. CATEGORIES is a list of
	-- LANG is an object encapsulating a language; if nil, the object for
	   language code 'und' (undetermined) will be used.
	-- SORT_KEY is placed in the category invocation, and indicates how the
	   page will sort in the respective category. Normally this should be nil,
	   and a default sort key based on the subpage name (the part after the
	   colon) will be used.
	-- SORT_BASE lets you override the default sort key used when SORT_KEY is
	   nil. Normally, this should be nil, and a language-specific default sort
	   key is computed from the subpage name (e.g. for Russian this converts
	   Cyrillic ё to a string consisting of Cyrillic е followed by U+10FFFF,
	   so that effectively ё sorts after е instead of the default Wikimedia
	   sort, which (I think) is based on Unicode sort order and puts ё after я,
	   the last letter of the Cyrillic alphabet.
	-- FORCE_OUTPUT forces normal output in all namespaces. Normally, nothing
	   is output if the page isn't in the main, Appendix: or Reconstruction:
function export.format_categories(categories, lang, sort_key, sort_base, force_output)
	NAMESPACE = NAMESPACE or mw.title.getCurrentTitle().nsText
	if force_output or NAMESPACE == "" or NAMESPACE == "Appendix" or NAMESPACE == "Reconstruction" then
		PAGENAME = PAGENAME or mw.title.getCurrentTitle().text
		SUBPAGENAME = SUBPAGENAME or mw.title.getCurrentTitle().subpageText
		if not lang then
			lang = require("Module:languages").getByCode("und")
		-- Generate a default sort key
		sort_base = lang:makeSortKey(sort_base or SUBPAGENAME)
		if sort_key then
			-- Gather some statistics regarding sort keys
			if mw.ustring.lower(sort_key) == sort_base then
				table.insert(categories, "Sort key tracking/redundant")
			sort_key = sort_base
		-- If the resulting key is the same as the wiki software's default, remove it
		if sort_key == PAGENAME then
			sort_key = nil
		for key, cat in ipairs(categories) do
			categories[key] = "[[Category:" .. cat .. (sort_key and "|" .. sort_key or "") .. "]]"
		return table.concat(categories, "")
		return ""

-- Used by {{categorize}}
function export.template_categorize(frame)
	NAMESPACE = NAMESPACE or mw.title.getCurrentTitle().nsText
	local format = frame.args["format"]
	local args = frame:getParent().args
	local langcode = args[1]; if langcode == "" then langcode = nil end
	local sort_key = args["sort"]; if sort_key == "" then sort_key = nil end
	local categories = {}
	if not langcode then
		if NAMESPACE == "Template" then return "" end
		error("Language code has not been specified. Please pass parameter 1 to the template.")
	local lang = require("Module:languages").getByCode(langcode)
	if not lang then
		if NAMESPACE == "Template" then return "" end
		error("The language code \"" .. langcode .. "\" is not valid.")
	local prefix = ""
	if format == "pos" then
		prefix = lang:getCanonicalName() .. " "
	elseif format == "topic" then
		prefix = lang:getCode() .. ":"
	local i = 2
	local cat = args[i]
	while cat do
		if cat ~= "" then
			table.insert(categories, prefix .. cat)
		i = i + 1
		cat = args[i]
	return export.format_categories(categories, lang, sort_key)

return export