Zum Inhalt springen

Modul:LRR

aus Wikipedia, der freien Enzyklopädie

Dieses Modul transkludiert vorübergehend die folgenden Vorlagen:

Nachdem diese Vorlagen in Lua-Module übersetzt wurden, können die Transklusionen durch Funktionsaufrufe der dann entstandenen Module ersetzt werden.


local xp = {}

-- load standard colors
local _, Standardfarbe = pcall( require, "Module:Vorlage:Standardfarbe" )
if type( Standardfarbe ) == "table" then
    Standardfarbe = Standardfarbe()
end

-- TODO: import this from an external module once similar one exists
xp.countrycode = {
 BG="[[Bulgarien|BG]]",
 CZ="[[Tschechien|CZ]]",
 NO="[[Norwegen|NO]]",
 PL="[[Polen|PL]]",
 D ="[[Deutschland|D]]",
 BW="[[Baden-Württemberg|BW]]",
 BY="[[Bayern|BY]]",
 BB="[[Brandenburg|BB]]",
 BE="[[Berlin|BE]]",
 DE="[[Deutschland|DE]]",
 SH="[[Freie Hansestadt Bremen|HB]]",
 HH="[[Hamburg|HH]]",
 HE="[[Hessen|HE]]",
 MV="[[Mecklenburg-Vorpommern|MV]]",
 NI="[[Niedersachsen|NI]]",
 NW="[[Nordrhein-Westfalen|NW]]",
 RP="[[Rheinland-Pfalz|RP]]",
 SL="[[Saarland|SL]]",
 SN="[[Sachsen|SN]]",
 ST="[[Sachsen-Anhalt|ST]]",
 SH="[[Schleswig-Holstein|SH]]",
 TH="[[Thüringen|TH]]",
 coda="''coda''",
}
xp.countrycode[""]=""

function cond(c, t, f)
    if c then return t else return f end
end

-- genRefs solely exists to workaround a bug in Mediawiki:
-- If ANY input parameter contains <ref> these are translated to strip markers.
-- _Regardless_ of wheter any of them are returned, Mediawiki complains about a
-- missing <references> section.
-- Use '&lt;ref ' instead of '<ref ' and decide here wheter ref tags are to be
-- expanded or not.
function genRefs(f, s)
    if mw.title.getCurrentTitle().isTalkPage
       then return s
           :gsub('&lt;ref [^>]*/>', '')
           :gsub('&lt;ref [^>]*>[^>]*</ref>', '')
       else return f:preprocess(s:gsub('&lt;ref ', '<ref '))
    end
end

function genSortkey(s) -- use DIN 5007-1
    return s
    :gsub("^.[^!]+!", ""):gsub("%[%[[^]]-|([^]]-)]]", "%1") -- strip wikilink
    :gsub("ä", "a"):gsub("Ä", "A")
    :gsub("ö", "o"):gsub("Ö", "O")
    :gsub("ü", "u"):gsub("Ü", "U")
    :gsub("ß", "ss")
    :gsub("%f[%w].", function(s) return s:upper() end) -- upper first in word
    :gsub("[^%w_]", '') -- strip any character not a letter nor an underscore
end

function xp.getArgs(frame)
    local ret = {}
    local f = frame

    if frame.getParent and frame:getParent() and
        mw.title.getCurrentTitle().subjectNsText~="Vorlage"
    then f = frame:getParent()
    end

    -- lowercase argument names and preprocess refs
    for k, v in pairs(f.args)
    do ret[k:lower()] = genRefs(f, v)
    end

    -- map alternative argument names
    for k, v in pairs(frame.alt_arg_names)
    do for sk, _ in pairs(v)
        do if ret[sk] then ret[k] = ret[sk] end
        end

        -- assign nil parms a default if given or the empty string
        if not ret[k] then ret[k] = cond(v.default, v.default, "") end
    end

    return ret
end

function xp.wikilink(frame)
    setmetatable(frame.args, {__index={sep=""}})
    local ret = ""
    local s, sep, ext =
        frame.args[1] or frame.args.s,
        frame.args[2] or frame.args.sep,
        nil

    for v in mw.text.gsplit(s, ", *")
    do if #v>0
        then if v:sub(1, 1)=="!"
            then ret = ret..v:sub(2)..sep
            else local t = mw.text.split(v:gsub('!.*$',
                    function(s) return s:gsub(':',"&#58;") end), ": *")

                if #t>1
                then
                    if not ext
                    then ext  = t[1]
                         t[1] = cond(#t[1]>3,"","<small>").."("..
                                xp.countrycode[t[1]]..": "
                    elseif ext==t[1]
                    then t[1] = ""
                    else ext  = t[1]
                         t[1] = xp.countrycode[t[1]]..": "
                    end
                else     t[2] = t[1]
                         t[1] = ""
                    if ext
                    then ret  = ret:sub(1, #ret - #sep)
                         t[1] = ")"..cond(#ext>3,"","</small>")..sep
                         ext  = nil
                    end
                end

                if #t[2]>0
                then
                    ret = ret..t[1].."[["..mw.ustring.gsub(
                      t[2]:gsub('!','|'):gsub("Bad ", "Bad&nbsp;"),
                      "^([^|]-)([^|%w–]?)(%w+–[%w–]*)([^|%w–]?)([^|]-)$",
                      "%0|%1%2<span style=\"white-space:nowrap\">%3</span>%4%5")
                    .."]]"..sep
                else
                    ret = ret..t[1]:gsub(": $", "")..sep
                end
            end
        end
    end

    if #ret>0
    then ret = ret:sub(1, #ret - #sep)..cond(ext, ")</small>", "")
    end

    return ret
end

function xp.row(frame)
    frame.alt_arg_names = {
        logo   = { symbol=1, zeichen=1, icon=1 },
        ldim   = { lsize=1 },
        name   = { titel=1 },
        nalt   = { talt=1, nameerg=1, titelerg=1 },
        nsort  = { tsort=1 },
        _von   = { vonerg=1, starterg=1 },
        von    = { start=1 },
        via    = { ueber=1, stationen=1 },
        bis    = { ende=1, nach=1, ziel=1 },
        _bis   = { biserg=1, endeerg=1, nacherg=1, zielerg=1 },
        km     = { laenge=1 },
        bt     = { bahntrasse=1, bahndamm=1 },
        fc     = { adfc=1, minkrit=1 },
        rk     = { rundkurs=1 },
        region = { iso_rgn=1 },
        pkarte = { karte=1, lagekarte=1, positionskarte=1 },
        profil = { kommentar=1 }
    }

    local a = xp.getArgs(frame)

    math.randomseed(os.time()-os.clock()*1000)
    math.random()
    math.random()

    -- if no sortkey is given, plain name is used
    a.nsort = genSortkey(a.nsort..a.name)

    -- wikilink strings
    for p in mw.text.gsplit("name nalt von bis", " ", true)
    do a[p] = xp.wikilink{ args = { a[p], ", " } }
    end
    for p in mw.text.gsplit("via _von _bis", " ", true)
    do a[p] = xp.wikilink{ args = { a[p], "&nbsp;↔ " } }
    end

    -- column logo/pikto, Spalte Logo/Piktogramm
    if #a.ldim==0 then a.ldim = "48x48px" end
    if #a.logo>0 and not a.logo:find("[[", 1, true)
    then a.logo = "[[Datei:"..a.logo.."|"..a.ldim.."]]"
    end

    -- column name/title, Spalte Name/Titel und Ergänzung falls angegeben
    if #a.nalt>0 then a.nalt = ", <small>"..a.nalt.."</small>" end
    local stname = "data-sort-value=\""..a.nsort.."\"|"

    -- columns start/dst, Spalten von/bis und Prä-/Suffix falls angegeben
    a._von = a._von:gsub("[^>]$", "%0, "):gsub("%)</small>$", "&nbsp;↔%0 ")
    a._bis = a._bis:gsub("^[^<]", ", %0"):gsub("^<small>%(", " %0↔ ")
    local stvon  = "data-sort-value=\""..genSortkey(a.von).."\"|"
    local stbis  = "data-sort-value=\""..genSortkey(a.bis).."\"|"

    -- column length,     Spalte Länge (in Kilometer)
    if #a.km>0 and not a.km:find("km") then a.km = a.km.." km" end

    -- column railtrail,  Spalte Bahntrasse / Bahndamm
    if a.bt:match("[jJyYtT1]")
    then local v = mw.text.split(a.bt, ", *")
        if v[1]:match("weise")
    	then a.bt = "data-sort-value=\"Teilweise"..a.nsort.."\" "..
            frame:expandTemplate{ title = "Teilweise-Feld", args = { "" } }
        else a.bt = "data-sort-value=\"Vollständig"..a.nsort.."\" "..
            frame:expandTemplate{ title = "Ja-Feld", args = { "" } }
        end
        a.bt = a.bt.."[[Datei:BSicon lDAMPF.svg|20px|verweis="..
            cond(v[2], v[2], "").."]]<br/><small>("..v[1]..")</small>"
    else
        if a.bt:match("[-nNfF0]")
        then a.bt = "data-sort-value=\"–Nirgends"..a.nsort.."\" "..
            frame:expandTemplate{ title = "N/A-Feld", args = {} }
        else a.bt = "data-sort-value=\"–Unbekannt"..a.nsort.."\"|"
        end
    end

    -- column wayquality, Spalte Mindestkriterien / Fahrradclub / ADFC
    if a.fc:match("[jJyYtT1-9]")
    then a.fc = frame:expandTemplate{ title = "Ja-Feld", args = { "" } }..
        "<span style='font-size:larger'>"..cond(a.fc:match("[1-9]"), a.fc, "").."&#9733;</span>"
    elseif a.fc:match("[-nNfF0]")
    then a.fc = frame:expandTemplate{ title = "Nein-Feld", args = { "" } }..
        "<span style='font-size:larger'>&#10008;</span>"
    end

    -- column roundtrip,  Spalte Rundkurs
    if a.rk:match("[jJyYtT1]")
    then a.rk = "data-sort-value=\"Einer"..a.nsort.."\" "..
        frame:expandTemplate{ title = "Ja-Feld", args = { "<span style='font-size:larger'>♺</span>" } }
    elseif a.rk:match("[mMvV]")
    then a.rk = "data-sort-value=\"Viele"..a.nsort.."\" "..
        frame:expandTemplate{title = "Ja-Feld", args = { "♺ ♺<br/>♺" } }
    elseif a.rk:match("[-nNfF0]")
    then a.rk = frame:expandTemplate{ title = "N/A-Feld", args = {} }
    end

    -- column minimap,    Spalte Mini-Lagekarte
    if #a.pkarte>0
    then local img, fmt, lnk, ipos, ivert = nil, "|64px", "", "left", "-18px"
        for v in mw.text.gsplit(a.pkarte, ", *")
        do  if v:sub(1, 1)=="!"
            then fmt = v:gsub("!", "|")
            elseif v:find("^%d+$")
            then lnk = "https://cycling.waymarkedtrails.org/#route?type=relation&id="..v
            elseif v:find("^r%d+$")
            then lnk = "http://www.openstreetmap.org/relation/"..v:sub(2)
            elseif v:find("^%[")
            then lnk = v
            else img = "File:"..v
            end
        end

        lnk = lnk:gsub("^http.*", "|verweis=%0|Lagekarte unter %0 aufrufen")
                 :gsub("^%[+(.-)%]+$", "|verweis=%1|%1")

        if a.region == "DE-SN" or a.region == "DE-TH"
        then ipos = "right"
        end

        if a.region == "DE-TH"
        then ivert = "-58px;height:58px"
        end

        a.pkarte = "style=\"background:#E0E0E0;padding:.2em 0em\"|[["..img..fmt..
            lnk.."]]<div style=\"margin-top:"..ivert..";padding:0em .2em;"..
            "text-align:"..ipos.."\">[[File:Desc-i_gray.svg|18px|verweis="..
            "commons:"..img..'|'..img:sub(5).."]]</div>"
    else
        a.pkarte = [[style="background:#E0E0E0;padding:0px"|]]
    end

    -- return entry depending on page title, default is a table row
    if mw.title.getCurrentTitle().text:find("/[Dd]ruck$", -6)
    then return ";"..a.name
        ..cond(a.nsort:find("[Ww]eg%f[%W%u]"),"\nDer ","\nDie "
            ..cond(a.nsort:find("[Rr]oute%f[%W%u]") or
                a.nsort:find("[Tt]our%f[%W%u]"),"","Radroute "))..a.name.." "
        ..({"verläuft","führt","weist","leitet"})[math.random(1,4)]
        .." von "..a.von.." nach "..a.bis.." "
        ..({"und durchquert","über","durch die Orte", "mit Stationen in",
            "und verbindet","mit Halt in","und erschließt den Radelnden",
            "und zeigt RadlerInnen Landschaft und Natur um"})[math.random(1,8)]
        .." "..a.via:gsub("&nbsp;↔",","):gsub(", ([^,]*)$", " und %1")..". "
        ..({"Die Route","Der Weg","Die Tour",
            cond(a.nsort:find("[Ww]eg%f[%W]"),"Er ","Sie ")})[math.random(1,4)]
        .." ist"..cond(not a.rk:find("♺"),""," als Rundkurs "
            ..({"fahrbar","angelegt","verwirklicht"})[math.random(1,3)].." und")
        .." insgesamt"..a.km:gsub("^.-([%d.,]+)%D-$"," %1&nbsp;Kilometer lang")
        ..cond(not a.km:find("%d+%D+%d"),".",a.km:gsub("^%D-([%d.,]+).-$",
        	", wovon %1&nbsp;km auf "..xp.countrycode[a.region:sub(-2)]
        	    :gsub("^%[?%[?([^]|]*).-$","%1").." entfallen."))
    elseif mw.title.getCurrentTitle().isTalkPage
    then return '*'..a.name
    else return "|-\n|style=\"text-align:center; background:#" .. Standardfarbe.getColor("hintergrund", "1", "light", false) .. ";\"|"..a.logo.." ||"..stname..a.name..a.nalt
        .." ||"..stvon..a._von..a.von.." ||"..a.via.." ||"..stbis..a.bis..a._bis
        .." ||"..a.km.." ||"..a.bt.." ||"..a.fc.." ||"..a.rk
        .." ||"..a.pkarte.." ||"..a.profil
    end
end

function xp.emptyrow(frame)
    frame.alt_arg_names = {
        farbe = { color=1, colour=1, default = "grey" }
    }

    local a = xp.getArgs(frame)

    -- if used on a Talk/Disk page, supress output
    if mw.title.getCurrentTitle().isTalkPage then return '<!-- // -->' end

    -- return table row entry
    return [[|- style="border-top:]]..a.farbe..[[ 2px solid"]]..'\n'..
        string.rep([[ ||data-sort-value="ZZZ" style="padding:0px"|]], 11)
        :gsub("ZZZ",
            (function()
                local n=0
                return function(s) n=n+1 return cond(n==6, "99999", s) end
            end)())
        :sub(3)
end

function xp.header(frame)
    return [==[
{|class="wikitable sortable"
|-style="font-size:small;"
!class="unsortable"|Logo
!Name
!style="vertical-align:top;padding-left:21px;min-width:64px"|von
!style="vertical-align:top;padding-left:21px;min-width:64px"|Stationen<br>(Auswahl)
!style="vertical-align:top;padding-left:21px;min-width:64px"|bis
!style="min-width:48px" data-sort-type="number"|Länge<br>(ca.)
!title="verläuft auf ehem. Bahntrasse"|Bahn&shy;trasse
!title="erfüllt ADFC-Mindeststandards für Radfernweg"|Mindest&shy;standards
!Rund&shy;kurs
!class="unsortable"|Lage&shy;karte
!class="unsortable"|Streckenprofil&nbsp;und<br>Kommentare]==]
end

function xp.footer(frame)
    return "|}"
end

--function xp.print_invisible_debug_info(frame)
--    local ret = ""
--    for c in frame.args[1]:gmatch(".")
--    do ret = ret..mw.ustring.format("%x %s ", c:byte(), c)
--    end
--    return "<div style=\"display:none\">this: "..frame:getTitle()..
--        " parent: "..frame:getParent():getTitle()..
--        " namespace: "..mw.title.getCurrentTitle().subjectNsText..
--        " fulltitle: "..mw.title.getCurrentTitle().prefixedText..
--        " hexdump_firstarg: "..ret..
--        "</div>"
--end

return xp