Permanently protected module
From Wikipedia, the free encyclopedia


-- Creates a slideshow gallery where the order is randomised. Intended for use on portal pages.

local p = {}

local excerptModule =  require('Module:Excerpt/portals')

local randomModule = require('Module:Random')



function cleanupArgs(argsTable)

	local cleanArgs = {}

	for key, val in pairs(argsTable) do

		if type(val) == 'string' then

			val = val:match('^%s*(.-)%s*$')

			if val ~= '' then

				cleanArgskey = val

			end

		else

			cleanArgskey = val

		end

	end

	return cleanArgs

end



function normaliseCssMeasurement(input)

	local suffix = string.reverse(string.sub(string.reverse(input), 1, 2))

	if ( suffix == 'px' ) or ( suffix == 'em' ) or ( string.sub(suffix, 2, 2) == '%' ) then

		return input

	else

		return input .. 'px'

	end

end



function isDeclined(val)

	if not val then return false end

	local declinedWords = " decline declined exclude excluded false none not no n off omit omitted remove removed "

	return string.find(declinedWords , ' '..val..' ', 1, true ) and true or false

end



function makeOutput(galleryLines, maxWidth, containerClassName, nonRandom)

	local randomiseArgs = {	't' = galleryLines }

	local sortedLines = nonRandom and galleryLines or randomModule.main('array', randomiseArgs)

	for i = 1, #sortedLines do

		-- insert a switcher-label span just after the first pipe, which should ideally be the caption

		sortedLinesi = sortedLinesi]:gsub(

			"|",

			'|<span class="switcher-label" style="display:none"><span class="randomSlideshow-sr-only">Image ' .. tostring(i) .. '</span></span>',

			1)

	end

	local galleryContent = table.concat(sortedLines, '\n')

	local output = '<div class="' .. containerClassName .. '" style="max-width:' .. normaliseCssMeasurement(maxWidth) .. '; margin:-4em auto;"><div class="nomobile"><!--intentionally empty on desktop, and is not present on mobile website (outside template namesapce)--></div>'

		.. mw.getCurrentFrame():extensionTag({name="gallery",content=galleryContent,args={mode="slideshow",class="switcher-container"}}) .. '</div>'

	return output

end



function makeGalleryLine(file, caption, credit)

	local title = mw.title.new(file, "File" )

	if not title

	then

		return "File:Blank.png|{{Error|File [[:File:" .. file .. "]] does not exist.}}"

	end

	local creditLine = ( credit and '<p><span style="font-size:88%">' .. credit .. '</span></p>' or '' )

	return title.prefixedText .. '|' .. ( caption or '' ) .. creditLine

end



function makeGalleryLinesTable(args)

	local galleryLinesTable = {}

	local i = 1

	while argsi do

		table.insert(galleryLinesTable, makeGalleryLine(argsi], argsi+1], args'credit' .. (i+1)/2]))

		i = i + 2

	end

	return galleryLinesTable 

end



function hasCaption(line)

	local caption = mw.ustring.match(line, ".-|(.*)")

	-- require caption to exist with more than 5 characters (avoids sizes etc being mistaken for captions)

	return caption and #caption>5 and true or false

end



function extractGalleryFiles(wikitext)

	local gallery = mw.ustring.match(wikitext, '<gallery.->%s*(.-)%s*</gallery>')

	if not gallery then

		return false

	end

	return mw.text.split(gallery, '%c')

end



function extractRegularFiles(wikitext)

	local files = {}

	local frame = mw.getCurrentFrame()

	local expand = function(template)

		return frame:preprocess(template)

	end

	for file in mw.ustring.gmatch(wikitext, '%b[]' ) do

		-- remove keywords that don't work in galleries

		file = mw.ustring.gsub(file, '|%s*thumb%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*thumbnail%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*border%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*left%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*right%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*center%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*centre%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*none%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*baseline%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*sub%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*super%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*top%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*text%-top%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*bottom%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*text%-bottom%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*framed?%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*frameless%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*upright%s*[0-9%.]*%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*upright%s*=.-([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*link%s*=.-([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*lang%s*=.-([|%]])', '%1')

		-- remove spaces prior to captions (which cause pre-formatted text)

		file = mw.ustring.gsub(file, '|%s*', '|')

		-- remove sizes, which sometimes get mistaken for captions

		file = mw.ustring.gsub(file, '|%s*%d*x?%d+%s*px%s*([|%]])', '%1')

		-- remove linebreaks

		file = mw.ustring.gsub(file, '\n\n', '<br>')

		file = mw.ustring.gsub(file, '\n', '')

		-- remove surrounding square brackets

		file = mw.ustring.gsub(file, '^%[%[', '')

		file = mw.ustring.gsub(file, '%]%]$', '')

		table.insert(files, file)

	end

	return files

end



--Central function for fixing issues that could occur in both gallery-fetched and file-fetched files

local function doubleCheck(file)

	-- disable pipes in wikilinks

	file = file:gsub(

		"%[%[([^%]]-)|(.-)]]",

		"[[%1__PIPE__%2]]")

	-- move any alt parameter to the end to avoid putting the switcher in too early and causing a linter error

	file = file:gsub(

		"^(.+)(|alt=[^|]*)(.*)$",

		"%1%3%2")

	-- bring back pipes in wikilinks

	file = file:gsub(

		"%[%[(.-)__PIPE__(.-)]]",

		"[[%1|%2]]")

	return file

end



function makeTranscludedGalleryLinesTables(args)

	local namespaceNumber = function(pagetitle)

		local titleObject = mw.title.new(pagetitle)

		return titleObject and titleObject.namespace

	end

	local lines = {}

	local i = 1

	while argsi do

		if namespaceNumber(argsi]) == 6 then -- file namespace

			-- args[i] is either just the filename, or uses syntax File:Name.jpg##Caption##Credit

			local parts = mw.text.split(argsi], '##%s*')

			local filename = parts1

			local caption = args'caption'..i or parts2 or false

			local credit = args'credit'..i or parts3 or false

			local line = makeGalleryLine(filename, caption, credit)

			table.insert(lines, line)

		else

			local content, pagename = excerptModule.getContent(argsi])

			if not pagename then

				return error('Cannot read a valid page for "' .. argsi .. '"', 0)

			elseif not content then

				return error('No content found on page "' .. argsi .. '"', 0)

			end

			if args'section'..i then

				content = excerptModule.getSection(content, args'section'..i]) or ''

			end

			content = excerptModule.cleanupText(content, {keepSubsections=true}) -- true means keep subsections

	

			local galleryFiles = extractGalleryFiles(content)

			if galleryFiles then

				for _, f in pairs(galleryFiles) do

					if hasCaption(f) then

						local filename = string.gsub(f, '|.*', '')

						local isOkay = excerptModule.checkImage(filename)

						if isOkay then

							table.insert(lines, doubleCheck(f.." (from '''[["..pagename.."]]''')"))

						end

					end

				end

			end

	

			local otherFiles = excerptModule.parse(content, {fileflags="1-100", filesOnly=true})

			if otherFiles then

				for _, f in pairs(extractRegularFiles(otherFiles)) do

					if f and f ~= '' and mw.ustring.sub(f, 1, 5) == 'File:' and hasCaption(f) then

						table.insert(lines, doubleCheck(f.." (from '''[["..pagename.."]]''')"))

					end

				end

			end

		

		end

		i = i + 1

	end

	return ( #lines > 0 ) and lines or error('No images found')

end



p._main = function(args, transclude, extraClassName)

	if not args1 then

		return error(linked and 'No page specified' or 'No page specified', 0)

	end

	local lines = transclude and makeTranscludedGalleryLinesTables(args) or makeGalleryLinesTable(args)

	local classNames = 'randomSlideshow-container'

	if extraClassName then classNames = classNames .. ' ' .. extraClassName end

	return makeOutput(lines, args.width or '100%', classNames, isDeclined(args.random))

end



p.main = function(frame)

	local parent = frame.getParent(frame)

	local parentArgs = parent.args

	local args = cleanupArgs(parentArgs)

	local output = p._main(args, false)

	return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } 

		.. frame:preprocess(output)

end



p.transclude = function(frame)

	local parent = frame.getParent(frame)

	local parentArgs = parent.args

	local args = cleanupArgs(parentArgs)

	local output = p._main(args, true)

	return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } 

		.. frame:preprocess(output)

end



return p
Permanently protected module
From Wikipedia, the free encyclopedia


-- Creates a slideshow gallery where the order is randomised. Intended for use on portal pages.

local p = {}

local excerptModule =  require('Module:Excerpt/portals')

local randomModule = require('Module:Random')



function cleanupArgs(argsTable)

	local cleanArgs = {}

	for key, val in pairs(argsTable) do

		if type(val) == 'string' then

			val = val:match('^%s*(.-)%s*$')

			if val ~= '' then

				cleanArgskey = val

			end

		else

			cleanArgskey = val

		end

	end

	return cleanArgs

end



function normaliseCssMeasurement(input)

	local suffix = string.reverse(string.sub(string.reverse(input), 1, 2))

	if ( suffix == 'px' ) or ( suffix == 'em' ) or ( string.sub(suffix, 2, 2) == '%' ) then

		return input

	else

		return input .. 'px'

	end

end



function isDeclined(val)

	if not val then return false end

	local declinedWords = " decline declined exclude excluded false none not no n off omit omitted remove removed "

	return string.find(declinedWords , ' '..val..' ', 1, true ) and true or false

end



function makeOutput(galleryLines, maxWidth, containerClassName, nonRandom)

	local randomiseArgs = {	't' = galleryLines }

	local sortedLines = nonRandom and galleryLines or randomModule.main('array', randomiseArgs)

	for i = 1, #sortedLines do

		-- insert a switcher-label span just after the first pipe, which should ideally be the caption

		sortedLinesi = sortedLinesi]:gsub(

			"|",

			'|<span class="switcher-label" style="display:none"><span class="randomSlideshow-sr-only">Image ' .. tostring(i) .. '</span></span>',

			1)

	end

	local galleryContent = table.concat(sortedLines, '\n')

	local output = '<div class="' .. containerClassName .. '" style="max-width:' .. normaliseCssMeasurement(maxWidth) .. '; margin:-4em auto;"><div class="nomobile"><!--intentionally empty on desktop, and is not present on mobile website (outside template namesapce)--></div>'

		.. mw.getCurrentFrame():extensionTag({name="gallery",content=galleryContent,args={mode="slideshow",class="switcher-container"}}) .. '</div>'

	return output

end



function makeGalleryLine(file, caption, credit)

	local title = mw.title.new(file, "File" )

	if not title

	then

		return "File:Blank.png|{{Error|File [[:File:" .. file .. "]] does not exist.}}"

	end

	local creditLine = ( credit and '<p><span style="font-size:88%">' .. credit .. '</span></p>' or '' )

	return title.prefixedText .. '|' .. ( caption or '' ) .. creditLine

end



function makeGalleryLinesTable(args)

	local galleryLinesTable = {}

	local i = 1

	while argsi do

		table.insert(galleryLinesTable, makeGalleryLine(argsi], argsi+1], args'credit' .. (i+1)/2]))

		i = i + 2

	end

	return galleryLinesTable 

end



function hasCaption(line)

	local caption = mw.ustring.match(line, ".-|(.*)")

	-- require caption to exist with more than 5 characters (avoids sizes etc being mistaken for captions)

	return caption and #caption>5 and true or false

end



function extractGalleryFiles(wikitext)

	local gallery = mw.ustring.match(wikitext, '<gallery.->%s*(.-)%s*</gallery>')

	if not gallery then

		return false

	end

	return mw.text.split(gallery, '%c')

end



function extractRegularFiles(wikitext)

	local files = {}

	local frame = mw.getCurrentFrame()

	local expand = function(template)

		return frame:preprocess(template)

	end

	for file in mw.ustring.gmatch(wikitext, '%b[]' ) do

		-- remove keywords that don't work in galleries

		file = mw.ustring.gsub(file, '|%s*thumb%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*thumbnail%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*border%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*left%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*right%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*center%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*centre%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*none%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*baseline%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*sub%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*super%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*top%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*text%-top%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*bottom%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*text%-bottom%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*framed?%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*frameless%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*upright%s*[0-9%.]*%s*([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*upright%s*=.-([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*link%s*=.-([|%]])', '%1')

		file = mw.ustring.gsub(file, '|%s*lang%s*=.-([|%]])', '%1')

		-- remove spaces prior to captions (which cause pre-formatted text)

		file = mw.ustring.gsub(file, '|%s*', '|')

		-- remove sizes, which sometimes get mistaken for captions

		file = mw.ustring.gsub(file, '|%s*%d*x?%d+%s*px%s*([|%]])', '%1')

		-- remove linebreaks

		file = mw.ustring.gsub(file, '\n\n', '<br>')

		file = mw.ustring.gsub(file, '\n', '')

		-- remove surrounding square brackets

		file = mw.ustring.gsub(file, '^%[%[', '')

		file = mw.ustring.gsub(file, '%]%]$', '')

		table.insert(files, file)

	end

	return files

end



--Central function for fixing issues that could occur in both gallery-fetched and file-fetched files

local function doubleCheck(file)

	-- disable pipes in wikilinks

	file = file:gsub(

		"%[%[([^%]]-)|(.-)]]",

		"[[%1__PIPE__%2]]")

	-- move any alt parameter to the end to avoid putting the switcher in too early and causing a linter error

	file = file:gsub(

		"^(.+)(|alt=[^|]*)(.*)$",

		"%1%3%2")

	-- bring back pipes in wikilinks

	file = file:gsub(

		"%[%[(.-)__PIPE__(.-)]]",

		"[[%1|%2]]")

	return file

end



function makeTranscludedGalleryLinesTables(args)

	local namespaceNumber = function(pagetitle)

		local titleObject = mw.title.new(pagetitle)

		return titleObject and titleObject.namespace

	end

	local lines = {}

	local i = 1

	while argsi do

		if namespaceNumber(argsi]) == 6 then -- file namespace

			-- args[i] is either just the filename, or uses syntax File:Name.jpg##Caption##Credit

			local parts = mw.text.split(argsi], '##%s*')

			local filename = parts1

			local caption = args'caption'..i or parts2 or false

			local credit = args'credit'..i or parts3 or false

			local line = makeGalleryLine(filename, caption, credit)

			table.insert(lines, line)

		else

			local content, pagename = excerptModule.getContent(argsi])

			if not pagename then

				return error('Cannot read a valid page for "' .. argsi .. '"', 0)

			elseif not content then

				return error('No content found on page "' .. argsi .. '"', 0)

			end

			if args'section'..i then

				content = excerptModule.getSection(content, args'section'..i]) or ''

			end

			content = excerptModule.cleanupText(content, {keepSubsections=true}) -- true means keep subsections

	

			local galleryFiles = extractGalleryFiles(content)

			if galleryFiles then

				for _, f in pairs(galleryFiles) do

					if hasCaption(f) then

						local filename = string.gsub(f, '|.*', '')

						local isOkay = excerptModule.checkImage(filename)

						if isOkay then

							table.insert(lines, doubleCheck(f.." (from '''[["..pagename.."]]''')"))

						end

					end

				end

			end

	

			local otherFiles = excerptModule.parse(content, {fileflags="1-100", filesOnly=true})

			if otherFiles then

				for _, f in pairs(extractRegularFiles(otherFiles)) do

					if f and f ~= '' and mw.ustring.sub(f, 1, 5) == 'File:' and hasCaption(f) then

						table.insert(lines, doubleCheck(f.." (from '''[["..pagename.."]]''')"))

					end

				end

			end

		

		end

		i = i + 1

	end

	return ( #lines > 0 ) and lines or error('No images found')

end



p._main = function(args, transclude, extraClassName)

	if not args1 then

		return error(linked and 'No page specified' or 'No page specified', 0)

	end

	local lines = transclude and makeTranscludedGalleryLinesTables(args) or makeGalleryLinesTable(args)

	local classNames = 'randomSlideshow-container'

	if extraClassName then classNames = classNames .. ' ' .. extraClassName end

	return makeOutput(lines, args.width or '100%', classNames, isDeclined(args.random))

end



p.main = function(frame)

	local parent = frame.getParent(frame)

	local parentArgs = parent.args

	local args = cleanupArgs(parentArgs)

	local output = p._main(args, false)

	return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } 

		.. frame:preprocess(output)

end



p.transclude = function(frame)

	local parent = frame.getParent(frame)

	local parentArgs = parent.args

	local args = cleanupArgs(parentArgs)

	local output = p._main(args, true)

	return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } 

		.. frame:preprocess(output)

end



return p

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook