Module:RandomArticle

local p = {}

custom_info = {} function DataInsert(pagename, name, image, desc) custom_info[pagename] = {['name'] = name, ['image'] = image, ['description'] = desc} end --==================================== Custom Info ==================================== --===== Use this to replace the automated info with custom image, description, etc ==== --Syntax: DataInsert("pagename","custom name", "custom image", [=[custom description]=]) --if you don't want to change one or more fields, leave them blank. --for the sake of maintenance, please add entries in alphabetical order

function CustomInfo 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("marble≠marble","","",[=[Tnaka is a solo idol that performs in the techno project marble≠marble.]=]) DataInsert("OLDCODEX","","",[=[OLDCODEX (オルドコデック) was a Japanese rock band under Lantis. They are best known for performing the theme songs of the animes Kuroko's Basketball, and Free!.]=]) 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("","","",[=[]=]) end

--========================== Module functions ========================== function firstToLower(str) return (str:gsub("^%u", string.lower)) end

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 empty parenthesis	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	return description end

function ParsePage(frame, articleType, pagename) page = mw.title.new(pagename) content = page:getContent --checking if page is valid if(content == nil) then --if page doesn't exist or is empty, get another page return p.GetArticle(frame) else --checking if page is a redirect redirect_pattern = '#REDIRECT%s*%[%[(.*)%]%]' redirect_link = pagename while(redirect_link ~= null) do       	--navigating through redirects until a page with content is found or not found redirect_link = string.match(content, redirect_pattern) if(redirect_link ~= null) then --if a redirect is found, link is replaced by the target of the redirect pagename = redirect_link page = mw.title.new(link) content = page:getContent end end end --loading custom info into tables CustomInfo --using custom info if available, otherwise get date from page --if no custom name is given, use pagename as the name if(custom_info[pagename] == nil or custom_info[pagename]['name'] == '') then --cleaning up name --stripping text between parenthesis from pagename name = pagename:gsub('%s%(.-%)', '') --if name is used in page with first letter in lowercase, name is converted to first letter in lowercase local name_pattern = EscapeStringSymbols(name) lowercase_pattern = "'''%s*" .. firstToLower(name_pattern) .. "%s*'''.*" lowercase_match = string.match(content, lowercase_pattern) if(lowercase_match ~= nil) then name = firstToLower(name) end else name = custom_info[pagename]['name'] end --if no custom image is given, get it from the article content if(custom_info[pagename] == nil or custom_info[pagename]['image'] == '') then --get image from the article content image = ParseImage(content) else image = custom_info[pagename]['image'] end

--if no custom description is given, get it from the article content if(custom_info[pagename] == nil or custom_info[pagename]['description'] == '') then --get description from the article content description = ParseDescription(content, name) else description = custom_info[pagename]['description'] end return BuildOutput(frame, "Featured " .. articleType, pagename, 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 doesn'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.GetArticle(frame) articleType = frame.args[1] if(articleType == 'Group' or articleType == 'Soloist' or articleType == 'Band' or articleType == 'Test') then --loading predefined data into tables local data = {} if(articleType == 'Test') then data = {"AmiinA", "Elfloat", "Predia", "Avandoned"} else data = require('Module:RandomArticle/' .. articleType .. 's') end

if(#data > 0) then --getting random pagename math.randomseed(os.time) pagename = data[math.random(#data)] data = nil return ParsePage(frame, articleType, pagename) else return "RandomArticle:GetArticle: " .. articleType .. ": PAGENAME list not found or empty." end else return "RandomArticle:GetArticle: Invalid Type. Supported: Groups, Bands, Soloists." end end return p