Jump to content

Module:Sandbox/Izno

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Izno (talk | contribs) at 00:55, 10 June 2023 (add tonumber). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}

function p.file() --frame
	
	local image = 'File:US 730.svg'
	local title = mw.title.new(image)
	
	local width = title.file.width
	local height = title.file.height
	
	return string.format('%s width: %d, height: %d', image, width, height)
end

function p.basic_iteration(frame)
	
	local pv = require('Module:If preview')
	local t = { 'a', 'b', 'c', 'd', }
	local t2 = { a = 'a', b = 'b', c = 'c', d = 'd' }
	local preview = ''
	for _, v in ipairs(t) do -- guarantees ordering
		preview = preview .. pv._warning({
			v
		})
	end
	for _, v in pairs(t2) do -- doesn't guarantee ordering
		preview = preview .. pv._warning({
			v
		})
	end
	
	return preview
end

local msg = mw.message.newRawMessage

function p.message(frame)
	local messages = {}
	table.insert(messages, 'This is an inserted message')
	local msg1 = msg('This is a $1 message.', 'raw')
	local msg2 = msg('This is a $1 message of $2 quality.', '[[raw]]', '{{icon|fa}}')
	local msg3 = msg('This is a $1 message of $2 quality.', '[[raw]]', '{{icon|fa}}'):plain()
	if frame.args[1] then
		table.insert(messages, frame.args[1])
	end
	
	return -- tostring(messages) .. '\n\n' .. -- this prints string 'table'
		 table.concat(messages) .. tostring(msg1) .. '\n\n' .. tostring(msg2) .. '\n\n' .. tostring(msg3)
end

function p.tostringnil()
	return tostring(nil)
end

function p.tonumber()
	return tonumber('')
end

-- Returns the union of the values of two tables, as a sequence.
local function union(t1, t2)

	local vals = {}
	for k, v in pairs(t1) do
		vals[v] = true
	end
	for k, v in pairs(t2) do
		vals[v] = true
	end
	local ret = {}
	for k, v in pairs(vals) do
		table.insert(ret, k)
	end
	return ret
end

-- Returns a table containing the numbers of the arguments that exist
-- for the specified prefix. For example, if the prefix was 'data', and
-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
local function get_arg_nums(args, prefix)
	local nums = {}
	for k, v in pairs(args) do
		local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
		if num then table.insert(nums, tonumber(num)) end
	end
	table.sort(nums)
	return nums
end

local function trim_args(args)
	local new_args = {}
	for k,v in pairs(args) do
		new_args[k] = mw.text.trim(v)
	end
	return new_args
end

local function responses_have_signatures(response, response_signature)
	return response and response ~= '' and response_signature and response_signature ~= ''
end

local function get_responses(args)
	local response_numbers = union(
		get_arg_nums(args, 'response'),
		get_arg_nums(args, 'response signature')
	)
	table.sort(response_numbers)
	local responses = {}
	local response_signatures = {}
	for _, num in ipairs(response_numbers) do
		local response = args['response' .. num]
		local response_signature = args['response signature' .. num]
		if not responses_have_signatures(response, response_signature) then
			error('|response' .. num .. '= or |response signature' .. num .. '= is missing')
		end
		table.insert(responses, response)
		table.insert(response_signatures, response_signature)
	end
	return responses, response_signatures
end

local function wordcount(word_limit, statement, signature, responses, response_signatures)
	-- this actually gets the word count. we slightly overcount because this is
	-- wikitext, so things like '\n* ' and elinks will cause an extra word.
	-- we can get a count of the '*' and similar constructs separately if we want.
	-- but parsing wikitext to count links is :(
	-- tables are doomed and probably would just always be better placed on a
	-- different page than the primary statements are.
	-- from https://stackoverflow.com/questions/29133416/how-to-count-the-amount-of-words-in-a-text-file-in-lua
	local _, n_statement = mw.ustring.gsub(statement .. table.concat(responses, '\n'), '%S+', '')
	
	if n_statement > word_limit then error('Too many words') end
	if n_statement <= 0 then error('No words') end

	if not signature or signature == '' then error('No signature') end
	local joined_responses = {
		statement,
		signature
	}
	for k, _ in ipairs(responses) do
		table.insert(joined_responses, responses[k] .. '\n' .. response_signatures[k])
	end
	return table.concat(joined_responses)
end

function p.statement(frame)
	local args = trim_args(frame.args)

	local statement = args.statement or ''
	local signature = args.signature or ''
	local added_words = tonumber(args['added words']) or 0
	local word_limit = 500 + added_words
	local responses, response_signatures = get_responses(args)
	
	return wordcount(word_limit, statement, signature, responses, response_signatures)
end

return p