Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus


--[=[ 2017-03-08
Vorlagen zur Archivierung
]=]



local Kategorien = { Frequenz    = false,
                     Kopfvorlage = false,
                     Namensraum  = false,
                     Parameter   = false }
local Vorlagen   = { }
local Frame, Page, Schrei, Selbst
Vorlagen.Autoarchiv =
                   { p = { ["aktuelles Archiv"] = { c = "p" },
                           Alter                = { c = "n" },
                           clear                = { c = "()" },
                           Frequenz             = { c = "()" },
                           Icon                 = { c = "f" },
                           Kommentar            = { c = "-" },
                           Klein                = { c = "l" },
                           Kopfvorlage          = { c = "-" },
                           Mindestabschnitte    = { c = "n" },
                           ["Mindestbeiträge"]  = { c = "n" },
                           Modus                = { c = "()" },
                           Namensraum           = { c = "n" },
                           ["Übersicht"]        = { c = "p" },
                           Zeigen               = { c = "l" },
                           Ziel                 = { c = "'" } },
                     t = { Halbjahr = "##|i|I",
                           Jahr     = "",
                           Monat    = "##|kurz|Kurz|KURZ|lang|Lang|LANG",
                           Quartal  = "##|i|I",
                           Semester = "##|i|I",
                           Tag      = "##|kurz|Kurz|KURZ|lang|Lang|LANG",
                           Woche    = "##" } }



local function faculty( adjust )
    -- Test template arg for boolean
    --     adjust  -- string or nil
    -- Returns boolean
    local s = type( adjust )
    local r
    if s == "string" then
        r = mw.text.trim( adjust )
        r = ( r ~= ""  and  r ~= "0" )
    elseif s == "boolean" then
        r = adjust
    else
        r = false
    end
    return r
end -- faculty()



local function failures( absent )
    if #absent == 1 then
        Schrei = string.format( "Unbekannter Parameter: '%s'",
                                absent[ 1 ] )
    else
        Schrei = "Unbekannte Parameter: " .. table.concat( absent, ", " )
    end
    Kategorien.Parameter = true
end -- failures()



local function fault()
    -- Format message, if any, with class="error"
    -- Returns string
    local r
    if Schrei then
        local e = mw.html.create( "span" )
                         :attr( "class", "error" )
                         :wikitext( Schrei )
        r = tostring( e )
    else
        r = ""
    end
    return r
end -- fault()



local function features()
    local template = Vorlagen[ Selbst ]
    local scream, set
    for k, v in pairs( template.p ) do
        set = v.v
        if set then
            if v.c == "n" then
                if not set:match( "^%d+$" ) then
                    scream = "nicht numerisch"
                end
            elseif v.c == "l" then
                if set ~= "Ja"  and  set ~= "Nein"  and  set ~= "0"  and
                   set ~= "ja"  and  set ~= "nein" then
                    scream = "nicht 'logisch'"
                end
            elseif v.c == "()" then
                scream = template[ k ]( set )
            elseif v.c == "p" then
                if not set:find( ":", 1, true )  and
                   not set:find( "[[/", 1, true ) then
                    scream = "Kein Seitenname enthalten"
                end
            elseif v.c == "f" then
                if not set:match( "^[^:/#\n]+%.%a+$" ) then
                    scream = "Kein Dateiname"
                end
            end
            if scream then
                if Schrei then
                    Schrei = Schrei .. ", "
                else
                    Schrei = ""
                    Kategorien.Parameter = true
                end
                if scream:sub( 1,1 ) ~= "<" then
                    scream = " " .. scream
                end
                Schrei = string.format( "%s<code>%s=</code>%s",
                                        Schrei, k, scream )
                scream = false
            end
        end
    end -- for k, v
end -- features()



local function figure()
    -- Retrieve current page size
    -- Returns number
    local r
    if not Page then
        Page = mw.title.getCurrentTitle()
    end
    if Page.id > 0 then
        if not Frame then
            Frame = mw.getCurrentFrame()
        end
        r = Frame:callParserFunction( "PAGESIZE",
                                      { Page.prefixedText, "R" } )
        r = tonumber( r )  or  0
    else
        r = 0
    end
    return r
end -- figure()



local function fit( arglist )
    -- Store parameter values
    -- Returns table with unknown parameter names, or nil
    local params = Vorlagen[ Selbst ].p
    local r
    for k, v in pairs( arglist ) do
        if params[ k ] then
            if v ~= "" then
                params[ k ].v = v
            end
        else
            if not r then
                r = { }
            end
            table.insert( r, k )
        end
    end -- for k, v
    return r
end -- fit()



local function floater( attribute, assigned )
    local s = "|right|left|none|"
    local r
    if attribute == "clear" then
        s = s .. "both|"
    end
    if not s:find( string.format( "|%s|", assigned ),  1,  true ) then
        r = "unzulässig"
    end
    return r
end -- floater()



local function focus()
    -- Format return string
    -- Returns string
    local r = fault()
    for k, v in pairs( Kategorien ) do
        if Kategorien[ k ] then
            r = string.format( "%s[[Kategorie:%s/Vorlage:%s/%s]]",
                               r,
                               "Wikipedia:Vorlagenfehler",
                               Selbst,
                               k )
        end
    end -- for k, v
    return r
end -- focus()



local function fromto()
    -- Validate target namespace
    local now  = Page.namespace
    local move = Vorlagen[ Selbst ].nsn  or  -999
    local scream
    if move <= 0  or  now <= 0 then
        scream = "Ungeeigneter Namensraum"
    elseif move%2 == 0 then
        if move ~=   4  and
           move ~= 100  and
           move ~=   2  and
           move ~=  12 then
            scream = "Unerwarteter Namensraum"
        end
    end
    if not scream  and  now ~= move  and
       ( now < 2  or  now > 3  or  move < 2  or  move > 3 )  and
       ( now < 4  or  now > 5  or  move < 4  or  move > 5 )  and
       ( now < 100   or  ( move ~= 4  and  move ~= 5  and
                           move ~= 100  and  move ~= 101 ) ) then
        scream = "Namensraumkombination unerwünscht"
    end
    if scream then
        Schrei = scream
        Kategorien.Namensraum = true
    end
end -- fromto()



Vorlagen.Autoarchiv.clear = function ( assigned )
    return floater( "clear", assigned )
end -- Vorlagen.Autoarchiv.clear()



Vorlagen.Autoarchiv.Frequenz = function ( assigned )
assigned="dienstags:mittags, sonntags:mittags"
    local syntax1 = "|ständig|" ..
     "montags|dienstags|mittwochs|donnerstags|freitags|samstags|sonntags"
                     .. "|halbmonatlich|monatlich|halbjährlich|jährlich|"
    local syntax2 = "|ständig|morgens|mittags|"
    local parts   = mw.text.split( assigned, ",%s*" )
    local got, r, s, slice, supply
    if #parts > 1 then
        got = { }
    end
    for i = 1, #parts do
        s = parts[ i ]
        if got then
            if got[ s ] then
                r = string.format( "<code>%s</code> mehrfach", s )
            else
                got[ s ] = true
            end
        end
        if s:find( ":", 1, true ) then
            supply, slice = s:match( "^(.*):(.*)$", 1 )
        else
            supply = s
        end
        s = string.format( "|%s|", supply )
        if syntax1:find( s, 1, true ) then
            if slice then
                s = string.format( "|%s|", slice )
                if not syntax2:find( s, 1, true ) then
                    r = string.format( "<code>%s:%s</code> %s",
                                       supply,
                                       slice,
                                       "ist unbekannte Einschränkung" )
                end
            end
        elseif not syntax2:find( s, 1, true ) then
            r = string.format( "<code>%s</code> unzulässig", supply )
        end
        if r then
            break -- for i
        end
    end -- for i
    return r
end -- Vorlagen.Autoarchiv.Frequenz()



Vorlagen.Autoarchiv.Modus = function ( assigned )
    local r
    if assigned ~= "Alter" then
        if assigned:find( "[Ee]rledigt" )  then
            if assigned ~= "Erledigt"  and
               assigned ~= "erledigt"  and
               not assigned:match( "^Alter, *[Ee]rledigt$" ) then
                r = "<code>Alter, Erledigt</code>"
            end
        else
            r = "unzulässig"
        end
    end
    return r
end -- Vorlagen.Autoarchiv.Modus()



Vorlagen.Autoarchiv.Ziel = function ()
    local template = Vorlagen.Autoarchiv
    local s        = template.p.Ziel.v:match( "^'(.+)'$" )
    if s then
        if s:find( "((", 1, true ) then
            local i = 1
            local k, q, seek, slice, supply, support
            if s:find( "((Lemma))", 1, true ) then
                Page = mw.title.getCurrentTitle()
                s    = s:gsub( "%(%(Lemma%)%)", Page.prefixedText )
            end
            repeat    -- until not i
                i, k = s:find( "%(%(%u%l+:?[^:%)]*%)%)", i )
                if i then
                    supply = s:sub( i + 2,  k - 2 )
                    if supply:find( ":", 3, true ) then
                        supply, slice = supply:match( "^(.+):(.+)$" )
                    else
                        slice = false
                    end
                    q = template.t[ supply ]
                    if q then
                        if slice then
                            support = string.format( "|%s|", q )
                            seek    = string.format( "|%s|", slice )
                            if not support:find( seek ) then
                               if Schrei then
                                   Schrei = Schrei .. ", "
                               else
                                   Schrei = ""
                               end
                               Schrei = string.format( "%s((%s:%s)) %s",
                                                       Schrei,
                                                       supply,
                                                       slice,
                                                       "ungültig" )
                            end
                            if slice == "##" then
                                slice = "__"
                            end
                            supply = string.format( "%s:%s",
                                                    supply, slice )
                        end
                    else
                        if Schrei then
                            Schrei = Schrei .. ", "
                        else
                            Schrei = ""
                        end
                        Schrei = string.format( "%s((%s)) unbekannt",
                                                Schrei, supply )
                    end
                    s = string.format( "%s__%s__%s",
                                       s:sub( 1, i - 1 ),
                                       supply,
                                       s:sub( k + 1 ) )
                    i = k + 1
                end
            until not i
        end
        if not Schrei then
            if s:find( "((", 1, true )  or
               s:find( "))", 1, true ) then
                Schrei = "Doppelklammersyntax"
            else
                local space = s:match( "^([^:]+):" )
                if space then
                    q = mw.site.namespaces[ space ]
                    if q then
                        template.nsn = q.id
                    else
                        Schrei = "Namensraum nicht erkannt"
                    end
                else
                    Schrei = "ANR (unzulässig)"
                end
                if Schrei then
                    Kategorien.Namensraum = true
                end
            end
        end
    else
        Schrei = "in <code>'</code> einschließen"
    end
    if Schrei then
        Schrei = "<code>Ziel=</code> " .. Schrei
        Kategorien.Parameter = true
    end
end -- Vorlagen.Autoarchiv.Ziel()



Vorlagen.Autoarchiv.fire = function ( arglist, frame )
    local template = Vorlagen.Autoarchiv
    local params   = template.p
    local unknown
    Frame   = frame
    Selbst  = "Autoarchiv"
    unknown = fit( arglist )
    if unknown then
        failures( unknown )
    else
        if not Page then
            Page = mw.title.getCurrentTitle()
        end
        if params.Alter.v and params.Ziel.v then
            template.Ziel()
            features()
            if not Schrei  and  template.nsn then
                fromto()
                if not Schrei  and  template.nsn == 1 then
                    local n = params.Mindestabschnitte.v
                    if n then
                        n = tonumber( n )
                    else
                        n = 0
                    end
                    if n < 3  and  figure() < 2000 then
                        Kategorien.Frequenz = true
                    end
                end
                if params.Kopfvorlage.v then
                    Kategorien.Kopfvorlage = true
                end
            end
        elseif Page.namespace ~= 10 then
            Schrei = "Pflichtparameter fehlt"
            Kategorien.Parameter = true
        end
    end
    return focus()
end -- Vorlagen.Autoarchiv.fire()



-- Export
local p = { }

p.Autoarchiv = function ( frame )
    local lucky, r = pcall( Vorlagen.Autoarchiv.fire,
                            frame:getParent().args,
                            frame )
    if not lucky then
        r = "[[Kategorie:Wikipedia:Vorlagenfehler/Vorlage:Autoarchiv]]"
    end
    return r
end -- p.Autoarchiv()

p.test = function ( at, args )
    return Vorlagen[ at ].fire( args )
end -- p.test()

return p