This module was made as a sandbox for the user The JoTS. This documentation is kept to prevent redlinks.
--| Module: DynamicWelcome (v1.2.4)
--- Allows for customizable welcome messages.
--by "The JoTS"
-- update v1.2.4 ~ Internal code formatting, and removing function aliases.
--TODO create message library for errors
-- <nowiki>
-- [==[ Import modules ]==] --
local getArgs = require("Dev:Arguments").getArgs
local yesno = require "Dev:Yesno"
local custom, messages =
pcall(function() return mw.loadData "Module:DynamicWelcome/msg" end)
-- user error: msg dict exists, not formatted properly
if (not custom) and messages:match("^%%") then
error(messages:sub(2))
end
--TODO implement default messages
--messages = custom and messages or mw.loadData "Dev:DynamicWelcome/default"
-- [==[ Meta functions ]==] --
--% Creates a wrapped function that returns an argument table to the provided
--- function 'func' and processes returned text from 'func'.
--@ func (function) A function to be wrapped.
--: (function) ...A wrapped function.
local function arg_wrap(func)
return function(frame)
return frame:preprocess( func(getArgs(frame)) )
end
end
--% Returns the namespace of a given page name
--- or removes the namespace from a given page name, if 'gsub' is true.
--@ pageName (string) A page's name.
--@ gsub (bool) If true, removes the namespace from a page name.
--: (string) A string of a formatted page name, or of a namespace.
local function namespaceOp(pageName, gsub)
-- consider splitting into two different funcs?
return
string[gsub and "gsub" or "match"](
pageName,
"^([^:]+):",
gsub and '' or nil)
end
--% Dynamic processing of the "pipe trick," instead of at page save time.
--- See http://wikipedia.org/wiki/Help:Pipe_trick for more details.
--@ txt (string) Text to be processed.
--: (string) Processed string.
local function processPipeTrick(txt)
-- the pipe trick involving the comma is NOT implemented
return txt:gsub("%[%[([^|]+)|%]%]", function(page)
-- get page name
local name = page
:gsub ("^[%w%s_]+:", '')
:match "[%w%s_]+"
:match "^%s*(.-)%s*$"
-- return formatted link
return "[[" .. page .. '|' .. name .. "]]"
end)
end
--% Validates user input.
--@ provided (multiple) User input.
--@ options (table) Selection of possible inputs.
--: (multiple) ...I mean, in this script, it'll be a bool/nil.
--- Or, at the very least, it should be treated as such.
local function validate(provided, options)
return options[provided]
end
-- [==[ Module Functions ]==] --
local MODES = {
["message-wall"] = true, ["message"] = true
}
local VAR_ENUM = {
-- Implement custom enum for vars
page = 1, greeter_talk = 2,
greeter_sig = 3, welcomed = 4
}
local SETUP_CONST = {
ADMIN = true, MODE = true, ANON = true
}
--% Generates a greeting message according the the provided args.
--@ vargs (table) A table of raw "virtual" arguments retrieved from frame.
--: (string) Generated greeting.
local function _greet(vargs)
if vargs[5] then
-- Handle a two part "page" argument (e.g. "Thread:1234|Lorem Ipsum")
-- Does NOT properly handle an error in which a user
-- somehow provides 5 args
vargs[1] = vargs[1] .. '|' .. vargs[2] -- merge argument back together
-- shift arguments in table
for i=2,4 do
vargs[i] = vargs[i + 1]
vargs[i + 1] = nil
end
end
-- Set enumerator
local args = setmetatable({}, { __index = function(t, key)
return vargs[VAR_ENUM[key] or key]
end })
assert((not args.mode) or validate(args.mode, MODES),
"An invalid mode was provided")
-- defaults
args.mode = (type(args.mode) ~= "string" and "message-wall" or args.mode)
args.anon = yesno(args.anon) and "anon" or "user"
local dict = messages[args.mode][args.anon] -- selected root dictionary
-- Selected greeter dictionary ("Wikia" is fallback)
local gDict = (not dict)
and error("The \"" .. args.anon .. "\" dictionary does not exist")
or dict[namespaceOp(args.greeter_talk, true)]
or dict.Wikia
or error("The default greeter dictionary,\"Wikia\", does not exist")
local entry = gDict[namespaceOp(args.page)]
or gDict.DEFAULT
or error("The default entry does not exist")
-- Return formatted entry
return processPipeTrick( entry:gsub("%$(%d)", function(var)
-- Substitute variable numbers w/ value
return args[tonumber(var)] or var
end) )
end
local greet = arg_wrap( _greet )
--% An assistive function for creating a table of greeting templates
--@ admin (string) An admin to generate a greeting for.
--@ mode (string) A messaging mode. "message-wall" or "
--@ globals (string) Must be _G or getfenv()
local function setup(admin, mode, globals)
-- errors
assert(globals.ADMIN == admin,
"%Admin mismatch: " .. globals.ADMIN .. " x " .. admin)
assert(globals.MODE == mode,
"%Mode mismatch: " .. globals.MODE .. " x " .. mode)
assert(validate(mode, MODES),
"%An invalid mode was provided: " .. mode)
assert(type(globals.ANON) == "boolean",
"%Global \"ANON\" was not initialized or is not a boolean")
local frm = globals.__DYNAWELC__ or {} -- formatted table
local anon = globals.ANON and "anon" or "user"
-- setup
globals.__DYNAWELC__ = frm
frm[mode] = frm[mode] or {}
frm[mode][anon] = frm[mode][anon] or {}
frm[mode][anon][admin] = frm[mode][anon][admin] or {}
-- create entry
for k,v in pairs(globals) do
if k:match("^(%u[%w_]+)$") and (not validate(k, SETUP_CONST)) then
globals[k] = nil
frm[mode][anon][admin][k:gsub('_',' ')] = v:gsub("\\n", "\n")
end
end
return frm
end
--- Module interface ---------------------------
return {
-- en
greet = greet;
setup = setup;
}