Modul:WLink: Unterschied zwischen den Versionen

10.569 Bytes hinzugefügt ,  vor 2 Jahren
K
35 Versionen von wikivoyage:Modul:WLink importiert
w>PerfektesChaos
(updates)
K (35 Versionen von wikivoyage:Modul:WLink importiert)
 
(33 dazwischenliegende Versionen von 15 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
--[=[ 2014-10-28
local WLink = { suite  = "WLink",
WLink
                serial = "2016-10-05" };
--[=[
ansiPercent()
ansiPercent()
formatURL()
formatURL()
getArticleBase()
getArticleBase()
getBaseTitle()
getBaseTitle()
getEscapedTitle()
getExtension()
getExtension()
getFile()
getFile()
Zeile 15: Zeile 17:
getTargetPage()
getTargetPage()
getTitle()
getTitle()
getWeblink()
isBracketedLink()
isBracketedLink()
isBracketedURL()
isBracketedURL()
isCategorization()
isExternalLink()
isExternalLink()
isInterlanguage()
isInterlanguage()
isInterwiki()
isInterwiki()
isMedia()
isTitledLink()
isTitledLink()
isValidLink()
isValidLink()
isWikilink()
isWikilink()
wikilink()
failsafe()
]=]
]=]


Zeile 28: Zeile 35:


-- local globals
-- local globals
local WLink  = { };
local URLutil = false;
local URLutil = false;


Zeile 196: Zeile 202:




function target( attempt, lonely )
local prefix = function ( ask, ahead )
    -- Interprete prefix of language or project type
    -- Precondition:
    --    ask    -- string, with presumable prefix
    --    ahead  -- true, if first segment
    -- Postcondition:
    --    Returns  string,string or nil
    --                    first  string one of "lead", "lang", "project"
    --                    second string is formatted value
    --                      type is one of "lead", "lang", "project"
    --              nil if nothing found
    local r1, r2;
    local prefixes = { b          = true,
                      c          = "commons",
                      d          = true,
                      commons    = true,
                      m          = "meta",
                      mediawiki  = "mw",
                      mw          = true,
                      meta        = true,
                      n          = true,
                      q          = true,
                      s          = true,
                      simple      = false,
                      v          = true,
                      voy        = true,
                      w          = true,
                      wikibooks  = "b",
                      wikidata    = "d",
                      wikinews    = "n",
                      wikipedia  = "w",
                      wikiquote  = "q",
                      wikisource  = "s",
                      wikiversity = "v",
                      wikivoyage  = "voy",
                      wikt        = true,
                      wiktionary  = "wikt"
                    };
    local s = mw.text.trim( ask );
    if s == "" then
        if ahead then
            r1 = "lead";
            r2 = true;
        end
    else
        local p;
        s = s:lower();
        p = prefixes[ s ];
        if p == true then
            r1 = "project";
            r2 = s;
        elseif p then
            r1 = "project";
            r2 = p;
        elseif p == false then
            r1 = "lang";
            r2 = s;
        elseif s:match( "^%l%l%l?$" )
              and  mw.language.isSupportedLanguage( s ) then
            r1 = "lang";
            r2 = s;
        end
    end
    return r1, r2;
end -- prefix()
 
 
 
local target = function ( attempt, lonely )
     -- Retrieve first target (wikilink or URL), or entire string
     -- Retrieve first target (wikilink or URL), or entire string
     -- Precondition:
     -- Precondition:
Zeile 211: Zeile 285:
     end
     end
     if lonely then
     if lonely then
         local i = r1:find( "#", 1, true )
         local i = r1:find( "#", 1, true );
         if i == 1 then
         if i == 1 then
             r1 = "";
             r1 = "";
Zeile 223: Zeile 297:




function WLink.ansiPercent( attempt )
function WLink.ansiPercent( attempt, alter )
     -- Convert string by ANSI encoding rather than UTF-8 encoding
     -- Convert string by ANSI encoding rather than UTF-8 encoding
     -- Precondition:
     -- Precondition:
     --    attempt  -- string, with presumable ANSI characters
     --    attempt  -- string, with presumable ANSI characters
    --    alter    -- string or nil, to use for spaces instead of %20
     -- Postcondition:
     -- Postcondition:
     --    Returns  string, encoded
     --    Returns  string, encoded
     local k, s;
     local k, s;
     local r = attempt;
     local r = attempt;
     for i = mw.ustring.len( attempt ), 1, -1 do
    if alter then
         k = mw.ustring.codepoint( attempt, i, i );
        r = r:gsub( " ", alter );
    end
     for i = mw.ustring.len( r ), 1, -1 do
         k = mw.ustring.codepoint( r, i, i );
         if k <= 32  or  k > 126 then
         if k <= 32  or  k > 126 then
             if k > 255 then
             if k > 255 then
                 s = mw.ustring.sub( attempt, i, i );
                 s = mw.ustring.sub( r, i, i );
                 if k > 2047 then
                 if k > 2047 then
                     s = string.format( "%%%2X%%%2X%%%2X",
                     s = string.format( "%%%2X%%%2X%%%2X",
Zeile 250: Zeile 328:
             end
             end
             r = string.format( "%s%s%s",
             r = string.format( "%s%s%s",
                               mw.ustring.sub( attempt,  1,  i - 1 ),
                               mw.ustring.sub( r,  1,  i - 1 ),
                               s,
                               s,
                               mw.ustring.sub( r,  i + 1 ) );
                               mw.ustring.sub( r,  i + 1 ) );
         end
         end
     end -- for --i
     end -- for --i
    r = mw.ustring.gsub(r, '^%*', '%%2A')
     return r;
     return r;
end -- WLink.ansiPercent()
end -- WLink.ansiPercent()
Zeile 278: Zeile 357:
             if not host then
             if not host then
                 url  = "http://" .. adjust;
                 url  = "http://" .. adjust;
                 host = URLutil.getHost( adjust );
                 host = URLutil.getHost( url );
             end
             end
             if host then
             if host then
Zeile 289: Zeile 368:
                     show = host;
                     show = host;
                 else
                 else
                    local i = path:find( "#" );
                    if i then
                        path = path:sub( 1,  i - 1 );
                    end
                     show = host .. path;
                     show = host .. path;
                 end
                 end
                 r = string.format( "[%s %s]", url, show );
                 r = string.format( "[%s %s]", url, show );
             else
             else
                 r = false;
                 r = adjust;
             end
             end
         end
         end
Zeile 354: Zeile 437:
end -- WLink.getBaseTitle()
end -- WLink.getBaseTitle()


 
function WLink.getEscapedTitle( attempt )
    -- Retrieve escaped link title
    -- Precondition:
    --    attempt  -- string, with presumable link title
    -- Postcondition:
    --    Returns  string, with suitable link title
    local s = mw.text.trim( attempt );
    return s:gsub( "\n", " " )
            :gsub( "%[", "&#91;" )
            :gsub( "%]", "&#93;" )
            :gsub( "|",  "&#124;" );
end -- WLink.getEscapedTitle()


function WLink.getExtension( attempt )
function WLink.getExtension( attempt )
Zeile 469: Zeile 563:
     --              false if no project language found
     --              false if no project language found
     local r = false;
     local r = false;
     local s, m = target( attempt );
     local s, m = WLink.getTarget( attempt );
    if m == 2 then
        local w = WLink.wikilink( s );
        if w  and  w.lang then
            r = w.lang;
        end
    end
     return r;
     return r;
end -- WLink.getLanguage()
end -- WLink.getLanguage()
Zeile 483: Zeile 583:
     --              false if no namespace found
     --              false if no namespace found
     local r = false;
     local r = false;
     local s, m = target( attempt );
     local s, m = WLink.getTarget( attempt );
    if m == 2 then
        local w = WLink.wikilink( s );
        if w  and  not w.lang  and  not w.project  and  w.ns then
            r = w.ns;
        end
    end
     return r;
     return r;
end -- WLink.getNamespace()
end -- WLink.getNamespace()
Zeile 497: Zeile 603:
     local r = attempt;
     local r = attempt;
     local i = 1;
     local i = 1;
     local j, k, n, lean, s, shift, suffix;
     local j, k, n, lean, s, shift, space, suffix;
     while ( true ) do
     while ( true ) do
         j = r:find( "[", i, true );
         j = r:find( "[", i, true );
Zeile 518: Zeile 624:
                 if lean then
                 if lean then
                     s, shift = extractWikilink( suffix );
                     s, shift = extractWikilink( suffix );
                     if not shift then
                     if s then
                         shift = s;
                        space = s:match( "^([^:]+):" );
                        if space then
                            space = mw.site.namespaces[ space ];
                            if space then
                                space = space.id;
                            end
                        end
                        if space == 6  or  space == 14 then
                            shift = "";
                        elseif not shift then
                            shift = s;
                        end
                    else
                        s    = "";
                         shift = "";
                     end
                     end
                 else
                 else
                     s, shift = extractExtlink( suffix );
                     s, shift = extractExtlink( suffix );
                    if not s then
                        s = "";
                    end
                     if not shift then
                     if not shift then
                         shift = "";
                         shift = "";
Zeile 549: Zeile 672:


function WLink.getProject( attempt )
function WLink.getProject( attempt )
     -- Retrieve project identifier
     -- Retrieve wikifarm project identifier
     -- Precondition:
     -- Precondition:
     --    attempt  -- string, with wikilink or page title
     --    attempt  -- string, with wikilink or page title
Zeile 556: Zeile 679:
     --              false if no project identifier found
     --              false if no project identifier found
     local r = false;
     local r = false;
    local s, m = WLink.getTarget( attempt );
    if m == 2 then
        local w = WLink.wikilink( s );
        if w  and  w.project then
            r = w.project;
        end
    end
     return r;
     return r;
end -- WLink.getProject()
end -- WLink.getProject()
Zeile 651: Zeile 781:
     return r;
     return r;
end -- WLink.getTitle()
end -- WLink.getTitle()
function WLink.getWeblink( attempt, anURLutil )
    -- Retrieve bracketed link from resource URL
    -- Precondition:
    --    attempt    -- string, with URL, or something different
    --    anURLutil  -- library module object, or nil
    -- Postcondition:
    --    Returns  string, with first detected link target
    --              false if nothing found
    local second = ".ac.co.go.gv.or.";
    local r;
    if type( anURLutil ) == "table" then
        URLutil = anURLutil;
    else
        utilURL();
    end
    if URLutil.isResourceURL( attempt ) then
        local site = URLutil.getAuthority( attempt );
        local show;
        if #attempt == #site then
          site = site .. "/";
        end
        show = URLutil.getTop3domain( "//" .. site );
        if show then
            local scan  = "[%./](%a+)(%.%l%l%.)(%a+)$";
            local search = "." .. show;
            local s1, s2, s3 = search:match( scan );
            if s2 then
                if not second:find( s2, 1, true ) then
                    show = string.format( "%s.%s", s2, s3 );
                end
            else
                show = false;
            end
        end
        if not show then
            show = URLutil.getTop2domain( "//" .. site );
            if not show then
                show = URLutil.getHost( "//" .. site );
            end
        end
        r = string.format( "[%s %s]", attempt, show );
    else
        r = attempt;
    end
    return r;
end -- WLink.getWeblink()




Zeile 687: Zeile 866:
     return ( r == 1 );
     return ( r == 1 );
end -- WLink.isBracketedURL()
end -- WLink.isBracketedURL()
function WLink.isCategorization( attempt )
    -- Does attempt match a categorization?
    -- Precondition:
    --    attempt  -- string, with presumable link somewhere
    -- Postcondition:
    --    Returns  boolean
    local r = false;
    local s, m = WLink.getTarget( attempt );
    if m == 2 then
        local w = WLink.wikilink( s );
        if w  and  w.ns == 14
              and  not ( w.lead or w.lang or w.project )
              and  w.title ~= "" then
            r = true;
        end
    end
    return r;
end -- WLink.isCategorization()




Zeile 712: Zeile 912:
     --    Returns  boolean
     --    Returns  boolean
     local r = false;
     local r = false;
     --    if m == 2 and
     local s, m = WLink.getTarget( attempt );
    --      s:find( ":", 3, true ) and  s:byte( 1, 1 ) ~= 58 then
    if m == 2 then
    --        local s
        local w = WLink.wikilink( s );
     --    end
        if w and w.lang and not w.project and not w.lead
            and  w.title ~= "" then
            r = true;
        end
     end
     return r;
     return r;
end -- WLink.isInterlanguage()
end -- WLink.isInterlanguage()
Zeile 722: Zeile 926:


function WLink.isInterwiki( attempt )
function WLink.isInterwiki( attempt )
     -- Does attempt match an interwiki link?
     -- Does attempt match an interwiki link within wikifarm?
     -- Precondition:
     -- Precondition:
     --    attempt  -- string, with presumable link somewhere
     --    attempt  -- string, with presumable link somewhere
Zeile 729: Zeile 933:
     local r = false;
     local r = false;
     local s, m = WLink.getTarget( attempt );
     local s, m = WLink.getTarget( attempt );
     if m == 2 and
     if m == 2 then
      s:find( ":", 3, true )  and  s:byte( 1, 1 ) ~= 58 then
        local w = WLink.wikilink( s );
         local s
        if w and  ( w.lang or w.project ) and  w.title ~= "" then
            r = true;
         end
     end
     end
     return r;
     return r;
end -- WLink.isInterwiki()
end -- WLink.isInterwiki()
function WLink.isMedia( attempt )
    -- Does attempt match a media translusion?
    -- Precondition:
    --    attempt  -- string, with presumable link somewhere
    -- Postcondition:
    --    Returns  boolean
    local r = false;
    local s, m = WLink.getTarget( attempt );
    if m == 2 then
        local w = WLink.wikilink( s );
        if w  and  w.ns == 6
          and  not ( w.lead or w.lang or w.project )
          and  w.title ~= ""
          and  WLink.getExtension( w.title ) then
            r = true;
        end
    end
    return r;
end -- WLink.isMedia()




Zeile 792: Zeile 1.020:
     return ( m == 2 );
     return ( m == 2 );
end -- WLink.isWikilink()
end -- WLink.isWikilink()
function WLink.wikilink( attempt )
    -- Retrieve wikilink components
    -- Precondition:
    --    attempt  -- string, with presumable link
    --                        expected to be enclosed in "[[" "]]"
    --                        else wikilink
    -- Postcondition:
    --    Returns  table or false
    --              table of assignments with { type, value}
    --                      type is one of "lead",
    --                          "project", "lang",
    --                          "ns", "space", "title"
    --              false if nothing found
    local s = contentWikilink( attempt );
    local got, n, r;
    if not s then
        s = attempt;
    end
    i = s:find( "|", 1, true );
    if i then
        s = s:sub( 1, i - 1 );
    end
    got = mw.text.split( s, ":" );
    n  = table.maxn( got );
    if n == 1 then
        r = { title = mw.text.trim( s ) };
    else
        local j, k, o, v;
        r = { title = "" };
        if n > 4 then
            k = 4;
        else
            k = n - 1;
        end
        j = k;
        for i = 1, j do
            s = mw.text.trim( got[ i ] );
            if s ~= "" then
                o = mw.site.namespaces[ mw.text.trim( got[ i ] ) ];
                if o then
                    r.ns    = o.id;
                    r.space = o.name;
                    k = i + 1;
                    j = i - 1;
                    break; -- for i
                end
            end
        end -- for i
        for i = 1, j do
            o, v = prefix( got[ i ],  ( i == 1 ) );
            if o then
                if r[ o ] then
                    k = i;
                    break; -- for i
                else
                    r[ o ] = v;
                end
            else
                k = i;
                break; -- for i
            end
        end -- for i
        for i = k, n do
            r.title = r.title .. got[ i ];
            if i < n then
                r.title = r.title .. ":";
            end
        end -- for i
    end
    if r.lead and
      ( r.project  or  not r.title  or
        ( not r.lang  and  r.ns ~= 6  and  r.ns ~= 14 ) ) then
        r.lead = false;
    end
    return r;
end -- WLink.wikilink()
function WLink.failsafe( assert )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --    assert  -- string, with required version, or false
    -- Postcondition:
    --    Returns  string with appropriate version, or false
    local r;
    if assert  and  assert > WLink.serial then
        r = false;
    else
        r = WLink.serial;
    end
    return r
end -- WLink.failsafe()




Zeile 804: Zeile 1.128:
     -- Postcondition:
     -- Postcondition:
     --    Return string; might be error message
     --    Return string; might be error message
    local k, v;
     local lucky = true;
     local lucky = true;
     local s = false;
     local s = false;
     local r = false;
     local r = false;
    local space;
     for k, v in pairs( frame.args ) do
     for k, v in pairs( frame.args ) do
         if k == 1 then
         if k == 1 then
Zeile 814: Zeile 1.138:
             else
             else
                 s = mw.text.trim( v );
                 s = mw.text.trim( v );
            end
        elseif action == "ansiPercent"  and  k == "space" then
            if v ~= "" then
                space = v;
             end
             end
         elseif k ~= "template" then
         elseif k ~= "template" then
Zeile 827: Zeile 1.155:
     if lucky then
     if lucky then
         if s or lone then
         if s or lone then
             lucky, r = pcall( WLink[ action ], s );
             lucky, r = pcall( WLink[ action ], s,  space );
         else
         else
             r = "Parameter missing";
             r = "Parameter missing";
Zeile 850: Zeile 1.178:


-- Export
-- Export
local p = { }
local p = { };


p.ansiPercent = function ( frame )
p.ansiPercent = function ( frame )
     return Template( frame, "ansiPercent" );
     return Template( frame, "ansiPercent" );
end
p.formatURL = function ( frame )
    return Template( frame, "formatURL" );
end
end
p.getArticleBase = function ( frame )
p.getArticleBase = function ( frame )
Zeile 860: Zeile 1.191:
p.getBaseTitle = function ( frame )
p.getBaseTitle = function ( frame )
     return Template( frame, "getBaseTitle" );
     return Template( frame, "getBaseTitle" );
end
p.getEscapedTitle = function ( frame )
    return Template( frame, "getEscapedTitle" );
end
end
p.getExtension = function ( frame )
p.getExtension = function ( frame )
Zeile 866: Zeile 1.200:
p.getFile = function ( frame )
p.getFile = function ( frame )
     return Template( frame, "getFile" );
     return Template( frame, "getFile" );
end
p.formatURL = function ( frame )
    return Template( frame, "formatURL" );
end
end
p.getFragment = function ( frame )
p.getFragment = function ( frame )
     return Template( frame, "getFragment" );
     return Template( frame, "getFragment" );
end
p.getInterwiki = function ( frame )
    return Template( frame, "getInterwiki" );
end
end
p.getLanguage = function ( frame )
p.getLanguage = function ( frame )
Zeile 877: Zeile 1.211:
end
end
p.getNamespace = function ( frame )
p.getNamespace = function ( frame )
     return Template( frame, "getNamespace" );
     return tostring( Template( frame, "getNamespace" ) );
end
end
p.getPlain = function ( frame )
p.getPlain = function ( frame )
Zeile 894: Zeile 1.228:
     return Template( frame, "getTitle" );
     return Template( frame, "getTitle" );
end
end
p.getInterwiki = function ( frame )
p.getWeblink = function ( frame )
     return Template( frame, "getInterwiki" );
     return Template( frame, "getWeblink" );
end
end
p.isBracketedLink = function ( frame )
p.isBracketedLink = function ( frame )
Zeile 902: Zeile 1.236:
p.isBracketedURL = function ( frame )
p.isBracketedURL = function ( frame )
     return Template( frame, "isBracketedURL" );
     return Template( frame, "isBracketedURL" );
end
p.isCategorization = function ( frame )
    return Template( frame, "isCategorization" );
end
end
p.isExternalLink = function ( frame )
p.isExternalLink = function ( frame )
Zeile 911: Zeile 1.248:
p.isInterwiki = function ( frame )
p.isInterwiki = function ( frame )
     return Template( frame, "isInterwiki" );
     return Template( frame, "isInterwiki" );
end
p.isMedia = function ( frame )
    return Template( frame, "isMedia" );
end
end
p.isTitledLink = function ( frame )
p.isTitledLink = function ( frame )
Zeile 923: Zeile 1.263:
p.isWikilink = function ( frame )
p.isWikilink = function ( frame )
     return Template( frame, "isWikilink" );
     return Template( frame, "isWikilink" );
end
p.failsafe = function ( frame )
    local since = frame.args[ 1 ];
    if since then
        since = mw.text.trim( since );
        if since == "" then
            since = false;
        end
    end
    return WLink.failsafe( since ) or "";
end
end
p.WLink = function ()
p.WLink = function ()
Zeile 928: Zeile 1.278:
end
end


return p
return p;