<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://maruneko.autumns.page/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AStr_find_word</id>
	<title>Module:Str find word - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://maruneko.autumns.page/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AStr_find_word"/>
	<link rel="alternate" type="text/html" href="https://maruneko.autumns.page/mediawiki/index.php?title=Module:Str_find_word&amp;action=history"/>
	<updated>2026-04-24T15:46:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://maruneko.autumns.page/mediawiki/index.php?title=Module:Str_find_word&amp;diff=8540&amp;oldid=prev</id>
		<title>Marie: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://maruneko.autumns.page/mediawiki/index.php?title=Module:Str_find_word&amp;diff=8540&amp;oldid=prev"/>
		<updated>2026-03-05T07:14:36Z</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;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:14, 5 March 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&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;!-- diff cache key jth_wiki:diff:1.41:old-8539:rev-8540 --&gt;
&lt;/table&gt;</summary>
		<author><name>Marie</name></author>
	</entry>
	<entry>
		<id>https://maruneko.autumns.page/mediawiki/index.php?title=Module:Str_find_word&amp;diff=8539&amp;oldid=prev</id>
		<title>wikipedia&gt;Lemondoge: Undid revision 1147915801 by Lemondoge (talk): oh dear. I checked with testcases - don't know how this goofed</title>
		<link rel="alternate" type="text/html" href="https://maruneko.autumns.page/mediawiki/index.php?title=Module:Str_find_word&amp;diff=8539&amp;oldid=prev"/>
		<updated>2023-04-03T00:35:55Z</updated>

		<summary type="html">&lt;p&gt;Undid revision 1147915801 by &lt;a href=&quot;/mediawiki/index.php/Special:Contributions/Lemondoge&quot; title=&quot;Special:Contributions/Lemondoge&quot;&gt;Lemondoge&lt;/a&gt; (&lt;a href=&quot;/mediawiki/index.php?title=User_talk:Lemondoge&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User talk:Lemondoge (page does not exist)&quot;&gt;talk&lt;/a&gt;): oh dear. I checked with testcases - don&amp;#039;t know how this goofed&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require('strict')&lt;br /&gt;
local p = {}&lt;br /&gt;
local getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
local str = require('Module:String')&lt;br /&gt;
local yesno = require('Module:Yesno')&lt;br /&gt;
local defaultSep = ','&lt;br /&gt;
local iMaxWords = 16&lt;br /&gt;
local warningIMaxWordsReached = nil&lt;br /&gt;
local xpLitWordCount = 0&lt;br /&gt;
local report -- to be initinated when explain needed&lt;br /&gt;
&lt;br /&gt;
-- Initialise the /report subpage.&lt;br /&gt;
-- only invoked when 'explain' asked&lt;br /&gt;
local function initReport()&lt;br /&gt;
	report = require('Module:Str find word/report')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Turn &amp;quot;&amp;amp;#x0041;&amp;quot; into &amp;quot;A&amp;quot; etc. asap&lt;br /&gt;
-- and reduce multi-spaces (including nbsp etc.) into single space&lt;br /&gt;
local function decodeUnicode(str)&lt;br /&gt;
	return mw.ustring.gsub(mw.text.decode(str), '%s+', ' ')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- %-Escape any word (character string) before feeding it into a string pattern function&lt;br /&gt;
-- all punctuation (%p) will be %-escaped&lt;br /&gt;
local function escape_word(word)&lt;br /&gt;
	return str._escapePattern(word)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Reads and parses a word list and returns a table with words (simple array)&lt;br /&gt;
-- words list can be: source, andwords-to-check, orwords-to-check&lt;br /&gt;
-- step 1: when case-insensitive, turn string into lowercase&lt;br /&gt;
-- step 2: read &amp;amp; remove Literals (&amp;quot;..&amp;quot;)&lt;br /&gt;
-- step 3: read comma-separated words&lt;br /&gt;
-- step 4: when booleans=T, change boolean words into true/false (module:yesno rules)&lt;br /&gt;
--		all words returned are trimmed, TODO and all ws into single-plainspace?&lt;br /&gt;
--		only T/F words are edited, other words remain, untouched&lt;br /&gt;
-- return the table (a straight array)&lt;br /&gt;
local function buildWordTable(tArgs, sWordlist)&lt;br /&gt;
local wordTable = {}&lt;br /&gt;
local hitWord	= ''&lt;br /&gt;
local hitCount	= 0&lt;br /&gt;
	if sWordlist == '' then return wordTable end&lt;br /&gt;
&lt;br /&gt;
	-- Step 1: case-sensitive&lt;br /&gt;
	if yesno(tArgs.case, true) == false then&lt;br /&gt;
		sWordlist = string.lower(sWordlist)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Step 2: read &amp;quot;literals&amp;quot;, &lt;br /&gt;
	-- then remove them from the string:&lt;br /&gt;
	-- replaced by single comma; idle &amp;amp; keeps word separation&lt;br /&gt;
	--- if yesno(tArgs.literals, false) then&lt;br /&gt;
	if false then&lt;br /&gt;
		local _, sCount&lt;br /&gt;
		_, sCount = mw.ustring.gsub(sWordlist, '&amp;quot;', '')&lt;br /&gt;
		if sCount &amp;gt; 1 then&lt;br /&gt;
			local litWord = ''&lt;br /&gt;
			local i, j&lt;br /&gt;
&lt;br /&gt;
			while sCount &amp;gt; 1 do -- could do here: only when even?&lt;br /&gt;
				i = string.find(sWordlist, '%&amp;quot;', 1, false)&lt;br /&gt;
				j = string.find(sWordlist, '%&amp;quot;', i+1, false)&lt;br /&gt;
				litWord = mw.text.trim(string.sub(sWordlist, i+1, j-1))&lt;br /&gt;
				if #litWord &amp;gt; 0 then -- not an empty string or spaces only&lt;br /&gt;
					xpLitWordCount = xpLitWordCount + 1&lt;br /&gt;
					table.insert(wordTable, litWord)&lt;br /&gt;
				end&lt;br /&gt;
				-- remove from source, and do next gsub search:&lt;br /&gt;
				sWordlist = string.gsub(sWordlist, '%&amp;quot;%s*'&lt;br /&gt;
												.. escape_word(litWord) &lt;br /&gt;
												.. '%s*%&amp;quot;', ',')&lt;br /&gt;
				_, sCount = mw.ustring.gsub(sWordlist, '&amp;quot;', '')&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Step 3: parse comma-delimited words&lt;br /&gt;
	hitCount = 0&lt;br /&gt;
	sWordlist = tArgs.sep .. sWordlist .. tArgs.sep&lt;br /&gt;
	local eSep&lt;br /&gt;
	eSep = escape_word(tArgs.sep)&lt;br /&gt;
	local patstring = '%f[^' .. eSep .. '][^' .. eSep .. ']+%f[' .. eSep .. ']'&lt;br /&gt;
	if yesno(tArgs.explain, false) then&lt;br /&gt;
		report.xpMessage('1.eSep: ' .. eSep) -- dev&lt;br /&gt;
		report.xpMessage('2.pattern: ' .. patstring) -- dev&lt;br /&gt;
	end&lt;br /&gt;
 	while hitCount &amp;lt;= iMaxWords do&lt;br /&gt;
		hitCount = hitCount + 1&lt;br /&gt;
		&lt;br /&gt;
		hitWord = str._match(sWordlist, patstring, 1, hitCount, false, tArgs.sep)&lt;br /&gt;
		hitWord = mw.text.trim(hitWord)&lt;br /&gt;
		if hitWord == tArgs.sep then&lt;br /&gt;
			-- no more words found in the string&lt;br /&gt;
			break&lt;br /&gt;
		elseif hitWord ~= '' then&lt;br /&gt;
			table.insert(wordTable, hitWord)&lt;br /&gt;
		end&lt;br /&gt;
 	end&lt;br /&gt;
 	if hitCount &amp;gt; iMaxWords then &lt;br /&gt;
	 	warningIMaxWordsReached = 'Max number of words (' .. tostring(iMaxWords) .. ') reached. Extra words are ignored.'&lt;br /&gt;
	 								.. ' (' .. mw.ustring.sub(mw.text.trim(sWordlist), 1, 90) .. '&amp;amp;nbsp;...). '&lt;br /&gt;
 	end&lt;br /&gt;
&lt;br /&gt;
	-- Step 4: when read booleans, converse words to true/false&lt;br /&gt;
	-- todo: check parameter here not elsewhere&lt;br /&gt;
	if tArgs.booleans then -- TODO if Yesno(tArgs.booleans) ... &lt;br /&gt;
		local sBool&lt;br /&gt;
		for i, v in ipairs(wordTable) do&lt;br /&gt;
			sBool = yesno(v)&lt;br /&gt;
			if sBool ~= nil then&lt;br /&gt;
				wordTable[i] = tostring(sBool)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return wordTable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Check whether a single word is in a table (a simple array of words)&lt;br /&gt;
-- returns hitword or nil&lt;br /&gt;
local function findWordInTable(sourceWordTable, word)&lt;br /&gt;
	local bHit = false&lt;br /&gt;
	for i, v in ipairs(sourceWordTable) do&lt;br /&gt;
		if v == word then&lt;br /&gt;
			bHit = true&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if bHit then&lt;br /&gt;
		return word&lt;br /&gt;
	else&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- AND-logic with andWordTable words: ALL words must be found&lt;br /&gt;
-- returns {T/F, hittable}&lt;br /&gt;
--		T when *all* AND words are found&lt;br /&gt;
--		hittable with all hit words&lt;br /&gt;
-- note 1: when F, the hittable still contains the words that were found&lt;br /&gt;
-- note 2: empty AND-wordlist =&amp;gt; True by logic (because: not falsified)&lt;br /&gt;
local function checkANDwords(sourceWordTable, andWordTable)&lt;br /&gt;
local result1&lt;br /&gt;
local bAND&lt;br /&gt;
local tHits&lt;br /&gt;
&lt;br /&gt;
	bAND = true&lt;br /&gt;
	tHits = {}&lt;br /&gt;
	result1 = nil&lt;br /&gt;
	if #andWordTable &amp;gt; 0 then&lt;br /&gt;
		for i, word in ipairs(andWordTable) do&lt;br /&gt;
			result1 = findWordInTable(sourceWordTable, word) or nil&lt;br /&gt;
			if result1 == nil then&lt;br /&gt;
				bAND = false -- Falsified!&lt;br /&gt;
				-- could break after this logically but &lt;br /&gt;
				-- continue to complete the table (bAND remains false)&lt;br /&gt;
			else&lt;br /&gt;
				table.insert(tHits, result1)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		bAND = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return bAND, tHits&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- OR-logic with orWordTable words: at least one word must be found&lt;br /&gt;
-- returns {T/F, hittable}&lt;br /&gt;
--		True when at least one OR word is found&lt;br /&gt;
--		hittable has all hit words&lt;br /&gt;
-- note 1: empty OR-wordlist =&amp;gt; True by logic (because: not falsified)&lt;br /&gt;
-- note 2: while just one hitword is a True result, the hittable contains all words found&lt;br /&gt;
local function checkORwords(sourceWordTable, orWordTable)&lt;br /&gt;
local result1&lt;br /&gt;
local bOR&lt;br /&gt;
local tHits&lt;br /&gt;
&lt;br /&gt;
	bOR = false&lt;br /&gt;
	tHits = {}&lt;br /&gt;
	result1 = nil&lt;br /&gt;
	if #orWordTable &amp;gt; 0 then&lt;br /&gt;
		for i, word in ipairs(orWordTable) do&lt;br /&gt;
			result1 = findWordInTable(sourceWordTable, word) or nil&lt;br /&gt;
			if result1 == nil then&lt;br /&gt;
				-- this one is false; bOR unchanged; do next&lt;br /&gt;
			else&lt;br /&gt;
				bOR = true -- Confirmed!&lt;br /&gt;
				table.insert(tHits, result1)&lt;br /&gt;
				-- could break here logically, but complete the check&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		bOR = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return bOR, tHits&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Determine the requested return value (string).&lt;br /&gt;
-- sYeslist is the _main return value (logically defined value)&lt;br /&gt;
-- this function applies tArgs.yes / tArgs.no return value&lt;br /&gt;
-- note: yes='' implies: blank return value&lt;br /&gt;
-- note: no parameter yes= (that is, yes=nil) implies: by default, return the sYeslist&lt;br /&gt;
local function yesnoReturnstring(tArgs, sYeslist)&lt;br /&gt;
	if sYeslist == '' then -- False &lt;br /&gt;
		return tArgs.no or ''&lt;br /&gt;
	else -- True&lt;br /&gt;
		if tArgs.yes == nil then&lt;br /&gt;
			return sYeslist&lt;br /&gt;
		else -- some |yes= value is entered, could be ''&lt;br /&gt;
			return tArgs.yes&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isPreview()&lt;br /&gt;
local ifPreview = require('Module:If preview')&lt;br /&gt;
	return not (ifPreview._warning( {'is_preview'} ) == '')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Explain options (=report info), interprets parameter explain=&lt;br /&gt;
-- returns true/false/'testcases'&lt;br /&gt;
-- explain=true =&amp;gt; show report in Preview&lt;br /&gt;
-- explain=testcases =&amp;gt; WHEN in ns: template: or user: AND subpage = '/testcases' THEN show permanently&lt;br /&gt;
local function checkExplain(tArgs)&lt;br /&gt;
	return false  -- never. 22Mar2023 checkExplain(newArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== =====&lt;br /&gt;
-- _main function: check for presence of words in source string&lt;br /&gt;
-- Checks and returns:&lt;br /&gt;
--		when T: the string of all hitwords (default), or the |yes=... input&lt;br /&gt;
--		when F: empty string '' (default), or the |no=... input&lt;br /&gt;
-- steps:&lt;br /&gt;
-- 1. input word strings are prepared (parsed into an array of words)&lt;br /&gt;
-- 2. words checks are made (applying AND-logic, OR-logic)&lt;br /&gt;
-- 3. final conclusion drawn (T/F)&lt;br /&gt;
-- 4. optionally, the preview report is prepared (debug, feedback)&lt;br /&gt;
-- 5. based on T or F status, the return value (string) is established and returned&lt;br /&gt;
-- note 1: each return value (yes=.., no=..) can be '' (nulstring)&lt;br /&gt;
function p._main(tArgs)&lt;br /&gt;
local sourceWordTable	= {}&lt;br /&gt;
local andWordTable		= {}&lt;br /&gt;
local orWordTable		= {}&lt;br /&gt;
local tANDhits&lt;br /&gt;
local tORhits&lt;br /&gt;
-- logical finding:&lt;br /&gt;
local bANDresult	= false&lt;br /&gt;
local bORresult 	= false&lt;br /&gt;
local resultALL 	= false&lt;br /&gt;
local sYeslist		= ''&lt;br /&gt;
&lt;br /&gt;
	sourceWordTable	= buildWordTable(tArgs, tArgs.source)&lt;br /&gt;
	andWordTable	= buildWordTable(tArgs, tArgs.andString)&lt;br /&gt;
	orWordTable		= buildWordTable(tArgs, tArgs.orString)&lt;br /&gt;
&lt;br /&gt;
	if (#sourceWordTable == 0) or (#andWordTable + #orWordTable == 0) then&lt;br /&gt;
		-- No words to check&lt;br /&gt;
		resultALL = false&lt;br /&gt;
		if yesno(tArgs.explain, false) then&lt;br /&gt;
			report.xpNoWords(tArgs, sourceWordTable, andWordTable, orWordTable)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		bANDresult, tANDhits	= checkANDwords(sourceWordTable, andWordTable)&lt;br /&gt;
		bORresult, tORhits		= checkORwords(sourceWordTable, orWordTable)&lt;br /&gt;
		resultALL = (bANDresult) and (bORresult)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	sYeslist = ''&lt;br /&gt;
	if resultALL then&lt;br /&gt;
		-- concat the sYeslist (= all hit words; from 2 tables)&lt;br /&gt;
		if bANDresult then&lt;br /&gt;
			sYeslist = sYeslist .. table.concat(tANDhits, tArgs.sep)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if #tORhits &amp;gt; 0 then&lt;br /&gt;
			if #tANDhits &amp;gt; 0 then&lt;br /&gt;
				sYeslist = sYeslist .. tArgs.sep&lt;br /&gt;
			end&lt;br /&gt;
			sYeslist = sYeslist .. table.concat(tORhits, tArgs.sep)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if yesno(tArgs.explain, false) then&lt;br /&gt;
		if tArgs.yes ~= nil then&lt;br /&gt;
			if (tArgs.yes == '') and (tArgs.no == '') then&lt;br /&gt;
				report.xpYesNoBothBlank()&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if warningIMaxWordsReached ~= nil then&lt;br /&gt;
			report.xpMessage(warningIMaxWordsReached)&lt;br /&gt;
		end&lt;br /&gt;
		report.xpBuildReport(tArgs, sourceWordTable, &lt;br /&gt;
						bANDresult, andWordTable, tANDhits,&lt;br /&gt;
						bORresult, orWordTable, tORhits,&lt;br /&gt;
						sYeslist, xpLitWordCount)&lt;br /&gt;
	end&lt;br /&gt;
	return yesnoReturnstring(tArgs, sYeslist)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- set wordt separator &lt;br /&gt;
local function setSep(sSep)&lt;br /&gt;
	if sSep == nil then return defaultSep end&lt;br /&gt;
	local msg = ''&lt;br /&gt;
	-- todo what with {{!}}&lt;br /&gt;
	local newSep = defaultSep&lt;br /&gt;
&lt;br /&gt;
	newSep  = sSep&lt;br /&gt;
	sSep = decodeUnicode(sSep)&lt;br /&gt;
	if string.match(sSep, '[%s%w%d]') ~= nil then -- not ok&lt;br /&gt;
		msg = 'Irregular characters in sep: ' .. sSep&lt;br /&gt;
		newSep = defaultSep&lt;br /&gt;
	end&lt;br /&gt;
	newSep = string.sub(sSep, 1, 1)&lt;br /&gt;
	if newSep == '' then --- ???&lt;br /&gt;
		newSep = defaultSep&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return newSep&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function concatAndLists(s1, s2, newSep)&lt;br /&gt;
	local tLists = {} -- working table: both s1 and s2 to concat&lt;br /&gt;
	table.insert(tLists, s1)&lt;br /&gt;
	table.insert(tLists, s2)&lt;br /&gt;
	return table.concat(tLists, newSep)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseArgs(origArgs)&lt;br /&gt;
local newArgs = {}&lt;br /&gt;
	newArgs['sep']		= setSep(origArgs['sep']) -- do first, needed below&lt;br /&gt;
	newArgs['source']	= decodeUnicode(origArgs['s'] or origArgs['source'] or '')&lt;br /&gt;
	newArgs['andString'] = decodeUnicode(concatAndLists(&lt;br /&gt;
									origArgs['w'] or origArgs['word'] or nil,&lt;br /&gt;
									origArgs['andw'] or origArgs['andwords'] or nil, &lt;br /&gt;
									newArgs.sSep)&lt;br /&gt;
									)&lt;br /&gt;
	newArgs['orString']	= decodeUnicode(origArgs['orw'] or origArgs['orwords'] or '')&lt;br /&gt;
	-- boolean options: catch both parameters, also handle nil &amp;amp; nonsense input values:&lt;br /&gt;
	newArgs['case']		= yesno(origArgs['case'] or origArgs['casesensitive'] or true, true) -- defaults to True&lt;br /&gt;
	newArgs['booleans']	= yesno(origArgs['bool'] or origArgs['booleans'] or false, false) -- defaults to False&lt;br /&gt;
	newArgs['literals']	= yesno(origArgs['literals'] or origArgs['lit'] or true, true) -- defaults to True&lt;br /&gt;
	newArgs['yes']		= origArgs['yes'] or nil -- nil; default so return sYeslist; keep '' as legal input &amp;amp; return value&lt;br /&gt;
	newArgs['no']		= origArgs['no'] or ''&lt;br /&gt;
	newArgs['explain']	= false -- never. 22Mar2023 checkExplain(newArgs)&lt;br /&gt;
&lt;br /&gt;
	newArgs.explain = false -- never. 22Mar2023 checkExplain(newArgs)&lt;br /&gt;
	&lt;br /&gt;
	return newArgs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
local origArgs = getArgs(frame)&lt;br /&gt;
local sReturn = ''&lt;br /&gt;
local tArgs = {}&lt;br /&gt;
&lt;br /&gt;
	tArgs = parseArgs(origArgs)&lt;br /&gt;
	if yesno(tArgs.explain, false) then&lt;br /&gt;
		initReport()&lt;br /&gt;
		report.xpListArguments(origArgs)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	sReturn = p._main(tArgs)&lt;br /&gt;
	&lt;br /&gt;
	if warningIMaxWordsReached ~=nil then&lt;br /&gt;
		local preview = require('Module:If preview')&lt;br /&gt;
		sReturn = sReturn .. preview._warning({warningIMaxWordsReached})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if yesno(tArgs.explain, false) then&lt;br /&gt;
		return sReturn .. report.xpPresent(tArgs.explain)&lt;br /&gt;
	else&lt;br /&gt;
		return sReturn&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>wikipedia&gt;Lemondoge</name></author>
	</entry>
</feed>