Content deleted Content added
use a different function for each html list type |
add function to get random dates; and add support for random numbers over 2^32-1 (using an algorithm supplied by User:Anomie) |
||
Line 12:
--------------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------------
local function raiseError(msg)
-- This helps to generate a wikitext error. It is the calling function's responsibility as to how to include it in the output.
return mw.ustring.format('<b class="error">[[Module:Random]] error: %s.</b>', msg)
end
--------------------------------------------------------------------------------------
-- random number function
--------------------------------------------------------------------------------------
local function bigRandom(l, u)
-- Gets a random integer between l and u, and is not limited to RAND_MAX (which here we assume is 2^31-1).
local r = math.random() + math.random() / 2147483648
return math.floor(r * (u - l + 1)) + l
end
function p._number(args)
Line 21 ⟶ 36:
-- This needs to use if statements as math.random won't accept explicit nil values as arguments.
if first then
if second
if first end
return bigRandom(first, second)
else
return
end
else
return math.random()
end
end
--------------------------------------------------------------------------------------
-- Date function
--------------------------------------------------------------------------------------
function p._date(args)
-- This function gets random dates, and takes timestamps as positional arguments.
-- With no arguments specified, it outputs a random date in the current year.
-- With two arguments specified, it outputs a random date between the timestamps.
-- With one argument specified, the date is a random date between the unix epoch (1 Jan 1970) and the timestamp.
-- The output can be formatted using the "format" argument, which works in the same way as the #time parser function.
-- The default format is the standard Wikipedia timestamp.
local lang = mw.language.getContentLanguage()
local function getDate(format, ts)
local success, date = pcall(lang.formatDate, lang, format, ts)
if success then
return date
end
end
local function getUnixTimestamp(ts)
local unixts = getDate('U', ts)
if unixts then
return tonumber(unixts)
end
end
local t1 = args[1]
local t2 = args[2]
-- Find the start timestamp and the end timestamp.
local startTimestamp, endTimestamp
if not t1 then
-- Find the first and last second in the current year.
local currentYear = tonumber(getDate('Y'))
local currentYearStartUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear)))
local currentYearEndUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear + 1))) - 1
startTimestamp = '@' .. tostring(currentYearStartUnix) -- @ is used to denote Unix timestamps with lang:formatDate.
endTimestamp = '@' .. tostring(currentYearEndUnix)
elseif t1 and not t2 then
startTimestamp = '@0' -- the Unix epoch, 1 January 1970
endTimestamp = t1
elseif t1 and t2 then
startTimestamp = t1
endTimestamp = t2
end
-- Get Unix timestamps and return errors for bad input (or for bugs in the underlying PHP library, of which there are unfortunately a few)
local startTimestampUnix = getUnixTimestamp(startTimestamp)
local endTimestampUnix = getUnixTimestamp(endTimestamp)
if not startTimestampUnix then
return raiseError('"' .. tostring(startTimestamp) .. '" was not recognised as a valid timestamp')
elseif not endTimestampUnix then
return raiseError('"' .. tostring(endTimestamp) .. '" was not recognised as a valid timestamp')
elseif startTimestampUnix > endTimestampUnix then
return raiseError('the start date must not be later than the end date (start date: "' .. startTimestamp .. '", end date: "' .. endTimestamp .. '")')
end
-- Get a random number between the two Unix timestamps and return it using the specified format.
local randomTimestamp = bigRandom(startTimestampUnix, endTimestampUnix)
local dateFormat = args.format or 'H:i, d F Y (T)'
local result = getDate(dateFormat, '@' .. tostring(randomTimestamp))
if result then
return result
else
return raiseError('"' .. dateFormat .. '" is not a valid date format')
end
end
Line 168 ⟶ 256:
-- Process arguments for other functions.
local otherFuncs = {'number', 'date', 'item', 'list', 'text_list'}
for _, funcName in ipairs(otherFuncs) do
p[funcName] = makeWrapper('_' .. funcName)
|