Module:ComicsInfobox/Comic

local Infobox = {}

-- Libraries of functions --

-- stands for High Frequency local HF = require('Module:ComicsHF') -- Parses invocation parameters, trims whitespace, and removes blanks local getArgs = require('Dev:Arguments').getArgs -- Common and centralized functions local ComicsInfobox = require('Module:ComicsInfobox') local MonthParse = require("Module:Month") local L = require('Dev:List') local lang = mw.language.new('en')

--- -- Libraries of data -- --- -- Data tables for common Staff contributors local StaffNames = require( 'Module:StaffCorrection' )

-- Since this should only be evaluated once per pageview, it's now global _G.vars = { Pagename = mw.title.getCurrentTitle.text }

- -- Local functions -- - local function invokeInt(funcName) -- This wrapper allows invocation of an internal function from a frame. return function (frame) local args = getArgs(frame, { trim = true, removeBlanks = true }) return Infobox[funcName](args, vars) end end

Infobox.HeadTitle = invokeInt('_deriveHeadTitle') Infobox.Events = invokeInt('_EventCollate') Infobox.Image1 = invokeInt('_PrimaryCover') Infobox.Image2 = invokeInt('_TextlessCover') Infobox.ComicTitle = invokeInt('_deriveTitle') Infobox.DigitalTitle = invokeInt('_deriveTitleDigital') Infobox.ReleaseDate = invokeInt('_releaseDate') Infobox.PublicationDate = invokeInt('_publicationDate')

function Infobox._deriveHeadTitle( args, vars ) local Title = mw.html.create('div'):addClass('comic-headtitle') local category = {} if not HF.isempty( args.HeadTitle ) then if string.lower( args.HeadTitle ) ~= 'none' then Title:tag('span'):addClass('comic-headtitle'):wikitext(args.HeadTitle):done end end if not HF.isempty( args.StoryArc or args.StoryArc2 ) then local StoryArc = mw.html.create('div'):addClass('comic-subtitle') local ArcText = string.format('Part of the '..'%s', args.StoryArc ) table.insert( category, string.format( ''..'Category:%s', args.StoryArc )) if not HF.isempty(args.StoryArc2) then ArcText = ArcText .. string.format(' and '..'%s story arcs', args.StoryArc2 ) table.insert( category, string.format( ''..'Category:%s', args.StoryArc2 )) else ArcText = ArcText .. ' story arc' end StoryArc:wikitext(ArcText):done Title:node( StoryArc ) end if not HF.isempty( args.Event or args.Event2 ) then local Event = mw.html.create('div'):addClass('comic-subtitle') local EventText = string.format('Part of the '..'%s', args.Event ) if not HF.isempty(args.Event2) then EventText = EventText .. string.format(' and '..'%s events', args.Event2 ) else EventText = EventText .. ' event' end Event:wikitext(EventText):done Title:node( Event ) end if not HF.isempty( args.Storyline ) then local Storyline = mw.html.create('div'):addClass('comic-subtitle') :wikitext(string.format('Part of the %s storyline.', args.Storyline )):done table.insert( category, string.format( ''..'Category'..':%s', args.Storyline )) Title:node( Storyline ) end Title:tag('div'):addClass('comic-subtitle'):tag('br', { selfClosing = true }):done return tostring(Title) .. table.concat( category ) end

function Infobox._EventCollate( args, vars ) if not HF.isempty( args.Event or args.Event2 or args.Event3 ) then local EventText = string.format('Part of the '..'%s', args.Event ) if not HF.isempty(args.Event2) and HF.isempty(args.Event3) then EventText = EventText .. string.format(' and '..'%s events',               args.Event2 ) elseif not HF.isempty(args.Event2) and not HF.isempty(args.Event3) then EventText = EventText .. string.format(', '..'%s, and '..'%s events',                args.Event2, args.Event3 ) else EventText = EventText .. ' event' end end end

function Infobox._StoryCollate( args, vars ) end

function Infobox._PrimaryCover( args, vars ) local givenImage = args.Image or args[1] or nil local fromPage = vars.Pagename .. '.jpg' local label = args.ImageText or args[2] or 'Cover' if givenImage and mw.title.new( givenImage, 'File' ).exists == true then return givenImage .. '|' .. label elseif fromPage and mw.title.new( fromPage, 'File' ).exists == true then return fromPage .. '|' .. label elseif givenImage then return givenImage .. '|' .. label else return nil end end

function Infobox._TextlessCover( args, vars ) local givenImage = args.Image2 or args[1] or nil local fromPage = vars.Pagename .. ' Textless.jpg' local label = args.Image2Text or args[2] or 'Textless' if givenImage and mw.title.new( givenImage, 'File' ).exists == true then return givenImage .. '|' .. label elseif fromPage and mw.title.new( fromPage, 'File' ).exists == true then return fromPage .. '|' .. label elseif givenImage then return givenImage .. '| ' .. label else return nil end end

function Infobox._deriveTitle( args, vars ) local Title, Volume, Issue = string.match( vars.Pagename, "(.*)%s*Vol%s*(%d)%s*(%d*)") Title = args.Title or Title or nil Volume = args.Volume or Volume or nil Issue = args.Issue or Issue or nil if Title and Volume and Issue then return string.format('%s'..' Vol %s # %s', Title, Volume, Issue) elseif Title and Volume then return string.format('%s', Title, Volume, Title) else return '' end end function Infobox._deriveTitleDigital( args, vars ) local Title, Volume, Chapter = string.match( vars.Pagename, "(.*)%s*Vol%s*(%d)%s*(%d*)%s*%(Digital%)") Title = args.Title or Title or nil Volume = args.Volume or Volume or nil Chapter = args.Chapter or Chapter or nil if Title and Volume and Chapter then return string.format('%s'..' Vol %s # %s', Title, Volume, Chapter) elseif Title and Volume then return string.format('%s', Title, Volume, Title) else return '' end end function Infobox._releaseDate( args, vars ) local ReleaseDate = args.ReleaseDate or nil local Date, Week, Year, CategoryTitle if not ReleaseDate then return '' end

if string.match(ReleaseDate, 'Week') then Week, Year = string.match( ReleaseDate, "Week (.*),%s*(.*)") Week = tonumber(Week) - 3 Date = lang:formatDate( 'F j, Y', Year..'-W'..Week ) else Week = lang:formatDate( 'W', ReleaseDate) Year = lang:formatDate( 'Y', ReleaseDate) Date = lang:formatDate( 'F j, Y', ReleaseDate) end

CategoryTitle = string.format('Category:Week %s, %s', Week, Year)

if mw.title.new( CategoryTitle ) then return string.format('%s', CategoryTitle, Date) else return Date end end

function Infobox._publicationDate( args, vars ) local links = {} local Month, Year = args.Month or nil, args.Year or nil local gMonth = args.Month -- The given month input local Season = args.Season or nil if Month then if string.find( gMonth, 'Late' ) then Month = string.match( gMonth, "Late (.*)" ) elseif string.find( gMonth, 'Early' ) then Month = string.match( gMonth, "Early (.*)" ) elseif string.find( gMonth, 'Mid' ) then Month = string.match( gMonth, "Mid (.*)" ) elseif string.find( gMonth, 'x' ) then Month = string.match( gMonth, "(.*)x" ) else Month = MonthParse._month( { gMonth } ) end

table.insert( links,	       string.format( '%s', Year, Month, Month )	    ) table.insert( links, ', ' ) end if Season then local ParsedSeason = MonthParse._month( Season ) table.insert( links,           string.format( '%s', Year, ParsedSeason, PasedSeason )        ) table.insert( links, ', ' ) end table.insert( links,		string.format( '%s', Year, Year )	)

return table.concat( links ) end

Infobox.CreditCheck = invokeInt('_CreditCheck') Infobox.ContributorLink = invokeInt('_ContributorLink') Infobox.Contributors = invokeInt('_Contributors') Infobox.UContributors = invokeInt('_UContributors') Infobox.StoryTitleHeader = invokeInt('_StoryTitleHeader') Infobox.PreviousIssue = invokeInt('_PreviousIssue') Infobox.NextIssue = invokeInt('_NextIssue')

function Infobox._CreditCheck( parameters ) if string.match( parameters[1], 'redited') or     string.match( parameters[1], 'NA') or      string.match( string.lower(parameters[1]), 'N/A') then return 'Uncredited' elseif parameters[2] then --Cancelation return '' elseif not parameters[2] then return Infobox._ContributorLink( 			           { parameters[1],			                role = parameters.role,			                nocorrect = parameters.nocorrection }			             ) end end

function Infobox._ContributorLink( args ) local output = {} local role = args.role or args[2] or nil local correction table.insert( output, StaffNames:link( args[1] ) ) if role then table.insert( output, StaffNames:cat_role( args[1], role ) ) end return table.concat( output ) end

function Infobox._Contributors( parameters ) -- This is a magical function that takes anywhere from 1 to infinite -- parameters and cuts them down to size. It makes links for contributors. local field = { -- If parameters are numbered, where do the numbers start and end? min = tonumber(parameters['Contributors.min']), max = tonumber(parameters['Contributors.max']), -- This can be "Writer" or "Writer1_" prefix = parameters['Contributors.prefix'], -- If it's specified that they contributed to certain pages... pages = parameters['Contributors.pagesprefix'], -- If the output is a list, what kind of list? --- 'horizontal' (default), 'bulleted', --- 'unbulleted' (aka ), --- 'ordered', or 'horizontal_ordered' list = parameters['Contributors.list'] or 'horizontal', role = parameters['Contributors.role'], between = parameters['Contributors.between'], nocreditcheck = parameters['Contributors.nocreditcheck'], nocorrection = parameters['Contributors.nocorrection'], canceled = parameters['Contributors.canceled'], }	local output = {} if field.min and field.max then for i = field.min, field.max do           local argcheck = field.prefix .. i           local nextarg = field.prefix .. (i + 1) if field.pages then pagestext = field.pages .. i           end -- somewhere in here needs to be an assertion that the parameter you're looking for exists. Like "Writer" vs "Writer1_". if i == 1 and field.nocreditcheck ~= nil then Infobox._CreditCheck( { argcheck,                   field.canceled,			        role = field.role,			        nocorrection = field.nocorrection                     }) elseif i == 1 or parameters[argcheck] then local link = Infobox._ContributorLink(			           { parameters[argcheck],			                role = field.role,			                nocorrect = field.nocorrection }		            ) if pagestext and parameters[pagestext] then -- Value exists link = link .. ('&#32; (pg. '..parameters[pagestext]..') ') end table.insert( output, link ) end -- if parameters[nextarg] and field.between then --	table.insert( output, field.between ) -- end end -- return table.concat( output ) return L.makeList( 'horizontal', output ) else -- A single parameter, huh? -- We can just do a singleton. local argcheck = field.prefix if field.pages then pagestext = field.pages end if field.nocreditcheck ~= nil then Infobox._CreditCheck( { argcheck,                   field.canceled,			        role = field.role,			        nocorrection = field.nocorrection                     }) elseif parameters[argcheck] then local link = Infobox._ContributorLink(			           { parameters[argcheck],			                role = field.role,			                nocorrect = field.nocorrection }		            ) if pagestext and parameters[pagestext] then -- Value exists link = link .. ('&#32; (pg. '..parameters[pagestext]..') ') end end end end

function Infobox._ContributorsDigital( parameters ) -- This is a magical function that takes anywhere from 1 to infinite -- parameters and cuts them down to size. It makes links for contributors. local field = { -- If parameters are numbered, where do the numbers start and end? min = tonumber(parameters['Contributors.min']), max = tonumber(parameters['Contributors.max']), -- This can be "Writer" or "Writer1_" prefix = parameters['Contributors.prefix'], -- If it's specified that they contributed to certain pages... pages = parameters['Contributors.pagesprefix'], -- If the output is a list, what kind of list? --- 'horizontal' (default), 'bulleted', --- 'unbulleted' (aka ), --- 'ordered', or 'horizontal_ordered' list = parameters['Contributors.list'] or 'horizontal', role = parameters['Contributors.role'], between = parameters['Contributors.between'], nocreditcheck = parameters['Contributors.nocreditcheck'], nocorrection = parameters['Contributors.nocorrection'], canceled = parameters['Contributors.canceled'], }	local output = {} if field.min and field.max then for i = field.min, field.max do           local argcheck = field.prefix .. i           local nextarg = field.prefix .. (i + 1) if field.pages then pagestext = field.pages .. i           end -- somewhere in here needs to be an assertion that the parameter you're looking for exists. Like "Writer" vs "Writer1_". if i == 1 and field.nocreditcheck ~= nil then Infobox._CreditCheck( { argcheck,                   field.canceled,			        role = field.role,			        nocorrection = field.nocorrection                     }) elseif i == 1 or parameters[argcheck] then local link = Infobox._ContributorLink(			           { parameters[argcheck],			                role = field.role,			                nocorrect = field.nocorrection }		            ) if pagestext and parameters[pagestext] then -- Value exists link = link .. ('&#32; (pg. '..parameters[pagestext]..') ') end table.insert( output, link ) end -- if parameters[nextarg] and field.between then --	table.insert( output, field.between ) -- end end -- return table.concat( output ) return L.makeList( 'horizontal', output ) else -- A single parameter, huh? -- We can just do a singleton. local argcheck = field.prefix if field.pages then pagestext = field.pages end if field.nocreditcheck ~= nil then Infobox._CreditCheck( { argcheck,                   field.canceled,			        role = field.role,			        nocorrection = field.nocorrection                     }) elseif parameters[argcheck] then local link = Infobox._ContributorLink(			           { parameters[argcheck],			                role = field.role,			                nocorrect = field.nocorrection }		            ) if pagestext and parameters[pagestext] then -- Value exists link = link .. ('&#32; (pg. '..parameters[pagestext]..') ') end end end end

function Infobox._StoryTitleHeader( args ) -- if " then -- if!" then "" if args[1] then local story = args[1] if string.match( story, '"') then            return string.format( '%s',            mw.title.getCurrentTitle.prefixedText, story, story )        else            return string.format( '"%s"',            mw.title.getCurrentTitle.prefixedText, string.format( '"%s"', story ), story )        end    else        return ' '    end end

function Infobox._PreviousIssue( args ) local Title, Volume, Issue if args.PreviousIssue then Title, Volume, Issue = string.match( PreviousIssue, "(.*)%s*Vol%s*(%d)%s*(%d*)") else Title, Volume, Issue = string.match( vars.Pagename, "(.*)%s*Vol%s*(%d)%s*(%d*)") end Title = args.Title or Title or nil OneShot = args.OneShot or OneShot or nil Volume = tonumber(args.Volume) or tonumber(Volume) or nil Issue = tonumber(args.Issue) or tonumber(Issue) or nil if (Volume == 1 and Issue == 1) or (Volume == nil and Issue == nil) or OneShot ~= nil then -- new title, no previous return '' elseif Issue > 1 and Volume ~= 1 then -- same volume, new issue Issue = Issue - 1 return string.format('%s Vol %s # %s', Title, Volume, Issue, Title, Volume, Issue ) elseif Issue > 1 and Volume == 1 then -- same first volume, new issue Issue = Issue - 1 return string.format('%s # %s', Title, Volume, Issue, Title, Issue ) else -- no other use cases return '' end end

function Infobox._NextIssue( args ) local Title, Volume, Issue if args.NextIssue then Title, Volume, Issue = string.match( NextIssue, "(.*)%s*Vol%s*(%d)%s*(%d*)") else Title, Volume, Issue = string.match( vars.Pagename, "(.*)%s*Vol%s*(%d)%s*(%d*)") end Title = args.Title or Title or nil Volume = tonumber(args.Volume) or tonumber(Volume) or nil Issue = tonumber(args.Issue) or tonumber(Issue) or nil if Volume == nil and Issue == nil then -- new title, no previous return '' else NextIssue = string.format('%s Vol %s %s', Title, Volume, Issue + 1 ) NextVolume = string.format('%s Vol %s', Title, Volume + 1 ) end if mw.title.new( NextIssue ).exists == true then if Volume == 1 then return string.format('%s # %s', NextIssue, Title, Issue + 1) else return string.format('%s Vol %s # %s', NextIssue, Title, Volume, Issue + 1) end else return '' end end

return Infobox