モジュール:TemplUtl

local TemplUtl = { suite  = "TemplUtl",
serial = "2019-06-09",
item   = 52364930 };
local fiatTitleRegExp = function ( accept )
-- Create pattern to detect page name
-- Precondition:
--     accept  -- string; trimmed title
-- Postcondition:
--     Returns string with pattern
local start = mw.ustring.sub( accept, 1, 1 );
local r;
if mw.ustring.match( start, "%a" ) then
r = string.format( "%s%s%s",
mw.ustring.lower( start ),
mw.ustring.upper( start ),
mw.ustring.sub( accept, 2 ) );
else
r = accept;
end
if r:match( " " ) then
r = r:gsub( "%", "%%" )
:gsub( "%-^.?+*()$", "%$1" )
:gsub( "_", " " )
:gsub( "%s+", "%s_+" );
end
return r;
end -- fiatTitleRegExp()
local framing = function ( frame )
if not TemplUtl.frame then
if type( frame ) == "table" then
TemplUtl.frame = frame;
else
TemplUtl.frame = mw.getCurrentFrame();
end
end
return TemplUtl.frame;
end -- framing()
TemplUtl.faculty = function ( analyze, another )
-- Test template arg for boolean
--     analyze  -- string, boolean, number or nil
--     another  -- fallback: string, boolean, or nil
-- Returns boolean
local s = type( analyze );
local r;
if s == "string" then
r = mw.text.trim( analyze );
if r == ""  then
r = TemplUtl.faculty( another, nil );
elseif r:find( "1", 1, true )  and
r:match( "^0%-*101%-*$") then
r = true;
elseif r:match( "^0%-+$") then
r = false;
else
r = r:lower();
if r == "y"  or  r == "yes"  or  r == "true" then
r = true;
elseif r == "n"  or  r == "no"  or  r == "false" then
r = false;
else
if not TemplUtl.L10N then
local lucky;
s = string.format( "Module:%s/local",
TemplUtl.suite );
lucky, TemplUtl.L10N = pcall( mw.loadData, s );
end
if type( TemplUtl.L10N ) == "table" then
local entry;
if not TemplUtl.lang then
-- TODO: page language
TemplUtl.lang =
mw.language.getContentLanguage():getCode();
end
entry = TemplUtl.L10N TemplUtl.lang ;
if type( entry ) == "table" then
s = entry r ;
if type( s ) == "boolean" then
r = s;
end
end
else
TemplUtl.L10N = true;
end
if type( r ) ~= "boolean" then
if type( another ) ~= "nil"  then
r = TemplUtl.faculty( another );
else
r = true;
end
end
end
end
elseif s == "boolean" then
r = analyze;
elseif s == "number" then
r = ( analyze ~= 0 );
else
r = false;
end
return r;
end -- TemplUtl.faculty()
TemplUtl.failsafe = function ( atleast )
-- Retrieve versioning and check for compliance
-- Precondition:
--     atleast  -- string, with required version or "wikidata"
--                 or false
-- Postcondition:
--     Returns  string with appropriate version, or false
local since = atleast
local r
if since == "wikidata" then
local item = TemplUtl.item
since = false
if type( item ) == "number"  and  item > 0 then
local entity = mw.wikibase.getEntity( string.format( "Q%d",
item ) )
if type( entity ) == "table" then
local vsn = entity:formatPropertyValues( "P348" )
if type( vsn ) == "table"  and
type( vsn.value ) == "string" and
vsn.value ~= "" then
r = vsn.value
end
end
end
end
if not r then
if not since  or  since >>" );
sign = string.format( "%s",  sign,  tostring( btn ) );
top:wikitext( sign, " ", alert );
mw.addWarning( tostring( top:attr( "role", "alert" ) ) );
elseif not always then
err:css( { "display"     = "none" } );
--      err:css( { "display"     = "inline-block",
--                 "line-height" = "0",
--                 "max-height"  = "0",
--                 "max-width"   = "0",
--                 "visibility"  = "hidden" } );
end
return tostring( err );
end -- TemplUtl.failure()
TemplUtl.fake = function ( access )
-- Simulation of template transclusion
-- Precondition:
--    access  -- string; page name (template)
if type( access ) == "string" then
local s = mw.text.trim( access );
if s ~= "" then
local t = mw.title.new( s, 10 );
if not mw.title.equals( mw.title.getCurrentTitle(), t )  and
t.exists then
t:getContent();
end
end
end
end -- TemplUtl.fake()
TemplUtl.fakes = function ( array, frame, ahead, answer )
-- Simulation of template transclusions
-- Precondition:
--    array   -- table, with template title strings
--    frame   -- object, or nil
--    ahead   -- string, or nil, with common prefix
--    answer  -- true, or nil, for list creation
-- Postcondition:
--     Returns string, if answer requested
local e = framing( frame );
local f = function ( a )
e:expandTemplate{ title = a };
end
local s = ahead or "";
local r;
for k, v in pairs( array ) do
if type( k ) == "number" and
type( v ) == "string" then
v = s .. mw.text.trim( v );
pcall( f, v );
if answer then
if r then
r = r .. "\n";
else
r = "";
end
r = string.format( "%s* %s", r, v, v );
end
end
end -- for k, v
return r;
end -- TemplUtl.fakes()
TemplUtl.feasible = function ( address )
-- Does this describe an URL beginning?
-- Precondition:
--    address  -- string; what to inspect, URL presumed
-- Postcondition:
--     Returns true, if URL beginning
local start, r = address:match( "^%s*((%a*:?)//)" );
if start then
if r == "" then
r = true;
elseif r:sub( -1, -1 ) == ":" then
local schemes = ":ftp:ftps:http:https:";
r = ":" .. r:lower();
if schemes:find( r, 1, true ) then
r = true;
else
r = false;
end
else
r = false;
end
end
return r;
end -- TemplUtl.feasible()
TemplUtl.feed = function ( area, ahead, at, after )
-- Detect next free "|" or "}}"
-- Precondition:
--     area   -- string; template transclusion
--     ahead  -- string; opening element, or false
--     at     -- number; byte position in area where to start
--     after  -- true, if only to search for "}}"
-- Postcondition:
--     Returns
--          -- number; byte position in area
--             -- before "|" or "}}", may be at end
--             -- to continue search; ahead has been closed
--          -- true, if to be continued at number
local j    = at;
local loop = true;
local c, k, r, s, seek;
if after then
seek = "{}<";
else
seek = "%%|{}<:";
end
while loop do
j = area:find( seek, j );
if j then
c = area:byte( j, j );
if c == 123 then    -- {
k = j + 1;
if area:byte( k, k ) == 123 then
k = k + 1;
if area:byte( k, k ) == 123 then
j, loop = TemplUtl.feed( area, "