--- Entrypoint templating wrapper for Scribunto packages.-- The module generates an entrypoint function that can execute Scribunto-- package calls in the template context. This allows a package to support-- both direct and template invocations.-- -- @script entrypoint-- @release beta-- @author 8nml (Fandom Dev Wiki)-- @param package Scribunto package.-- @error[85] 'you must specify a function to call'-- @error[91] 'the function you specified did not exist'-- @error[opt,95] '$2 is not a function'-- @return Template entrypoint - @.-- @note Parent frames are not available in Entrypoint's-- `frame`. This is because recursive (grandparent)-- frame access is impossible in legacy Scribunto-- due to empty-argument expansion cache limitations.-- @note As Entrypoint enables template access rather than-- a new extension hook, it does not work with named-- numeric parameters such as `1=` or `2=`. This may-- result in unexpected behaviour such as Entrypoint-- and module errors.
--- Stateless, sequential Lua iterator.-- @function inext-- @param t Invariant state to loop over.-- @param i Control variable (current index).-- @return[opt] Next index.-- @return[opt] Next value.-- @see https://github.com/lua/lua/blob/v5.1.1/lbaselib.c#L247local inext = select(1, ipairs)
--- Check for MediaWiki version 1.25.-- The concurrent Scribunto release adds a type check for package functions.-- @variable func_check-- @see local func_check = tonumber(mw.site.currentVersion:match('^%d+.%d+')) >= 1.25
--- MediaWiki error message getter.-- Mimics Scribunto error formatting for script errors. -- @function msg-- @param key MediaWiki i18n message key.-- @param[opt] fn_name Name of package function.-- @return Formatted lowercase message.-- @locallocal function msg(key, fn_name) return select(1, mw.message.new(key) :plain :match(':%s*(.-)[.۔。෴։።]?$') :gsub('^.', mw.ustring.lower) :gsub('$2', fn_name or '$2'))end
--- Template entrypoint function generated by this module.-- @function main-- @param frame Scribunto frame in module context.-- @return Module output in template context.return function(package) return function(f) local frame = f:getParent
local args_mt = local arg_cache =
args_mt.__pairs = function return next, arg_cache, nil end args_mt.__ipairs = function return inext, arg_cache, 0 end args_mt.__index = function(t, k) return arg_cache[k] end
for key, val in pairs(frame.args) do arg_cache[key] = val end local fn_name = table.remove(arg_cache, 1)
f.args = setmetatable(args_mt) frame.args = setmetatable(args_mt)
if not fn_name then error(msg('scribunto-common-nofunction')) end
fn_name = mw.text.trim(fn_name)
if not package[fn_name] then error(msg('scribunto-common-nosuchfunction', fn_name)) end
if func_check and type(package[fn_name]) ~= 'function' then error(msg('scribunto-common-notafunction', fn_name)) end
return package[fn_name](frame)end end