-- Creates a slideshow gallery where the order is randomised. Intended for use on portal pages.localp={}localexcerptModule=require('Module:Excerpt/portals')localrandomModule=require('Module:Random')functioncleanupArgs(argsTable)localcleanArgs={}forkey,valinpairs(argsTable)doiftype(val)=='string'thenval=val:match('^%s*(.-)%s*$')ifval~=''thencleanArgs[key]=valendelsecleanArgs[key]=valendendreturncleanArgsendfunctionnormaliseCssMeasurement(input)localsuffix=string.reverse(string.sub(string.reverse(input),1,2))if(suffix=='px')or(suffix=='em')or(string.sub(suffix,2,2)=='%')thenreturninputelsereturninput..'px'endendfunctionisDeclined(val)ifnotvalthenreturnfalseendlocaldeclinedWords=" decline declined exclude excluded false none not no n off omit omitted remove removed "returnstring.find(declinedWords,' '..val..' ',1,true)andtrueorfalseendfunctionmakeOutput(galleryLines,maxWidth,containerClassName,nonRandom)localrandomiseArgs={['t']=galleryLines}localsortedLines=nonRandomandgalleryLinesorrandomModule.main('array',randomiseArgs)fori=1,#sortedLinesdo-- insert a switcher-label span just after the first pipe, which should ideally be the captionsortedLines[i]=sortedLines[i]:gsub("|",'|<span class="switcher-label" style="display:none"><span class="randomSlideshow-sr-only">Image '..tostring(i)..'</span></span>',1)endlocalgalleryContent=table.concat(sortedLines,'\n')localoutput='<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>'returnoutputendfunctionmakeGalleryLine(file,caption,credit)localtitle=mw.title.new(file,"File")ifnottitlethenreturn"File:Blank.png|{{Error|File [[:File:"..file.."]] does not exist.}}"endlocalcreditLine=(creditand'<p><span style="font-size:88%">'..credit..'</span></p>'or'')returntitle.prefixedText..'|'..(captionor'')..creditLineendfunctionmakeGalleryLinesTable(args)localgalleryLinesTable={}locali=1whileargs[i]dotable.insert(galleryLinesTable,makeGalleryLine(args[i],args[i+1],args['credit'..(i+1)/2]))i=i+2endreturngalleryLinesTableendfunctionhasCaption(line)localcaption=mw.ustring.match(line,".-|(.*)")-- require caption to exist with more than 5 characters (avoids sizes etc being mistaken for captions)returncaptionand#caption>5andtrueorfalseendfunctionextractGalleryFiles(wikitext)localgallery=mw.ustring.match(wikitext,'<gallery.->%s*(.-)%s*</gallery>')ifnotgallerythenreturnfalseendreturnmw.text.split(gallery,'%c')endfunctionextractRegularFiles(wikitext)localfiles={}localframe=mw.getCurrentFrame()localexpand=function(template)returnframe:preprocess(template)endforfileinmw.ustring.gmatch(wikitext,'%b[]')do-- remove keywords that don't work in galleriesfile=mw.ustring.gsub(file,'|%s*baseline%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*border%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*bottom%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*class%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*lang%s*=.-([|%]])','%1')file=mw.ustring.gsub(file,'|%s*left%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*link%s*=.-([|%]])','%1')file=mw.ustring.gsub(file,'|%s*none%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*right%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*text%-bottom%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*text%-top%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*thumb%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*thumbnail%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*top%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*upright%s*[0-9%.]*%s*([|%]])','%1')file=mw.ustring.gsub(file,'|%s*upright%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 captionsfile=mw.ustring.gsub(file,'|%s*%d*x?%d+%s*px%s*([|%]])','%1')-- remove linebreaksfile=mw.ustring.gsub(file,'\n\n','<br>')file=mw.ustring.gsub(file,'\n','')-- remove surrounding square bracketsfile=mw.ustring.gsub(file,'^%[%[','')file=mw.ustring.gsub(file,'%]%]$','')table.insert(files,file)endreturnfilesend--Central function for fixing issues that could occur in both gallery-fetched and file-fetched fileslocalfunctiondoubleCheck(file)-- disable pipes in wikilinksfile=file:gsub("%[%[([^%]]-)|(.-)]]","[[%1__PIPE__%2]]")-- move any alt parameter to the end to avoid putting the switcher in too early and causing a linter errorfile=file:gsub("^(.+)(|alt=[^|]*)(.*)$","%1%3%2")-- bring back pipes in wikilinksfile=file:gsub("%[%[(.-)__PIPE__(.-)]]","[[%1|%2]]")returnfileendfunctionmakeTranscludedGalleryLinesTables(args)localnamespaceNumber=function(pagetitle)localtitleObject=mw.title.new(pagetitle)returntitleObjectandtitleObject.namespaceendlocallines={}locali=1whileargs[i]doifnamespaceNumber(args[i])==6then-- file namespace-- args[i] is either just the filename, or uses syntax File:Name.jpg##Caption##Creditlocalparts=mw.text.split(args[i],'##%s*')localfilename=parts[1]localcaption=args['caption'..i]orparts[2]orfalselocalcredit=args['credit'..i]orparts[3]orfalselocalline=makeGalleryLine(filename,caption,credit)table.insert(lines,line)elselocalcontent,pagename=excerptModule.getContent(args[i])ifnotpagenamethenreturnerror('Cannot read a valid page for "'..args[i]..'"',0)elseifnotcontentthenreturnerror('No content found on page "'..args[i]..'"',0)endifargs['section'..i]thencontent=excerptModule.getSection(content,args['section'..i])or''endcontent=excerptModule.cleanupText(content,{keepSubsections=true,ignoreOnlyincludes=true})-- true means keep subsectionslocalgalleryFiles=extractGalleryFiles(content)ifgalleryFilesthenfor_,finpairs(galleryFiles)doifhasCaption(f)thenlocalfilename=string.gsub(f,'|.*','')localisOkay=excerptModule.checkImage(filename)ifisOkaythentable.insert(lines,doubleCheck(f.." (from '''[["..pagename.."]]''')"))endendendendlocalotherFiles=excerptModule.parse(content,{fileflags="1-100",filesOnly=true})ifotherFilesthenfor_,finpairs(extractRegularFiles(otherFiles))doiffandf~=''andmw.ustring.sub(f,1,5)=='File:'andhasCaption(f)thentable.insert(lines,doubleCheck(f.." (from '''[["..pagename.."]]''')"))endendendendi=i+1endreturn(#lines>0)andlinesorerror('No images found')endp._main=function(args,transclude,extraClassName)ifnotargs[1]thenreturnerror(linkedand'No page specified'or'No page specified',0)endlocallines=transcludeandmakeTranscludedGalleryLinesTables(args)ormakeGalleryLinesTable(args)localclassNames='randomSlideshow-container'ifextraClassNamethenclassNames=classNames..' '..extraClassNameendreturnmakeOutput(lines,args.widthor'100%',classNames,isDeclined(args.random))endp.main=function(frame)localparent=frame.getParent(frame)localparentArgs=parent.argslocalargs=cleanupArgs(parentArgs)localoutput=p._main(args,false)returnframe:extensionTag{name='templatestyles',args={src='Module:Random slideshow/styles.css'}}..frame:preprocess(output)endp.transclude=function(frame)localparent=frame.getParent(frame)localparentArgs=parent.argslocalargs=cleanupArgs(parentArgs)localoutput=p._main(args,true)returnframe:extensionTag{name='templatestyles',args={src='Module:Random slideshow/styles.css'}}..frame:preprocess(output)endreturnp