Module:Delink and Module:Protection banner: Difference between pages

From Frontierpedia, the Microsoft Agent encyclopedia
(Difference between pages)
en>Mr. Stradivarius
(full delete character handling in urls)
 
en>Mr. Stradivarius
(various category table fixes)
 
Line 1: Line 1:
-- This module de-links most wikitext.
-- This module implements {{pp-meta}} and its daughter templates such as
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.


p = {}
local categories = {
['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages',
['edit-semi-project-all-all'] = 'Semi-protected project pages',
['edit-semi-file-all-all'] = 'Semi-protected images',
['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates',
['edit-semi-portal-all-all'] = 'Semi-protected portals',
['edit-semi-talk-all-all'] = 'Semi-protected talk pages',
['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism',
['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages',
['edit-full-file-all-all'] = 'Protected images',
['edit-full-project-all-all'] = 'Protected project pages',
['edit-full-template-all-all'] = 'Wikipedia protected templates',
['edit-full-talk-all-all'] = 'Protected talk pages',
['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism',
['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute',
['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute',
['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute',
['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages',
['move-full-project-all-all'] = 'Wikipedia move-protected project pages',
['move-full-portal-all-all'] = 'Wikipedia move-protected portals',
['move-full-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism',
['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates',
['move-full-template-all-all'] = 'Wikipedia move-protected templates',
['edit-all-template-all-all'] = 'Wikipedia protected templates',
['move-full-portal-all-all'] = 'Wikipedia move-protected portals',
['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users',
['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users',
['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people',
['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people',
['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people',
['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people',
['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages',
['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages',
['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages',
['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages',
['all-all-all-all-all'] = 'Wikipedia protected pages',
['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories',
['edit-full-category-all-all'] = 'Wikipedia protected categories',
['move-full-all-all-all'] = 'Wikipedia move-protected pages',
['all-all-all-office-all'] = 'Wikipedia Office-protected pages',
['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)',
['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)',
}


local function delinkReversePipeTrick(s)
local nskeys = {
    if mw.ustring.match(s, "^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes.
[2] = 'user',
        return s
[3] = 'user',
    else
[4] = 'project',
        return mw.ustring.match(s, "%[%[|(.*)%]%]")
[6] = 'file',
    end
[10] = 'template',
end
[12] = 'project',
[14] = 'category',
[100] = 'portal',
}
 
local error_categories = {
incorrect = 'Wikipedia pages with incorrect protection templates',
no_expiry = 'Wikipedia protected pages without expiry',
create = 'Wikipedia pages tagged as create-protected',
template = 'Wikipedia template-protected pages other than templates and modules'
}
 
local template_types = {
vandalism = {
namespaces = false, -- defaults to all namespaces
editLevels = false, -- all edit protection levels
moveLevels = false, -- all move protection levels
createLevels = false, -- all create protection levels
header = false,
reason = 'due to [[Wikipedia:Vandalism|vandalism]]',
icon_reason = 'due to vandalism',
}
}
 
--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------


local function delinkPipeTrick(s)
local getArgs = require('Module:Arguments').getArgs
    local linkarea, display = "", ""
local yesno = require('Module:Yesno')
    -- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]].
   
    -- First, remove the text before the first colon, if any.
    if mw.ustring.match(s, ":") then
        s = mw.ustring.match(s, "%[%[.-:(.*)|%]%]")
    -- If there are no colons, grab all of the text apart from the square brackets and the pipe.
    else
        s = mw.ustring.match(s, "%[%[(.*)|%]%]")
    end
   
    -- Next up, brackets and commas.
    if mw.ustring.match(s, "%(.-%)$") then -- Brackets trump commas.
        s = mw.ustring.match(s, "(.-) ?%(.-%)$")
    elseif mw.ustring.match(s, ",") then -- If there are no brackets, display only the text before the first comma.
        s = mw.ustring.match(s, "(.-),.*$")
    end
    return s
end


local function delinkWikilink(s)
local p = {}
    -- Deal with the reverse pipe trick.
    if mw.ustring.match(s, "%[%[|") then
        return delinkReversePipeTrick(s)
    end
   
    -- Check for bad titles. To do this we need to find the
    -- title area of the link, i.e. the part before any pipes.
    local titlearea
    if mw.ustring.match(s, "|") then -- Find if we're dealing with a piped link.
        titlearea = mw.ustring.match(s, "^%[%[(.-)|.*%]%]")
    else
        titlearea = mw.ustring.match(s, "^%[%[(.-)%]%]")
    end
    -- If the title area is not a valid title, return the whole string.
    -- Use pcall in case we're over the expensive functions limit.
    local goodcall, title = pcall(mw.title.new, titlearea, "")
    if not (goodcall and title) then
        return s
    end
    -- Check for characters that are allowed in titles but not in wikilinks.
    local other_invalid_link_strings = { '�' }
    for i,v in ipairs(other_invalid_link_strings) do
        if mw.ustring.match(titlearea, v) then
            return s
        end
    end
   
    -- Check for categories, interwikis, and files.
    local colonprefix = mw.ustring.match(s, "%[%[(.-):.*%]%]") or "" -- Get the text before the first colon.
    if mw.language.isKnownLanguageTag(colonprefix)
    or mw.ustring.match(colonprefix, "^[Cc]ategory$")
    or mw.ustring.match(colonprefix, "^[Ff]ile$")
    or mw.ustring.match(colonprefix, "^[Ii]mage$") then
        return ""
    end
   
    -- Remove the colon if the link is using the [[Help:Colon trick]].
    if mw.ustring.match(s, "%[%[:") then
        s = "[[" .. mw.ustring.match(s, "%[%[:(.*%]%])")
    end
   
    -- Deal with links using the [[Help:Pipe trick]].
    if mw.ustring.match(s, "^%[%[[^|]*|%]%]") then
        return delinkPipeTrick(s)
    end
   
    -- Find the display area of the wikilink
    local display
    if mw.ustring.match(s, "|") then -- Find if we're dealing with a piped link.
        display = mw.ustring.match(s, "^%[%[.-|(.+)%]%]")
        -- Remove new lines from the display of multiline piped links,
        -- where the pipe is before the first new line.
        display = mw.ustring.gsub(display, "\n", "")
    else
        display = mw.ustring.match(s, "^%[%[(.-)%]%]")
    end


    return display
function p.main(frame)
end
-- Get data
local args = getArgs(frame)
local title = p.getTitle(args.page)
local protType, protLevel = p.getProtectionStatus(title)
local namespace = p.getNamespace(title)
local expiry = p.getExpiry(args.expiry)
local reason = p.getReason(args.reason)


local function delinkURL(s)
-- Sort categories and build a category link with the best match
    -- Assume we have already delinked internal wikilinks, and that
categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason)
    -- we have been passed some text between two square brackets [foo].
local category = categories[1].name
   
category = string.format('[[Category:%s]]', category)
    -- Check if the text has a valid URL prefix and at least one valid URL character.
    local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"}
    local url_prefix
    for i,v in ipairs(valid_url_prefixes) do
        if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then
            url_prefix = v
            break
        end
    end
   
    -- Get display text
    if not url_prefix then
        return s
    else
        s = mw.ustring.match(s, "^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket.
        s = mw.ustring.match(s, '^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ).
        s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off.
        return s
    end
end


local function delinkLinkClass(s, pattern, delinkFunction)
-- Find whether we are small or not and output a padlock or a banner as appropriate
    if not type(s) == "string" then
local isSmall = yesno(args.small, true)
        error("Attempt to de-link non-string input.", 2)
if isSmall then
    end
return p.exportPadlock()
    if not ( type(pattern) == "string" and mw.ustring.sub(pattern, 1, 1) == "^" ) then
else
        error('Invalid pattern detected. Patterns must begin with "^".', 2)
return p.exportBanner()
    end
end
    -- Iterate over the text string, and replace any matched text. using the
    -- delink function. We need to iterate character by character rather
    -- than just use gsub, otherwise nested links aren't detected properly.
    local result = ""
    while mw.ustring.len(s) > 0 do
        -- Replace text using one iteration of gsub.
        s = mw.ustring.gsub(s, pattern, delinkFunction, 1)
        -- Append the left-most character to the result string.
        result = result .. mw.ustring.sub(s, 1, 1)
        s = mw.ustring.sub(s, 2, -1)
    end
    return result
end
end


local function _delink(args)
function p.parseNamespace(ns)
    local text = args[1] or ""
-- The ns variable is the namespace number.
    if args.stripmarkers == "yes" then
if not ns or type(ns) ~= 'number' then
        -- Remove strip markers. Only use this if you know what you are doing!
return 'all'
        -- In most situations this is not a good idea. See [[Help:Strip markers]].
end
        text = mw.ustring.gsub(text, "UNIQ.-QINU", "")
local nskey = nskeys[ns]
    end
if not nskey and ns % 2 == 1 then
    if not (args.comments == "no") then
nskey = 'talk'
        text = mw.ustring.gsub(text, "<!%-%-.-%-%->", "") -- Remove html comments.
elseif not nskey then
    end
nskey = 'all'
    if not (args.wikilinks == "no") then
end
        text = delinkLinkClass(text, "^%[%[.-%]%]", delinkWikilink) -- De-link wikilinks.
return nskey
    end
    if not (args.urls == "no") then
        text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs.
    end
    if not (args.whitespace == "no") then
        text = mw.ustring.gsub(text, "[ \t]+", " ") -- Remove extra tabs and spaces.
        text = mw.ustring.gsub(text, "([^\n])(\n)([^\n])", "%1 %3") -- Remove single new lines (but not double new lines).
    end
    return text
end
end


function p.delink(frame)
function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry)
    local args
-- Preprocess parameters
    if frame == mw.getCurrentFrame() then
cats = cats or categories
        -- We're being called via #invoke. If the invoking template passed any args, use
protType = protType or 'all'
        -- them. Otherwise, use the args that were passed into the template.
protLevel = protLevel or 'all'
        args = frame:getParent().args
namespace = p.parseNamespace(namespace)
        for k, v in pairs(frame.args) do
reason = reason or 'all'
            args = frame.args
if not expiry then
            break
expiry = 'all'
        end
elseif expiry ~= 'indef' then
    else
expiry = 'temp'
        -- We're being called from another module or from the debug console, so assume
end
        -- the args are passed in directly.
        args = frame
-- Define the key table and the order to test it in.
    end
-- This part is a little like playing regex golf - we have to make up a new
    return _delink(args)
-- rule for every idiosyncracy that was in the old template system.
end
local keyTable = {protType, protLevel, namespace, reason, expiry}
local attemptOrder = {
--  type, level, ns, reason, expiry
{true, true, true, true, true},    -- 1
{true, true, true, true, false},    -- 2
{true, true, true, false, true},    -- 3
{true, true, false, true, true},    -- 4
{true, true, true, false, false},  -- 5
{true, true, false, true, false},  -- 6
{true, true, false, false, true},  -- 7
{true, true, false, false, false},  -- 8
{true, false, false, false, false}, -- 9
{false, false, false, false, false} -- 10
}
if reason ~= 'vandalism' then
attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3]
attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5]
end
-- Try successively generic matches until we run out of key combinations
for i, t in ipairs(attemptOrder) do
local key = {}
for j, useKeyTable in ipairs(t) do
if useKeyTable then
key[j] = keyTable[j]
else
key[j] = 'all'
end
end
key = table.concat(key, '-')
mw.log(key) -- for debugging
local attempt = cats[key]
if attempt then
return attempt
end
end
error('No category match found; please define the category for key "all-all-all-all-all"')
end


return p
return p

Revision as of 01:36, 5 March 2014

Documentation for this module may be created at Module:Protection banner/doc

-- This module implements {{pp-meta}} and its daughter templates such as
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.

local categories = {
	['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages',
	['edit-semi-project-all-all'] = 'Semi-protected project pages',
	['edit-semi-file-all-all'] = 'Semi-protected images',
	['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates',
	['edit-semi-portal-all-all'] = 'Semi-protected portals',
	['edit-semi-talk-all-all'] = 'Semi-protected talk pages',
	['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism',
	['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages',
	['edit-full-file-all-all'] = 'Protected images',
	['edit-full-project-all-all'] = 'Protected project pages',
	['edit-full-template-all-all'] = 'Wikipedia protected templates',
	['edit-full-talk-all-all'] = 'Protected talk pages',
	['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism',
	['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute',
	['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute',
	['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute',
	['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages',
	['move-full-project-all-all'] = 'Wikipedia move-protected project pages',
	['move-full-portal-all-all'] = 'Wikipedia move-protected portals',
	['move-full-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism',
	['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates',
	['move-full-template-all-all'] = 'Wikipedia move-protected templates',
	['edit-all-template-all-all'] = 'Wikipedia protected templates',
	['move-full-portal-all-all'] = 'Wikipedia move-protected portals',
	['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users',
	['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users',
	['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people',
	['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people',
	['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people',
	['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people',
	['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages',
	['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages',
	['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages',
	['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages',
	['all-all-all-all-all'] = 'Wikipedia protected pages',
	['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories',
	['edit-full-category-all-all'] = 'Wikipedia protected categories',
	['move-full-all-all-all'] = 'Wikipedia move-protected pages',
	['all-all-all-office-all'] = 'Wikipedia Office-protected pages',
	['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)',
	['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)',
}

local nskeys = {
	[2] = 'user',
	[3] = 'user',
	[4] = 'project',
	[6] = 'file',
	[10] = 'template',
	[12] = 'project',
	[14] = 'category',
	[100] = 'portal',
}

local error_categories = {
	incorrect = 'Wikipedia pages with incorrect protection templates',
	no_expiry = 'Wikipedia protected pages without expiry',
	create = 'Wikipedia pages tagged as create-protected',
	template = 'Wikipedia template-protected pages other than templates and modules'
}

local template_types = {
	vandalism = {
		namespaces = false, -- defaults to all namespaces
		editLevels = false, -- all edit protection levels
		moveLevels = false, -- all move protection levels
		createLevels = false, -- all create protection levels
		header = false,
		reason = 'due to [[Wikipedia:Vandalism|vandalism]]',
		icon_reason = 'due to vandalism',
	}
}

--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------

local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')

local p = {}

function p.main(frame)
	-- Get data
	local args = getArgs(frame)
	local title = p.getTitle(args.page)
	local protType, protLevel = p.getProtectionStatus(title)
	local namespace = p.getNamespace(title)
	local expiry = p.getExpiry(args.expiry)
	local reason = p.getReason(args.reason)

	-- Sort categories and build a category link with the best match
	categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason)
	local category = categories[1].name
	category = string.format('[[Category:%s]]', category)

	-- Find whether we are small or not and output a padlock or a banner as appropriate
	local isSmall = yesno(args.small, true)
	if isSmall then
		return p.exportPadlock()
	else
		return p.exportBanner()
	end
end

function p.parseNamespace(ns)
	-- The ns variable is the namespace number.
	if not ns or type(ns) ~= 'number' then
		return 'all'
	end
	local nskey = nskeys[ns]
	if not nskey and ns % 2 == 1 then
		nskey = 'talk'
	elseif not nskey then
		nskey = 'all'
	end
	return nskey
end

function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry)
	-- Preprocess parameters
	cats = cats or categories
	protType = protType or 'all'
	protLevel = protLevel or 'all'
	namespace = p.parseNamespace(namespace)
	reason = reason or 'all'
	if not expiry then
		expiry = 'all'
	elseif expiry ~= 'indef' then
		expiry = 'temp'
	end
	
	-- Define the key table and the order to test it in.
	-- This part is a little like playing regex golf - we have to make up a new
	-- rule for every idiosyncracy that was in the old template system.
	local keyTable = {protType, protLevel, namespace, reason, expiry}
	local attemptOrder = {
	--   type, level, ns, reason, expiry
		{true, true, true, true, true},     -- 1
		{true, true, true, true, false},    -- 2
		{true, true, true, false, true},    -- 3
		{true, true, false, true, true},    -- 4
		{true, true, true, false, false},   -- 5
		{true, true, false, true, false},   -- 6
		{true, true, false, false, true},   -- 7
		{true, true, false, false, false},  -- 8
		{true, false, false, false, false}, -- 9
		{false, false, false, false, false} -- 10
	}
	if reason ~= 'vandalism' then
		attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3]
		attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5]
	end
	
	-- Try successively generic matches until we run out of key combinations
	for i, t in ipairs(attemptOrder) do
		local key = {}
		for j, useKeyTable in ipairs(t) do
			if useKeyTable then
				key[j] = keyTable[j]
			else
				key[j] = 'all'
			end
		end
		key = table.concat(key, '-')
		mw.log(key) -- for debugging
		local attempt = cats[key]
		if attempt then
			return attempt
		end
	end
	error('No category match found; please define the category for key "all-all-all-all-all"')
end			

return p