<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AStr_find_word%2Freport</id>
	<title>Module:Str find word/report - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AStr_find_word%2Freport"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Str_find_word/report&amp;action=history"/>
	<updated>2026-04-21T13:24:40Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Str_find_word/report&amp;diff=147053&amp;oldid=prev</id>
		<title>imported&gt;WOSlinker: use require(&#039;strict&#039;) instead of require(&#039;Module:No globals&#039;)</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Str_find_word/report&amp;diff=147053&amp;oldid=prev"/>
		<updated>2022-10-22T09:10:35Z</updated>

		<summary type="html">&lt;p&gt;use require(&amp;#039;strict&amp;#039;) instead of require(&amp;#039;Module:No globals&amp;#039;)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--- STABLE: 16-11-2021 20:30&lt;br /&gt;
--- start dv sSep&lt;br /&gt;
require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
local reportSep	= &amp;#039;|&amp;#039;&lt;br /&gt;
local defaultSep = &amp;#039;, &amp;#039; -- copied from parent&lt;br /&gt;
local str		= require(&amp;#039;Module:String&amp;#039;)&lt;br /&gt;
local yesno		= require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local br		= &amp;#039;&amp;lt;br/&amp;gt;&amp;#039;&lt;br /&gt;
-- Top = top 3 table lines: title, result (T/F), and the Return value string&lt;br /&gt;
-- Bottom = bottom ~1-6 table lines, echoing input and logical process steps&lt;br /&gt;
local tTitleHeader	= {}&lt;br /&gt;
local tBottom	= {}&lt;br /&gt;
&lt;br /&gt;
-- Format string in &amp;lt;code&amp;gt; tag&lt;br /&gt;
-- replaces whitespace by single nbsp (keep untrimmed ws visible)&lt;br /&gt;
local function inCode(s)&lt;br /&gt;
	if s == nil then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	s = string.gsub(s, &amp;#039;%s+&amp;#039;, &amp;#039;&amp;amp;nbsp;&amp;#039;)&lt;br /&gt;
	return &amp;#039;&amp;lt;code&amp;gt;&amp;#039; .. s .. &amp;#039;&amp;lt;/code&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Use mono font-family (from: Template:Mono)&lt;br /&gt;
local function inMono(s)&lt;br /&gt;
	if s == nil then s = &amp;#039;&amp;#039; end&lt;br /&gt;
	return &amp;#039;&amp;lt;span class=&amp;quot;monospaced&amp;quot; style=&amp;quot;font-family: monospace, monospace;&amp;quot;&amp;gt;&amp;#039; .. s .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Formats table (array) using concat&lt;br /&gt;
-- replace space by nbsp (keep untrimmed sp)&lt;br /&gt;
-- in monospace font-family&lt;br /&gt;
local function formatTablelist(t)&lt;br /&gt;
	if t == nil then return &amp;#039;&amp;lt;&amp;gt;&amp;#039; end&lt;br /&gt;
	&lt;br /&gt;
	local s = &amp;#039;&amp;#039;&lt;br /&gt;
	s = table.concat(t, reportSep)&lt;br /&gt;
	s = mw.text.decode(string.gsub(s, &amp;#039;%s+&amp;#039;, &amp;#039;&amp;amp;nbsp;&amp;#039;))&lt;br /&gt;
	s = &amp;#039;&amp;lt;&amp;#039; .. inMono(s) .. &amp;#039;&amp;gt;&amp;#039;&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Make sYeslist returnstring into flat text (while keeping image name etc)&lt;br /&gt;
-- for reporting only&lt;br /&gt;
-- issue: somehow an [[Image:name]] is not :-ised (showing [[:Image:name]] in text)&lt;br /&gt;
local function xpWikicodePlain(sReturnString)&lt;br /&gt;
local plain = require(&amp;#039;Module:Plain text&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if sReturnString == nil or sReturnString == &amp;#039;&amp;#039; then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	sReturnString = mw.text.killMarkers(sReturnString)&lt;br /&gt;
	sReturnString = mw.text.decode(sReturnString)&lt;br /&gt;
	sReturnString&lt;br /&gt;
		:gsub(&amp;#039;%&amp;lt;%/? *div[^%&amp;gt;]*%&amp;gt;&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
		:gsub(&amp;#039;%&amp;lt;%/? *span[^%&amp;gt;]*%&amp;gt;&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
		:gsub(&amp;#039;%[%[%s*[Ff][Ii][Ll][Ee]%s*:&amp;#039;, &amp;#039;[[:File:&amp;#039;) --prevent stripping out file:&lt;br /&gt;
		:gsub(&amp;#039;%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:&amp;#039;, &amp;#039;[[:Image:&amp;#039;) --prevent stripping out image:&lt;br /&gt;
		:gsub(&amp;#039;%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:&amp;#039;, &amp;#039;[[:Category:&amp;#039;) --prevent stripping out category:&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;br ?/?&amp;gt;&amp;#039;, &amp;#039;, &amp;#039;) --replace br with commas&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;i.-&amp;gt;(.-)&amp;lt;/i&amp;gt;&amp;#039;, &amp;#039;%1&amp;#039;) --remove italics while keeping text inside&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;b.-&amp;gt;(.-)&amp;lt;/b&amp;gt;&amp;#039;, &amp;#039;%1&amp;#039;) --remove bold while keeping text inside&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;em.-&amp;gt;(.-)&amp;lt;/em&amp;gt;&amp;#039;, &amp;#039;%1&amp;#039;) --remove emphasis while keeping text inside&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;strong.-&amp;gt;(.-)&amp;lt;/strong&amp;gt;&amp;#039;, &amp;#039;%1&amp;#039;) --remove strong while keeping text inside&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;.-&amp;gt;.-&amp;lt;.-&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) --strip out remaining tags and the text inside&lt;br /&gt;
		:gsub(&amp;#039;&amp;lt;.-&amp;gt;&amp;#039;, &amp;#039;&amp;#039;) --remove any other tag markup&lt;br /&gt;
		:gsub(&amp;#039;%[%[[^%]]-|&amp;#039;, &amp;#039;&amp;#039;) --strip out piped link text&lt;br /&gt;
		:gsub(&amp;#039;([^%[])%[[^%[%]][^%]]-%s&amp;#039;, &amp;#039;%1&amp;#039;) --strip out external link text&lt;br /&gt;
		:gsub(&amp;#039;^%[[^%[%]][^%]]-%s&amp;#039;, &amp;#039;&amp;#039;) --strip out external link text&lt;br /&gt;
		:gsub(&amp;#039;[%[%]]&amp;#039;, &amp;#039;&amp;#039;) --then strip out remaining [ and ]&lt;br /&gt;
		:gsub(&amp;quot;&amp;#039;&amp;#039;&amp;#039;?&amp;quot;, &amp;quot;&amp;quot;) --not stripping out &amp;#039;&amp;#039;&amp;#039;&amp;#039; gives correct output for bolded text in quotes&lt;br /&gt;
		:gsub(&amp;#039;----+&amp;#039;, &amp;#039;&amp;#039;) --remove ---- lines&lt;br /&gt;
		:gsub(&amp;quot;%s+&amp;quot;, &amp;quot; &amp;quot;) --strip redundant spaces&lt;br /&gt;
		:gsub(&amp;quot;^%s+&amp;quot;, &amp;quot;&amp;quot;) --strip leading&lt;br /&gt;
		:gsub(&amp;quot;%s+$&amp;quot;, &amp;quot;&amp;quot;) --and trailing spaces&lt;br /&gt;
&lt;br /&gt;
	if mw.ustring.len(sReturnString) &amp;gt; 200 then&lt;br /&gt;
		sReturnString = mw.ustring.sub(sReturnString, 1, 200) .. &amp;#039;&amp;amp;nbsp;...&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return sReturnString&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Build top three lines of the reporttable&lt;br /&gt;
local function xpBuildTop(tArgs, sYeslist)&lt;br /&gt;
local bResultALL = not (sYeslist == &amp;#039;&amp;#039;)&lt;br /&gt;
local aye = &amp;#039;[[File:Green check.svg|15px|alt=Green tick]]&amp;#039;&lt;br /&gt;
local nay = &amp;#039;[[File:Red x.svg|15px|alt=Red X]]&amp;#039;&lt;br /&gt;
local msg&lt;br /&gt;
&lt;br /&gt;
	-- report line 1. Title&lt;br /&gt;
	local title&lt;br /&gt;
	title = &amp;#039;&amp;lt;strong&amp;gt;&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Preview report&amp;lt;/span&amp;gt; &amp;#039; .. &lt;br /&gt;
		&amp;#039;&amp;amp;#123;&amp;amp;#123;[[:Template:Str find word|Str find word]]&amp;amp;#125;&amp;amp;#125; &amp;#039; ..&lt;br /&gt;
		&amp;#039;explain&amp;lt;/strong&amp;gt;=&amp;#039; .. inMono(tostring(tArgs.explain))&lt;br /&gt;
	table.insert(tTitleHeader, 1, title)&lt;br /&gt;
&lt;br /&gt;
	-- report line 2. Result (T/F)&lt;br /&gt;
	msg = &amp;#039;RESULT: &amp;#039;&lt;br /&gt;
	if bResultALL then&lt;br /&gt;
		msg = msg .. aye .. &amp;#039; TRUE words found in source: &amp;lt;&amp;#039; .. sYeslist .. &amp;#039;&amp;gt;&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		msg = msg .. nay .. &amp;#039; FALSE&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(tTitleHeader, 2, msg)&lt;br /&gt;
&lt;br /&gt;
	-- report line 3. Return value (Yes/No value)&lt;br /&gt;
	msg = &amp;#039;RETURN VALUE &amp;#039;&lt;br /&gt;
	if bResultALL then -- True &lt;br /&gt;
		if (tArgs.yes == nil) then -- default = return sYeslist&lt;br /&gt;
			msg = msg .. &amp;#039;|yes= (default, list of words found):&amp;amp;nbsp;&amp;#039;&lt;br /&gt;
						.. inCode(sYeslist)&lt;br /&gt;
		else&lt;br /&gt;
			msg = msg .. &amp;#039;|yes=&amp;amp;nbsp;&amp;#039;&lt;br /&gt;
						.. inCode(xpWikicodePlain(tArgs.yes))&lt;br /&gt;
		end&lt;br /&gt;
	else -- False  &lt;br /&gt;
		msg = msg .. &amp;#039;|no=&amp;amp;nbsp;&amp;#039;.. inCode(xpWikicodePlain(tArgs.no))&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(tTitleHeader, 3, msg)&lt;br /&gt;
&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Build report tables, exported: &lt;br /&gt;
-- top table: title &amp;amp; results, 3 lines&lt;br /&gt;
-- bottom table has processing results&lt;br /&gt;
-- including messages like noWords (already in the table)&lt;br /&gt;
local function xpBuildReport(tArgs, sourceWordTable, &lt;br /&gt;
						bANDresult, andWordTable, hitsANDtable, &lt;br /&gt;
						bORresult, orWordTable, hitsORtable,&lt;br /&gt;
						sYeslist, litWordCount)&lt;br /&gt;
local msg&lt;br /&gt;
&lt;br /&gt;
	-- Three top title rows&lt;br /&gt;
	xpBuildTop(tArgs, sYeslist)&lt;br /&gt;
	&lt;br /&gt;
	-- Part 2 (bottom lines): settings &amp;amp; process steps results&lt;br /&gt;
	-- SEP separator&lt;br /&gt;
	local msg&lt;br /&gt;
	--- if tArgs.sep == defaultSep then	return end&lt;br /&gt;
	msg = &amp;#039;SEP: &amp;gt;&amp;#039; .. inCode(tArgs.sep) .. &amp;#039;&amp;lt;&amp;#039;&lt;br /&gt;
	table.insert(tBottom, msg)&lt;br /&gt;
&lt;br /&gt;
	-- CASE: case-sensitive?&lt;br /&gt;
	local msg = &amp;#039;&amp;#039;&lt;br /&gt;
	if yesno(tArgs.case) == true then&lt;br /&gt;
		msg = &amp;#039;Case-sensitive: true (Foo ≠ foo)&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		msg = &amp;#039;Case-sensitive: false (Foo = foo)&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(tBottom, msg)&lt;br /&gt;
	&lt;br /&gt;
	-- LITERALS: read literals?&lt;br /&gt;
	msg = &amp;#039;Read literals: &amp;#039; .. tostring(yesno(tArgs.literals))&lt;br /&gt;
	if yesno(tArgs.literals) then&lt;br /&gt;
		msg = msg .. &amp;#039; (found &amp;#039; .. tostring(litWordCount) .. &amp;#039;)&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(tBottom, msg)&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	-- BOOLEANS: read as booleans?&lt;br /&gt;
	table.insert(tBottom, &amp;#039;Read booleans: &amp;#039; &lt;br /&gt;
						.. tostring(yesno(tArgs.booleans)))&lt;br /&gt;
&lt;br /&gt;
	-- SOURCE: words string to look in&lt;br /&gt;
	msg = &amp;#039;&amp;lt;b&amp;gt;SOURCE&amp;lt;/b&amp;gt; word list= &amp;#039;&lt;br /&gt;
					.. inCode(tArgs.source)&lt;br /&gt;
					.. &amp;#039; &amp;amp;rarr; &amp;#039; .. formatTablelist(sourceWordTable)&lt;br /&gt;
	table.insert(tBottom, msg)&lt;br /&gt;
	&lt;br /&gt;
	-- AND-words to find, found&lt;br /&gt;
	local msgWordTtoFind, msgWordsFound &lt;br /&gt;
	if #andWordTable ~= 0 then&lt;br /&gt;
		msgWordTtoFind = &amp;#039;AND words to find: &amp;#039;&lt;br /&gt;
							.. inCode(tArgs.andString) &lt;br /&gt;
							.. &amp;#039; &amp;amp;rarr; &amp;#039; .. formatTablelist(andWordTable)&lt;br /&gt;
		table.insert(tBottom, msgWordTtoFind)&lt;br /&gt;
		msgWordsFound  = &amp;#039;AND words found: &amp;#039;&lt;br /&gt;
							.. formatTablelist(hitsANDtable)&lt;br /&gt;
							.. &amp;#039; &amp;amp;rArr; &amp;#039; .. string.upper(tostring(bANDresult))&lt;br /&gt;
		table.insert(tBottom, msgWordsFound)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- OR-words to find, found&lt;br /&gt;
	if #orWordTable ~= 0 then&lt;br /&gt;
		msgWordTtoFind = &amp;#039;OR words to find: &amp;#039;&lt;br /&gt;
							.. inCode(tArgs.orString)&lt;br /&gt;
							.. &amp;#039; &amp;amp;rarr; &amp;#039; .. formatTablelist(orWordTable)&lt;br /&gt;
		table.insert(tBottom, msgWordTtoFind)				&lt;br /&gt;
		msgWordsFound  = &amp;#039;OR words found: &amp;#039; &lt;br /&gt;
							.. formatTablelist(hitsORtable) &lt;br /&gt;
							.. &amp;#039; &amp;amp;rArr; &amp;#039; .. string.upper(tostring(bORresult))&lt;br /&gt;
		table.insert(tBottom, msgWordsFound)&lt;br /&gt;
	end&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- List the input arguments&lt;br /&gt;
-- could be normalised newArgs&lt;br /&gt;
-- no nils expected&lt;br /&gt;
local function xpListArguments(origA)&lt;br /&gt;
	local sList = &amp;#039;Arguments: &amp;#039;&lt;br /&gt;
	for k, v in pairs(origA) do&lt;br /&gt;
		sList = sList .. &amp;#039; |&amp;#039; .. k .. &amp;#039;=&amp;#039; .. v&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(tBottom, sList)&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returnvalues |yes= and |no= are both blank so the check is irrelevant.&lt;br /&gt;
local function xpYesNoBothBlank()&lt;br /&gt;
	table.insert(tBottom, &lt;br /&gt;
					&amp;#039;Both returnvalues |yes= |no= | &amp;#039; &lt;br /&gt;
					.. &amp;#039;are &amp;lt;blank&amp;gt;, so check is trivial&amp;#039;)&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- One or both wordsets (sourcewords / to-find-words) is empty, so not check to do at all.&lt;br /&gt;
local function xpNoWords(tArgs, sourceWordTable, andWordTable, orWordTable)&lt;br /&gt;
	table.insert(tBottom, &amp;#039;no words to check:&amp;#039;)&lt;br /&gt;
	if (#sourceWordTable == 0) then&lt;br /&gt;
		table.insert(tBottom, &amp;#039;No words in |source: &amp;#039;&lt;br /&gt;
							.. inCode(tArgs.source))&lt;br /&gt;
	end&lt;br /&gt;
	if (#andWordTable + #orWordTable == 0) then&lt;br /&gt;
		local sWords &lt;br /&gt;
			sWords = mw.text.trim(tArgs.andString .. &amp;#039; &amp;#039; .. tArgs.orString)&lt;br /&gt;
			table.insert(tBottom, &amp;#039;No words to find &amp;#039; &lt;br /&gt;
							.. &amp;#039;(|word= |andwords= |orwords=): &amp;#039; &lt;br /&gt;
							.. inCode(sWords))&lt;br /&gt;
	end&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Add single message to report, bottom half (usually in debugging)&lt;br /&gt;
local function xpMessage(sMsg)&lt;br /&gt;
	table.insert(tBottom, sMsg or &amp;#039;&amp;#039;)&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Format return box (the Preview presentation)&lt;br /&gt;
local function xpPresent()&lt;br /&gt;
	local divInTop, divInBottom, divOut&lt;br /&gt;
	divInTop	= br .. &amp;#039;&amp;lt;div style=&amp;quot;padding-left:0.5em; background:#FFF599;&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
	divInBottom	= &amp;#039;&amp;lt;div style=&amp;quot;padding-left:0.5em; background:lemonchiffon;&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
	divOut		= &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	local reportBox	&lt;br /&gt;
	reportBox = divInTop .. table.concat(tTitleHeader, br) .. divOut&lt;br /&gt;
				.. divInBottom .. table.concat(tBottom, br) .. divOut&lt;br /&gt;
	return reportBox &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Exported functions&lt;br /&gt;
return {&lt;br /&gt;
	xpPresent		= xpPresent,&lt;br /&gt;
	xpBuildReport	= xpBuildReport,&lt;br /&gt;
	xpListArguments	= xpListArguments,&lt;br /&gt;
	xpYesNoBothBlank = xpYesNoBothBlank,&lt;br /&gt;
	xpNoWords		= xpNoWords,&lt;br /&gt;
	xpMessage		= xpMessage,&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>imported&gt;WOSlinker</name></author>
	</entry>
</feed>