Jump to content

Module:Str find word/report

From Wikipedia, the free encyclopedia

-- 17-4-2023 working with /sandbox now.
-- not fit for mainspace in any form (uncontrolled effects while dev/sandbox) 23-3-2023
require('strict')
local sReportType	= nil
local reportSep	= '|'
local str		= require('Module:String')
local yesno		= require('Module:Yesno')
local br		= '<br/>'
local tMSG		= {}
-- Explain options ( =report info ), interprets parameter explain=
-- returns true/false/'testcases'
-- explain=true => show report in Preview
-- explain=testcases => WHEN in ns:template: AND subpage = '/testcases' THEN show permanently
-- 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, 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 tResults.sRESULTstring 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

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

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

--- ===== ===== ===== ===== ===== ===== ===== ===== ===== 
-- Build top three lines of the reporttable
local function xpBuildTopreport(tArgs, tWork, tResults)
local aye = '[[File:Green check.svg|15px|alt=Green tick]]'
local nay = '[[File:Red x.svg|15px|alt=Red X]]'
local msg
local tTitle = {}

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

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

	-- report line 3. Return value (Yes/No value)
	msg = 'RETURN VALUE '
	if tResults.resultALL then -- True 
		if (tArgs.yes == nil) then -- default = return tResults.sRESULTstring
			msg = msg .. '(default) |out-true= :&nbsp;'
						.. inCode(tResults.sRESULTstring)
		else
			msg = msg .. '|out-true=&nbsp;'
						.. inCode(xpWikicodePlain(tArgs.yes))
		end
	else -- False
		msg = msg .. '|out-false=&nbsp;'.. inCode(xpWikicodePlain(tArgs.no))
	end
	table.insert(tTitle, 3, msg)

	return tTitle
end

local function xpBuildWorkreport(tArgs, tWork, tResults)
local tReport ={}
	tReport = {'tReport todo'}
	--- todo usde xpListArguments
	return tReport
end

local function xpBuildMsgreport(tArgs, tWork, tResults)
local tReport = {}
local msg

	--  (bottom lines): settings & process steps results
	msg = 'MSGs: #todo>' .. #tMSG
	table.insert(tReport, msg)

	-- SEP separator
	msg = 'SEP: >' .. inCode(tArgs.sep) .. '< [' .. tArgs.sep_pattern .. '] SEP-OUT: >' .. inCode(tArgs.out_sep) .. '<'
	table.insert(tReport, msg)

	-- CASE: case-sensitive?
	local msg = ''
	if yesno(tArgs.case) == true then
		msg = 'Case-sensitive: true (A≠a)'
	else
		msg = 'Case-sensitive: false (A=a)'
	end
	table.insert(tReport, msg)

	-- BOOLEANS: read as booleans?
	table.insert(tReport, 'Read booleans: ' 
						.. tostring(yesno(tArgs.booleans)))
	
	return tReport
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, tWork, tResults)
local tTopreport	= {}
local tWorkreport	= {}
local tMsgreport	= {}
local msg

	-- Three top title rows
	tTopreport	= xpBuildTopreport(tArgs, tWork, tResults)
	tWorkreport	= xpBuildWorkreport(tArgs, tWork, tResults)
	tMsgreport	= xpBuildMsgreport(tArgs, tWork, tResults)
	
end

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

-- Format return box (the Preview presentation)
local function xpPresent(tArgs, tWork, tResults)
local tTopreport	= {}
local tWorkreport	= {}
local tMsgreport	= {} -- msg lines
local divInTop		= br .. '<div style="padding-left:0.5em; background:#FFF599;">'
local divInWorks	= '<div style="padding-left:0.5em; background:pink;">'
local divInMsg		= '<div style="padding-left:0.5em; background:lemonchiffon;">'
local divEnd		= '</div>'

local tTopreport	= xpBuildTopreport(tArgs, tWork, tResults)
local tWorkreport	= xpBuildWorkreport(tArgs, tWork, tResults)
local tMsgreport	= xpBuildMsgreport(tArgs, tWork, tResults)

	local reportBox
	reportBox = divInTop .. table.concat(tTopreport, br) .. divEnd
				.. divInWorks .. table.concat(tWorkreport, br) .. divEnd
				.. divInMsg .. table.concat(tMsgreport, br) .. divEnd
	return reportBox 
end

-- Exported functions
return {
	xpCheckExplain	= xpCheckExplain,
	xpPresent		= xpPresent,
	xpMessage		= xpMessage,
}