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') -- For determining release dates local MonthParse = require("Module:Month") -- Date and Time functions local lang = mw.language.new('en')

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

local ContributorNames = mw.loadData( 'Module:ComicsHF/dataContributors' ).ContributorNames

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.Image1 = invokeInt('_PrimaryCover') Infobox.Image2 = invokeInt('_TextlessCover') Infobox.ComicTitle = invokeInt('_deriveTitle') 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( '', args.StoryArc )) if not HF.isempty(args.StoryArc2) then ArcText = ArcText .. string.format(' and %s story arcs', args.StoryArc2 ) table.insert( category, string.format( '', 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( '', 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._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 mw.title.new( givenImage, 'File' ).exists == true then return givenImage .. '|' .. label elseif 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 mw.title.new( givenImage, 'File' ).exists == true and givenImage then return givenImage .. '| Textless' elseif mw.title.new( fromPage, 'File' ).exists == true then return fromPage .. '| Textless' elseif mw.title.new( givenImage, 'File' ).exists == true then return givenImage .. '| ' .. 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 == 1 and Issue then return string.format('%s # %s', Title, Volume, Title, Issue) elseif Title and Volume > 1 and Issue then return string.format('%s (Volume %s) # %s', Title, Volume, Title, Volume, Issue) else return '' end end

function Infobox._releaseDate( args, vars ) local ReleaseDate = args.ReleaseDate or nil if not ReleaseDate then return '' end if string.match(ReleaseDate, 'Week') then local Week, Year = string.match( ReleaseDate, "Week (.*),%s*(.*)") Week = tonumber(Week) - 3 Date = lang:formatDate( 'F j, Y', Year..'-W'..Week ) return string.format('%s', Week, Year, Date) elseif string.match(ReleaseDate, ',') then Week = lang:formatDate( 'W', ReleaseDate) Year = lang:formatDate( 'Y', ReleaseDate) Date = lang:formatDate( 'F j, Y', ReleaseDate) if mw.title.new( string.format('Category:Week %s, %s', Week, Year), 'Category' ) then return string.format('%s', Week, Year, Date) else return Date end else Week = lang:formatDate( 'W', ReleaseDate) Year = lang:formatDate( 'Y', ReleaseDate) Date = lang:formatDate( 'F j, Y', ReleaseDate) if mw.title.new( string.format('Category:Week %s, %s', Week, Year), 'Category' ) then return string.format('%s', Week, Year, Date) else return Date end end end

function Infobox._publicationDate( args, vars ) local links = {} local Month, Year = args.Month or nil, args.Year or nil local gMonth = args.Month or nil -- The given month input local Season = args.Season or nil if Month then if string.find( gMonth, 'Late' ) then Month = string.match( gMonth, "Late (.*)" ) table.insert( links,				string.format( '%s', Year, Month, gMonth )			) table.insert( links, ', ' ) elseif string.find( gMonth, 'Early' ) then Month = string.match( gMonth, "Early (.*)" ) table.insert( links,				string.format( '%s', Year, Month, gMonth )			) table.insert( links, ', ' ) elseif string.find( gMonth, 'Mid' ) then Month = string.match( gMonth, "Mid (.*)" ) table.insert( links,				string.format( '%s', Year, Month, gMonth )			) table.insert( links, ', ' ) elseif string.find( gMonth, 'x' ) then Month = string.match( gMonth, "(.*)x" ) table.insert( links,				string.format( '%s', Year, Month, gMonth )			) table.insert( links, ', ' ) elseif Year then table.insert( links,				string.format( '%s', Year, MonthParse._month(gMonth), MonthParse._month(gMonth .. 'x') )			) table.insert( links, ', ' ) elseif not Year then table.insert( links, MonthParse._month(gMonth .. x) ) end end if not Season and not Year then table.insert( links,			string.format( '%s', Year, MonthParse._month( Season ), Season )		) table.insert( links, ', ' ) end if Season and not Year then table.insert( links, Season ) end if Year then table.insert( links,			string.format( '%s', Year, Year )		) end 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 keyname = string.lower( args[1] ) local role = args.role or args[2] or nil local correction if args.nocorrect then correction = args[1] else correction = ContributorNames.keyname or args[1] end table.insert( output, string.format('%s', correction, args[1]) ) if role then table.insert( output, string.format(' ', correction, role) ) end return table.concat( output ) end

function Infobox._Contributors( parameters ) local field = { min = tonumber(parameters['Contributors.min']), max = tonumber(parameters['Contributors.max']), prefix = parameters['Contributors.prefix'], 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 i == 1 and field.nocreditcheck ~= nil then Infobox._CreditCheck( { argcheck,                   field.canceled,			        role = field.role,			        nocorrection = field.nocorrection                     }) elseif i == 1 then table.insert( output, 			       Infobox._ContributorLink( { parameters[argcheck], role = field.role, nocorrect = field.nocorrection } )               )            elseif parameters[argcheck] then -- Value exists table.insert( output, 			       Infobox._ContributorLink( { parameters[argcheck], role = field.role, nocorrect = field.nocorrection } )               )			end if parameters[nextarg] and field.between then table.insert( output, field.between ) end end end return table.concat( output ) end

function Infobox._UContributors( parameters ) local field = { min = parameters['Contributors.min'], max = parameters['Contributors.max'], prefix = parameters['Contributors.prefix'], role = parameters['Contributors.role'], between = parameters['Contributors.between'], }	local output = {} if field.min and field.max then for i = field.min, field.max do local argument = field.prefix .. i			local next = i + 1 local nextargument = field.prefix .. next if parameters[argument] then table.insert( output, 			       Infobox._Contributors( { parameters[argument], role = field.role, nocorrect = true } )               ) end if parameters[nextargument] and field.between then table.insert( output, field.between ) end end elseif parameters[field.prefix] then table.insert( output, 			       Infobox._Contributors( { parameters[argument], role = field.role, nocorrect = true } )       ) end return table.concat( output ) end

function Infobox._StoryTitleHeader( args ) -- if " then -- if!" then "" if args[1] then local story = args[1] if not 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 Volume = tonumber(args.Volume) or tonumber(Volume) or nil Issue = tonumber(args.Issue) or tonumber(Issue) or nil if Volume == 1 and Issue == 1 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 ) elseif Volume > 1 and Issue == 1 then -- first issue of a new volume, refer to last volume Volume = Volume - 1 return string.format('%s Vol %s', Title, Volume) 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 NextIssue = string.format('%s Vol %s %s', Title, Volume, Issue + 1 ) NextVolume = string.format('%s Vol %s', Title, Volume + 1 ) if mw.title.new( NextIssue ).exists == true then return string.format('%s Vol %s # %s', NextIssue, Title, Volume, Issue + 1) elseif mw.title.new( NextVolume ).exists == true then return string.format('%s Vol %s', Title, Volume + 1 ) else return '' end end

return Infobox