<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://academia.la/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Autilities</id>
	<title>Module:utilities - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://academia.la/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Autilities"/>
	<link rel="alternate" type="text/html" href="https://academia.la/w/index.php?title=Module:utilities&amp;action=history"/>
	<updated>2026-04-29T19:47:07Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://academia.la/w/index.php?title=Module:utilities&amp;diff=1485&amp;oldid=prev</id>
		<title>Jācōbus: Created page with &quot;local export = {}  local data = mw.loadData(&quot;Module:utilities/data&quot;) local notneeded = data.notneeded local neededhassubpage = data.neededhassubpage  -- A helper function to escape magic characters in a string -- Magic characters: ^$()%.[]*+-? function export.pattern_escape(text) 	if type(text) == &quot;table&quot; then 		text = text.args[1] 	end 	text = mw.ustring.gsub(text, &quot;([%^$()%%.%[%]*+%-?])&quot;, &quot;%%%1&quot;) 	return text end  function export.plain_gsub(text, pattern, replacement)...&quot;</title>
		<link rel="alternate" type="text/html" href="https://academia.la/w/index.php?title=Module:utilities&amp;diff=1485&amp;oldid=prev"/>
		<updated>2023-02-07T22:43:52Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  local data = mw.loadData(&amp;quot;Module:utilities/data&amp;quot;) local notneeded = data.notneeded local neededhassubpage = data.neededhassubpage  -- A helper function to escape magic characters in a string -- Magic characters: ^$()%.[]*+-? function export.pattern_escape(text) 	if type(text) == &amp;quot;table&amp;quot; then 		text = text.args[1] 	end 	text = mw.ustring.gsub(text, &amp;quot;([%^$()%%.%[%]*+%-?])&amp;quot;, &amp;quot;%%%1&amp;quot;) 	return text end  function export.plain_gsub(text, pattern, replacement)...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
local data = mw.loadData(&amp;quot;Module:utilities/data&amp;quot;)&lt;br /&gt;
local notneeded = data.notneeded&lt;br /&gt;
local neededhassubpage = data.neededhassubpage&lt;br /&gt;
&lt;br /&gt;
-- A helper function to escape magic characters in a string&lt;br /&gt;
-- Magic characters: ^$()%.[]*+-?&lt;br /&gt;
function export.pattern_escape(text)&lt;br /&gt;
	if type(text) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		text = text.args[1]&lt;br /&gt;
	end&lt;br /&gt;
	text = mw.ustring.gsub(text, &amp;quot;([%^$()%%.%[%]*+%-?])&amp;quot;, &amp;quot;%%%1&amp;quot;)&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.plain_gsub(text, pattern, replacement)&lt;br /&gt;
	local invoked = false&lt;br /&gt;
	&lt;br /&gt;
	if type(text) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		invoked = true&lt;br /&gt;
		&lt;br /&gt;
		if text.args then&lt;br /&gt;
			local frame = text&lt;br /&gt;
			&lt;br /&gt;
			local params = {&lt;br /&gt;
				[1] = {},&lt;br /&gt;
				[2] = {},&lt;br /&gt;
				[3] = { allow_empty = true },&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			local args = require(&amp;quot;Module:parameters&amp;quot;).process(frame.args, params)&lt;br /&gt;
			&lt;br /&gt;
			text = args[1]&lt;br /&gt;
			pattern = args[2]&lt;br /&gt;
			replacement = args[3]&lt;br /&gt;
		else&lt;br /&gt;
			error(&amp;quot;If the first argument to plain_gsub is a table, it should be a frame object.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if not ( type(pattern) == &amp;quot;string&amp;quot; or type(pattern) == &amp;quot;number&amp;quot; ) then&lt;br /&gt;
			error(&amp;quot;The second argument to plain_gsub should be a string or a number.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if not ( type(replacement) == &amp;quot;string&amp;quot; or type(replacement) == &amp;quot;number&amp;quot; ) then&lt;br /&gt;
			error(&amp;quot;The third argument to plain_gsub should be a string or a number.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	pattern = export.pattern_escape(pattern)&lt;br /&gt;
	&lt;br /&gt;
	if invoked then&lt;br /&gt;
		text = mw.ustring.gsub(text, pattern, replacement)&lt;br /&gt;
		return text&lt;br /&gt;
	else&lt;br /&gt;
		return mw.ustring.gsub(text, pattern, replacement)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Format the categories with the appropriate sort key. CATEGORIES is a list of&lt;br /&gt;
categories.&lt;br /&gt;
	-- LANG is an object encapsulating a language; if nil, the object for&lt;br /&gt;
	   language code 'und' (undetermined) will be used.&lt;br /&gt;
	-- SORT_KEY is placed in the category invocation, and indicates how the&lt;br /&gt;
	   page will sort in the respective category. Normally this should be nil,&lt;br /&gt;
	   and a default sort key based on the subpage name (the part after the&lt;br /&gt;
	   colon) will be used.&lt;br /&gt;
	-- SORT_BASE lets you override the default sort key used when SORT_KEY is&lt;br /&gt;
	   nil. Normally, this should be nil, and a language-specific default sort&lt;br /&gt;
	   key is computed from the subpage name (e.g. for Russian this converts&lt;br /&gt;
	   Cyrillic ё to a string consisting of Cyrillic е followed by U+10FFFF,&lt;br /&gt;
	   so that effectively ё sorts after е instead of the default Wikimedia&lt;br /&gt;
	   sort, which (I think) is based on Unicode sort order and puts ё after я,&lt;br /&gt;
	   the last letter of the Cyrillic alphabet.&lt;br /&gt;
	-- FORCE_OUTPUT forces normal output in all namespaces. Normally, nothing&lt;br /&gt;
	   is output if the page isn't in the main, Appendix:, Reconstruction: or&lt;br /&gt;
	   Citations: namespaces.&lt;br /&gt;
]]&lt;br /&gt;
function export.format_categories(categories, lang, sort_key, sort_base, force_output, sc)&lt;br /&gt;
	if type(lang) == &amp;quot;table&amp;quot; and not lang.getCode then&lt;br /&gt;
		error(&amp;quot;The second argument to format_categories should be a language object.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local title_obj = mw.title.getCurrentTitle()	&lt;br /&gt;
	local allowedNamespaces = {&lt;br /&gt;
		[0] = true, [100] = true, [114] = true, [118] = true -- (main), Appendix, Citations, Reconstruction&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if force_output or allowedNamespaces[title_obj.namespace] or title_obj.prefixedText == &amp;quot;Wiktionary:Sandbox&amp;quot; then&lt;br /&gt;
		local PAGENAME = title_obj.text&lt;br /&gt;
		local SUBPAGENAME = title_obj.subpageText&lt;br /&gt;
		&lt;br /&gt;
		if not lang then&lt;br /&gt;
			lang = require(&amp;quot;Module:languages&amp;quot;).getByCode(&amp;quot;und&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if sort_key ~= &amp;quot;-&amp;quot; then&lt;br /&gt;
			-- Generate a default sort key&lt;br /&gt;
			sort_base = lang:makeSortKey(sort_base or SUBPAGENAME, sc)&lt;br /&gt;
			if sort_key and sort_key ~= &amp;quot;&amp;quot; then&lt;br /&gt;
				-- Gather some statistics regarding sort keys&lt;br /&gt;
				if mw.ustring.upper(sort_key) == sort_base then&lt;br /&gt;
					table.insert(categories, &amp;quot;Sort key tracking/redundant&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				sort_key = sort_base&lt;br /&gt;
			end&lt;br /&gt;
			-- If the sortkey is empty, remove it.&lt;br /&gt;
			-- Leave the sortkey if it is equal to PAGENAME, because it still&lt;br /&gt;
			-- might be different from DEFAULTSORT and therefore have an effect; see&lt;br /&gt;
			-- [[Wiktionary:Grease pit/2020/April#Module:utilities#format categories]].&lt;br /&gt;
			if sort_key == &amp;quot;&amp;quot; then&lt;br /&gt;
				sort_key = nil&lt;br /&gt;
			end&lt;br /&gt;
		-- If the sort key is &amp;quot;-&amp;quot;, bypass the process of generating a sort key altogether. This is desirable when categorising (e.g.) translation requests, as the pages to be categorised are always in English/Translingual.&lt;br /&gt;
		else&lt;br /&gt;
			sort_key = mw.ustring.upper(sort_base or SUBPAGENAME)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local out_categories = {}&lt;br /&gt;
		for key, cat in ipairs(categories) do&lt;br /&gt;
			out_categories[key] = &amp;quot;[[Category:&amp;quot; .. cat .. (sort_key and &amp;quot;|&amp;quot; .. sort_key or &amp;quot;&amp;quot;) .. &amp;quot;]]&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		return table.concat(out_categories, &amp;quot;&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.catfix(lang, sc)&lt;br /&gt;
	if not lang then&lt;br /&gt;
		require(&amp;quot;Module:debug&amp;quot;).track(&amp;quot;catfix/no lang&amp;quot;)&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif type(lang) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		require(&amp;quot;Module:debug&amp;quot;).track(&amp;quot;catfix/lang not table&amp;quot;)&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local canonicalName = lang:getCanonicalName() or error('The first argument to the function &amp;quot;catfix&amp;quot; should be a language object from Module:languages.')&lt;br /&gt;
	&lt;br /&gt;
	if sc and not sc.getCode then&lt;br /&gt;
		error('The second argument to the function &amp;quot;catfix&amp;quot; should be a script object from Module:scripts.')&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- To add script classes to links on pages created by category boilerplate templates.&lt;br /&gt;
	if not sc then&lt;br /&gt;
		sc = data.catfix_scripts[lang:getCode()]&lt;br /&gt;
		if sc then&lt;br /&gt;
			sc = require(&amp;quot;Module:scripts&amp;quot;).getByCode(sc)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return &amp;quot;&amp;lt;span id=\&amp;quot;catfix\&amp;quot; style=\&amp;quot;display:none;\&amp;quot; class=\&amp;quot;CATFIX-&amp;quot; .. mw.uri.anchorEncode(canonicalName) .. &amp;quot;\&amp;quot;&amp;gt;&amp;quot; ..&lt;br /&gt;
		require(&amp;quot;Module:script utilities&amp;quot;).tag_text(&amp;quot;&amp;amp;nbsp;&amp;quot;, lang, sc, nil) ..&lt;br /&gt;
		&amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.catfix_template(frame)&lt;br /&gt;
	local params = {&lt;br /&gt;
		[1] = {},&lt;br /&gt;
		[2] = { alias_of = &amp;quot;sc&amp;quot; },&lt;br /&gt;
		[&amp;quot;sc&amp;quot;] = {},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	local args = require(&amp;quot;Module:parameters&amp;quot;).process(frame:getParent().args, params)&lt;br /&gt;
	&lt;br /&gt;
	local lang = require(&amp;quot;Module:languages&amp;quot;).getByCode(args[1]) or require(&amp;quot;Module:languages&amp;quot;).err(args[1], 1)&lt;br /&gt;
	&lt;br /&gt;
	local sc = args.sc&lt;br /&gt;
	if sc then&lt;br /&gt;
		sc = require(&amp;quot;Module:scripts&amp;quot;).getByCode(sc) or error('The script code &amp;quot;' .. sc .. '&amp;quot;, provided in the second parameter, is not valid.')&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return export.catfix(lang, sc)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Not exporting because it is not used yet.&lt;br /&gt;
local function getDateTense(frame) &lt;br /&gt;
	local name_num_mapping = {[&amp;quot;January&amp;quot;] = 1, [&amp;quot;February&amp;quot;] = 2, [&amp;quot;March&amp;quot;] = 3, [&amp;quot;April&amp;quot;] = 4, [&amp;quot;May&amp;quot;] = 5, [&amp;quot;June&amp;quot;] = 6, &lt;br /&gt;
		[&amp;quot;July&amp;quot;] = 7, [&amp;quot;August&amp;quot;] = 8, [&amp;quot;September&amp;quot;] = 9, [&amp;quot;October&amp;quot;] = 10, [&amp;quot;November&amp;quot;] = 11, [&amp;quot;December&amp;quot;] = 12, &lt;br /&gt;
		[1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12}&lt;br /&gt;
	local month = name_num_mapping[frame.args[2]]&lt;br /&gt;
	local date = os.time({year = frame.args[1], day = frame.args[3], month = month})&lt;br /&gt;
	local today = os.time() -- 12 AM/PM&lt;br /&gt;
	local diff = os.difftime(date, today)&lt;br /&gt;
	local daylength = 24 * 3600&lt;br /&gt;
	&lt;br /&gt;
	if diff &amp;lt; -daylength / 2 then return &amp;quot;past&amp;quot;&lt;br /&gt;
	else &lt;br /&gt;
		if diff &amp;gt; daylength / 2  then return &amp;quot;future&amp;quot;&lt;br /&gt;
		else return &amp;quot;present&amp;quot; end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.make_id(lang, str)&lt;br /&gt;
	--[[	If called with invoke, first argument is a frame object.&lt;br /&gt;
			If called by a module, first argument is a language object. ]]&lt;br /&gt;
	local invoked = false&lt;br /&gt;
	&lt;br /&gt;
	if type(lang) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		if lang.args then&lt;br /&gt;
			invoked = true&lt;br /&gt;
			&lt;br /&gt;
			local frame = lang&lt;br /&gt;
			&lt;br /&gt;
			local params = {&lt;br /&gt;
				[1] = {},&lt;br /&gt;
				[2] = {},&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			local args = require(&amp;quot;Module:parameters&amp;quot;).process(frame:getParent().args, params)&lt;br /&gt;
			&lt;br /&gt;
			local langCode = args[1]&lt;br /&gt;
			str = args[2]&lt;br /&gt;
			&lt;br /&gt;
			local m_languages = require(&amp;quot;Module:languages&amp;quot;)&lt;br /&gt;
			&lt;br /&gt;
			lang = m_languages.getByCode(langCode) or m_languages.err(langCode, 1)&lt;br /&gt;
		elseif not lang.getCanonicalName then&lt;br /&gt;
			error(&amp;quot;The first argument to make_id should be a language object.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not ( type(str) == &amp;quot;string&amp;quot; or type(str) == &amp;quot;number&amp;quot; ) then&lt;br /&gt;
		error(&amp;quot;The second argument to make_id should be a string or a number.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local id = require(&amp;quot;Module:senseid&amp;quot;).anchor(lang, str)&lt;br /&gt;
	&lt;br /&gt;
	if invoked then&lt;br /&gt;
		return '&amp;lt;li class=&amp;quot;senseid&amp;quot; id=&amp;quot;' .. id .. '&amp;quot;&amp;gt;'&lt;br /&gt;
	else&lt;br /&gt;
		return id&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Jācōbus</name></author>
	</entry>
</feed>