Importer, Bürokraten, Moderatoren (CommentStreams), Strukturierte-Diskussionen-Bots, Oberflächenadministratoren, Push-Abonnementverwalter, Oversighter, Administratoren, Kampagnenbearbeiter (Hochladeassistent)
855
Bearbeitungen
w>PerfektesChaos (Setup) |
K (35 Versionen von wikivoyage:Modul:WLink importiert) |
||
| (40 dazwischenliegende Versionen von 16 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
--[=[ | local WLink = { suite = "WLink", | ||
serial = "2016-10-05" }; | |||
--[=[ | |||
ansiPercent() | |||
formatURL() | |||
getArticleBase() | |||
getBaseTitle() | |||
getEscapedTitle() | |||
getExtension() | |||
getFile() | |||
getFragment() | |||
getLanguage() | |||
getNamespace() | |||
getPlain() | |||
getProject() | |||
getTarget() | |||
getTargetPage() | |||
getTitle() | |||
getWeblink() | |||
isBracketedLink() | |||
isBracketedURL() | |||
isCategorization() | |||
isExternalLink() | |||
isInterlanguage() | |||
isInterwiki() | |||
isMedia() | |||
isTitledLink() | |||
isValidLink() | |||
isWikilink() | |||
wikilink() | |||
failsafe() | |||
]=] | ]=] | ||
-- | -- local globals | ||
local | |||
local URLutil = false; | local URLutil = false; | ||
| Zeile 37: | Zeile 65: | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with presumable link | -- attempt -- string, with presumable link | ||
-- | -- the first char is expected to be "[" | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, number, number | -- Returns string, number, number | ||
| Zeile 57: | Zeile 85: | ||
r2 = 1; | r2 = 1; | ||
end | end | ||
else | |||
r3 = false; | |||
end | end | ||
return r1, r2; | return r1, r2, r3; | ||
end -- contentExtlink() | end -- contentExtlink() | ||
| Zeile 140: | Zeile 170: | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, string | -- Returns string, string | ||
-- first with target | -- first with target | ||
-- second result false if not piped | -- second result title, or false if not piped | ||
-- false if nothing found | -- false if nothing found | ||
local r1 = false; | local r1 = false; | ||
| Zeile 157: | Zeile 187: | ||
if r1 == "" then | if r1 == "" then | ||
r1 = false; | r1 = false; | ||
else | |||
r1 = r1:gsub( "_", " " ) | |||
:gsub( " ", " " ) | |||
:gsub( " ", " " ) | |||
:gsub( " ", " " ) | |||
:gsub( " ", " " ) | |||
:gsub( " +", " " ); | |||
r1 = mw.text.decode( r1 ); | |||
end | end | ||
end | end | ||
| Zeile 164: | Zeile 202: | ||
function WLink.ansiPercent( attempt ) | 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 | |||
-- Precondition: | |||
-- attempt -- string, with presumable link somewhere | |||
-- lonely -- remove fragment, if true | |||
-- Postcondition: | |||
-- Returns string, number | |||
-- string, with detected link target, or entire | |||
-- number, with number of brackets, if found, or 2 | |||
local r1, r2 = WLink.getTarget( attempt ); | |||
if not r1 then | |||
r1 = mw.text.trim( attempt ); | |||
r2 = 2; | |||
end | |||
if lonely then | |||
local i = r1:find( "#", 1, true ); | |||
if i == 1 then | |||
r1 = ""; | |||
elseif i then | |||
r1 = r1:sub( 1, i - 1 ); | |||
end | |||
end | |||
return r1, r2; | |||
end -- target() | |||
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 r = attempt; | local r = attempt; | ||
if alter then | |||
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 > 255 then | |||
s = mw.ustring.sub( r, i, i ); | |||
if k > 2047 then | |||
s = string.format( "%%%2X%%%2X%%%2X", | |||
s:byte( 1, 1 ), | |||
s:byte( 2, 2 ), | |||
s:byte( 3, 3 ) ); | |||
else | |||
s = string.format( "%%%2X%%%2X", | |||
s:byte( 1, 1 ), | |||
s:byte( 2, 2 ) ); | |||
end | |||
else | |||
s = string.format( "%%%2X", k ); | |||
end | |||
r = string.format( "%s%s%s", | |||
mw.ustring.sub( r, 1, i - 1 ), | |||
s, | |||
mw.ustring.sub( r, i + 1 ) ); | |||
end | |||
end -- for --i | |||
r = mw.ustring.gsub(r, '^%*', '%%2A') | |||
return r; | |||
end -- WLink.ansiPercent() | |||
function WLink.formatURL( adjust ) | |||
-- Create bracketed link, if not yet | |||
-- Precondition: | |||
-- adjust -- string, with URL or domain/path or bracketed link | |||
-- Postcondition: | |||
-- Returns string, with bracketed link | |||
-- false on invalid format | |||
local r; | |||
if type( adjust ) == "string" then | |||
if WLink.isBracketedLink( adjust ) then | |||
r = adjust; | |||
else | |||
local url = mw.text.trim( adjust ); | |||
local host; | |||
utilURL(); | |||
host = URLutil.getHost( adjust ); | |||
if not host then | |||
url = "http://" .. adjust; | |||
host = URLutil.getHost( url ); | |||
end | |||
if host then | |||
local path = URLutil.getRelativePath( url ); | |||
local show; | |||
if path == "/" then | |||
if not url:match( "/$" ) then | |||
url = url .. "/"; | |||
end | |||
show = host; | |||
else | |||
local i = path:find( "#" ); | |||
if i then | |||
path = path:sub( 1, i - 1 ); | |||
end | |||
show = host .. path; | |||
end | |||
r = string.format( "[%s %s]", url, show ); | |||
else | |||
r = adjust; | |||
end | |||
end | |||
else | |||
r = false; | |||
end | |||
return r; | |||
end -- WLink.formatURL() | |||
function WLink.getArticleBase( attempt ) | |||
-- Retrieve generic article title, no fragment nor brackets | |||
-- Precondition: | |||
-- attempt -- string, with wikilink or page title | |||
-- current page title, if missing | |||
-- Postcondition: | |||
-- Returns string, with identified lemma, or all | |||
-- false on invalid format | |||
local r; | |||
if attempt then | |||
local m; | |||
r, m = target( attempt, true ); | |||
if m ~= 2 then | |||
r = false; | |||
end | |||
else | |||
r = mw.title.getCurrentTitle().text; | |||
end | |||
if r then | |||
local sub = r:match( "^(.*%S) *%(.+%)$" ); | |||
if sub then | |||
r = sub; | |||
end | |||
end | |||
return r; | return r; | ||
end -- WLink. | end -- WLink.getArticleBase() | ||
function WLink.getBaseTitle( attempt ) | function WLink.getBaseTitle( attempt ) | ||
-- Retrieve last segment in subpage, no | -- Retrieve last segment in subpage, no fragment | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with wikilink or page title | -- attempt -- string, with wikilink or page title | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, with identified segment | -- Returns string, with identified segment, or all | ||
local r = false; | local r; | ||
local s, m = target( attempt, true ); | |||
if m == 2 then | |||
local sub = s:match( "/([^/]+)$" ); | |||
if sub then | |||
r = sub; | |||
else | |||
r = s; | |||
end | |||
else | |||
r = false; | |||
end | |||
return r; | return r; | ||
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( "%[", "[" ) | |||
:gsub( "%]", "]" ) | |||
:gsub( "|", "|" ); | |||
end -- WLink.getEscapedTitle() | |||
function WLink.getExtension( attempt ) | function WLink.getExtension( attempt ) | ||
| Zeile 193: | Zeile 454: | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with wikilink (media link) or page title | -- attempt -- string, with wikilink (media link) or page title | ||
-- | -- if URL, PDF may be detected | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, with detected downcased media type | -- Returns string, with detected downcased media type | ||
-- false if no extension found | -- false if no extension found | ||
local r = false; | local r = false; | ||
local s, m = target( attempt ); | |||
if m == 2 then | |||
s = s:match( "%.(%a+)$" ); | |||
if s then | |||
r = s:lower(); | |||
end | |||
elseif s:upper():match( "[%./](PDF)%W?" ) then | |||
r = "pdf"; | |||
end | |||
return r; | return r; | ||
end -- WLink.getExtension() | end -- WLink.getExtension() | ||
| Zeile 212: | Zeile 482: | ||
-- false if no file found | -- false if no file found | ||
local r = false; | local r = false; | ||
local s, m = target( attempt ); | |||
if m == 2 then | |||
local slow = ":" .. s:lower(); | |||
local find = function ( a ) | |||
local seek = string.format( ":%s:().+%%.%%a+$", | |||
a:lower() ); | |||
local join = slow:find( seek ); | |||
local ret; | |||
if join then | |||
ret = s:sub( join + #a + 1 ); | |||
end | |||
return ret; | |||
end; | |||
r = find( "file" ); | |||
if not r then | |||
local trsl = mw.site.namespaces[6]; | |||
r = find( trsl.name ); | |||
if not r then | |||
trsl = trsl.aliases; | |||
for k, v in pairs( trsl ) do | |||
r = find( v ); | |||
if r then | |||
break; -- for k, v | |||
end | |||
end -- for k, v | |||
end | |||
end | |||
end | |||
return r; | return r; | ||
end -- WLink.getFile() | end -- WLink.getFile() | ||
| Zeile 218: | Zeile 516: | ||
function WLink.getFragment( attempt ) | function WLink.getFragment( attempt ) | ||
-- Retrieve | -- Retrieve fragment | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with presumable | -- attempt -- string, with presumable fragment | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, with | -- Returns string, with detected fragment | ||
-- false if | -- false if no address found | ||
local r = false; | local r = false; | ||
local s = | local s, m = target( attempt ); | ||
if | if s then | ||
local i = s:find( "#", 1, true ); | local i = s:find( "#", 1, true ); | ||
if i then | if i then | ||
if i > 1 then | |||
s = s:sub( i - 1 ); | |||
i = 2; | |||
end | |||
if s:find( "&#", 1, true ) then | |||
s = mw.text.decode( s ); | |||
i = s:find( "#", 1, true ); | |||
if not i then | |||
s = ""; | |||
i = 0; | |||
end | |||
end | |||
s = s:sub( i + 1 ); | |||
r = mw.text.trim( s ); | |||
if r == "" then | if r == "" then | ||
r = false; | r = false; | ||
elseif m == 2 then | |||
r = r:gsub( "%.(%x%x)", "%%%1" ) | |||
:gsub( "_", " " ); | |||
r = mw.uri.decode( r, "PATH" ); | |||
end | end | ||
end | end | ||
| Zeile 248: | Zeile 563: | ||
-- false if no project language found | -- false if no project language 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.lang then | |||
r = w.lang; | |||
end | |||
end | |||
return r; | return r; | ||
end -- WLink.getLanguage() | end -- WLink.getLanguage() | ||
| Zeile 261: | Zeile 583: | ||
-- false if no namespace found | -- false if no namespace 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 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 274: | 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 295: | Zeile 624: | ||
if lean then | if lean then | ||
s, shift = extractWikilink( suffix ); | s, shift = extractWikilink( suffix ); | ||
if not shift then | if s then | ||
shift = | 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 = ""; | ||
end | end | ||
i = i - 1; | |||
end | end | ||
if j > 1 then | if j > 1 then | ||
| Zeile 311: | Zeile 658: | ||
r = string.format( "%s%s%s", | r = string.format( "%s%s%s", | ||
s, shift, r:sub( n + i ) ); | s, shift, r:sub( n + i ) ); | ||
i = i + #shift; | i = i + #shift; | ||
else | else | ||
break; -- while true | break; -- while true | ||
| Zeile 325: | 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 332: | 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 342: | Zeile 696: | ||
-- attempt -- string, with presumable link somewhere | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, with first detected link target | -- Returns string, number | ||
-- string, with first detected link target | |||
-- number, with number of brackets, if found | |||
-- false if nothing found | -- false if nothing found | ||
local | local r1 = false; | ||
local i = attempt:find( "[", 1, true ); | local r2 = false; | ||
local i = attempt:find( "[", 1, true ); | |||
if i then | if i then | ||
local m; | |||
if | r1 = attempt:sub( i ); | ||
if r1:byte( 2, 2 ) == 91 then | |||
m = 2; | |||
r1 = extractWikilink( r1 ); | |||
else | else | ||
m = 1; | |||
r1 = extractExtlink( r1 ); | |||
end | |||
if r1 then | |||
r2 = m; | |||
end | end | ||
else | else | ||
r1 = attempt:match( "%A?([hf]t?tps?://%S+)%s?" ); | |||
if | if r1 then | ||
if | if utilURL().isResourceURL( r1 ) then | ||
r2 = 0; | |||
else | |||
r1 = false; | |||
end | end | ||
else | else | ||
r1 = false; | |||
end | end | ||
end | end | ||
return | return r1, r2; | ||
end -- WLink.getTarget() | end -- WLink.getTarget() | ||
| Zeile 375: | Zeile 740: | ||
-- Returns string, with first detected linked page | -- Returns string, with first detected linked page | ||
-- false if nothing found | -- false if nothing found | ||
local | local r1, r2 = WLink.getTarget( attempt ); | ||
if | if r1 then | ||
local i = | local i = r1:find( "#", 1, true ); | ||
if i == 1 then | if i then | ||
if i == 1 then | |||
r1 = false; | |||
else | |||
r1 = mw.text.trim( r1:sub( 1, i - 1 ) ); | |||
end | |||
end | end | ||
end | end | ||
return | return r1, r2; | ||
end -- WLink.getTargetPage() | end -- WLink.getTargetPage() | ||
| Zeile 414: | 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 420: | Zeile 836: | ||
-- Does attempt match a bracketed link? | -- Does attempt match a bracketed link? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
local r = false; | local r = false; | ||
local i = attempt:find( "[", 1, true ); | |||
if i then | |||
local s = attempt:sub( i ); | |||
if s:byte( 2, 2 ) == 91 then | |||
s = extractWikilink( s ); | |||
else | |||
s = extractExtlink( s ); | |||
end | |||
if s then | |||
r = true; | |||
end | |||
end | |||
return r; | return r; | ||
end -- WLink.isBracketedLink() | end -- WLink.isBracketedLink() | ||
| Zeile 432: | Zeile 860: | ||
-- Does attempt match a bracketed URL? | -- Does attempt match a bracketed URL? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | |||
-- Returns boolean | |||
local s, r = WLink.getTarget( attempt ); | |||
return ( r == 1 ); | |||
end -- WLink.isBracketedURL() | |||
function WLink.isCategorization( attempt ) | |||
-- Does attempt match a categorization? | |||
-- Precondition: | |||
-- attempt -- string, with presumable link somewhere | |||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
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.ns == 14 | |||
and not ( w.lead or w.lang or w.project ) | |||
and w.title ~= "" then | |||
r = true; | |||
end | |||
end | |||
return r; | return r; | ||
end -- WLink. | end -- WLink.isCategorization() | ||
| Zeile 444: | Zeile 893: | ||
-- Does attempt match an external link? | -- Does attempt match an external link? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
local r = | local s, r = WLink.getTarget( attempt ); | ||
if r then | |||
r = ( r < 2 ); | |||
end | |||
return r; | return r; | ||
end -- WLink.isExternalLink() | end -- WLink.isExternalLink() | ||
| Zeile 456: | Zeile 908: | ||
-- Does attempt match an interlanguage link? | -- Does attempt match an interlanguage link? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
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.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 466: | 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 | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
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.lang or w.project ) and w.title ~= "" then | |||
r = true; | |||
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 480: | Zeile 969: | ||
-- Does attempt match a titled link? | -- Does attempt match a titled link? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
local r = false; | local r = false; | ||
local i = attempt:find( "[", 1, true ); | |||
if i then | |||
local c, n; | |||
local s = attempt:sub( i ); | |||
if s:byte( 2, 2 ) == 91 then | |||
n = s:find( "%]%]", 5 ); | |||
c = "|"; | |||
else | |||
n = s:find( "%]", 8 ); | |||
c = "%s%S"; | |||
end | |||
if n then | |||
local m = s:find( c, 2 ); | |||
if m and m + 1 < n and WLink.getTarget( attempt ) then | |||
r = true; | |||
end | |||
end | |||
end | |||
return r; | return r; | ||
end -- WLink.isTitledLink() | end -- WLink.isTitledLink() | ||
| Zeile 492: | Zeile 999: | ||
-- Does attempt match a link? | -- Does attempt match a link? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
local r = | local s, r = WLink.getTarget( attempt ); | ||
if r then | |||
r = true; | |||
end | |||
return r; | return r; | ||
end -- WLink.() | end -- WLink.isValidLink() | ||
function WLink. | function WLink.isWikilink( attempt ) | ||
-- Does attempt match | -- Does attempt match a wikilink? | ||
-- Precondition: | -- Precondition: | ||
-- attempt -- string, with | -- attempt -- string, with presumable link somewhere | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
local r = false; | local s, m = WLink.getTarget( attempt ); | ||
return ( m == 2 ); | |||
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; | return r; | ||
end -- WLink. | end -- WLink.wikilink() | ||
function WLink. | function WLink.failsafe( assert ) | ||
-- | -- Retrieve versioning and check for compliance | ||
-- Precondition: | -- Precondition: | ||
-- | -- assert -- string, with required version, or false | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns | -- Returns string with appropriate version, or false | ||
local r = false; | local r; | ||
return r | if assert and assert > WLink.serial then | ||
end -- WLink. | r = false; | ||
else | |||
r = WLink.serial; | |||
end | |||
return r | |||
end -- WLink.failsafe() | |||
local function Template( frame, action, leave ) | local function Template( frame, action, leave, lone ) | ||
-- Run actual code from template transclusion | -- Run actual code from template transclusion | ||
-- Precondition: | -- Precondition: | ||
| Zeile 531: | Zeile 1.125: | ||
-- action -- string, with function name | -- action -- string, with function name | ||
-- leave -- true: keep whitespace around | -- leave -- true: keep whitespace around | ||
-- lone -- true: permit call without parameters | |||
-- Postcondition: | -- Postcondition: | ||
-- Return string; might be error message | -- Return string; might be error message | ||
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 543: | 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 555: | Zeile 1.154: | ||
end -- for k, v | end -- for k, v | ||
if lucky then | if lucky then | ||
if s 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 563: | Zeile 1.162: | ||
end | end | ||
if lucky then | if lucky then | ||
r = r | if type( r ) == "boolean" then | ||
if r then | |||
r = "1"; | |||
else | |||
r = ""; | |||
end | |||
end | |||
else | else | ||
r = string.format( "<span class=\"error\">%s</span>", r ); | r = string.format( "<span class=\"error\">%s</span>", r ); | ||
end | end | ||
return r | return r; | ||
end -- Template() | end -- Template() | ||
| Zeile 573: | 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 | |||
p.getArticleBase = function ( frame ) | |||
return Template( frame, "getArticleBase", false, true ); | |||
end | end | ||
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 589: | Zeile 1.203: | ||
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 594: | 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 611: | Zeile 1.228: | ||
return Template( frame, "getTitle" ); | return Template( frame, "getTitle" ); | ||
end | end | ||
p. | p.getWeblink = function ( frame ) | ||
return Template( frame, " | return Template( frame, "getWeblink" ); | ||
end | end | ||
p.isBracketedLink = function ( frame ) | p.isBracketedLink = function ( frame ) | ||
| Zeile 619: | 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 628: | 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 640: | 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 645: | Zeile 1.278: | ||
end | end | ||
return p | return p; | ||