Module:Str find word/report

From MOASSpedia
Jump to navigation Jump to search

Documentation for this module may be created at Module:Str find word/report/doc

--- STABLE: 16-11-2021 20:30
--- start dv sSep
require('Module:No globals')
local reportSep	= '|'
local defaultSep = ', ' -- copied from parent
local str		= require('Module:String')
local yesno		= require('Module:Yesno')
local br		= '<br/>'
-- Top = top 3 table lines: title, result (T/F), and the Return value string
-- Bottom = bottom ~1-6 table lines, echoing input and logical process steps
local tTitleHeader	= {}
local tBottom	= {}

-- Format string in <code> tag
-- replaces whitespace by single nbsp (keep untrimmed ws visible)
local function inCode(s)
	if s == nil then return '' end

	s = string.gsub(s, '%s+', '&nbsp;')
	return '<code>' .. s .. '</code>'
end

-- Use mono font-family (from: Template:Mono)
local function inMono(s)
	if s == nil then s = '' end
	return '<span class="monospaced" style="font-family: monospace;">' .. s .. '</span>'
end

-- Formats table (array) using concat
-- replace space by nbsp (keep untrimmed sp)
-- in monospace font-family
local function formatTablelist(t)
	if t == nil then return '<>' end
	
	local s = ''
	s = table.concat(t, reportSep)
	s = mw.text.decode(string.gsub(s, '%s+', '&nbsp;'))
	s = '<' .. inMono(s) .. '>'
	return s
end

-- Make sYeslist returnstring into flat text (while keeping image name etc)
-- for reporting only
-- issue: somehow an [[Image:name]] is not :-ised (showing [[:Image:name]] in text)
local function xpWikicodePlain(sReturnString)
local plain = require('Module:Plain text')

	if sReturnString == nil or sReturnString == '' then
		return ''
	end
	
	sReturnString = mw.text.killMarkers(sReturnString)
	sReturnString = mw.text.decode(sReturnString)
	sReturnString
		:gsub('%<%/? *div[^%>]*%>', '')
		:gsub('%<%/? *span[^%>]*%>', '')
		:gsub('%[%[%s*[Ff][Ii][Ll][Ee]%s*:', '[[:File:') --prevent stripping out file:
		:gsub('%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:', '[[:Image:') --prevent stripping out image:
		:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:', '[[:Category:') --prevent stripping out category:
		:gsub('<br ?/?>', ', ') --replace br with commas
		:gsub('<i.->(.-)</i>', '%1') --remove italics while keeping text inside
		:gsub('<b.->(.-)</b>', '%1') --remove bold while keeping text inside
		:gsub('<em.->(.-)</em>', '%1') --remove emphasis while keeping text inside
		:gsub('<strong.->(.-)</strong>', '%1') --remove strong while keeping text inside
		:gsub('<.->.-<.->', '') --strip out remaining tags and the text inside
		:gsub('<.->', '') --remove any other tag markup
		:gsub('%[%[[^%]]-|', '') --strip out piped link text
		:gsub('([^%[])%[[^%[%]][^%]]-%s', '%1') --strip out external link text
		:gsub('^%[[^%[%]][^%]]-%s', '') --strip out external link text
		:gsub('[%[%]]', '') --then strip out remaining [ and ]
		:gsub("'''?", "") --not stripping out '''' gives correct output for bolded text in quotes
		:gsub('----+', '') --remove ---- lines
		:gsub("%s+", " ") --strip redundant spaces
		:gsub("^%s+", "") --strip leading
		:gsub("%s+$", "") --and trailing spaces

	if mw.ustring.len(sReturnString) > 200 then
		sReturnString = mw.ustring.sub(sReturnString, 1, 200) .. '&nbsp;...'
	end
	return sReturnString
end

-- Build top three lines of the reporttable
local function xpBuildTop(tArgs, sYeslist)
local bResultALL = not (sYeslist == '')
local aye = '[[File:Green check.svg|15px|alt=Green tick]]'
local nay = '[[File:Red x.svg|15px|alt=Red X]]'
local msg

	-- report line 1. Title
	local title
	title = '<strong><span style="color:red;">Preview report</span> ' .. 
		'&#123;&#123;[[:Template:Str find word|Str find word]]&#125;&#125; ' ..
		'explain</strong>=' .. inMono(tostring(tArgs.explain))
	table.insert(tTitleHeader, 1, title)

	-- report line 2. Result (T/F)
	msg = 'RESULT: '
	if bResultALL then
		msg = msg .. aye .. ' TRUE words found in source: <' .. sYeslist .. '>'
	else
		msg = msg .. nay .. ' FALSE'
	end
	table.insert(tTitleHeader, 2, msg)

	-- report line 3. Return value (Yes/No value)
	msg = 'RETURN VALUE '
	if bResultALL then -- True 
		if (tArgs.yes == nil) then -- default = return sYeslist
			msg = msg .. '|yes= (default, list of words found):&nbsp;'
						.. inCode(sYeslist)
		else
			msg = msg .. '|yes=&nbsp;'
						.. inCode(xpWikicodePlain(tArgs.yes))
		end
	else -- False  
		msg = msg .. '|no=&nbsp;'.. inCode(xpWikicodePlain(tArgs.no))
	end
	table.insert(tTitleHeader, 3, msg)

	return
end

-- Build report tables, exported: 
-- top table: title & results, 3 lines
-- bottom table has processing results
-- including messages like noWords (already in the table)
local function xpBuildReport(tArgs, sourceWordTable, 
						bANDresult, andWordTable, hitsANDtable, 
						bORresult, orWordTable, hitsORtable,
						sYeslist, litWordCount)
local msg

	-- Three top title rows
	xpBuildTop(tArgs, sYeslist)
	
	-- Part 2 (bottom lines): settings & process steps results
	-- SEP separator
	local msg
	--- if tArgs.sep == defaultSep then	return end
	msg = 'SEP: >' .. inCode(tArgs.sep) .. '<'
	table.insert(tBottom, msg)

	-- CASE: case-sensitive?
	local msg = ''
	if yesno(tArgs.case) == true then
		msg = 'Case-sensitive: true (Foo ≠ foo)'
	else
		msg = 'Case-sensitive: false (Foo = foo)'
	end
	table.insert(tBottom, msg)
	
	-- LITERALS: read literals?
	msg = 'Read literals: ' .. tostring(yesno(tArgs.literals))
	if yesno(tArgs.literals) then
		msg = msg .. ' (found ' .. tostring(litWordCount) .. ')'
	end
	table.insert(tBottom, msg)

	
	-- BOOLEANS: read as booleans?
	table.insert(tBottom, 'Read booleans: ' 
						.. tostring(yesno(tArgs.booleans)))

	-- SOURCE: words string to look in
	msg = '<b>SOURCE</b> word list= '
					.. inCode(tArgs.source)
					.. ' &rarr; ' .. formatTablelist(sourceWordTable)
	table.insert(tBottom, msg)
	
	-- AND-words to find, found
	local msgWordTtoFind, msgWordsFound 
	if #andWordTable ~= 0 then
		msgWordTtoFind = 'AND words to find: '
							.. inCode(tArgs.andString) 
							.. ' &rarr; ' .. formatTablelist(andWordTable)
		table.insert(tBottom, msgWordTtoFind)
		msgWordsFound  = 'AND words found: '
							.. formatTablelist(hitsANDtable)
							.. ' &rArr; ' .. string.upper(tostring(bANDresult))
		table.insert(tBottom, msgWordsFound)
	end
	
	-- OR-words to find, found
	if #orWordTable ~= 0 then
		msgWordTtoFind = 'OR words to find: '
							.. inCode(tArgs.orString)
							.. ' &rarr; ' .. formatTablelist(orWordTable)
		table.insert(tBottom, msgWordTtoFind)				
		msgWordsFound  = 'OR words found: ' 
							.. formatTablelist(hitsORtable) 
							.. ' &rArr; ' .. string.upper(tostring(bORresult))
		table.insert(tBottom, msgWordsFound)
	end
	return
end

-- List the input arguments
-- could be normalised newArgs
-- no nils expected
local function xpListArguments(origA)
	local sList = 'Arguments: '
	for k, v in pairs(origA) do
		sList = sList .. ' |' .. k .. '=' .. v
	end
	table.insert(tBottom, sList)
	return
end

-- Returnvalues |yes= and |no= are both blank so the check is irrelevant.
local function xpYesNoBothBlank()
	table.insert(tBottom, 
					'Both returnvalues |yes= |no= | ' 
					.. 'are <blank>, so check is trivial')
	return
end

-- One or both wordsets (sourcewords / to-find-words) is empty, so not check to do at all.
local function xpNoWords(tArgs, sourceWordTable, andWordTable, orWordTable)
	table.insert(tBottom, 'no words to check:')
	if (#sourceWordTable == 0) then
		table.insert(tBottom, 'No words in |source: '
							.. inCode(tArgs.source))
	end
	if (#andWordTable + #orWordTable == 0) then
		local sWords 
			sWords = mw.text.trim(tArgs.andString .. ' ' .. tArgs.orString)
			table.insert(tBottom, 'No words to find ' 
							.. '(|word= |andwords= |orwords=): ' 
							.. inCode(sWords))
	end
	return
end

-- Add single message to report, bottom half (usually in debugging)
local function xpMessage(sMsg)
	table.insert(tBottom, sMsg or '')
	return
end

-- Format return box (the Preview presentation)
local function xpPresent()
	local divInTop, divInBottom, divOut
	divInTop	= br .. '<div style="padding-left:0.5em; background:#FFF599;">'
	divInBottom	= '<div style="padding-left:0.5em; background:lemonchiffon;">'
	divOut		= '</div>'
	
	local reportBox	
	reportBox = divInTop .. table.concat(tTitleHeader, br) .. divOut
				.. divInBottom .. table.concat(tBottom, br) .. divOut
	return reportBox 
end

-- Exported functions
return {
	xpPresent		= xpPresent,
	xpBuildReport	= xpBuildReport,
	xpListArguments	= xpListArguments,
	xpYesNoBothBlank = xpYesNoBothBlank,
	xpNoWords		= xpNoWords,
	xpMessage		= xpMessage,
}