local p = {}
-- 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
valsv = true
end
for k, v in pairs(t2) do
valsv = 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_argsk = 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, responsesk .. '\n' .. response_signaturesk])
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
local p = {}
-- 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
valsv = true
end
for k, v in pairs(t2) do
valsv = 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_argsk = 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, responsesk .. '\n' .. response_signaturesk])
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