Documentation for this module may be created at Module:ComicsInfobox/Comic/doc
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'..' Vol %s|%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'..' Vol %s|%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|%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( '[[:'..'Category:%s, %s|%s]]', Year, Month, Month )
)
table.insert( links, ', ' )
end
if Season then
local ParsedSeason = MonthParse._month( Season )
table.insert( links,
string.format( '[[:'..'Category:%s, %s|%s]]', Year, ParsedSeason, PasedSeason )
)
table.insert( links, ', ' )
end
table.insert( links,
string.format( '[[:'..'Category:%s|%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 <br/>),
--- '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 .. (' <small>(pg. '..parameters[pagestext]..')</small>')
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 .. (' <small>(pg. '..parameters[pagestext]..')</small>')
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 <br/>),
--- '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 .. (' <small>(pg. '..parameters[pagestext]..')</small>')
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 .. (' <small>(pg. '..parameters[pagestext]..')</small>')
end
end
end
end
function Infobox._StoryTitleHeader( args )
-- if " then [[{{FULLPAGENAME}}#Appearing in {{{StoryTitle1}}}|{{{StoryTitle1}}}]]
-- if!" then "[[{{FULLPAGENAME}}#Appearing in "{{{StoryTitle1}}}"|{{{StoryTitle1}}}]]"
if args[1] then
local story = args[1]
if string.match( story, '"') then
return string.format( '[[%s#Appearing in %s|%s]]',
mw.title.getCurrentTitle().prefixedText, story, story )
else
return string.format( '[[%s#Appearing in %s|"%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|%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 Vol %s %s|%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 # %s]]', NextIssue, Title, Issue + 1)
else
return string.format('[['..'%s|%s Vol %s # %s]]', NextIssue, Title, Volume, Issue + 1)
end
else
return ''
end
end
return Infobox