Documentation for this module may be created at Module:ComicsInfobox/Character/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')
-----------------------
-- Libraries of data --
-----------------------
-- Various data tables which can be refactored for paradigm
-- Eventually, these will be sorted into:
-- * dataCitizenship_DC
-- * dataCitizenship_Marvel
-- * etc
-- local ctznTable = mw.loadData('Module:ComicsInfobox/dataCitizenship')
local occupations = mw.loadData('Module:ComicsInfobox/dataOccupation')
local unusualFeatures = mw.loadData('Module:ComicsInfobox/dataUnusualFeatures')
local origins = mw.loadData('Module:ComicsInfobox/dataOrigins')
-- Since this should only be evaluated once per pageview, it's now global
_G.vars = { Pagename = mw.title.getCurrentTitle().text }
---------------------
-- Local functions --
---------------------
local function transition(funcName)
-- This module's initial functions were made for InfoboxBuilder.
-- As a result, most of them can't be invoked for Portable Infoboxes.
-- To allow the existing code without rewriting it, this wrapper allows invocation.
return function (frame)
local args = getArgs(frame, { trim = true, removeBlanks = true })
return Infobox[funcName](args, vars)
end
end
local CitizenshipCheck = function( values, table )
local output = ""
local valueUpper = ""
local valueLower = ""
local pagename = vars.Pagename
for i, value in ipairs( values ) do
if type( value ) ~= nil then
valueUpper = HF.firstToUpper( HF.trim( value ) )
valueLower = string.lower( HF.trim( value ) )
if type( table.valid[valueUpper] ) ~= nil and table.valid[valueUpper] == true then
output = output .. HF.CategoryLink( valueUpper, pagename, valueUpper ) .. ", "
elseif type( table.substitutes[valueLower] ) == "string" then
output = output .. HF.CategoryLink( table.substitutes[valueLower], pagename, valueUpper ) .. ", "
else
output = output .. value .. ", "
end
else
output = output .. value
end
end
return output
end
local WeightSubcategory = function( weight )
local subcategory = ""
if
weight < 100 then
subcategory = 0
elseif weight >= 100 and weight < 150 then
subcategory = 100
elseif weight >= 150 and weight < 200 then
subcategory = 150
elseif weight >= 200 and weight < 300 then
subcategory = 200
elseif weight >= 300 and weight < 400 then
subcategory = 300
elseif weight >= 400 and weight < 500 then
subcategory = 400
elseif weight >= 500 then
subcategory = 500
end
return subcategory
end
local EyesCategory = function( eyes, vars )
local output = ""
local eyes = HF.firstToUpper( eyes )
local eyeslc = string.lower( eyes )
if eyeslc == "none" or eyeslc == "n/a" or eyeslc == "no eyes" then
output = output .. HF.CategoryLink( "No Eyes", vars.Pagename, "No Eyes" )
end
if mw.site.stats.pagesInCategory( eyes .. " Eyes", "pages" ) > 0 then
output = output .. HF.CategoryLink( eyes .. " Eyes", vars.Pagename, eyes )
else
output = output .. eyes
end
return output
end
local HairCategory = function( hair, vars )
local output = ""
local hair = HF.firstToUpper( hair )
local hairlc = string.lower( hair )
if hairlc == "gray" then
hair = "Grey"
elseif hairlc == "blonde" then
hair = "Blond"
elseif hairlc == "strawberry blonde" then
hair = "Strawberry Blond"
end
if hairlc == "bald" then
output = HF.CategoryLink( hair, vars.Pagename, hair )
elseif hairlc == "none" or hairlc == "no hair" then
output = HF.CategoryLink( "No Hair", vars.Pagename, "No Hair" )
else
if mw.site.stats.pagesInCategory( hair .. " Hair", "pages" ) > 0 then
output = HF.CategoryLink( hair .. " Hair", vars.Pagename, hair )
else
output = hair
end
end
return output
end
----------------------
-- Public functions --
----------------------
-- These are the invocation-friendly calls.
-- These are backward from the normal '_' order, for legacy purposes.
Infobox.getTitle = transition('_getTitle')
Infobox.MainImage = transition('_MainImage')
Infobox.MainImageLabel = transition('_MainImageLabel')
Infobox.RealName = transition('_RealName')
Infobox.CurrentAlias = transition('_CurrentAlias')
Infobox.Alignment = transition('_Alignment')
Infobox.Identity = transition('_Identity')
--Infobox.Citizenship = transition('_Citizenship')
Infobox.MaritalStatus = transition('_MaritalStatus')
Infobox.Occupation = transition('_Occupation')
Infobox.Characteristics = transition('_Characteristics')
Infobox.Gender = transition('_Gender')
Infobox.Height = transition('_Height')
Infobox.Weight = transition('_Weight')
Infobox.Eyes = transition('_Eyes')
Infobox.Hair = transition('_Hair')
Infobox.Skin = transition('_Skin')
Infobox.UnusualFeatures = transition('_UnusualFeatures')
Infobox.Origin = transition('_Origin')
Infobox.Universe = transition('_Universe')
Infobox.Sector = transition('_Sector')
Infobox.Ctry = transition('_Ctry')
Infobox.Creators = transition('_Creators')
Infobox.OriginalPublisher = transition('_OriginalPublisher')
function Infobox._getTitle( field, vars )
local title = field.Value
if not HF.isempty(field.Title) then
title = field.Title
elseif not HF.isempty(field.CurrentAlias) then
title = field.CurrentAlias
elseif not HF.isempty(field.CurrentAliasRef) then
title = field.CurrentAliasRef
elseif not HF.isempty(field.RealName) then
title = field.RealName
end
local link = '<span style="position:relative; float:right; font-size:70%;">[[File:Help.png|link=Help:Template Fields#Character Template|Character Template Help]]</span>'
local titleObj = mw.title.new( title )
if type(titleObj) ~= "nil" then
if titleObj.exists then
link = link .. HF.Link( title, "" )
else
link = link .. title
end
else
link = link .. title
end
if HF.isempty( field.Death ) then
link = link .. HF.CategoryLink( "Living Characters", vars.Pagename, "" )
else
link = link .. HF.CategoryLink( "Deceased Characters", vars.Pagename, "" )
end
return link
end
function Infobox._MainImage( field, vars )
if HF.isempty( field.ImageText ) then field.ImageText = vars.Pagename end
return '[[File:' .. field.Value .. '|center|' .. field.ImageText .. ']]'
end
function Infobox._MainImageLabel( field, vars )
if HF.isempty( field.Gallery ) then field.Gallery = vars.Pagename .. "/Gallery" end
return HF.Link( field.Gallery, field.Label )
end
function Infobox._RealName( field, vars )
local output = ""
if HF.isempty( field.ValueReal ) then
output = field.Value
else
if string.find( field.ValueReal, "%[%[.+%]%]" ) == nil then
link = HF.Link( field.ValueReal, "" )
else
link = field.ValueReal
end
output = output .. link
end
if not HF.isempty( field.Value2 ) then
output = output .. " " .. field.Value2
end
if not HF.isempty( field.ValueRef ) then
output = output .. "" .. field.ValueRef
end
return output
end
function Infobox._CurrentAlias( field, vars )
local output = { field.Value, field.ValueRef }
return table.concat( output, ' ' )
end
function Infobox._Alignment( field, vars )
local output = ""
local alignment = ""
if not HF.isempty( field.Value ) then
if field.Value:lower() == "evil" or field.Value:lower() == "bad" then
alignment = "Bad"
elseif field.Value:lower() == "neutral" then
alignment = "Neutral"
elseif field.Value:lower() == "good" then
alignment = "Good"
elseif field.Value:lower() == "civilian" then
alignment = "Civilian"
end
output = HF.CategoryLink( alignment .. " Characters", vars.Pagename, alignment )
else
output = ""
end
return output
end
function Infobox._Identity( field, vars )
local output = {}
if not HF.isempty( field.Value ) then
local category = field.Value .. ' Identity'
table.insert( output, HF.CategoryLink( category, vars.Pagename, category ) )
end
table.insert( output, field.Value2 )
return table.concat( output, ' ' )
end
function Infobox._MaritalStatus( field, vars )
local statuses = HF.explode( ";", field.Value )
local o = {}
for i, status in ipairs( statuses ) do
if string.lower(status) == "married" or string.lower(status) == "remarried" then
table.insert( o, HF.CategoryLink( "Married Characters", vars.Pagename, status ) )
else
table.insert( o, HF.CategoryLink( status .. " Characters", vars.Pagename, status ) )
end
end
table.insert( o, field.Value2 )
return table.concat(o, ' ')
end
function Infobox._Occupation( field, vars )
local output = field.Value
for key, value in pairs(occupations) do
if string.find( string.lower(field.Value), key ) ~= nil then
for i, category in ipairs( value ) do
output = output .. HF.CategoryLink( category, vars.Pagename, "" )
end
end
end
return HF._TrimOverflow( output )
end
function Infobox._Characteristics( field, vars )
local output = field.Value
if not HF.isempty( field.CharRef ) then
output = output .. field.CharRefTag
end
return HF._TrimOverflow( output )
end
function Infobox._Gender( field, vars )
local output = {}
local genderExploded = HF.explode( ';', field.Value )
for i, gender in ipairs( genderExploded ) do
local category = gender .. " Characters"
table.insert(output, HF.CategoryLink( category, vars.Pagename, gender ))
end
if HF.isempty( field.Value2 ) then
field.Value2 = ''
end
return table.concat(output, ', ') .. field.Value2 or ''
end
function Infobox._Height( field, vars )
local output = ""
local valid = false -- to check if the height (in ft.) is in a valid format
local validInch = false -- to check if the height (in inches) is in a valid format
local delimiter = ""
if string.find( field.Value, "'" ) ~= nil then
valid = true
delimiter = "'"
elseif string.find( field.Value, "ft" ) ~= nil then
valid = true
delimiter = "ft"
end
if valid == true then
local heightExploded = HF.explode( delimiter, field.Value )
local feet = string.match( tostring( heightExploded[1] ), "%d+" )
local inches = string.match( tostring( heightExploded[2] ), "%d+" )
if feet == nil then
feet = "0"
end
if inches == nil then
inches = "0"
end
local heightValid = feet .. "\' " .. inches .. "\""
local feetPadded = HF.AddZeros( feet, 5 )
local inchesPadded = HF.AddZeros( inches, 2 )
local heightPadded = feetPadded .. "\' " .. inchesPadded .. "\""
local footCategory = "Height " .. feet .. "'"
local inchesCategory = "Height " .. heightValid
local from = mw.uri.encode( "%20" .. feetPadded .. "'" .. inchesPadded .. "\"", "PATH" )
local category = tostring( mw.uri.canonicalUrl( ":Category:Height", "from=" .. from ) )
-- Link to Height Category with from= parameter
output = HF.ExternalLink( category, heightValid, true )
-- All into Height Category, sorted by Height and then Pagename
output = output .. HF.CategoryLink( "Height", heightPadded .. vars.Pagename, "" )
-- All of the same 'Feet' into appropriate Foot category, sorted by inches then pagename.
output = output .. HF.CategoryLink( footCategory, inchesPadded .. vars.Pagename, "" )
-- All of the same inches in the same feet category, sorted by pagename.
output = output .. HF.CategoryLink( inchesCategory, vars.Pagename, "" )
-- Concat Height2
if not HF.isempty( field.Value2 ) then
output = output .. " " .. field.Value2
end
else
if HF.isempty( field.Value2 ) then
field.Value2 = ''
end
output = field.Value .. " " .. field.Value2
end
return output
end
function Infobox._Weight( field, vars )
local output = ""
local Units = {
["lbs"] = {
["lbs"] = 1.0,
["kg"] = 0.453592,
["ton"] = 0.0005
},
["kg"] = {
["lbs"] = 2.20462,
["kg"] = 1.0,
["ton"] = 0.00110231
},
["ton"] = {
["lbs"] = 2000,
["kg"] = 907.185,
["ton"] = 1.0
}
}
local unit = ""
if string.find( field.Value, "lbs" ) then
unit = "lbs"
elseif string.find( field.Value, "kg" ) then
unit = "kg"
elseif string.find( field.Value, "ton" ) then
unit = "ton"
else
unit = ""
end
if unit ~= "" then
local weight = tonumber( string.match( field.Value, "%d+" ) )
local weightLbs = HF.round( weight * Units[unit].lbs , 0 )
local weightKg = HF.round( weight * Units[unit].kg , 0 )
local weightValid = weightLbs .. " lbs (" .. weightKg .. " kg)"
local subcategory = WeightSubcategory( weightLbs )
local parameter = "from="
if subcategory == 0 then
parameter = "until="
subcategory = 100
end
local category = tostring( mw.uri.canonicalUrl( ":Category:Weight", parameter .. HF.AddZeros( subcategory, 5 ) ) )
output = HF.ExternalLink( category, weightValid, true )
output = output .. HF.CategoryLink( "Weight", "Weight " .. weightLbs, "" )
if not HF.isempty( field.Value2 ) then
output = output .. " " .. field.Value2
end
else
if HF.isempty( field.Value2 ) then
field.Value2 = ''
end
output = field.Value .. " " .. field.Value2
end
return output
end
function Infobox._Eyes( field, vars )
local output = {}
local eyes_table = HF.explode( ',', field.Value )
for i, eyes in ipairs(eyes_table) do
table.insert(output, EyesCategory( eyes, vars ) )
end
out = { table.concat(output, ', '), field.Value2 }
return table.concat( out, ' ' )
end
function Infobox._Hair( field, vars )
local output = {}
local hair_table = HF.explode( ',', field.Value )
for i, eyes in ipairs(hair_table) do
table.insert(output, HairCategory( eyes, vars ) )
end
out = { table.concat(output, ', '), field.Value2 }
return table.concat( out, ' ' )
end
function Infobox._Skin( field, vars )
local output = {}
local skin = HF.firstToUpper( field.Value )
if string.lower( skin ) == "none" or string.lower( skin ) == "n/a" then
table.insert( output, HF.CategoryLink( "No Skin", vars.Pagename, "No Skin" ) )
else
table.insert( output, HF.CategoryLink( skin .. " Skin", vars.Pagename, skin ) )
end
out = { table.concat( output ), field.Value2 }
return table.concat( out, ' ' )
end
function Infobox._UnusualFeatures( field, vars )
local output = field.Value
local valid = unusualFeatures.valid
local exceptions = unusualFeatures.exceptions
output = output .. ComicsInfobox.CategoriesFromKeywords( field.Value, valid, exceptions, vars )
return HF._TrimOverflow( output )
end
function Infobox._Origin( field, vars )
local output = field.Value
local valid = origins.valid
local exceptions = origins.exceptions
output = output .. ComicsInfobox.CategoriesFromKeywords( field.Value, valid, exceptions, vars )
return HF._TrimOverflow( output )
end
function Infobox._Universe( field, vars )
local o = {}
local c = {}
local UniverseNo = string.match( field.Value, "%d+" )
local UniverseValid = field.Value
if UniverseNo ~= nil then -- Universe has digits (Probably Marvel)
if string.match( string.lower( field.Value ), "trn" ) then
UniverseValid = "Earth-TRN" .. UniverseNo
table.insert(o, HF.Link( UniverseValid ))
table.insert(c, HF.CategoryLink( UniverseValid .. " Characters", vars.Pagename, "" ))
elseif string.match( string.lower( field.Value ), "bw" ) then
UniverseValid = "Earth-BW" .. UniverseNo
table.insert(o, HF.Link( UniverseValid ))
table.insert(c, HF.CategoryLink( UniverseValid .. " Characters", vars.Pagename, "" ))
else
UniverseValid = "Earth-" .. UniverseNo
table.insert(o, HF.Link( UniverseValid ))
table.insert(c, HF.CategoryLink( UniverseValid .. " Characters", vars.Pagename, "" ))
end
else -- Universe has no digits
if string.find( field.Value, ";" ) == nil then
table.insert(o, HF.Link( field.Value ) )
table.insert(c, HF.CategoryLink( field.Value .. " Characters", vars.Pagename, "" ) )
else
local universes = HF.explode( ';', field.Value )
for i, universe in ipairs( universes ) do
table.insert(o, HF.Link( universe ) )
table.insert(c,
HF.CategoryLink( universe .. " Characters",
vars.Pagename, ''
)
)
end
end
end
out = { table.concat(o, ', '), field.Value2, field.ValueRef }
return table.concat(out, ' ') .. table.concat(c)
end
function Infobox._Sector( field, vars )
local output = HF.Link( field.Value, "Sector " .. field.Value )
if string.find( vars.Theme, "greenlantern" ) ~= nil then
output = output .. HF.CategoryLink( "Green Lantern Corps member", vars.Pagename, "" )
end
return output
end
function Infobox._Ctry( field, vars )
local substitutes = {
["USA"] = "United States of America",
["US"] = "United States of America",
["United States"] = "United States of America",
["U.S.A."] = "United States of America",
["America"] = "United States of America"
}
local output = ""
if string.find( field.Value, "%[%[.+%]%]" ) == nil then
if type( substitutes[field.Value] ) == "string" then
output = HF.Link( substitutes[field.Value] )
else
output = HF.Link( field.Value )
end
else
output = field.Value
end
return output
end
function Infobox._Creators( field, vars )
local o = {}
local categories = {}
local creators = HF.explode( ';', field.Value )
for i, creator in ipairs( creators ) do
if type( creator ) ~= nil then
creator = HF.ContributorNameCorrection( HF.trim(creator) )
table.insert(categories, HF.CategoryLink( creator .. "/Creator", vars.Pagename, "" ) )
table.insert(o, HF.Link( creator, creator ) )
else
table.insert(o,
CategoryLink ("Character Creators Needed",
vars.Pagename, "" )
)
end
end
out = { table.concat(o, ', '), field.Value2 }
return table.concat(out, ' ') .. table.concat(categories)
end
function Infobox._OriginalPublisher( field, vars )
local output = field.Value
if string.lower( field.Value ) ~= "dc" then
output = output .. HF.CategoryLink( field.Value .. "Characters", vars.Pagename, "" )
end
return output
end
return Infobox