Nicht angemeldeter Benutzer - Bearbeiten von Seiten ist nur als angemeldeter Benutzer möglich.

Modul:Shortcuts: Unterschied zwischen den Versionen

Aus imedwiki
Zur Navigation springen Zur Suche springen
(update)
(update)
Zeile 1: Zeile 1:
--[=[ 2014-06-03
+
--[=[ 2014-06-06
 
Module:Shortcuts
 
Module:Shortcuts
 
]=]
 
]=]
Zeile 119: Zeile 119:
 
     if absent  and  type( Config ) == "table" then
 
     if absent  and  type( Config ) == "table" then
 
         local s = Config.suppress
 
         local s = Config.suppress
         if type( s ) == "string" and  s:find( "%s", 1, true ) then
+
         if type( s ) == "string" then
 +
            finds( s, "suppress" )
 
             r = string.format( s, r )
 
             r = string.format( s, r )
 
         end
 
         end
Zeile 154: Zeile 155:
 
     return r
 
     return r
 
end -- fiat()
 
end -- fiat()
 +
 +
 +
 +
local function finds( attempt, about )
 +
    -- Checks whether string may be used for text formatting
 +
    --    attempt  -- string, with format pattern
 +
    --    about    -- string, with name
 +
    -- Throws error with message, else does nothing
 +
    if type( attempt ) ~= "string"  or
 +
      not attempt:find( "%s", 1, true ) then
 +
        error( string.format( "/config '%s' invalid", about ) )
 +
    end
 +
end -- finds()
  
  
Zeile 159: Zeile 173:
 
local function first( a1, a2 )
 
local function first( a1, a2 )
 
     -- Compare a1 with a2 in reverse title order
 
     -- Compare a1 with a2 in reverse title order
     --    a1     -- table, with assignment
+
     --    a1 -- table, with assignment
     --    a2     -- table, with assignment
+
     --    a2 -- table, with assignment
 
     -- Returns true if a1 < a2
 
     -- Returns true if a1 < a2
 
     local r
 
     local r
Zeile 186: Zeile 200:
 
     if page.exists then
 
     if page.exists then
 
         if page.isRedirect then
 
         if page.isRedirect then
 +
            local say
 
             local story    = page:getContent()
 
             local story    = page:getContent()
 
             local shift    = story:match( "^#[^%[]+%[%[([^%]\n]+)%]%]" )
 
             local shift    = story:match( "^#[^%[]+%[%[([^%]\n]+)%]%]" )
Zeile 203: Zeile 218:
 
                   and  Config.signature
 
                   and  Config.signature
 
                   and  not story:find( Config.signature, 15, true ) then
 
                   and  not story:find( Config.signature, 15, true ) then
                    local say
 
 
                     if type( Config.signal ) == "string" then
 
                     if type( Config.signal ) == "string" then
 
                         say = Config.signal
 
                         say = Config.signal
Zeile 212: Zeile 226:
 
                 end
 
                 end
 
             else
 
             else
 +
                say = Config.sayTarget
 
                 failure( alone, "wrong target" )
 
                 failure( alone, "wrong target" )
 
             end
 
             end
 
         else
 
         else
 +
            say = Config.sayRegular
 
             failure( alone, "regular page" )
 
             failure( alone, "regular page" )
 
         end
 
         end
Zeile 264: Zeile 280:
 
     -- Present table row
 
     -- Present table row
 
     --    arglist  -- table, with parameters
 
     --    arglist  -- table, with parameters
    --        .self      -- string, target page
 
 
     --        .story      -- string or nil, append to target page link
 
     --        .story      -- string or nil, append to target page link
 
     --        .suffix    -- string or nil, append to shortcut list
 
     --        .suffix    -- string or nil, append to shortcut list
 
     -- Returns table row markup
 
     -- Returns table row markup
 
     local l, nsn, shortcuts, t
 
     local l, nsn, shortcuts, t
     local space, subject = arglist.self:match( "^([^:]+):(.+)$" )
+
     local space, subject = Current.self:match( "^([^:]+):(.+)$" )
 
     if space then
 
     if space then
 
         local o = mw.site.namespaces[ space ]
 
         local o = mw.site.namespaces[ space ]
Zeile 285: Zeile 300:
 
         shortcuts = t[ subject ]
 
         shortcuts = t[ subject ]
 
     end
 
     end
     subject = string.format( "[[:%s]]", arglist.self )
+
     subject = string.format( "[[:%s]]", Current.self )
 
     if type( arglist.story ) == "string" then
 
     if type( arglist.story ) == "string" then
 
         subject = subject .. arglist.story
 
         subject = subject .. arglist.story
Zeile 315: Zeile 330:
 
     --        .leave      -- true, if dummy entry
 
     --        .leave      -- true, if dummy entry
 
     -- Throws error with message, else returns string with text
 
     -- Throws error with message, else returns string with text
     local style = Config.style
+
     local got  = faces( arglist.shortcuts )
 +
    local pages = { }
 
     local r
 
     local r
     if type( style ) == "string"  and  style:find( "%s", 1, true ) then
+
     if Config.show then
         local pages = { }
+
        finds( Config.show, "show" )
         local got  = faces( arglist.shortcuts )
+
        r = string.format( Config.show, arglist.shortcuts )
         r = string.format( style, arglist.shortcuts )
+
    else
        for k, v in pairs( got ) do
+
        r = arglist.shortcuts
            if not arglist.leave then
+
    end
                flag( arglist, v, pages )
+
    if Config.style and not Config.light then
             end
+
         finds( Config.style, "style" )
 +
         r = string.format( Config.style, r )
 +
    end
 +
    if Config.styleTEMP then
 +
         r = string.format( Config.styleTEMP, arglist.shortcuts )
 +
    end
 +
    for k, v in pairs( got ) do
 +
        if not arglist.leave then
 +
            flag( arglist, v, pages )
 +
        end
 +
    end    -- for k, v
 +
    if Errors then
 +
        local s = ""
 +
        for k, v in pairs( Errors ) do
 +
             s = string.format( "%s [[%s]]:&#160;%s", s, k, v )
 
         end    -- for k, v
 
         end    -- for k, v
         if Errors then
+
         r = r .. fault( s, true )
            local s = ""
 
            for k, v in pairs( Errors ) do
 
                s = string.format( "%s [[%s]]:&#160;%s", s, k, v )
 
            end    -- for k, v
 
            r = r .. fault( s, true )
 
        end
 
    else
 
        error( "/config 'style' invalid" )
 
 
     end
 
     end
 
     return r
 
     return r
Zeile 364: Zeile 386:
 
         if args.self then
 
         if args.self then
 
             Current.self = args.self
 
             Current.self = args.self
             Current.page = mw.title.new( args.self )
+
             Current.page = mw.title.new( Current.self )
 
             if not Current.page.exists then
 
             if not Current.page.exists then
 
                 Current.page = false
 
                 Current.page = false
 
                 r            = string.format( "'%s' not found",
 
                 r            = string.format( "'%s' not found",
                                               args.self )
+
                                               Current.self )
 
             end
 
             end
 
         elseif args.service == "trow" then
 
         elseif args.service == "trow" then
Zeile 378: Zeile 400:
 
             Current.page = mw.title.getCurrentTitle()
 
             Current.page = mw.title.getCurrentTitle()
 
             Current.self = Current.page.prefixedText
 
             Current.self = Current.page.prefixedText
            args.self    = Current.self    -- OBSOLETING
 
 
         end
 
         end
 
         if Current.page then
 
         if Current.page then
Zeile 459: Zeile 480:
 
     if params.service == "template" then
 
     if params.service == "template" then
 
         params.shortcuts = pars[ 1 ]
 
         params.shortcuts = pars[ 1 ]
 +
        params.light    = pars.light
 
     elseif params.service == "trow" then
 
     elseif params.service == "trow" then
 
         params.self  = pars[ 1 ]
 
         params.self  = pars[ 1 ]

Version vom 7. Juni 2014, 22:07 Uhr

Die Dokumentation für dieses Modul kann unter Modul:Shortcuts/Doku erstellt werden

--[=[ 2014-06-06
Module:Shortcuts
]=]



-- local globals
local Config
local Current = { }
local Errors  = false
local Sort    = false



local function faces( any )
    -- Retrieve single shortcut names
    --     any  -- string, with shortcut name list
    -- Returns table with shortcut page names
    local s = any:gsub( "<[^>]+>", "," )
                 :gsub( "%[%[", "" )
                 :gsub( "%]%]", "" )
    local r = mw.text.split( s, "%s*,%s*" )
    for k, v in pairs( r ) do
        if mw.text.trim( v ) == "" then
            r[ k ] = nil
        end
    end    -- for k, v
    return r
end -- faces()



local function facet( area, assign, assigned )
    -- Create mapping shortcut->target
    --     area      -- string, with target namespace name and colon
    --     assign    -- string, with target page name
    --     assigned  -- string, with shortcut page name
    -- Returns table with entry
    --     .shift     -- string, with target page name
    --     .shortcut  -- string, with shortcut page name
    --     .nsn       -- number, of shortcut namespace
    --     .sort      -- string, with sortable shortcut page title
    local space, subject = assigned:match( "^([^:]+):(.+)$" )
    local r = { }
    r.shift    = area .. assign
    r.shortcut = assigned
    if space then
        local o = mw.site.namespaces[ space ]
        if o then
            r.nsn = o.id
        end
    end
    if not r.nsn then
        r.nsn   = 0
        subject = assigned
    end
    if Sort then
        subject = Sort.lex( subject, "latin", false )
    end
    r.sort = string.upper( subject )
    return r
end -- facet()



local function factory( account, alone, assembly )
    -- Retrieve mappings shortcut->target for entire target namespace
    --     account   -- string, with module name
    --     alone     -- number, of namespace
    --     assembly  -- table, collecting assignments
    -- Extending assembly
    local space = mw.site.namespaces[ alone ]
    if space then
        local got
        local sub = string.format( "%s/%d", account, alone )
        local l, t = pcall( mw.loadData, sub )
        if type( t ) == "table" then
            if space.id == 0 then
                space = ""
            else
                space = space.name .. ":"
            end
            for k, v in pairs( t ) do
                got = faces( v )
                for i, s in pairs( got ) do
                    table.insert( assembly,  facet( space, k, s ) )
                end    -- for i, s
            end    -- for k, v
        end
    end
end -- factory()



local function fair( above )
    -- Convert shortcut list namespaces into talk pages
    --     alert  -- string, with shortcuts
    -- Returns converted shortcuts
    local r = " " .. above
    if type( Config.talks ) == "table" then
        local seek, shift
        for k, v in pairs( Config.talks ) do
            seek  = string.format( "(%%A?)(%s):", k )
            shift = string.format( "%%1%s:", v )
            r = r:gsub( seek, shift )
        end    -- for k, v
    end
    return mw.text.trim( r )
end -- fair()



local function fault( alert, absent )
    -- Format message with class="error"; add Config (category etc.)
    --     alert   -- string, with message
    --     absent  -- boolean, hide message, trigger category
    -- Returns message with markup
    local r = string.format( "<span class=\"error\">%s</span>", alert )
    if absent  and  type( Config ) == "table" then
        local s = Config.suppress
        if type( s ) == "string" then
            finds( s, "suppress" )
            r = string.format( s, r )
        end
        if type( Config.scream ) == "string" then
            r = string.format( "%s[[Category:%s]]", r, Config.scream )
        end
    end
    return r
end -- fault()



local function failure( assigned, about )
    -- Add one message to Errors
    --     assigned  -- string, with shortcut page name
    --     about     -- string, with error keyword
    if type( Errors ) ~= "table" then
        Errors = { }
    end
    Errors[ assigned ] = about
end -- failure()



local function fiat( ahead, after )
    -- Format table row
    --     ahead  -- string, with first cell
    --     after  -- string or false, with second cell
    -- Returns table row markup
    local r = string.format( "\n|-\n|%s", ahead )
    if after then
        r = string.format( "%s||%s", r, after )
    end
    return r
end -- fiat()



local function finds( attempt, about )
    -- Checks whether string may be used for text formatting
    --     attempt  -- string, with format pattern
    --     about    -- string, with name
    -- Throws error with message, else does nothing
    if type( attempt ) ~= "string"  or
       not attempt:find( "%s", 1, true ) then
        error( string.format( "/config '%s' invalid", about ) )
    end
end -- finds()



local function first( a1, a2 )
    -- Compare a1 with a2 in reverse title order
    --     a1  -- table, with assignment
    --     a2  -- table, with assignment
    -- Returns true if a1 < a2
    local r
    if  a1.shortcut == a2.shortcut then
        r = ( string.upper( a1.shift )  >  string.upper( a2.shift ) )
    elseif a1.sort == a2.sort then
        r = ( a1.nsn > a2.nsn )
    else
        r = ( a1.sort > a2.sort )
    end
    return r
end -- first()



local function flag( arglist, alone, achieved )
    -- Analyze one shortcut
    --     arglist  -- table, with parameters
    --         .nsn    -- number, of current namespace
    --         .nsns   -- number, of subject namespace
    --     alone     -- string, with shortcut page name
    --     achieved  -- table, with title objects; will be extended
    -- Adds error message to collection
    local page = mw.title.new( alone )
    if page.exists then
        if page.isRedirect then
            local say
            local story    = page:getContent()
            local shift    = story:match( "^#[^%[]+%[%[([^%]\n]+)%]%]" )
            local redirect = mw.title.new( shift )
            if mw.title.equals( Current.page, redirect ) then
                for k, v in pairs( achieved ) do
                    if mw.title.equals( page, v ) then
                        failure( alone, "duplicated" )
                        page = false
                        break    -- for k, v
                    end
                end    -- for k, v
                if page then
                    table.insert( achieved, page )
                end
                if arglist.nsn == arglist.nsns
                   and  Config.signature
                   and  not story:find( Config.signature, 15, true ) then
                    if type( Config.signal ) == "string" then
                        say = Config.signal
                    else
                        say = ".signature (category) missing"
                    end
                    failure( alone, say )
                end
            else
                say = Config.sayTarget
                failure( alone, "wrong target" )
            end
        else
            say = Config.sayRegular
            failure( alone, "regular page" )
        end
    else
        failure( alone, "missing" )
    end
end -- flag()



local function flash( account, alone )
    -- Create all item table body with two columns; shortcut and target
    --     account   -- string, with module name
    --     alone     -- number or false, with namespace limitation
    -- Returns table rows until end
    local r = "\n|}"
    local collect = { }
    if type( alone ) == "number" then
        factory( account, alone, collect )
    elseif type( Config.rooms ) == "table" then
        for k, v in pairs( Config.rooms ) do
            factory( account, v, collect )
        end    -- for k, v
    else
        r       = r .. "'Config.rooms' not found"
        collect = false
    end
    if collect then
        local second, shortcut
        if not Sort then
            local l, t = pcall( require, "Module:Sort" )
            if type( t ) == "table" then
                Sort = t.Sort()
            end
        end
        table.sort( collect, first )
        for k, v in pairs( collect ) do
            shortcut = string.format( "[[%s]]", v.shortcut )
            second   = string.format( "[[:%s]]", v.shift )
            r        = fiat( shortcut, second ) .. r
        end    -- for k, v
    end
    return r
end -- flash()



local function folder( arglist )
    -- Present table row
    --     arglist  -- table, with parameters
    --         .story      -- string or nil, append to target page link
    --         .suffix     -- string or nil, append to shortcut list
    -- Returns table row markup
    local l, nsn, shortcuts, t
    local space, subject = Current.self:match( "^([^:]+):(.+)$" )
    if space then
        local o = mw.site.namespaces[ space ]
        if o then
            nsn = o.id
        else
            nsn = 0
        end
    else
        nsn = 0
    end
    t = string.format( "%s/%d", arglist.suite, nsn )
    l, t = pcall( mw.loadData, t )
    if type( t ) == "table" then
        shortcuts = t[ subject ]
    end
    subject = string.format( "[[:%s]]", Current.self )
    if type( arglist.story ) == "string" then
        subject = subject .. arglist.story
    end
    if type( shortcuts ) == "string" then
        if shortcuts:sub( 1, 2 ) ~= "[[" then
            local got = faces( shortcuts )
            shortcuts = ""
            for k, v in pairs( got ) do
                shortcuts = string.format( "%s, [[%s]]", shortcuts, v )
            end    -- for k, v
            shortcuts = shortcuts:sub( 3 )
        end
        if type( arglist.suffix ) == "string" then
            shortcuts = shortcuts .. arglist.suffix
        end
    else
        shortcuts = fault( "no shortcuts", false )
    end
    return fiat( subject, shortcuts )
end -- folder()



local function follow( arglist )
    -- Analyze list of shortcuts in single page context
    --     arglist  -- table, with parameters
    --         .shortcuts  -- string, comma separated list of shortcuts
    --         .leave      -- true, if dummy entry
    -- Throws error with message, else returns string with text
    local got   = faces( arglist.shortcuts )
    local pages = { }
    local r
    if Config.show then
        finds( Config.show, "show" )
        r = string.format( Config.show, arglist.shortcuts )
    else
        r = arglist.shortcuts
    end
    if Config.style and not Config.light then
        finds( Config.style, "style" )
        r = string.format( Config.style, r )
    end
    if Config.styleTEMP then
        r = string.format( Config.styleTEMP, arglist.shortcuts )
    end
    for k, v in pairs( got ) do
        if not arglist.leave then
            flag( arglist, v, pages )
        end
    end    -- for k, v
    if Errors then
        local s = ""
        for k, v in pairs( Errors ) do
            s = string.format( "%s [[%s]]:&#160;%s", s, k, v )
        end    -- for k, v
        r = r .. fault( s, true )
    end
    return r
end -- follow()



local function forward( args )
    -- Perform task
    --     args  -- table, with parameters
    --         .self       -- string, target page
    --         .shortcuts  -- string, comma separated list of shortcuts
    -- Throws error with message, else returns string with text
    local l, t, sub
    local lucky = false
    local r     = false
    if type( args.suite ) == "string" then
        sub = args.suite .. "/config"
        l, t = pcall( mw.loadData, sub )
        if type( t ) == "table" then
            Config = t
        else
            r = string.format( "'%s' invalid", sub )
        end
    else
        r = "bad .suite"
    end
    if Config then
        if args.self then
            Current.self = args.self
            Current.page = mw.title.new( Current.self )
            if not Current.page.exists then
                Current.page = false
                r            = string.format( "'%s' not found",
                                              Current.self )
            end
        elseif args.service == "trow" then
            r = "'1=' missing"
        elseif args.service == "total" then
            Current.page = false
            lucky        = true
        else
            Current.page = mw.title.getCurrentTitle()
            Current.self = Current.page.prefixedText
        end
        if Current.page then
            Current.nsn = Current.page.namespace
            args.nsn = Current.nsn     -- OBSOLETING
            if args.nsn % 2 == 0 then
                args.nsns = args.nsn
                args.nsnt = args.nsn + 1
            else
                args.nsnt = args.nsn
                args.nsns = args.nsn - 1
            end
            sub = string.format( "%s/%d", args.suite, args.nsns )
            l, t = pcall( mw.loadData, sub )
            if type( t ) == "table" then
                sub = Current.page.text
                if type( t[ sub ] ) == "string" then
                    if args.shortcuts  and  not Config.locally then
                        args.shortcuts = false
                        r              = "'1=' not permitted"
                    else
                        args.shortcuts = t[ sub ]
                        if args.nsn == args.nsnt then
                            args.shortcuts = fair( args.shortcuts )
                        end
                    end
                end
            end
            if args.service == "template" then
                if type( args.shortcuts ) == "string" then
                    args.shortcuts = mw.text.trim( args.shortcuts )
                    if args.shortcuts == "" then
                        r = "no shortcuts"
                    else
                        lucky = true
                    end
                elseif Current.page.prefixedText == Config.skip then
                    args.shortcuts = "NS:PT"
                    args.leave     = true
                    lucky          = true
                elseif Config.locally then
                    r = "Shortcuts template '1=' missing"
                end
            elseif args.service == "trow"  or
                   args.service == "total" then
                lucky = true
            else
                r = "bad .service"
            end
        end
        if lucky then
            if args.service == "template" then
                r = follow( args )
            elseif args.service == "trow" then
                r = folder( args )
            elseif args.service == "total" then
                r = flash( args.suite, args.nsn )
            end
        end
    end
    if not lucky then
        r = fault( r, true )
        if args.service == "trow" then
            r = fiat( r, false )
        end
    end
    return r
end -- forward()



local function framed( frame, action )
    -- #invoke call in template environment
    --     action  -- string, with keyword
    -- Returns markup
    local lucky, r
    local params = { service = action,
                     suite   = frame:getTitle() }
    local pars   = frame:getParent().args
    if params.service == "template" then
        params.shortcuts = pars[ 1 ]
        params.light     = pars.light
    elseif params.service == "trow" then
        params.self   = pars[ 1 ]
        params.story  = pars.story
        params.suffix = pars.suffix
    elseif params.service == "total" then
        params.nsn = pars[ 1 ]
        if params.nsn  and
           params.nsn:match( "^(%d+)$" ) then
            params.nsn = tonumber( params.nsn )
        else
            params.nsn = false
        end
    end
    lucky, r = pcall( forward, params )
    return r
end -- framed()



-- Export
local p = { }

function p.template( frame )
    return  framed( frame, "template" )
end -- p.template

function p.total( frame )
    return  framed( frame, "total" )
end -- p.total

function p.trow( frame )
    return  framed( frame, "trow" )
end -- p.trow

function p.twoletters( frame )
    return  framed( frame, "twoletters" )
end -- p.twoletters

function p.test( args )
    -- Debugging
    --     args  -- table, with arguments; mandatory:
    --              .suite      -- Module path
    --              .service    -- action mode, like "template"
    --              .shortcuts  -- list
    --              .self       -- (target) page name
    local lucky, r = pcall( forward, args )
    return r
end -- p.test()

return p