Jump to content

Module:Random slideshow/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Aidan9382 (talk | contribs) at 09:06, 4 November 2022 (Temporary somewhat working fix for the advanced-look processing/linter errors by avoiding (some) pipe replacement. This also disables the expansion of templates, as it was causing issues and im not entirely sure why its used right now other than for the old sake of {{#tag:). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
-- Creates a slideshow gallery where the order is randomised. Intended for use on portal pages.
local p = {}
local excerptModule =  require('Module:Excerpt/portals/sandbox')
local randomModule = require('Module:Random')
local redirectModule = require('Module:Redirect')

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
				cleanArgs[key] = val
			end
		else
			cleanArgs[key] = 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 }
	if #galleryLines > 50 then randomiseArgs.limit = 50 end
	local sortedLines = nonRandom and galleryLines or randomModule.main('array', randomiseArgs)
	for i = 1, #sortedLines do
		-- move the alt parameter to the end of the file should it exist to fix linter errors
		-- make sure the parameter isnt perhaps being confused by a wikilink inside it
		local altParam = sortedLines[i]:gsub(
			"^(.+)(%{%{!}}alt%{%{=}}[^{]*)(.*)$",
			"%2")
		if not string.find(altParam,"%[%[") then
			sortedLines[i] = sortedLines[i]:gsub(
				"^(.+)(%{%{!}}alt%{%{=}}[^{]*)(.*)$",
				"%1%3%2")
		end
		-- insert a switcher-label span just after the first pipe (which has already been escaped as {{!}} instead the | character)
		sortedLines[i] = sortedLines[i]:gsub(
			"|",
			'|<span class="switcher-label" style="display:none"><span class="randomSlideshow-sr-only">Image ' .. tostring(i) .. '</span></span>',
			1)
		mw.log("Workin with",sortedLines[i])
	end
	local galleryContent = table.concat(sortedLines, '\n')
	galleryContent = string.gsub(galleryContent,"%{%{!}}","|")
	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 args[i] do
		table.insert(galleryLinesTable, makeGalleryLine(args[i], args[i+1], args['credit' .. (i+1)/2]))
		i = i + 2
	end
	return galleryLinesTable 
end

function hasCaption(line)
	local caption = mw.ustring.match(line, ".-{{!}}(.*)") or 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
	gallery = mw.ustring.gsub(gallery, '|', '{{!}}')
	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*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')
		-- 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')
		-- expand templates
		-- file = mw.ustring.gsub(file, '{%b{}}', expand)
		-- remove loose closing braces which don't have matching opening braces
		-- file = mw.ustring.gsub(file, '}}', '')
		-- remove loose opening braces which don't have matching closing braces (and the subsequent content, which is probably just a template name)
		-- file = mw.ustring.gsub(file, '{{.-([|%]])', '%1')
		-- replace pipes and equals (which would otherwise break the {{#tag:}} syntax)
		-- file = mw.ustring.gsub(file, '|%s*alt%s*=', '{{!}}alt=')
		-- file = mw.ustring.gsub(file, '|', '{{!}}')
		-- file = mw.ustring.gsub(file, '=', '{{=}}')
		-- 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)
		mw.log(file)
	end
	return files
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 args[i] do
		if namespaceNumber(args[i]) == 6 then -- file namespace
			-- args[i] is either just the filename, or uses syntax File:Name.jpg##Caption##Credit
			local parts = mw.text.split(args[i], '##%s*')
			local filename = parts[1]
			local caption = args['caption'..i] or parts[2] or false
			local credit = args['credit'..i] or parts[3] or false
			local line = makeGalleryLine(filename, caption, credit)
			table.insert(lines, line)
		else
			local content, pagename = excerptModule.getContent(args[i])
			if not pagename then
				return error('Cannot read a valid page for "' .. args[i] .. '"', 0)
			elseif not content then
				return error('No content found on page "' .. args[i] .. '"', 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, 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, 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 args[1] 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