Nicht angemeldeter Benutzer - Bearbeiten von Seiten ist nur als angemeldeter Benutzer möglich.
Modul:WLink: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
(fix?) |
K (1 Version importiert: Import der Vorlage Infobox Unternehmen aus der deutschsprachigen Wikipedia) |
||
(37 dazwischenliegende Versionen von 15 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | --[=[ | + | local WLink = { suite = "WLink", |
− | + | serial = "2020-07-01", | |
+ | item = 19363224, | ||
+ | globals = { URLutil = 10859193 } }; | ||
+ | |||
+ | --[=[ | ||
+ | ansiPercent() | ||
+ | formatURL() | ||
+ | getArticleBase() | ||
+ | getBaseTitle() | ||
+ | getEscapedTitle() | ||
+ | getExtension() | ||
+ | getFile() | ||
+ | getFragment() | ||
+ | getLanguage() | ||
+ | getLinktextProblem() | ||
+ | getNamespace() | ||
+ | getNamespaced() | ||
+ | getPlain() | ||
+ | getProject() | ||
+ | getTarget() | ||
+ | getTalkPage() | ||
+ | getTargetPage() | ||
+ | getTitle() | ||
+ | getWeblink() | ||
+ | getWikilink() | ||
+ | isBracketedLink() | ||
+ | isBracketedURL() | ||
+ | isCategorization() | ||
+ | isExternalLink() | ||
+ | isInterlanguage() | ||
+ | isInterwiki() | ||
+ | isMedia() | ||
+ | isTalkPage() | ||
+ | isTitledLink() | ||
+ | isValidLink() | ||
+ | isValidLinktext() | ||
+ | isWikilink() | ||
+ | pageLink() | ||
+ | pageTarget() | ||
+ | wikilink() | ||
+ | failsafe() | ||
]=] | ]=] | ||
− | -- | + | -- local globals |
− | local WLink = | + | local URLutil = false; |
− | local | + | local Failsafe = WLink; |
+ | local GlobalMod = WLink; | ||
+ | |||
+ | |||
+ | |||
+ | local htmlInline = { b = true, | ||
+ | bdi = true, | ||
+ | bdo = true, | ||
+ | big = true, | ||
+ | code = true, | ||
+ | em = true, | ||
+ | i = true, | ||
+ | kbd = true, | ||
+ | s = true, | ||
+ | samp = true, | ||
+ | small = true, | ||
+ | span = true, | ||
+ | strong = true, | ||
+ | style = true, | ||
+ | sub = true, | ||
+ | sup = true, | ||
+ | tt = true, | ||
+ | var = true }; | ||
+ | |||
+ | |||
+ | |||
+ | local foreignModule = function ( access, advanced, append, alt, alert ) | ||
+ | -- Fetch global module | ||
+ | -- Precondition: | ||
+ | -- access -- string, with name of base module | ||
+ | -- advanced -- true, for require(); else mw.loadData() | ||
+ | -- append -- string, with subpage part, if any; or false | ||
+ | -- alt -- number, of wikidata item of root; or false | ||
+ | -- alert -- true, for throwing error on data problem | ||
+ | -- Postcondition: | ||
+ | -- Returns whatever, probably table | ||
+ | -- 2020-01-01 | ||
+ | local storage = access; | ||
+ | local finer = function () | ||
+ | if append then | ||
+ | storage = string.format( "%s/%s", | ||
+ | storage, | ||
+ | append ); | ||
+ | end | ||
+ | end | ||
+ | local fun, lucky, r, suited; | ||
+ | if advanced then | ||
+ | fun = require; | ||
+ | else | ||
+ | fun = mw.loadData; | ||
+ | end | ||
+ | GlobalMod.globalModules = GlobalMod.globalModules or { }; | ||
+ | suited = GlobalMod.globalModules[ access ]; | ||
+ | if not suited then | ||
+ | finer(); | ||
+ | lucky, r = pcall( fun, "Module:" .. storage ); | ||
+ | end | ||
+ | if not lucky then | ||
+ | if not suited and | ||
+ | type( alt ) == "number" and | ||
+ | alt > 0 then | ||
+ | suited = string.format( "Q%d", alt ); | ||
+ | suited = mw.wikibase.getSitelink( suited ); | ||
+ | GlobalMod.globalModules[ access ] = suited or true; | ||
+ | end | ||
+ | if type( suited ) == "string" then | ||
+ | storage = suited; | ||
+ | finer(); | ||
+ | lucky, r = pcall( fun, storage ); | ||
+ | end | ||
+ | if not lucky and alert then | ||
+ | error( "Missing or invalid page: " .. storage ); | ||
+ | end | ||
+ | end | ||
+ | return r; | ||
+ | end -- foreignModule() | ||
Zeile 17: | Zeile 132: | ||
-- Throws error, if not available | -- Throws error, if not available | ||
if not URLutil then | if not URLutil then | ||
− | local | + | local util = foreignModule( "URLutil", |
− | + | true, | |
− | + | false, | |
− | + | WLink.globals.URLutil ); | |
− | + | if type( util ) == "table" then | |
+ | URLutil = util.URLutil(); | ||
+ | else | ||
util = "library URLutil invalid"; | util = "library URLutil invalid"; | ||
end | end | ||
Zeile 30: | Zeile 147: | ||
return URLutil; | return URLutil; | ||
end -- utilURL() | end -- utilURL() | ||
+ | |||
+ | |||
+ | |||
+ | local cleanWikilink = function ( access ) | ||
+ | -- Refine wikilink spacing and decode | ||
+ | -- Precondition: | ||
+ | -- access -- string, with presumable link | ||
+ | -- Postcondition: | ||
+ | -- Returns string, with pretty target | ||
+ | local r; | ||
+ | if not WLink.lrm then | ||
+ | WLink.lrm = mw.ustring.char( 0x200E ); | ||
+ | WLink.rlm = mw.ustring.char( 0x200F ); | ||
+ | end | ||
+ | r = access:gsub( "_", " " ) | ||
+ | :gsub( " ", " " ) | ||
+ | :gsub( " ", " " ) | ||
+ | :gsub( " ", " " ) | ||
+ | :gsub( " ", " " ) | ||
+ | :gsub( "‎", "" ) | ||
+ | :gsub( "‏", "" ) | ||
+ | :gsub( WLink.lrm, "" ) | ||
+ | :gsub( WLink.rlm, "" ) | ||
+ | :gsub( "%s+", " " ); | ||
+ | r = mw.text.decode( r ); | ||
+ | return r; | ||
+ | end -- cleanWikilink() | ||
Zeile 37: | Zeile 181: | ||
-- 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 201: | ||
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 286: | ||
-- 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 303: | ||
if r1 == "" then | if r1 == "" then | ||
r1 = false; | r1 = false; | ||
+ | else | ||
+ | r1 = cleanWikilink( r1 ); | ||
end | end | ||
end | end | ||
Zeile 164: | Zeile 312: | ||
− | function WLink.ansiPercent( attempt ) | + | local farming = function ( already ) |
+ | -- Retrieve wikifarm project information | ||
+ | -- Precondition: | ||
+ | -- already -- table, with wikilink components | ||
+ | -- Postcondition: | ||
+ | -- Returns table, with wikilink components extended | ||
+ | local r = already; | ||
+ | if not r.project then | ||
+ | local codes = { mediawiki = "mw", | ||
+ | wikibooks = "b", | ||
+ | wikidata = "d", | ||
+ | wikinews = "n", | ||
+ | wikipedia = "w", | ||
+ | wikiquote = "q", | ||
+ | wikisource = "s", | ||
+ | wikiversity = "v", | ||
+ | wikivoyage = "voy", | ||
+ | wiktionary = "wikt" }; | ||
+ | local server = mw.site.server:gsub( "([/.])m%.", | ||
+ | "%1" ) | ||
+ | :gsub( "%.beta%.wmflabs%.org$", | ||
+ | ".org" ); | ||
+ | local site = server:match( "[/.](%l+)%.org$" ); | ||
+ | r.project = codes[ site ]; | ||
+ | if r.project then | ||
+ | if not r.lang and | ||
+ | r.project ~= "mw" and r.project ~= "d" then | ||
+ | r.lang = server:match( "//(%l+)%." ); | ||
+ | end | ||
+ | else | ||
+ | site = server:match( "//(%l+)%.wikimedia%.org$" ); | ||
+ | if site == "commons" or site == "meta" then | ||
+ | r.project = site; | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | if r.project and r.ns and | ||
+ | ( r.project == "commons" or | ||
+ | r.project == "d" or | ||
+ | r.project == "meta" or | ||
+ | r.project == "mw" ) then | ||
+ | r.language = true; | ||
+ | end | ||
+ | return r; | ||
+ | end -- farming() | ||
+ | |||
+ | |||
+ | |||
+ | local prefix = function ( ask ) | ||
+ | -- Interprete prefix of language or project type | ||
+ | -- Precondition: | ||
+ | -- ask -- string, with presumable prefix | ||
+ | -- 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 | ||
+ | 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( "%%%02X", 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 | ||
+ | return r; | ||
+ | end -- WLink.ansiPercent() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.formatURL( adjust, assure ) | ||
+ | -- Create bracketed link, if not yet | ||
+ | -- Precondition: | ||
+ | -- adjust -- string, with URL or domain/path or bracketed link | ||
+ | -- assure -- boolean, true for secure HTTP | ||
+ | -- 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 = "://" .. adjust; | ||
+ | if assure then | ||
+ | url = "s" .. url; | ||
+ | end | ||
+ | url = "http" .. url; | ||
+ | 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() | ||
Zeile 193: | Zeile 614: | ||
-- 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 642: | ||
-- 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 676: | ||
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 723: | ||
-- 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() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.getLinktextProblem( attempt ) | ||
+ | -- Which problem has this presumable link text? | ||
+ | -- Precondition: | ||
+ | -- attempt -- string, with presumable linktext | ||
+ | -- Postcondition: | ||
+ | -- Returns string, with error message, or false | ||
+ | local r; | ||
+ | if attempt:find( "]", 1, true ) then | ||
+ | r = "]"; | ||
+ | elseif mw.text.unstripNoWiki( attempt ) ~= attempt then | ||
+ | r = "<nowiki>"; | ||
+ | elseif attempt:find( "\n", 1, true ) then | ||
+ | r = "\n"; | ||
+ | elseif mw.text.unstrip( attempt ) ~= attempt then | ||
+ | if not WLink.stripREF then | ||
+ | WLink.stripREF = string.format( "%c%c%c%c%s%c%c%c%c", | ||
+ | 127, 39, 34, 96, | ||
+ | "UNIQ%-+ref%-%x+%-QINU", | ||
+ | 96, 34, 39, 127 ); | ||
+ | end | ||
+ | if mw.ustring.find( attempt, WLink.stripREF ) then | ||
+ | r = "<ref>"; | ||
+ | end | ||
+ | end | ||
+ | if not r then | ||
+ | local i = attempt:find( "<", 1, true ); | ||
+ | if i then | ||
+ | local s = mw.ustring.lower( attempt:sub( i ) ); | ||
+ | local sign = true; | ||
+ | local skip; | ||
+ | while sign and not r do | ||
+ | skip, sign = s:match( "^([^<]*< *)(%l[%l%d]*)[ /]*.*>" ); | ||
+ | if sign then | ||
+ | if htmlInline[ sign ] then | ||
+ | i = skip:len() + sign:len() + 1; | ||
+ | s = s:sub( i ); | ||
+ | else | ||
+ | r = string.format( "<%s>", sign ); | ||
+ | end | ||
+ | end | ||
+ | end -- while sign and not r | ||
+ | end | ||
+ | if not r then | ||
+ | local s = attempt .. " "; | ||
+ | if s:find( "ISBN ", 1, true ) then | ||
+ | r = s:match( "(ISBN %d[%-%d]+[%dxX])%W" ); | ||
+ | end | ||
+ | if not r then | ||
+ | if s:find( "PMID ", 1, true ) then | ||
+ | r = s:match( "(PMID [1-9]%d*)%W" ); | ||
+ | end | ||
+ | if not r then | ||
+ | if s:find( "RFC ", 1, true ) then | ||
+ | r = s:match( "(RFC [1-9]%d?%d?%d?)%W" ); | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | return r or false; | ||
+ | end -- WLink.getLinktextProblem() | ||
Zeile 261: | Zeile 807: | ||
-- 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() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.getNamespaced( area, attempt ) | ||
+ | -- Retrieve page in namespace | ||
+ | -- Precondition: | ||
+ | -- area -- string or number, with some namespace spec | ||
+ | -- attempt -- string, with wikilink or page title or page name | ||
+ | -- Postcondition: | ||
+ | -- Returns page prefixed by namespace, | ||
+ | -- false if invalid | ||
+ | local r = false; | ||
+ | local s = type( area ); | ||
+ | local room; | ||
+ | if s == "string" then | ||
+ | room = mw.site.namespaces[ tonumber( area ) or area ]; | ||
+ | elseif s == "number" then | ||
+ | room = mw.site.namespaces[ area ]; | ||
+ | end | ||
+ | if room then | ||
+ | local m; | ||
+ | s, m = WLink.getTarget( attempt ); | ||
+ | if not s then | ||
+ | s = attempt; | ||
+ | elseif m ~= 2 then | ||
+ | s = false; | ||
+ | end | ||
+ | if s then | ||
+ | local w = WLink.wikilink( s ); | ||
+ | if w and not w.lang and not w.project and | ||
+ | ( not w.ns or w.ns == room.id ) then | ||
+ | r = string.format( "%s:%s", | ||
+ | room.name, w.title ); | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.getNamespaced() | ||
Zeile 274: | Zeile 865: | ||
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, span, space, suffix; |
while ( true ) do | while ( true ) do | ||
j = r:find( "[", i, true ); | j = r:find( "[", i, true ); | ||
Zeile 289: | Zeile 880: | ||
if k > 1 then | if k > 1 then | ||
n = n - k; | n = n - k; | ||
− | i = j + k; | + | i = j + k + 1; |
j = i - 1; | j = i - 1; | ||
suffix = r:sub( j ); | suffix = r:sub( j ); | ||
Zeile 295: | Zeile 886: | ||
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 | ||
− | + | span, shift = extractExtlink( suffix ); | |
− | if not shift then | + | if span then |
− | shift = ""; | + | if not shift then |
+ | shift = ""; | ||
+ | end | ||
+ | else | ||
+ | shift = string.format( "[%s]", s ); | ||
end | end | ||
+ | i = i - 1; | ||
end | end | ||
if j > 1 then | if j > 1 then | ||
Zeile 318: | Zeile 928: | ||
break; -- while true | break; -- while true | ||
end | end | ||
− | end -- while true | + | end -- while true |
return r; | return r; | ||
end -- WLink.getPlain() | end -- WLink.getPlain() | ||
Zeile 325: | Zeile 935: | ||
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 942: | ||
-- 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() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.getTalkPage( attempt ) | ||
+ | -- Retrieve talk page name for attempt, or that page name itself | ||
+ | -- Precondition: | ||
+ | -- attempt -- string, with presumable link somewhere | ||
+ | -- Postcondition: | ||
+ | -- Returns string or false | ||
+ | local r = false; | ||
+ | local s, m = WLink.getTarget( attempt ); | ||
+ | if m ~= 2 and attempt then | ||
+ | s = mw.text.trim( attempt ); | ||
+ | end | ||
+ | if s and s ~= "" then | ||
+ | local w = mw.title.new( s ); | ||
+ | if w then | ||
+ | w = w.talkPageTitle; | ||
+ | if w then | ||
+ | r = w.prefixedText; | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.getTalkPage() | ||
Zeile 342: | Zeile 984: | ||
-- 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 1.028: | ||
-- 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 then | if i then | ||
if i == 1 then | if i == 1 then | ||
− | + | r1 = false; | |
else | else | ||
− | + | r1 = mw.text.trim( r1:sub( 1, i - 1 ) ); | |
end | end | ||
end | end | ||
end | end | ||
− | return | + | return r1, r2; |
end -- WLink.getTargetPage() | end -- WLink.getTargetPage() | ||
Zeile 416: | Zeile 1.069: | ||
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 service = attempt; | ||
+ | local show; | ||
+ | if #attempt == #site then | ||
+ | site = site .. "/"; | ||
+ | end | ||
+ | show = URLutil.getTop3domain( "//" .. site ); | ||
+ | if show then | ||
+ | local scan = "[%./](%a[%a%%%-]*%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:sub( 2 ), 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 | ||
+ | if not service:match( "^[a-z:]*//.+/" ) then | ||
+ | service = service .. "/"; | ||
+ | end | ||
+ | r = string.format( "[%s %s]", service, show ); | ||
+ | else | ||
+ | r = attempt; | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.getWeblink() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.getWikilink( attempt, appear ) | ||
+ | -- Retrieve bracketed link from text | ||
+ | -- Precondition: | ||
+ | -- attempt -- string, with current target, or plain | ||
+ | -- appear -- string, with link title, or nil | ||
+ | -- Postcondition: | ||
+ | -- Returns string, with first detected link target | ||
+ | -- false if nothing found | ||
+ | local r = WLink.pageTarget( attempt ); | ||
+ | if r then | ||
+ | if appear then | ||
+ | local show = WLink.getEscapedTitle( appear ); | ||
+ | if show ~= r and show ~= "" then | ||
+ | r = string.format( "%s|%s", r, show ); | ||
+ | end | ||
+ | end | ||
+ | r = string.format( "[[%s]]", r ); | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.getWikilink() | ||
Zeile 422: | Zeile 1.151: | ||
-- 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 434: | Zeile 1.175: | ||
-- 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 446: | Zeile 1.208: | ||
-- 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 458: | Zeile 1.223: | ||
-- 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 468: | Zeile 1.241: | ||
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() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.isTalkPage( attempt ) | ||
+ | -- Does attempt describe a talk page? | ||
+ | -- Precondition: | ||
+ | -- attempt -- string, with presumable link somewhere | ||
+ | -- Postcondition: | ||
+ | -- Returns boolean | ||
+ | local r = false; | ||
+ | local s, m = WLink.getTarget( attempt ); | ||
+ | if m ~= 2 and attempt then | ||
+ | s = mw.text.trim( attempt ); | ||
+ | end | ||
+ | if s and s ~= "" then | ||
+ | local w = mw.title.new( s ); | ||
+ | if w then | ||
+ | r = w.isTalkPage; | ||
+ | end | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.isTalkPage() | ||
Zeile 482: | Zeile 1.306: | ||
-- 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 494: | Zeile 1.336: | ||
-- 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 = false; | + | local u, r = WLink.getTarget( attempt ); |
+ | if r then | ||
+ | if r < 2 then | ||
+ | if u:find( "''", 1, true ) then | ||
+ | r = false; | ||
+ | else | ||
+ | r = true; | ||
+ | end | ||
+ | else | ||
+ | r = true; | ||
+ | end | ||
+ | end | ||
return r; | return r; | ||
− | end -- WLink.() | + | end -- WLink.isValidLink() |
− | function WLink. | + | function WLink.isValidLinktext( attempt, allow ) |
− | -- | + | -- Is attempt a plain inline text? |
-- Precondition: | -- Precondition: | ||
− | -- attempt -- string, with | + | -- attempt -- string, with presumable linktext |
+ | -- allow -- boolean or nil, if multiline permitted | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns boolean | -- Returns boolean | ||
− | local | + | local s; |
− | return | + | if allow and s:find( "\n", 1, true ) then |
− | end -- WLink. | + | s = attempt:gsub( "\n", " " ); |
+ | else | ||
+ | s = attempt; | ||
+ | end | ||
+ | return not WLink.getLinktextProblem( s ); | ||
+ | end -- WLink.isValidLinktext() | ||
Zeile 518: | Zeile 1.377: | ||
-- Does attempt match a wikilink? | -- 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.pageLink( attempt, appear, assure ) | ||
+ | -- Create safely standardized wikilink target of a page | ||
+ | -- attempt -- string, with presumable link | ||
+ | -- appear -- string or true or nil, with link title | ||
+ | -- assure -- string or nil, shield against wiki template syntax | ||
+ | -- "URL" or "WIKI" | ||
+ | -- Postcondition: | ||
+ | -- Returns string with link target | ||
+ | local r = WLink.pageTarget( attempt, assure ); | ||
+ | if appear then | ||
+ | local show; | ||
+ | if type( appear ) == "string" then | ||
+ | show = appear; | ||
+ | else | ||
+ | show = attempt; | ||
+ | end | ||
+ | r = string.format( "%s|%s", r, show ); | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.pageLink() | ||
+ | |||
+ | |||
+ | |||
+ | function WLink.pageTarget( attempt, assure ) | ||
+ | -- Create standardized wikilink target of a page | ||
+ | -- Precondition: | ||
+ | -- attempt -- string, with presumable link | ||
+ | -- expected to be enclosed in "[[" "]]" | ||
+ | -- else wikilink | ||
+ | -- table, of assignments with { type, value } | ||
+ | -- type is one of "lead", | ||
+ | -- "project", "lang", | ||
+ | -- "ns", "space", "title" | ||
+ | -- assure -- string or nil, shield against wiki template syntax | ||
+ | -- "URL" or "WIKI" | ||
+ | -- Postcondition: | ||
+ | -- Returns string with link target | ||
+ | local p = type( attempt ); | ||
+ | local s = assure; | ||
+ | local r; | ||
+ | if p == "string" then | ||
+ | p = WLink.wikilink( attempt ); | ||
+ | elseif p == "table" then | ||
+ | p = attempt; | ||
+ | else | ||
+ | p = false; | ||
+ | end | ||
+ | if p then | ||
+ | local site = p.project; | ||
+ | local slang = p.lang; | ||
+ | local lead; | ||
+ | if p.title:sub( 1, 1 ) == "#" then | ||
+ | p.title = mw.title.getCurrentTitle().text + p.title; | ||
+ | end | ||
+ | if p.ns then | ||
+ | if not slang then | ||
+ | p = farming( p ); | ||
+ | end | ||
+ | if p.lang and | ||
+ | p.lang ~= mw.language.getContentLanguage():getCode() then | ||
+ | p.language = true; | ||
+ | end | ||
+ | if p.language then | ||
+ | p.space = mw.site.namespaces[ p.ns ].canonicalName; | ||
+ | end | ||
+ | lead = ( p.ns == 6 or p.ns == 14 ); | ||
+ | end | ||
+ | if slang then | ||
+ | lead = true; | ||
+ | end | ||
+ | if s == "WIKI" then | ||
+ | if not site and | ||
+ | ( lead or | ||
+ | ( not p.space and | ||
+ | p.title and p.title:match( "^[*;]" ) ) ) then | ||
+ | p = farming( p ); | ||
+ | site = p.project; | ||
+ | slang = p.lang; | ||
+ | end | ||
+ | s = false; | ||
+ | end | ||
+ | if site then | ||
+ | r = site .. ":"; | ||
+ | elseif lead then | ||
+ | r = ":"; | ||
+ | else | ||
+ | r = ""; | ||
+ | end | ||
+ | if slang then | ||
+ | r = string.format( "%s%s:", r, slang ); | ||
+ | end | ||
+ | if p.space then | ||
+ | r = string.format( "%s%s:", r, p.space ); | ||
+ | end | ||
+ | if p.title then | ||
+ | r = r .. p.title; | ||
+ | end | ||
+ | if r == "" then | ||
+ | r = false; | ||
+ | end | ||
+ | end | ||
+ | if not r then | ||
+ | p = { lang = mw.language.getContentLanguage():getCode() }; | ||
+ | if s == "WIKI" then | ||
+ | r = WLink.pageTarget( p, s ); | ||
+ | s = false; | ||
+ | else | ||
+ | r = string.format( ":%s:", p.lang ); | ||
+ | end | ||
+ | end | ||
+ | if s == "URL" and r:match( "^[*#;:]" ) then | ||
+ | r = mw.uri.encode( r:sub( 1, 1 ) ) .. r:sub( 2 ); | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.pageTarget() | ||
+ | |||
+ | |||
+ | |||
+ | 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 or "" ); | ||
+ | local got, i, n, r; | ||
+ | if not s then | ||
+ | s = attempt; | ||
+ | end | ||
+ | if s:find( "%", 1, true ) then | ||
+ | s = mw.uri.decode( s, "PATH" ); | ||
+ | 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 = "" }; | ||
+ | while ( got[ 1 ] == "" ) do | ||
+ | r.lead = true; | ||
+ | table.remove( got, 1 ); | ||
+ | n = n - 1; | ||
+ | end -- while got[ 1 ] == "" | ||
+ | if n > 4 then | ||
+ | k = 4; | ||
+ | elseif n > 1 then | ||
+ | k = n - 1; | ||
+ | else | ||
+ | k = 1; | ||
+ | end | ||
+ | j = k; | ||
+ | for i = 1, j do | ||
+ | s = mw.text.trim( got[ i ] ); | ||
+ | if s ~= "" then | ||
+ | o = mw.site.namespaces[ s ]; | ||
+ | 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 ] ); | ||
+ | if o then | ||
+ | if r[ o ] then | ||
+ | k = i; | ||
+ | break; -- for i | ||
+ | else | ||
+ | if i >= k then | ||
+ | k = i + 1; | ||
+ | end | ||
+ | r[ o ] = v; | ||
+ | end | ||
+ | else | ||
+ | if i == 1 and r.ns then | ||
+ | r.ns = false; | ||
+ | r.space = false; | ||
+ | end | ||
+ | k = i; | ||
+ | break; -- for i | ||
+ | end | ||
+ | end -- for i | ||
+ | if k > 0 then | ||
+ | for i = k, n do | ||
+ | r.title = r.title .. got[ i ]; | ||
+ | if i < n then | ||
+ | r.title = r.title .. ":"; | ||
+ | end | ||
+ | end -- for i | ||
+ | end | ||
+ | end | ||
+ | r.title = cleanWikilink( r.title ); | ||
+ | if r.lead and | ||
+ | ( r.project or | ||
+ | ( not r.lang and r.ns ~= 6 and r.ns ~= 14 ) ) then | ||
+ | r.lead = false; | ||
+ | end | ||
+ | return r; | ||
+ | end -- WLink.wikilink() | ||
+ | |||
+ | |||
+ | |||
+ | Failsafe.failsafe = function ( atleast ) | ||
+ | -- Retrieve versioning and check for compliance | ||
+ | -- Precondition: | ||
+ | -- atleast -- string, with required version or "wikidata" or "~" | ||
+ | -- or false | ||
+ | -- Postcondition: | ||
+ | -- Returns string -- with queried version, also if problem | ||
+ | -- false -- if appropriate | ||
+ | local last = ( atleast == "~" ); | ||
+ | local since = atleast; | ||
+ | local r; | ||
+ | if last or since == "wikidata" then | ||
+ | local item = Failsafe.item; | ||
+ | since = false; | ||
+ | if type( item ) == "number" and item > 0 then | ||
+ | local ent = mw.wikibase.getEntity( string.format( "Q%d", | ||
+ | item ) ); | ||
+ | if type( ent ) == "table" then | ||
+ | local vsn = ent:formatPropertyValues( "P348" ); | ||
+ | if type( vsn ) == "table" and | ||
+ | type( vsn.value ) == "string" and | ||
+ | vsn.value ~= "" then | ||
+ | if last and vsn.value == Failsafe.serial then | ||
+ | r = false; | ||
+ | else | ||
+ | r = vsn.value; | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | if type( r ) == "nil" then | ||
+ | if not since or since <= Failsafe.serial then | ||
+ | r = Failsafe.serial; | ||
+ | else | ||
+ | r = false; | ||
+ | end | ||
+ | end | ||
return r; | return r; | ||
− | end -- | + | end -- Failsafe.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 533: | Zeile 1.652: | ||
-- 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 safe, 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 546: | Zeile 1.666: | ||
s = mw.text.trim( v ); | s = mw.text.trim( v ); | ||
end | end | ||
+ | elseif ( k == 2 and | ||
+ | ( action == "getNamespaced" or | ||
+ | action == "getWikilink" or | ||
+ | action == "pageLink" ) ) or | ||
+ | ( k == "space" and action == "ansiPercent" ) then | ||
+ | v = mw.text.trim( v ); | ||
+ | if v ~= "" then | ||
+ | space = v; | ||
+ | end | ||
+ | elseif k == "safe" and action == "pageLink" then | ||
+ | v = mw.text.trim( v ); | ||
+ | if v ~= "" then | ||
+ | safe = v; | ||
+ | end | ||
+ | elseif k == "lines" and action == "isValidLinktext" then | ||
+ | space = ( k == "1" ); | ||
elseif k ~= "template" then | elseif k ~= "template" then | ||
lucky = false; | lucky = false; | ||
Zeile 557: | Zeile 1.693: | ||
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, safe ); |
else | else | ||
r = "Parameter missing"; | r = "Parameter missing"; | ||
Zeile 565: | Zeile 1.701: | ||
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 | ||
− | + | local e = mw.html.create( "span" ); | |
+ | r = tostring( e:addClass( "error" ) | ||
+ | :wikitext( r ) ); | ||
end | end | ||
− | return r | + | return r; |
end -- Template() | end -- Template() | ||
Zeile 575: | Zeile 1.719: | ||
-- 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 591: | Zeile 1.744: | ||
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 ) | ||
return Template( frame, "getLanguage" ); | return Template( frame, "getLanguage" ); | ||
+ | end | ||
+ | p.getLinktextProblem = function ( frame ) | ||
+ | return Template( frame, "getLinktextProblem" ); | ||
end | end | ||
p.getNamespace = function ( frame ) | p.getNamespace = function ( frame ) | ||
− | return Template( frame, "getNamespace" ); | + | return tostring( Template( frame, "getNamespace" ) ); |
+ | end | ||
+ | p.getNamespaced = function ( frame ) | ||
+ | return tostring( Template( frame, "getNamespaced" ) ); | ||
end | end | ||
p.getPlain = function ( frame ) | p.getPlain = function ( frame ) | ||
Zeile 603: | Zeile 1.765: | ||
p.getProject = function ( frame ) | p.getProject = function ( frame ) | ||
return Template( frame, "getProject" ); | return Template( frame, "getProject" ); | ||
+ | end | ||
+ | p.getTalkPage = function ( frame ) | ||
+ | return Template( frame, "getTalkPage" ); | ||
end | end | ||
p.getTarget = function ( frame ) | p.getTarget = function ( frame ) | ||
Zeile 613: | Zeile 1.778: | ||
return Template( frame, "getTitle" ); | return Template( frame, "getTitle" ); | ||
end | end | ||
− | p. | + | p.getWeblink = function ( frame ) |
− | return Template( frame, " | + | return Template( frame, "getWeblink" ); |
+ | end | ||
+ | p.getWikilink = function ( frame ) | ||
+ | return Template( frame, "getWikilink" ); | ||
end | end | ||
p.isBracketedLink = function ( frame ) | p.isBracketedLink = function ( frame ) | ||
Zeile 621: | Zeile 1.789: | ||
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 630: | Zeile 1.801: | ||
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 | ||
+ | p.isTalkPage = function ( frame ) | ||
+ | return Template( frame, "isTalkPage" ); | ||
end | end | ||
p.isTitledLink = function ( frame ) | p.isTitledLink = function ( frame ) | ||
Zeile 636: | Zeile 1.813: | ||
p.isValidLink = function ( frame ) | p.isValidLink = function ( frame ) | ||
return Template( frame, "isValidLink" ); | return Template( frame, "isValidLink" ); | ||
+ | end | ||
+ | p.isValidLinktext = function ( frame ) | ||
+ | return Template( frame, "isValidLinktext" ); | ||
end | end | ||
p.isWeblink = function ( frame ) | p.isWeblink = function ( frame ) | ||
Zeile 643: | Zeile 1.823: | ||
return Template( frame, "isWikilink" ); | return Template( frame, "isWikilink" ); | ||
end | end | ||
+ | p.pageLink = function ( frame ) | ||
+ | return Template( frame, "pageLink" ); | ||
+ | end | ||
+ | p.failsafe = function ( frame ) | ||
+ | local s = type( frame ); | ||
+ | local since; | ||
+ | if s == "table" then | ||
+ | since = frame.args[ 1 ]; | ||
+ | elseif s == "string" then | ||
+ | since = frame; | ||
+ | end | ||
+ | if since then | ||
+ | since = mw.text.trim( since ); | ||
+ | if since == "" then | ||
+ | since = false; | ||
+ | end | ||
+ | end | ||
+ | return Failsafe.failsafe( since ) or ""; | ||
+ | end -- p.failsafe | ||
p.WLink = function () | p.WLink = function () | ||
return WLink; | return WLink; | ||
end | end | ||
− | return p | + | return p; |
Aktuelle Version vom 18. September 2020, 11:45 Uhr
Vorlagenprogrammierung | Diskussionen | Lua | Unterseiten | |||
Modul | Deutsch | English
|
Modul: | Dokumentation |
Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus |
Dieses Modul (und die Dokumentation) basieren (teilweise) auf Modul:WLink aus der freien Enzyklopädie Wikipedia in der Fassung 129808410 vom 14. December 2019 und steht unter der GNU Lizenz für freie Dokumentation und der Creative Commons Attribution/Share Alike. Auf Wikipedia ist eine Liste der Autoren verfügbar. Veränderungen seither in Imedwiki. Veränderungen seither in Wikipedia.Weiteres zum Import aus Wikipedia siehe Seite Imedwiki:Import aus Wikipedia.
local WLink = { suite = "WLink",
serial = "2020-07-01",
item = 19363224,
globals = { URLutil = 10859193 } };
--[=[
ansiPercent()
formatURL()
getArticleBase()
getBaseTitle()
getEscapedTitle()
getExtension()
getFile()
getFragment()
getLanguage()
getLinktextProblem()
getNamespace()
getNamespaced()
getPlain()
getProject()
getTarget()
getTalkPage()
getTargetPage()
getTitle()
getWeblink()
getWikilink()
isBracketedLink()
isBracketedURL()
isCategorization()
isExternalLink()
isInterlanguage()
isInterwiki()
isMedia()
isTalkPage()
isTitledLink()
isValidLink()
isValidLinktext()
isWikilink()
pageLink()
pageTarget()
wikilink()
failsafe()
]=]
-- local globals
local URLutil = false;
local Failsafe = WLink;
local GlobalMod = WLink;
local htmlInline = { b = true,
bdi = true,
bdo = true,
big = true,
code = true,
em = true,
i = true,
kbd = true,
s = true,
samp = true,
small = true,
span = true,
strong = true,
style = true,
sub = true,
sup = true,
tt = true,
var = true };
local foreignModule = function ( access, advanced, append, alt, alert )
-- Fetch global module
-- Precondition:
-- access -- string, with name of base module
-- advanced -- true, for require(); else mw.loadData()
-- append -- string, with subpage part, if any; or false
-- alt -- number, of wikidata item of root; or false
-- alert -- true, for throwing error on data problem
-- Postcondition:
-- Returns whatever, probably table
-- 2020-01-01
local storage = access;
local finer = function ()
if append then
storage = string.format( "%s/%s",
storage,
append );
end
end
local fun, lucky, r, suited;
if advanced then
fun = require;
else
fun = mw.loadData;
end
GlobalMod.globalModules = GlobalMod.globalModules or { };
suited = GlobalMod.globalModules[ access ];
if not suited then
finer();
lucky, r = pcall( fun, "Module:" .. storage );
end
if not lucky then
if not suited and
type( alt ) == "number" and
alt > 0 then
suited = string.format( "Q%d", alt );
suited = mw.wikibase.getSitelink( suited );
GlobalMod.globalModules[ access ] = suited or true;
end
if type( suited ) == "string" then
storage = suited;
finer();
lucky, r = pcall( fun, storage );
end
if not lucky and alert then
error( "Missing or invalid page: " .. storage );
end
end
return r;
end -- foreignModule()
local utilURL = function ()
-- Attach URLutil library module
-- Postcondition:
-- Returns table, with URLutil library
-- Throws error, if not available
if not URLutil then
local util = foreignModule( "URLutil",
true,
false,
WLink.globals.URLutil );
if type( util ) == "table" then
URLutil = util.URLutil();
else
util = "library URLutil invalid";
end
if type( URLutil ) ~= "table" then
error( util, 0 );
end
end
return URLutil;
end -- utilURL()
local cleanWikilink = function ( access )
-- Refine wikilink spacing and decode
-- Precondition:
-- access -- string, with presumable link
-- Postcondition:
-- Returns string, with pretty target
local r;
if not WLink.lrm then
WLink.lrm = mw.ustring.char( 0x200E );
WLink.rlm = mw.ustring.char( 0x200F );
end
r = access:gsub( "_", " " )
:gsub( " ", " " )
:gsub( " ", " " )
:gsub( " ", " " )
:gsub( " ", " " )
:gsub( "‎", "" )
:gsub( "‏", "" )
:gsub( WLink.lrm, "" )
:gsub( WLink.rlm, "" )
:gsub( "%s+", " " );
r = mw.text.decode( r );
return r;
end -- cleanWikilink()
local contentExtlink = function ( attempt )
-- Retrieve span of external link between brackets
-- Precondition:
-- attempt -- string, with presumable link
-- the first char is expected to be "["
-- Postcondition:
-- Returns string, number, number
-- string including whitespace
-- number with index of relevant "["
-- number with index after relevant "]"
-- false if nothing found
local r1 = false;
local r2 = false;
local r3 = attempt:find( "]", 2, true );
if r3 then
local s = attempt:sub( 2, r3 - 1 );
local i = s:find( "[", 1, true );
if i then
r1 = s:sub( i + 1 );
r2 = i;
else
r1 = s;
r2 = 1;
end
else
r3 = false;
end
return r1, r2, r3;
end -- contentExtlink()
local contentWikilink = function ( attempt )
-- Retrieve span of wikilink between brackets
-- Precondition:
-- attempt -- string, with presumable link
-- the first two chars are expected to be "[["
-- Postcondition:
-- Returns string, number, number
-- string including whitespace
-- number with index of relevant "[["
-- number with index after relevant "]]"
-- false if nothing found
local r1 = false;
local r2 = false;
local r3 = attempt:find( "]]", 3, true );
if r3 then
local s = attempt:sub( 3, r3 - 1 );
local i = s:find( "[[", 1, true );
if i then
r1 = s:sub( i + 2 );
r2 = i;
else
r1 = s;
r2 = 1;
end
end
return r1, r2, r3;
end -- contentWikilink()
local extractExtlink = function ( attempt )
-- Retrieve external link
-- Precondition:
-- attempt -- string, with presumable link
-- the first char is expected to be "["
-- Postcondition:
-- Returns string, string
-- first with target and title
-- second result false if not titled
-- false if nothing found
local r1 = false;
local r2 = false;
local s = contentExtlink( attempt );
if s then
local i = s:find( "%s", 1 );
if i then
r1 = s:sub( 1, i - 1 );
r2 = mw.text.trim( s:sub( i + 1 ) );
if r2 == "" then
r2 = false;
end
else
r1 = s;
end
if r1 then
r1 = mw.text.trim( r1 );
if r1 == "" or
not utilURL().isResourceURL( r1 ) then
r1 = false;
end
end
if not r1 then
r2 = false;
end
end
return r1, r2;
end -- extractExtlink()
local extractWikilink = function ( attempt )
-- Retrieve wikilink
-- Precondition:
-- attempt -- string, with presumable link
-- the first two chars are expected to be "[["
-- Postcondition:
-- Returns string, string
-- first with target
-- second result title, or false if not piped
-- false if nothing found
local r1 = false;
local r2 = false;
local s = contentWikilink( attempt );
if s then
local i = s:find( "|", 1, true );
if i then
r1 = s:sub( 1, i - 1 );
r2 = s:sub( i + 1 );
else
r1 = s;
end
r1 = mw.text.trim( r1 );
if r1 == "" then
r1 = false;
else
r1 = cleanWikilink( r1 );
end
end
return r1, r2;
end -- extractWikilink()
local farming = function ( already )
-- Retrieve wikifarm project information
-- Precondition:
-- already -- table, with wikilink components
-- Postcondition:
-- Returns table, with wikilink components extended
local r = already;
if not r.project then
local codes = { mediawiki = "mw",
wikibooks = "b",
wikidata = "d",
wikinews = "n",
wikipedia = "w",
wikiquote = "q",
wikisource = "s",
wikiversity = "v",
wikivoyage = "voy",
wiktionary = "wikt" };
local server = mw.site.server:gsub( "([/.])m%.",
"%1" )
:gsub( "%.beta%.wmflabs%.org$",
".org" );
local site = server:match( "[/.](%l+)%.org$" );
r.project = codes[ site ];
if r.project then
if not r.lang and
r.project ~= "mw" and r.project ~= "d" then
r.lang = server:match( "//(%l+)%." );
end
else
site = server:match( "//(%l+)%.wikimedia%.org$" );
if site == "commons" or site == "meta" then
r.project = site;
end
end
end
if r.project and r.ns and
( r.project == "commons" or
r.project == "d" or
r.project == "meta" or
r.project == "mw" ) then
r.language = true;
end
return r;
end -- farming()
local prefix = function ( ask )
-- Interprete prefix of language or project type
-- Precondition:
-- ask -- string, with presumable prefix
-- 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
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
-- Precondition:
-- attempt -- string, with presumable ANSI characters
-- alter -- string or nil, to use for spaces instead of %20
-- Postcondition:
-- Returns string, encoded
local k, s;
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( "%%%02X", 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
return r;
end -- WLink.ansiPercent()
function WLink.formatURL( adjust, assure )
-- Create bracketed link, if not yet
-- Precondition:
-- adjust -- string, with URL or domain/path or bracketed link
-- assure -- boolean, true for secure HTTP
-- 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 = "://" .. adjust;
if assure then
url = "s" .. url;
end
url = "http" .. url;
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;
end -- WLink.getArticleBase()
function WLink.getBaseTitle( attempt )
-- Retrieve last segment in subpage, no fragment
-- Precondition:
-- attempt -- string, with wikilink or page title
-- Postcondition:
-- Returns string, with identified segment, or all
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;
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 )
-- Retrieve media extension
-- Precondition:
-- attempt -- string, with wikilink (media link) or page title
-- if URL, PDF may be detected
-- Postcondition:
-- Returns string, with detected downcased media type
-- false if no extension found
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;
end -- WLink.getExtension()
function WLink.getFile( attempt )
-- Retrieve media page identifier
-- Precondition:
-- attempt -- string, with wikilink (media link) or page title
-- Postcondition:
-- Returns string, with detected file title
-- no namespace nor project
-- false if no file found
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;
end -- WLink.getFile()
function WLink.getFragment( attempt )
-- Retrieve fragment
-- Precondition:
-- attempt -- string, with presumable fragment
-- Postcondition:
-- Returns string, with detected fragment
-- false if no address found
local r = false;
local s, m = target( attempt );
if s then
local i = s:find( "#", 1, true );
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
r = false;
elseif m == 2 then
r = r:gsub( "%.(%x%x)", "%%%1" )
:gsub( "_", " " );
r = mw.uri.decode( r, "PATH" );
end
end
end
return r;
end -- WLink.getFragment()
function WLink.getLanguage( attempt )
-- Retrieve language project identifier
-- Precondition:
-- attempt -- string, with wikilink or page title
-- Postcondition:
-- Returns string, with detected downcased language identifier
-- false if no project language found
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;
end -- WLink.getLanguage()
function WLink.getLinktextProblem( attempt )
-- Which problem has this presumable link text?
-- Precondition:
-- attempt -- string, with presumable linktext
-- Postcondition:
-- Returns string, with error message, or false
local r;
if attempt:find( "]", 1, true ) then
r = "]";
elseif mw.text.unstripNoWiki( attempt ) ~= attempt then
r = "<nowiki>";
elseif attempt:find( "\n", 1, true ) then
r = "\n";
elseif mw.text.unstrip( attempt ) ~= attempt then
if not WLink.stripREF then
WLink.stripREF = string.format( "%c%c%c%c%s%c%c%c%c",
127, 39, 34, 96,
"UNIQ%-+ref%-%x+%-QINU",
96, 34, 39, 127 );
end
if mw.ustring.find( attempt, WLink.stripREF ) then
r = "<ref>";
end
end
if not r then
local i = attempt:find( "<", 1, true );
if i then
local s = mw.ustring.lower( attempt:sub( i ) );
local sign = true;
local skip;
while sign and not r do
skip, sign = s:match( "^([^<]*< *)(%l[%l%d]*)[ /]*.*>" );
if sign then
if htmlInline[ sign ] then
i = skip:len() + sign:len() + 1;
s = s:sub( i );
else
r = string.format( "<%s>", sign );
end
end
end -- while sign and not r
end
if not r then
local s = attempt .. " ";
if s:find( "ISBN ", 1, true ) then
r = s:match( "(ISBN %d[%-%d]+[%dxX])%W" );
end
if not r then
if s:find( "PMID ", 1, true ) then
r = s:match( "(PMID [1-9]%d*)%W" );
end
if not r then
if s:find( "RFC ", 1, true ) then
r = s:match( "(RFC [1-9]%d?%d?%d?)%W" );
end
end
end
end
end
return r or false;
end -- WLink.getLinktextProblem()
function WLink.getNamespace( attempt )
-- Retrieve namespace number
-- Precondition:
-- attempt -- string, with wikilink or page title
-- Postcondition:
-- Returns number, of detected namespace
-- false if no namespace found
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;
end -- WLink.getNamespace()
function WLink.getNamespaced( area, attempt )
-- Retrieve page in namespace
-- Precondition:
-- area -- string or number, with some namespace spec
-- attempt -- string, with wikilink or page title or page name
-- Postcondition:
-- Returns page prefixed by namespace,
-- false if invalid
local r = false;
local s = type( area );
local room;
if s == "string" then
room = mw.site.namespaces[ tonumber( area ) or area ];
elseif s == "number" then
room = mw.site.namespaces[ area ];
end
if room then
local m;
s, m = WLink.getTarget( attempt );
if not s then
s = attempt;
elseif m ~= 2 then
s = false;
end
if s then
local w = WLink.wikilink( s );
if w and not w.lang and not w.project and
( not w.ns or w.ns == room.id ) then
r = string.format( "%s:%s",
room.name, w.title );
end
end
end
return r;
end -- WLink.getNamespaced()
function WLink.getPlain( attempt )
-- Retrieve text with all links replaced by link titles
-- Precondition:
-- attempt -- string, with wikitext
-- Postcondition:
-- Returns string, with modified wikitext without links
local r = attempt;
local i = 1;
local j, k, n, lean, s, shift, span, space, suffix;
while ( true ) do
j = r:find( "[", i, true );
if j then
suffix = r:sub( j );
i = j + 1;
lean = ( r:byte( i, i ) == 91 );
if lean then
s, k, n = contentWikilink( suffix );
else
s, k, n = contentExtlink( suffix );
end
if s then
if k > 1 then
n = n - k;
i = j + k + 1;
j = i - 1;
suffix = r:sub( j );
end
if lean then
s, shift = extractWikilink( suffix );
if s then
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
else
span, shift = extractExtlink( suffix );
if span then
if not shift then
shift = "";
end
else
shift = string.format( "[%s]", s );
end
i = i - 1;
end
if j > 1 then
s = r:sub( 1, j - 1 );
else
s = "";
end
r = string.format( "%s%s%s",
s, shift, r:sub( n + i ) );
i = i + #shift;
else
break; -- while true
end
else
break; -- while true
end
end -- while true
return r;
end -- WLink.getPlain()
function WLink.getProject( attempt )
-- Retrieve wikifarm project identifier
-- Precondition:
-- attempt -- string, with wikilink or page title
-- Postcondition:
-- Returns string, with detected downcased project identifier
-- false if no project identifier found
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;
end -- WLink.getProject()
function WLink.getTalkPage( attempt )
-- Retrieve talk page name for attempt, or that page name itself
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns string or false
local r = false;
local s, m = WLink.getTarget( attempt );
if m ~= 2 and attempt then
s = mw.text.trim( attempt );
end
if s and s ~= "" then
local w = mw.title.new( s );
if w then
w = w.talkPageTitle;
if w then
r = w.prefixedText;
end
end
end
return r;
end -- WLink.getTalkPage()
function WLink.getTarget( attempt )
-- Retrieve first target (wikilink or URL)
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns string, number
-- string, with first detected link target
-- number, with number of brackets, if found
-- false if nothing found
local r1 = false;
local r2 = false;
local i = attempt:find( "[", 1, true );
if i then
local m;
r1 = attempt:sub( i );
if r1:byte( 2, 2 ) == 91 then
m = 2;
r1 = extractWikilink( r1 );
else
m = 1;
r1 = extractExtlink( r1 );
end
if r1 then
r2 = m;
end
else
r1 = attempt:match( "%A?([hf]t?tps?://%S+)%s?" );
if r1 then
if utilURL().isResourceURL( r1 ) then
r2 = 0;
else
r1 = false;
end
else
r1 = false;
end
end
return r1, r2;
end -- WLink.getTarget()
function WLink.getTargetPage( attempt )
-- Retrieve first target page (page name or URL of page)
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns string, with first detected linked page
-- false if nothing found
local r1, r2 = WLink.getTarget( attempt );
if r1 then
local i = r1:find( "#", 1, true );
if i then
if i == 1 then
r1 = false;
else
r1 = mw.text.trim( r1:sub( 1, i - 1 ) );
end
end
end
return r1, r2;
end -- WLink.getTargetPage()
function WLink.getTitle( attempt )
-- Retrieve first link title (wikilink or URL), or wikilink target
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns string, with first detected link target
-- false if nothing found
local r = false;
local i = attempt:find( "[", 1, true );
if i then
local s1, s2;
r = attempt:sub( i );
if r:byte( 2, 2 ) == 91 then
s1, s2 = extractWikilink( r );
if s2 then
r = s2;
else
r = s1;
end
else
s1, r = extractExtlink( r );
end
end
return r;
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 service = attempt;
local show;
if #attempt == #site then
site = site .. "/";
end
show = URLutil.getTop3domain( "//" .. site );
if show then
local scan = "[%./](%a[%a%%%-]*%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:sub( 2 ), 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
if not service:match( "^[a-z:]*//.+/" ) then
service = service .. "/";
end
r = string.format( "[%s %s]", service, show );
else
r = attempt;
end
return r;
end -- WLink.getWeblink()
function WLink.getWikilink( attempt, appear )
-- Retrieve bracketed link from text
-- Precondition:
-- attempt -- string, with current target, or plain
-- appear -- string, with link title, or nil
-- Postcondition:
-- Returns string, with first detected link target
-- false if nothing found
local r = WLink.pageTarget( attempt );
if r then
if appear then
local show = WLink.getEscapedTitle( appear );
if show ~= r and show ~= "" then
r = string.format( "%s|%s", r, show );
end
end
r = string.format( "[[%s]]", r );
end
return r;
end -- WLink.getWikilink()
function WLink.isBracketedLink( attempt )
-- Does attempt match a bracketed link?
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns boolean
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;
end -- WLink.isBracketedLink()
function WLink.isBracketedURL( attempt )
-- Does attempt match a bracketed URL?
-- Precondition:
-- 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:
-- 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()
function WLink.isExternalLink( attempt )
-- Does attempt match an external link?
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns boolean
local s, r = WLink.getTarget( attempt );
if r then
r = ( r < 2 );
end
return r;
end -- WLink.isExternalLink()
function WLink.isInterlanguage( attempt )
-- Does attempt match an interlanguage link?
-- 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.lang and not w.project and not w.lead
and w.title ~= "" then
r = true;
end
end
return r;
end -- WLink.isInterlanguage()
function WLink.isInterwiki( attempt )
-- Does attempt match an interwiki link within wikifarm?
-- 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.lang or w.project ) and w.title ~= "" then
r = true;
end
end
return r;
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()
function WLink.isTalkPage( attempt )
-- Does attempt describe a talk page?
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns boolean
local r = false;
local s, m = WLink.getTarget( attempt );
if m ~= 2 and attempt then
s = mw.text.trim( attempt );
end
if s and s ~= "" then
local w = mw.title.new( s );
if w then
r = w.isTalkPage;
end
end
return r;
end -- WLink.isTalkPage()
function WLink.isTitledLink( attempt )
-- Does attempt match a titled link?
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns boolean
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;
end -- WLink.isTitledLink()
function WLink.isValidLink( attempt )
-- Does attempt match a link?
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns boolean
local u, r = WLink.getTarget( attempt );
if r then
if r < 2 then
if u:find( "''", 1, true ) then
r = false;
else
r = true;
end
else
r = true;
end
end
return r;
end -- WLink.isValidLink()
function WLink.isValidLinktext( attempt, allow )
-- Is attempt a plain inline text?
-- Precondition:
-- attempt -- string, with presumable linktext
-- allow -- boolean or nil, if multiline permitted
-- Postcondition:
-- Returns boolean
local s;
if allow and s:find( "\n", 1, true ) then
s = attempt:gsub( "\n", " " );
else
s = attempt;
end
return not WLink.getLinktextProblem( s );
end -- WLink.isValidLinktext()
function WLink.isWikilink( attempt )
-- Does attempt match a wikilink?
-- Precondition:
-- attempt -- string, with presumable link somewhere
-- Postcondition:
-- Returns boolean
local s, m = WLink.getTarget( attempt );
return ( m == 2 );
end -- WLink.isWikilink()
function WLink.pageLink( attempt, appear, assure )
-- Create safely standardized wikilink target of a page
-- attempt -- string, with presumable link
-- appear -- string or true or nil, with link title
-- assure -- string or nil, shield against wiki template syntax
-- "URL" or "WIKI"
-- Postcondition:
-- Returns string with link target
local r = WLink.pageTarget( attempt, assure );
if appear then
local show;
if type( appear ) == "string" then
show = appear;
else
show = attempt;
end
r = string.format( "%s|%s", r, show );
end
return r;
end -- WLink.pageLink()
function WLink.pageTarget( attempt, assure )
-- Create standardized wikilink target of a page
-- Precondition:
-- attempt -- string, with presumable link
-- expected to be enclosed in "[[" "]]"
-- else wikilink
-- table, of assignments with { type, value }
-- type is one of "lead",
-- "project", "lang",
-- "ns", "space", "title"
-- assure -- string or nil, shield against wiki template syntax
-- "URL" or "WIKI"
-- Postcondition:
-- Returns string with link target
local p = type( attempt );
local s = assure;
local r;
if p == "string" then
p = WLink.wikilink( attempt );
elseif p == "table" then
p = attempt;
else
p = false;
end
if p then
local site = p.project;
local slang = p.lang;
local lead;
if p.title:sub( 1, 1 ) == "#" then
p.title = mw.title.getCurrentTitle().text + p.title;
end
if p.ns then
if not slang then
p = farming( p );
end
if p.lang and
p.lang ~= mw.language.getContentLanguage():getCode() then
p.language = true;
end
if p.language then
p.space = mw.site.namespaces[ p.ns ].canonicalName;
end
lead = ( p.ns == 6 or p.ns == 14 );
end
if slang then
lead = true;
end
if s == "WIKI" then
if not site and
( lead or
( not p.space and
p.title and p.title:match( "^[*;]" ) ) ) then
p = farming( p );
site = p.project;
slang = p.lang;
end
s = false;
end
if site then
r = site .. ":";
elseif lead then
r = ":";
else
r = "";
end
if slang then
r = string.format( "%s%s:", r, slang );
end
if p.space then
r = string.format( "%s%s:", r, p.space );
end
if p.title then
r = r .. p.title;
end
if r == "" then
r = false;
end
end
if not r then
p = { lang = mw.language.getContentLanguage():getCode() };
if s == "WIKI" then
r = WLink.pageTarget( p, s );
s = false;
else
r = string.format( ":%s:", p.lang );
end
end
if s == "URL" and r:match( "^[*#;:]" ) then
r = mw.uri.encode( r:sub( 1, 1 ) ) .. r:sub( 2 );
end
return r;
end -- WLink.pageTarget()
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 or "" );
local got, i, n, r;
if not s then
s = attempt;
end
if s:find( "%", 1, true ) then
s = mw.uri.decode( s, "PATH" );
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 = "" };
while ( got[ 1 ] == "" ) do
r.lead = true;
table.remove( got, 1 );
n = n - 1;
end -- while got[ 1 ] == ""
if n > 4 then
k = 4;
elseif n > 1 then
k = n - 1;
else
k = 1;
end
j = k;
for i = 1, j do
s = mw.text.trim( got[ i ] );
if s ~= "" then
o = mw.site.namespaces[ s ];
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 ] );
if o then
if r[ o ] then
k = i;
break; -- for i
else
if i >= k then
k = i + 1;
end
r[ o ] = v;
end
else
if i == 1 and r.ns then
r.ns = false;
r.space = false;
end
k = i;
break; -- for i
end
end -- for i
if k > 0 then
for i = k, n do
r.title = r.title .. got[ i ];
if i < n then
r.title = r.title .. ":";
end
end -- for i
end
end
r.title = cleanWikilink( r.title );
if r.lead and
( r.project or
( not r.lang and r.ns ~= 6 and r.ns ~= 14 ) ) then
r.lead = false;
end
return r;
end -- WLink.wikilink()
Failsafe.failsafe = function ( atleast )
-- Retrieve versioning and check for compliance
-- Precondition:
-- atleast -- string, with required version or "wikidata" or "~"
-- or false
-- Postcondition:
-- Returns string -- with queried version, also if problem
-- false -- if appropriate
local last = ( atleast == "~" );
local since = atleast;
local r;
if last or since == "wikidata" then
local item = Failsafe.item;
since = false;
if type( item ) == "number" and item > 0 then
local ent = mw.wikibase.getEntity( string.format( "Q%d",
item ) );
if type( ent ) == "table" then
local vsn = ent:formatPropertyValues( "P348" );
if type( vsn ) == "table" and
type( vsn.value ) == "string" and
vsn.value ~= "" then
if last and vsn.value == Failsafe.serial then
r = false;
else
r = vsn.value;
end
end
end
end
end
if type( r ) == "nil" then
if not since or since <= Failsafe.serial then
r = Failsafe.serial;
else
r = false;
end
end
return r;
end -- Failsafe.failsafe()
local function Template( frame, action, leave, lone )
-- Run actual code from template transclusion
-- Precondition:
-- frame -- object
-- action -- string, with function name
-- leave -- true: keep whitespace around
-- lone -- true: permit call without parameters
-- Postcondition:
-- Return string; might be error message
local lucky = true;
local s = false;
local r = false;
local safe, space;
for k, v in pairs( frame.args ) do
if k == 1 then
if leave then
s = v;
else
s = mw.text.trim( v );
end
elseif ( k == 2 and
( action == "getNamespaced" or
action == "getWikilink" or
action == "pageLink" ) ) or
( k == "space" and action == "ansiPercent" ) then
v = mw.text.trim( v );
if v ~= "" then
space = v;
end
elseif k == "safe" and action == "pageLink" then
v = mw.text.trim( v );
if v ~= "" then
safe = v;
end
elseif k == "lines" and action == "isValidLinktext" then
space = ( k == "1" );
elseif k ~= "template" then
lucky = false;
if r then
r = r .. "|";
else
r = "Unknown parameter: ";
end
r = string.format( "%s%s=", r, k );
end
end -- for k, v
if lucky then
if s or lone then
lucky, r = pcall( WLink[ action ], s, space, safe );
else
r = "Parameter missing";
lucky = false;
end
end
if lucky then
if type( r ) == "boolean" then
if r then
r = "1";
else
r = "";
end
end
else
local e = mw.html.create( "span" );
r = tostring( e:addClass( "error" )
:wikitext( r ) );
end
return r;
end -- Template()
-- Export
local p = { };
p.ansiPercent = function ( frame )
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
p.getBaseTitle = function ( frame )
return Template( frame, "getBaseTitle" );
end
p.getEscapedTitle = function ( frame )
return Template( frame, "getEscapedTitle" );
end
p.getExtension = function ( frame )
return Template( frame, "getExtension" );
end
p.getFile = function ( frame )
return Template( frame, "getFile" );
end
p.getFragment = function ( frame )
return Template( frame, "getFragment" );
end
p.getInterwiki = function ( frame )
return Template( frame, "getInterwiki" );
end
p.getLanguage = function ( frame )
return Template( frame, "getLanguage" );
end
p.getLinktextProblem = function ( frame )
return Template( frame, "getLinktextProblem" );
end
p.getNamespace = function ( frame )
return tostring( Template( frame, "getNamespace" ) );
end
p.getNamespaced = function ( frame )
return tostring( Template( frame, "getNamespaced" ) );
end
p.getPlain = function ( frame )
return Template( frame, "getPlain" );
end
p.getProject = function ( frame )
return Template( frame, "getProject" );
end
p.getTalkPage = function ( frame )
return Template( frame, "getTalkPage" );
end
p.getTarget = function ( frame )
return Template( frame, "getTarget" );
end
p.getTargetPage = function ( frame )
return Template( frame, "getTargetPage" );
end
p.getTitle = function ( frame )
return Template( frame, "getTitle" );
end
p.getWeblink = function ( frame )
return Template( frame, "getWeblink" );
end
p.getWikilink = function ( frame )
return Template( frame, "getWikilink" );
end
p.isBracketedLink = function ( frame )
return Template( frame, "isBracketedLink" );
end
p.isBracketedURL = function ( frame )
return Template( frame, "isBracketedURL" );
end
p.isCategorization = function ( frame )
return Template( frame, "isCategorization" );
end
p.isExternalLink = function ( frame )
return Template( frame, "isExternalLink" );
end
p.isInterlanguage = function ( frame )
return Template( frame, "isInterlanguage" );
end
p.isInterwiki = function ( frame )
return Template( frame, "isInterwiki" );
end
p.isMedia = function ( frame )
return Template( frame, "isMedia" );
end
p.isTalkPage = function ( frame )
return Template( frame, "isTalkPage" );
end
p.isTitledLink = function ( frame )
return Template( frame, "isTitledLink" );
end
p.isValidLink = function ( frame )
return Template( frame, "isValidLink" );
end
p.isValidLinktext = function ( frame )
return Template( frame, "isValidLinktext" );
end
p.isWeblink = function ( frame )
return Template( frame, "isWeblink" );
end
p.isWikilink = function ( frame )
return Template( frame, "isWikilink" );
end
p.pageLink = function ( frame )
return Template( frame, "pageLink" );
end
p.failsafe = function ( frame )
local s = type( frame );
local since;
if s == "table" then
since = frame.args[ 1 ];
elseif s == "string" then
since = frame;
end
if since then
since = mw.text.trim( since );
if since == "" then
since = false;
end
end
return Failsafe.failsafe( since ) or "";
end -- p.failsafe
p.WLink = function ()
return WLink;
end
return p;