Module:RandomArticle

local p = {}

--================================= Custom Info Table ================================= --===== Use this to replace the automated info with custom image, description, etc ==== --Syntax: ["PAGENAME"] = {name = "Custom Name", image = "Custom Image", description = [=[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 custom_info = { ["Ikimonogakari"] = {name = "", image = "", description = [=[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.]=]}, ["marble≠marble"] = {name = "", image = "", description = [=[Tnaka is a solo idol that performs in the techno project marble≠marble.]=]}, ["OLDCODEX"] = {name = "", image = "", description = [=[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!.]=]}, ["YOASOBI"] = {name = "", image = "", description = [=[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.]=]}, --[""] = {name = "", image = "", description = [=[]=]}, }

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

function ParseImage(content) local 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 --searching for image in the infobox field "image" in the format image.ext local imgpattern = 'image%s*=%s*(.-%.[gjpsw][einpv][befg][gp]?)' image = string.match(content, imgpattern) if(image ~= nil) then --removing possible gallery tag inside infobox field image = image:gsub(, ) --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, article_type, pagename) local name = nil local image = nil local description = nil local content = mw.title.new(pagename):getContent --checking if page is a redirect local redirect_pattern = '#REDIRECT%s*%[%[(.*)%]%]' local redirect_link = pagename while(redirect_link ~= null) do       --navigating through redirects until a page with no redirect is found redirect_link = string.match(content, redirect_pattern) if(redirect_link ~= null) then --if a redirect is found, pagename is replaced by the target of the redirect pagename = redirect_link content = mw.title.new(pagename):getContent end end --if page doesn't exist or is empty, get another page if(content == nil) then return p.GetArticle(frame) end

--using custom info if available, otherwise get data from page if(custom_info[pagename] == nil or custom_info[pagename]['name'] == '') then --determining article name --checking if name was changed using the magicword DISPLAYTITLE local displaytitle_pattern = "%{%{DISPLAYTITLE:(.-)%}%}" name = string.match(content, displaytitle_pattern) --getting name from PAGENAME if(name == nil) then --stripping text between parenthesis from PAGENAME name = pagename:gsub('%s%(.-%)', '') --checking if name was used with first letter in lowercase local lowercase_name_pattern = "'''%s*" .. FirstToLower(EscapeStringSymbols(name)) .. "%s*'''.*" lowercase_name_match = string.match(content, lowercase_name_pattern) if(lowercase_name_match ~= nil) then name = FirstToLower(name) end end else name = custom_info[pagename]['name'] end if(custom_info[pagename] == nil or custom_info[pagename]['image'] == '') then image = ParseImage(content) else image = custom_info[pagename]['image'] end if(custom_info[pagename] == nil or custom_info[pagename]['description'] == '') then description = ParseDescription(content, name) else description = custom_info[pagename]['description'] end return BuildOutput(frame, "Featured " .. article_type, pagename, name, image, description) end

function BuildOutput(frame, title, link, name, image, description) local IMG_SIZE = '250px' local PRIMARY_COLOR = '' --Using default from Template:Infocard local IMG_BACKGROUND_COLOR = '#3c3c3c' --Using Template:Infocard to display data for desktop only local desktop_output = frame:expandTemplate{ title = 'Infocard', args = {title = title, name = name, link = link, description = description, file = image, imgsize = IMG_SIZE, primarycolor = PRIMARY_COLOR, imgbackgroundcolor = IMG_BACKGROUND_COLOR} }	--Using Template:Infocard/mobile to display data for mobile only local mobile_output = frame:expandTemplate{ title = 'Infocard/mobile', args = {title = title, name = name, link = link, description = description, file = image, imgsize = IMG_SIZE, primarycolor = PRIMARY_COLOR, imgbackgroundcolor = IMG_BACKGROUND_COLOR} }	return ' ' .. desktop_output .. ' ' .. mobile_output .. ' ' end

function p.GetArticle(frame) local article_type = frame.args[1] if(article_type == 'Group' or article_type == 'Soloist' or article_type == 'Band' or article_type == 'Test') then --loading pagenames into tables local data = {} if(article_type == 'Test') then data = {"Pages to test goes here"} else data = require('Module:RandomArticle/' .. article_type .. 's') end

if(#data > 0) then --getting random index and accessing data table at that index math.randomseed(os.time) local pagename = data[math.random(#data)] data = nil return ParsePage(frame, article_type, pagename) else return "RandomArticle:GetArticle: " .. article_type .. ": PAGENAME list not found or empty." end else return "RandomArticle:GetArticle: Invalid Type. Supported: Group, Band, Soloist, Test." end end return p