Module:RandomArticle

local p = {}

L = {} N = {} I = {} D = {} n_items = 0

function DataInsert(link, name, image, desc) table.insert(L, link) table.insert(N, name) table.insert(I, image) table.insert(D, desc) n_items = n_items + 1 end

--====================== DATA INSERT: Syntax: DataInsert("link","name", "image", [=[description]=]) ======================== --if name is the same as link, you can leave it blank --if image is blank, it will be picked automatically from the article --if description is blank, it will be picked automatically from the article --if name or link includes a double quote, it needs to be written as \" so the quote is not interpreted as the end of the name. --for the sake of maintenance, please add entries in alphabetical order

function PopulateBand DataInsert("-Shintenchi Kaibyaku Shudan- zigzag","","","",[=[]=]) DataInsert("04 Limited Sazabys","","","",[=[]=]) DataInsert("a crowd of rebellion","","",[=[]=]) DataInsert("Accént","","",[=[]=]) DataInsert("ALI","","",[=[]=]) DataInsert("Alice Nine","","",[=[]=]) DataInsert("Amiliyah","","",[=[]=]) DataInsert("ANARCHY STONE","","",[=[]=]) DataInsert("Anzen Chitai","","",[=[]=]) DataInsert("Argonavis","","",[=[]=]) DataInsert("ASIAN KUNG-FU GENERATION","","",[=[]=]) DataInsert("BAAD","","",[=[]=]) DataInsert("BABYMETAL","","",[=[]=]) DataInsert("BAND-MAID","","",[=[]=]) DataInsert("BAND-MAIKO","","",[=[]=]) DataInsert("Boom Boom Satellites","","",[=[]=]) DataInsert("BRADIO","","",[=[]=]) DataInsert("BRATS","","",[=[]=]) DataInsert("BRIDEAR","","",[=[]=]) DataInsert("BUMP OF CHICKEN","","",[=[]=]) DataInsert("BURNOUT SYNDROMES","","",[=[]=]) DataInsert("CHiCO with HoneyWorks","","",[=[]=]) DataInsert("CIDER GIRL","","",[=[]=]) DataInsert("coldrain","","",[=[]=]) DataInsert("CLASSMATE⊿CINDERELLA","","","",[=[]=]) DataInsert("Cö shu Nie","","",[=[]=]) DataInsert("Dorodoro","","",[=[]=]) DataInsert("Dragon Guardian","","",[=[]=]) DataInsert("ELLEGARDEN","","",[=[]=]) DataInsert("FATE GEAR","","",[=[]=]) DataInsert("Fear, and Loathing in Las Vegas","","",[=[]=]) DataInsert("fripSide","","",[=[]=]) DataInsert("Fuyu no Doubutsuen","","",[=[]=]) DataInsert("Galneryus","","",[=[]=]) DataInsert("Gordon","","",[=[]=]) DataInsert("GRANRODEO","","",[=[]=]) DataInsert("HANABIE.","","",[=[]=]) DataInsert("hitorie","","",[=[]=]) DataInsert("Hitsujibungaku","","",[=[]=]) DataInsert("Humbreaders","","",[=[]=]) DataInsert("Ikimonogakari","","",[=[Ikimonogakari (いきものがかり) is a Japanese duo (formerly a trio) under Epic Records Japan. Several of their releases have topped the Oricon rankings and many of their songs have been featured in different media, such as Naruto Shippuden and the 2012 Olympic broadcast theme song etc.]]]=]) DataInsert("Imperial Circus Dead Decadence","","",[=[]=]) DataInsert("indigo la End","","",[=[]=]) DataInsert("Japanese Folk Metal","","",[=[]=]) DataInsert("Jupiter","","",[=[]=]) DataInsert("KANA-BOON","","",[=[]=]) DataInsert("Kidorikko","","",[=[]=]) DataInsert("King Gnu","","",[=[]=]) DataInsert("Knuckle Chiwawa","","",[=[]=]) DataInsert("L'Arc~en~Ciel","","",[=[]=]) DataInsert("Lenny code fiction","","",[=[]=]) DataInsert("Ling tosite sigure","","",[=[]=]) DataInsert("Linked Horizon","","",[=[]=]) DataInsert("LOVEBITES","","",[=[]=]) DataInsert("MAN WITH A MISSION","","",[=[]=]) DataInsert("Mary's Blood","","",[=[]=]) DataInsert("MAXIMUM THE HORMONE","","",[=[]=]) DataInsert("Mr.Children","","",[=[]=]) DataInsert("Mrs. GREEN APPLE","","",[=[]=]) DataInsert("MUTANT MONSTER","","",[=[]=]) DataInsert("MYTH & ROID","","",[=[]=]) DataInsert("nano.RIPE","","",[=[]=]) DataInsert("NecryTalkie","","",[=[]=]) DataInsert("NEMOPHILA","","",[=[]=]) DataInsert("NICO Touches the Walls","","",[=[]=]) DataInsert("Non Stop Rabbit","","",[=[]=]) DataInsert("Official HIGE DANdism","","",[=[]=]) DataInsert("OLDCODEX","","",[=[]=]) DataInsert("ONE OK ROCK","","",[=[]=]) DataInsert("ORANGE RANGE","","",[=[]=]) DataInsert("Otoboke Beaver","","",[=[]=]) DataInsert("OxT","","",[=[]=]) DataInsert("PELICAN FANCLUB","","",[=[]=]) DataInsert("POLKADOT STINGRAY","","",[=[]=]) DataInsert("Poppin'Party","","",[=[]=]) DataInsert("Porno Graffitti","","",[=[]=]) DataInsert("RADWIMPS","","",[=[]=]) DataInsert("RAISE A SUILEN","","",[=[]=]) DataInsert("Roselia","","",[=[]=]) DataInsert("Ryokuoushoku Shakai","","",[=[]=]) DataInsert("sakanaction","","",[=[]=]) DataInsert("SARD UNDERGROUND","","",[=[]=]) DataInsert("SCANDAL","","",[=[]=]) DataInsert("SEKAI NO OWARI","","",[=[]=]) DataInsert("Shinsei Kamattechan","","",[=[]=]) DataInsert("SHOW-YA","","",[=[]=]) DataInsert("SiM","","",[=[]=]) DataInsert("SPYAIR","","",[=[]=]) DataInsert("spira・spica","","",[=[]=]) DataInsert("SUPER BEAVER","","",[=[]=]) DataInsert("Survive Said The Prophet","","",[=[]=]) DataInsert("the brilliant green","","",[=[]=]) DataInsert("the GazettE","","",[=[]=]) DataInsert("THE ORAL CIGARETTES","","",[=[]=]) DataInsert("the peggies","","",[=[]=]) DataInsert("The Winking Owl","","",[=[]=]) DataInsert("Tokyo Jihen","","",[=[]=]) DataInsert("TRiDENT","","",[=[]=]) DataInsert("TRUSTRICK","","",[=[]=]) DataInsert("UNISON SQUARE GARDEN","","",[=[]=]) DataInsert("Unlucky Morpheus","","",[=[]=]) DataInsert("UVERworld","","",[=[]=]) DataInsert("Wagakki Band","","",[=[]=]) DataInsert("WEAVER","","",[=[]=]) DataInsert("Who-ya Extended","","",[=[]=]) DataInsert("X JAPAN","","",[=[]=]) DataInsert("YOASOBI","","",[=[YOASOBI is a pop duo formed by Vocaloid producer Ayase, and singer-songwriter ikura in 2019. Their debut song Yoru ni Kakeru topped multiple Japanese music charts and became the first song certified diamond for streaming by the RIAJ.]]]=]) DataInsert("Yorushika","","",[=[]=]) DataInsert("Yousei Teikoku","","",[=[]=]) DataInsert("Ziyoou-Vachi","","",[=[]=]) DataInsert("Zutto Mayonaka de ii No Ni.","","",[=[]=]) end

function PopulateSoloist DataInsert("2&","","",[=[]=]) DataInsert("Ado","","",[=[]=]) DataInsert("Akase Akari","","",[=[]=]) DataInsert("Akiyama Kiro","","",[=[]=]) DataInsert("Amuro Namie","","",[=[]=]) DataInsert("Aoi Eir","","",[=[]=]) DataInsert("BoA","","",[=[]=]) DataInsert("DAOKO","","",[=[]=]) DataInsert("DECO*27","","",[=[]=]) DataInsert("Eve (Singer-songwriter)","Eve","",[=[]=]) DataInsert("Fujii Kaze","","",[=[]=]) DataInsert("GACKT","","",[=[]=]) DataInsert("GARUDA","","",[=[]=]) DataInsert("Go Hiromi","","",[=[]=]) DataInsert("Hamasaki Ayumi","","",[=[]=]) DataInsert("Haru Nemuri","","",[=[]=]) DataInsert("Higuchi Ai","","",[=[]=]) DataInsert("Horiuchi Marina","","",[=[]=]) DataInsert("Hoshino Gen","","",[=[]=]) DataInsert("Hotei Tomoyasu","","",[=[]=]) DataInsert("Inoue Joe","","",[=[]=]) DataInsert("Ito Mio","","",[=[]=]) DataInsert("Iwai Yukiko","","",[=[]=]) DataInsert("J-JUN","","",[=[]=]) DataInsert("Juuyondaime Toire no Hanako-san","","",[=[]=]) DataInsert("Kanou Emiri","","",[=[]=]) DataInsert("Kosaka Riyu","","",[=[]=]) DataInsert("KOTO","","",[=[]=]) DataInsert("KOTOKO","","",[=[]=]) DataInsert("LiSA","","",[=[]=]) DataInsert("m.c.A・T","","",[=[]=]) DataInsert("Maharajan","","",[=[]=]) DataInsert("marble≠marble","","",[=[Tnaka is a solo idol that performs in the techno project marble≠marble.]=]) DataInsert("MIYAVI","","",[=[]=]) DataInsert("N Feni","","",[=[]=]) DataInsert("Nono Aimi","","",[=[]=]) DataInsert("Nujabes","","",[=[]=]) DataInsert("Okinawa Electric Girl Saya","","",[=[]=]) DataInsert("Oomori Seiko","","",[=[]=]) DataInsert("Rie a.k.a. Suzaku","","",[=[]=]) DataInsert("Sakiyama Soushi","","",[=[]=]) DataInsert("Sakurai Yune","","",[=[]=]) DataInsert("Sawano Hiroyuki","","",[=[]=]) DataInsert("Shiina Hikari","","",[=[]=]) DataInsert("Suda Keina","","",[=[]=]) DataInsert("Suda Masaki","","",[=[]=]) DataInsert("Tatsumi Rika (1965)","Tatsumi Rika","",[=[]=]) DataInsert("Tsukimori Kaede","","",[=[]=]) DataInsert("Uchida Yuma","","",[=[]=]) DataInsert("Ushima Yoshifumi","","",[=[]=]) DataInsert("Utada Hikaru","","",[=[]=]) DataInsert("Vaundy","","",[=[]=]) DataInsert("Vickeblanka","","",[=[]=]) DataInsert("Wada Koji","","",[=[]=]) DataInsert("wowaka","","",[=[]=]) DataInsert("Yajima Mai","","",[=[]=]) DataInsert("yama","","",[=[]=]) DataInsert("Yamazaki Mayumi","","",[=[]=]) DataInsert("Yonezu Kenshi","","",[=[]=]) DataInsert("YUC'e","","",[=[]=]) DataInsert("Yunomi","","",[=[]=]) DataInsert("Yuuri (Singer-songwriter)","Yuuri","",[=[]=]) DataInsert("ZAQ","","",[=[]=]) end

function PopulateGroup DataInsert("22/7","","",[=[]=]) DataInsert("2i2","","",[=[]=]) DataInsert("340.29m/s","","",[=[]=]) DataInsert("&Ch!ll","","",[=[]=]) DataInsert(".BPM","","",[=[]=]) DataInsert("@onefive","","",[=[]=]) DataInsert("26-Ji no Masquerade","","",[=[]=]) DataInsert("340.29m/s","","",[=[]=]) DataInsert("8bitBRAIN","","",[=[]=]) DataInsert("A.B.C-Z","","",[=[]=]) DataInsert("Aiiro Asterism","","",[=[]=]) DataInsert("Alice Juban","","",[=[]=]) DataInsert("alliance","","",[=[]=]) DataInsert("Amaterasu","","",[=[]=]) DataInsert("Angel Sisters","","",[=[]=]) DataInsert("Angel♡Heart","","",[=[]=]) DataInsert("Anthurium","","",[=[]=]) DataInsert("Aqua Note","","",[=[]=]) DataInsert("Armor Girls","","",[=[]=]) DataInsert("Atarashii Gakkou no Leaders","","",[=[]=]) DataInsert("BABYBEARD","","",[=[]=]) DataInsert("BeForU","","",[=[]=]) DataInsert("Bellring Shoujo Heart","","",[=[]=]) DataInsert("BLUEGOATS","","",[=[]=]) DataInsert("Boku wa Mada Shinanai","","",[=[]=]) DataInsert("BOYMEN AREA KENKYUSEI","","",[=[]=]) DataInsert("BROKEN BY THE SCREAM","","",[=[]=]) DataInsert("chelmico","","",[=[]=]) DataInsert("Chouonpa","","",[=[]=]) DataInsert("chuLa","","",[=[]=]) DataInsert("Ciào Smiles","","",[=[]=]) DataInsert("Cinder-ella","","",[=[]=]) DataInsert("COLORLESS","","",[=[]=]) DataInsert("CROSSNOESIS","","",[=[]=]) DataInsert("CY8ER","","",[=[]=]) DataInsert("Dempagumi.inc","","",[=[]=]) DataInsert("DEARDEVIL","","",[=[]=]) DataInsert("DESURABBITS","","",[=[]=]) DataInsert("DokidokiDreamCampus+","","",[=[]=]) DataInsert("DoublePeace","","",[=[]=]) DataInsert("EASTER GIRLS","","",[=[]=]) DataInsert("FiDZ","","",[=[]=]) DataInsert("GANG PARADE","","",[=[]=]) DataInsert("Gekizyou Refrain","","",[=[]=]) DataInsert("HAMIDASYSTEM","","",[=[]=]) DataInsert("Hamu!STAR","","",[=[]=]) DataInsert("HARP STAR","","",[=[]=]) DataInsert("HEROINES","","",[=[]=]) DataInsert("Hey! Say! JUMP","","",[=[]=]) DataInsert("Higeki no Heroine Syndrome","","",[=[]=]) DataInsert("Hikicomoteikoku","","",[=[]=]) DataInsert("Ichizen!","","",[=[]=]) DataInsert("iLiFE!","","",[=[]=]) DataInsert("INI","","",[=[]=]) DataInsert("INUWASI","","",[=[]=]) DataInsert("Item wa Teru Teru Nomi 3","","",[=[]=]) DataInsert("JAM Project","","",[=[]=]) DataInsert("Jyujyu","","",[=[]=]) DataInsert("Kamen Joshi","","",[=[]=]) DataInsert("Kamikaze Sensation","","",[=[]=]) DataInsert("Kanjani8","","",[=[]=]) DataInsert("KAQRIYOTERROR","","",[=[]=]) DataInsert("KATA☆CHU","","",[=[]=]) DataInsert("KAT-TUN","","",[=[]=]) DataInsert("KinKi Kids","","",[=[]=]) DataInsert("Konyanko","","",[=[]=]) DataInsert("LADYBABY","","",[=[]=]) DataInsert("Last Idol","","",[=[]=]) DataInsert("Lil na Valley","","",[=[]=]) DataInsert("link laze","","",[=[]=]) DataInsert("Little Glee Monster","","",[=[]=]) DataInsert("L★ROCK BAB","","",[=[]=]) DataInsert("L・I・E・P","","",[=[]=]) DataInsert("M!LK","","",[=[]=]) DataInsert("MAD JAMIE","","",[=[]=]) DataInsert("MAG!C☆PRINCE","","",[=[]=]) DataInsert("MANACLE","","",[=[]=]) DataInsert("Marble Angel","","",[=[]=]) DataInsert("MELON BATAKE A GO GO","","",[=[]=]) DataInsert("MERUCHU","","",[=[]=]) DataInsert("MIGMA SHELTER","","",[=[]=]) DataInsert("Minna no Kodomo-chan","","",[=[]=]) DataInsert("miscast","","",[=[]=]) DataInsert("misola de edison","","",[=[]=]) DataInsert("Monoclone","","",[=[]=]) DataInsert("Naniwa Danshi","","",[=[]=]) DataInsert("NECRONOMIDOL","","",[=[]=]) DataInsert("NEO JAPONISM","","",[=[]=]) DataInsert("NiceToMeetYou","","",[=[]=]) DataInsert("NILKLY","","",[=[]=]) DataInsert("NiziU","","",[=[]=]) DataInsert("Nogizaka46","","",[=[]=]) DataInsert("OHMIKAMI","","",[=[]=]) DataInsert("One Chance Yeah Hoi!","","",[=[]=]) DataInsert("OnePixcel","","",[=[]=]) DataInsert("Onyanko Club","","",[=[]=]) DataInsert("Paradox Risk","","",[=[]=]) DataInsert("PassCode","","",[=[]=]) DataInsert("PATI PATI CANDY...☆","","",[=[]=]) DataInsert("PIGGS","","",[=[]=]) DataInsert("PiXMiX","","",[=[]=]) DataInsert("PLANCK STARS","","",[=[]=]) DataInsert("Policy Nante Gongo Doudan!","","",[=[]=]) DataInsert("Ponkotsu Konpo","","",[=[]=]) DataInsert("POPPING EMO","","",[=[]=]) DataInsert("Pu Lathessa","","",[=[]=]) DataInsert("QueeenMarionette","","",[=[]=]) DataInsert("RABBIT HUTCH","","",[=[]=]) DataInsert("reaction","","",[=[]=]) DataInsert("RILISREVERSE","","",[=[]=]) DataInsert("Runup!!","","",[=[]=]) DataInsert("Sakura Gakuin","","",[=[]=]) DataInsert("Satanic Punish","","",[=[]=]) DataInsert("Seifuku Koujo Iinkai","","",[=[]=]) DataInsert("Seireki13ya","","",[=[]=]) DataInsert("Sexy Zone","","",[=[]=]) DataInsert("SixTONES","","",[=[]=]) DataInsert("Shinshi Todoroku, Gekijou no Gotoku.","","",[=[]=]) DataInsert("Smewthie","","",[=[]=]) DataInsert("Snow Man","","",[=[]=]) DataInsert("SPACE PIRATES class ZERO","","",[=[]=]) DataInsert("SPARK SPEAKER","","",[=[]=]) DataInsert("STARMARIE","","",[=[]=]) DataInsert("Steam Girls","","",[=[]=]) DataInsert("Suneeds","","",[=[]=]) DataInsert("TENRIN","","",[=[]=]) DataInsert("TOKYO GIRLS' STYLE","","",[=[]=]) DataInsert("Tokyo Psychopath","","",[=[]=]) DataInsert("Tsubaki Factory","","",[=[]=]) DataInsert("Twinkle","","",[=[]=]) DataInsert("ULTRA BUZZ","","",[=[]=]) DataInsert("Underbeasty","","",[=[]=]) DataInsert("WAGAMAMARAKIA","","",[=[]=]) DataInsert("Wa-Suta","","",[=[]=]) DataInsert("WONDER SNAKE","","",[=[]=]) DataInsert("X21","","",[=[]=]) DataInsert("XTEEN","","",[=[]=]) DataInsert("Yandoll","","",[=[]=]) DataInsert("YORUWA KOREKARA","","",[=[]=]) DataInsert("YURiMental","","",[=[]=]) DataInsert("Yurutto Kakumeidan","","",[=[]=]) DataInsert("Zenbu Kimi no Sei da.","","",[=[]=]) DataInsert("Zsasz","","",[=[]=]) DataInsert("ZOC","","",[=[]=]) DataInsert("ZOMBIE POWDER","","",[=[]=]) end

function PopulateArtist PopulateBand PopulateGroup PopulateSoloist end

--================================================ Module functions ================================================

function ParseImage(content) image = nil --searching for images using different patterns until one of them (or none) finds an image --note: [gjpsw][einpv][befg][gp]? is intended to capture the extensions jpg, png, jpeg, webp, gif and svg --this can also capture any combination of those letters, due to lua not having optional capturing groups --pattern 1 --search for image in the infobox field "image" as 	if(image == nil) then imgpattern = 'image%s*=%s*%[%[File:(.-%.[gjpsw][einpv][befg][gp]?)' image = string.match(content, imgpattern) end --pattern 2 --search for image in the infobox field "image" as image.ext if(image == nil) then imgpattern = 'image%s*=%s*(.-%.[gjpsw][einpv][befg][gp]?)' image = string.match(content, imgpattern) end --pattern 3 --search for image anywhere else as [[File:image.ext]] if(image == nil) then imgpattern = '%[%[File:(.-%.[gjpsw][einpv][befg][gp]?)' image = string.match(content, imgpattern) end --pattern 4 --search for image inside a gallery as image.ext if(image == nil) then imgpattern = , )		--removes the heading of the "Concept" section to include its content in the description, if available		description = description:gsub('==+%s*Concept%s*==+', )		--removes everything below (and including) the first section marker		description = description:gsub('==+.*==+.*', )		--replaces multiple linebreaks with a single one		description = description:gsub('\n\n+', '\n')		--removes any template in the text		description = description:gsub(, )		--removes 		description = description:gsub('%(%)', '')		--limiting maximum length of description		if(string.len(description) > 290) then			--cropping at 290 characters			description = description:sub(1,290)			--removing last word (possibly cropped) and replacing with "..."			description = description:gsub('%s%S*$', '...')		end	end	return description end

function ParsePage(frame, title) --getting random index math.randomseed(os.time) index = math.random(n_items) --accessing data table with random index link = L[index] name = N[index] image = I[index] description = D[index] page = mw.title.new(link) content = page:getContent --checking if page is a redirect if(content ~= nil) then redirectpattern = '#REDIRECT%s*%[%[(.*)%]%]' redirectlink = link --navigating through redirects until a page with content is found or not found while (redirectlink ~= null) do           redirectlink = string.match(content, redirectpattern) if (redirectlink ~= null) then --if a redirect is found, link is replaced by the target of the redirect link = redirectlink page = mw.title.new(link) content = page:getContent end end end

--if no name is given, use link as the name if(name == '') then name = link end --if no image is given, try to get it from the article if(image == '') then if(content == nil) then image = nil else --if article exists, get it from the article content image = ParseImage(content) end end --if no description is given, try to get it from the article if(description == '') then if(content == nil) then description = nil else --if article exists, get it from the article content description = ParseDescription(content, name) end end return BuildOutput(frame, title, link, name, image, description) end

function BuildOutput(frame, title, link, name, image, description) imgsize = '250px' primarycolor = '#e15467' imgbackgroundcolor = '#3c3c3c' if(image == nil) then --if no image was found, return empty string. This will be treated in Template:Infocard image = '' end if(description == nil) then --if description is nil, page don't exist. Return error message. description = 'No article found with PAGENAME ' .. link .. '. If you see this message, please contact an admin so it can be fixed.' end --Using Template:Infocard to display collected data on desktop desktop_output = frame:expandTemplate{ title = 'Infocard', args = {title = title, name = name, link = link, description = description, file = image, imgsize = imgsize, primarycolor = primarycolor, imgbackgroundcolor = imgbackgroundcolor} }	--Using Template:Infocard/mobile to display collected data on mobile --emphasizing title on mobile title = "'''" .. title .. "'''"	mobile_output = frame:expandTemplate{ title = 'Infocard/mobile', args = {title = title, name = name, link = link, description = description, file = image, imgsize = imgsize, primarycolor = primarycolor, imgbackgroundcolor = imgbackgroundcolor} }	return ' ' .. desktop_output .. ' ' .. mobile_output .. ' ' end

function p.GetBand(frame) --loading predefined data into tables PopulateBand if(n_items > 0) then return ParsePage(frame, "Featured Band") end end

function p.GetGroup(frame) --loading predefined data into tables PopulateGroup if(n_items > 0) then return ParsePage(frame, "Featured Group") end end

function p.GetSoloist(frame) --loading predefined data into tables PopulateSoloist if(n_items > 0) then return ParsePage(frame, "Featured Soloist") end end

function p.GetArtist(frame) --loading predefined data into tables PopulateArtist if(n_items > 0) then return ParsePage(frame, "Featured Artist") end end return p