Modul:TemplUtl: Unterschied zwischen den Versionen

10.063 Bytes entfernt ,  17. Februar 2019
K
Änderungen von PerfektesChaos (Diskussion) auf die letzte Version von Mabschaaf zurückgesetzt
(2019-02-17)
K (Änderungen von PerfektesChaos (Diskussion) auf die letzte Version von Mabschaaf zurückgesetzt)
Zeile 1: Zeile 1:
local TemplUtl = { suite  = "TemplUtl",
--[=[ 2014-11-24
                  serial = "2019-02-17" };
TemplUtl
]=]




Zeile 10: Zeile 11:
     -- Postcondition:
     -- Postcondition:
     --    Returns string with pattern
     --    Returns string with pattern
    local r;
     local start = mw.ustring.sub( accept, 1, 1 );
     local start = mw.ustring.sub( accept, 1, 1 );
    local r;
     if mw.ustring.match( start, "%a" ) then
     if mw.ustring.match( start, "%a" ) then
         r = string.format( "[%s%s]%s",
         r = string.format( "[%s%s]%s",
Zeile 22: Zeile 23:
     if r:match( " " ) then
     if r:match( " " ) then
         r = r:gsub( "%", "%%" )
         r = r:gsub( "%", "%%" )
             :gsub( "[%-^.?+*()$]", "%$1" )
             :gsub( "[^.?+*()$]+", "%$1" )
             :gsub( "_", " " )
             :gsub( "_", " " )
             :gsub( "%s+", "[%s_]+" );
             :gsub( "%s+", "[%s_]+" );
Zeile 31: Zeile 32:




local framing = function ( frame )
local TemplUtl = { };
    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%-]*1[01%-]*$") 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 ( assert )
    local r
    if not assert  or  assert <= TemplUtl.serial then
        r = TemplUtl.serial
    else
        r = false
    end
    return r
end -- TemplUtl.failsafe()
 
 
 
TemplUtl.failure = function ( alert, always, addClass, frame )
    -- Format error message, mostly hidden
    --    alert    -- string: message
    --    always    -- boolean, or nil: do not hide
    --    addClass  -- string, or nil: add classes to element
    --    frame    -- object, or nil
    -- Returns string
    local err  = mw.html.create( "span" )
                        :addClass( "error" )
                        :wikitext( alert );
    local live = ( framing( frame ):preprocess( "{{REVISIONID}}" )
                  == "" );
    if type( addClass ) == "string" then
        err:addClass( addClass )
    end
    if live then
        local max  = 1000000000;
        local id  = math.floor( os.clock() * max );
        local sign = string.format( "error_%d", id );
        local btn  = mw.html.create( "span" );
        local top  = mw.html.create( "div" );
        err:attr( "id", sign );
        -- TODO: LTR
        btn:css( { ["background"]      = "#FFFF00",
                  ["border"]          = "#FF0000 3px solid",
                  ["font-weight"]    = "bold",
                  ["padding"]        = "2px",
                  ["text-decoration"] = "none" } )
          :wikitext( "&gt;&gt;&gt;" );
        sign = string.format( "[[#%s|%s]]",  sign,  tostring( btn ) );
        top:wikitext( sign, "&#160;", 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, frame )
    -- Simulation of template transclusion
    -- Precondition:
    --    access  -- string, or nil; page name (template)
    --    frame  -- object, or nil
    local s;
    if type( access ) == "string" then
        s = mw.text.trim( access );
        if s == "" then
            s = false;
        end
    end
    if not s then
        local cnf, lucky;
        s = string.format( "Module:%s/self", TemplUtl.suite );
        lucky, cnf = pcall( mw.loadData, s );
        if type( cnf ) == "table"  and
          cnf.loop == true then
            s = mw.title.getCurrentTitle().text;
        else
            s = false;
        end
    end
    if s then
        local f = function ()
                      framing( frame ):expandTemplate{ title = s };
                  end
        pcall( f );
    end
end -- TemplUtl.fake()
 
 
 
TemplUtl.fakes = function ( array, frame, ahead )
    -- Simulation of template transclusions
    -- Precondition:
    --    array  -- table, with template title strings
    --    frame  -- object, or nil
    --    ahead  -- string, or nil, with common prefix
    local e = framing( frame );
    local f = function ( a )
                  e:expandTemplate{ title = a };
              end
    local s = ahead or "";
    for k, v in pairs( array ) do
        if type( k ) == "number" and
          type( v ) == "string" then
            v = mw.text.trim( v );
            pcall( f, s .. v );
        end
    end -- for k, v
end -- TemplUtl.fakes()




Zeile 395: Zeile 208:
     --    at    -- optional number; byte position in area of "{{"
     --    at    -- optional number; byte position in area of "{{"
     -- Postcondition:
     -- Postcondition:
     --    Returns
     --    Returns table
    --          -- table
     --              [0] template, page, parser function name
     --              [0]       -- template, page, parser function name
    --              [1]      -- unnamed parameter
    --              ["name"]  -- named parameter
    --          -- string; error message, if any, else nil
     local n = 0;
     local n = 0;
     local j, k, p, r, r2, s, v;
     local j, k, p, r, r2, s, v;
Zeile 496: Zeile 305:
     -- Requires:
     -- Requires:
     --    fiatTitleRegExp()
     --    fiatTitleRegExp()
    local r, space, start, suffix;
     local scan = string.format( "{{%s%s%s",
     local scan = string.format( "{{%s%s%s",
                                 "([%w_%s:]*)%s*",
                                 "([%w_%s:]*)%s*",
                                 fiatTitleRegExp( access ),
                                 fiatTitleRegExp( access ),
                                 "%s*([|}<]!?)" );
                                 "%s*([|}<]!?)" );
    local r, space, start, suffix;
     if type( at ) == "number" then
     if type( at ) == "number" then
         r = at;
         r = at;
Zeile 552: Zeile 361:
     return r;
     return r;
end -- TemplUtl.find()
end -- TemplUtl.find()
-- finder()
--      1 page name
--      2 template title / page name
--      3 4 5 6
--        more like 2
TemplUtl.flat = function ( area )
    -- Remove syntax elements that hide effective syntax only
    -- Precondition:
    --    area  -- string; wikitext to be reduced
    -- Postcondition:
    --    Returns cleared wikitext
    local delimiters = { { "<%s*NOWIKI%s*>", "<%s*/%s*NOWIKI%s*>" },
                        { "<!--", "-->", true },
                        { "<%s*PRE%s*>", "<%s*/%s*PRE%s*>" },
                        { "<%s*SYNTAXHIGHLIGHT[^<>]*>",
                          "<%s*/%s*SYNTAXHIGHLIGHT%s*>" } };
    local i          = 1;
    local r          = area;
    local k, m, n;
    if not TemplUtl.Delimiters then
        local c, sD, sP;
        TemplUtl.Delimiters = { };
        for j = 1, #delimiters do
            table.insert( TemplUtl.Delimiters, { } );
            for ji = 1, 2 do
                sD = delimiters[ j ][ ji ];
                sP = "";
                for js = 1, #sD, 1 do
                    c = sD:byte( js, js );
                    if c >= 65  and  c <= 90 then
                        sP = string.format( "%s[%c%c]",
                                            sP,  c,  c + 32 );
                    else
                        sP = sP .. string.char( c );
                    end
                end -- for js
                table.insert( TemplUtl.Delimiters[ j ], sP );
            end -- for ji
        end -- for j
    end
    while ( true ) do
        k = false;
        for j = 1, #delimiters do
            m = r:find( TemplUtl.Delimiters[ j ][ 1 ],
                        i,
                        TemplUtl.Delimiters[ j ][ 3 ] );
            if m  and  ( not k  or  m < k ) then
                k = m;
                n = j;
            end
        end -- for j
        if k then
            local s
            if k > 1 then
                i = k - 1;
                s = r:sub( 1, i );
            else
                s = "";
            end
            j, m  =  r:find( TemplUtl.Delimiters[ n ][ 2 ],
                            k + 1,
                            TemplUtl.Delimiters[ n ][ 3 ] );
            if m then
                r = s  ..  r:sub( m + 1 );
            else
                r = s;
                break; -- while true
            end
        else
            break; -- while true
        end
    end -- while true
    return r;
end -- TemplUtl.flat()




Zeile 636: Zeile 366:
-- Export
-- Export
local p = { };
local p = { };
function p.faculty( frame )
    return TemplUtl.faculty( frame.args[ 1 ],
                            frame.args[ 2 ] )  and  "1"
          or  "";
end -- p.faculty
function p.failure( frame )
    local scream = mw.text.trim( frame.args[ 1 ]  or  "" );
    local loud  = frame.args[ 2 ];
    local select = frame.args.class;
    if scream == "" then
        scream = "?????????";
    end
    if loud then
        loud = TemplUtl.faculty( loud, nil );
    end
    return TemplUtl.failure( scream, loud, select, frame );
end -- p.failure
function p.fake( frame )
    TemplUtl.fake( frame.args[ 1 ]  or  "",  frame );
    return "";
end -- p.fake
function p.fakes( frame )
    TemplUtl.fakes( frame.args, frame, frame.args.prefix );
    return "";
end -- p.fakes
function p.isRedirect()
    return mw.title.getCurrentTitle().isRedirect and "1"  or  "";
end -- p.isRedirect
p.failsafe = function ( frame )
    -- Versioning interface
    local s = type( frame )
    local since
    if s == "table" then
        since = frame.args[ 1 ]
    elseif s == "string" then
        since = frame
    end
    if since then
        since = mw.text.trim( since )
        if since == "" then
            since = false
        end
    end
    return TemplUtl.failsafe( since )  or  ""
end -- p.failsafe()


p.TemplUtl = function ()
p.TemplUtl = function ()
     return TemplUtl;
     return TemplUtl;
end -- p.TemplUtl()
end


return p;
return p;
Anonymer Benutzer