Module:ComicsInfobox/Character

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 CitizenshipCheck = require( 'Module:ComicsInfobox/Citizenship').CitizenshipCheck

--- -- Libraries of data -- --- -- Various data tables which can be refactored for paradigm -- Eventually, these will be sorted into: -- * dataCitizenship_DC -- * dataCitizenship_Marvel -- * etc Infobox._Occupation = require('Module:ComicsInfobox/Occupation')._Occupation Infobox._Citizenship = require( 'Module:ComicsInfobox/Citizenship')._Citizenship Infobox._Race = require( 'Module:ComicsInfobox/Race')._Race

-- 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 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 -- -- 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.Gallery = transition('_Gallery') 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.Race = transition('_Race') 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 or vars.Pagename if 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 elseif not HF.isempty(field.Title) then title, Universe = string.match( field.Title, "(.*)%s*%((.*)%)") end local o = {} local titleObj = mw.title.new( title ) or nil if type(titleObj) ~= "nil" then if titleObj.exists then table.insert(o, HF.Link( title ) ) else table.insert(o, title) end else table.insert(o, title) end if HF.isempty( field.Death ) then table.insert(o, HF.Category( 'Living Characters', vars.Pagename) ) end return table.concat( o ) end function Infobox._MainImage( field, vars ) if HF.isempty( field.ImageText ) then field.ImageText = vars.Pagename end return '' 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._Gallery( field, vars ) if HF.isempty( field.Gallery ) then field.Gallery = vars.Pagename .. "/Gallery" end return field.Gallery 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 if not HF.isempty( field.Value2 ) and not HF.isempty( field.ValueRef ) then output = output .. " " .. field.Value2 .. " " .. field.ValueRef end end return output end function Infobox._CurrentAlias( field, vars ) local output = field.Value if not HF.isempty( field.ValueRef ) then output = output .. " " .. field.ValueRef end return output end function Infobox._Alignment( field ) local o = {} local v = field.Value local alignment = { ['evil'] = HF.CategoryLink( 'Bad Characters', vars.Pagename, 'Bad' ), ['bad'] = HF.CategoryLink( 'Bad Characters', vars.Pagename, 'Bad' ), ['neutral'] = HF.CategoryLink( 'Neutral Characters', vars.Pagename, 'Neutral' ), ['good'] = HF.CategoryLink( 'Good Characters', vars.Pagename, 'Good' ), ['civilian'] = HF.CategoryLink( 'Civilian Characters', vars.Pagename, 'Civilian' ), }   if alignment[string.lower( v )] then return alignment[string.lower( v )] elseif mw.site.stats.pagesInCategory(      HF.firstToUpper(v) .. ' Characters', 'pages' ) > 0 then return HF.CategoryLink(                HF.firstToUpper(v) .. ' Characters',                vars.Pagename,                v ) else -- No Output end 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 ) if field.Value2 then field.Value = field.Value .. ',' .. field.Value2 end local o = {} local input = HF.explode( ',', field.Value ) local eyes = { ['none'] = HF.CategoryLink( 'No Eyes', vars.Pagename, 'No Eyes' ), ['n/a'] = HF.CategoryLink( 'No Eyes', vars.Pagename, 'No Eyes' ), ['no eyes'] = HF.CategoryLink( 'No Eyes', vars.Pagename, 'No Eyes' ) }   for i, v in ipairs(input) do        if eyes[string.lower( v )] then table.insert( o, eyes[string.lower( v )] ) elseif mw.site.stats.pagesInCategory( HF.firstToUpper(v) .. ' Eyes', 'pages' ) > 0 then table.insert( o,                    HF.CategoryLink( HF.firstToUpper(v) .. ' Eyes', vars.Pagename, v )               ) else table.insert( o, HF.firstToUpper(v) ) end end return table.concat( o, ' · ' ) end function Infobox._Hair( field ) if field.Value2 then field.Value = field.Value .. ',' .. field.Value2 end local o = {} local input = HF.explode( ',', field.Value ) local hair = { ['gray'] = HF.CategoryLink( 'Grey Hair', vars.Pagename, 'Grey Hair' ), ['blonde'] = HF.CategoryLink( 'Blond Hair', vars.Pagename, 'Blond Hair' ), ['strawberry blonde'] = HF.CategoryLink( 'Strawberry Blond Hair', vars.Pagename, 'Strawberry Blond Hair' ), ['bald'] = HF.CategoryLink( 'Bald', vars.Pagename, 'Bald' ), ['none'] = HF.CategoryLink( 'No Hair', vars.Pagename, 'No Hair' ), ['n/a'] = HF.CategoryLink( 'No Hair', vars.Pagename, 'No Hair' ), ['no hair'] = HF.CategoryLink( 'No Hair', vars.Pagename, 'No Hair' ), }   for i, v in ipairs(input) do        if hair[string.lower( v )] then table.insert( o, hair[string.lower( v )] ) elseif mw.site.stats.pagesInCategory( HF.firstToUpper(v) .. ' Hair', 'pages' ) > 0 then table.insert( o,                    HF.CategoryLink( HF.firstToUpper(v) .. ' Hair', vars.Pagename, v )               ) else table.insert( o, HF.firstToUpper(v) ) end end return table.concat( o, ' · ' ) end function Infobox._Skin( field, vars ) if field.Value2 then field.Value = field.Value .. ',' .. field.Value2 end local o = {} local input = HF.explode( ',', field.Value ) local skin = { ['none'] = HF.CategoryLink( 'No Skin', vars.Pagename, 'No Skin' ), ['no skin'] = HF.CategoryLink( 'No Skin', vars.Pagename, 'No Skin' ), ['n/a'] = HF.CategoryLink( 'No Skin', vars.Pagename, 'No Skin' ), }   for i, v in ipairs(input) do        if skin[string.lower( v )] then table.insert( o, skin[string.lower( v )] ) elseif mw.site.stats.pagesInCategory( HF.firstToUpper(v) .. ' Skin', 'pages' ) > 0 then table.insert( o,                    HF.CategoryLink( HF.firstToUpper(v) .. ' Skin', vars.Pagename, v )               ) else table.insert( o, HF.firstToUpper(v) ) end end return table.concat( o, ' · ' ) end function Infobox._UnusualFeatures( field, vars ) local unusualFeatures = require('Module:ComicsInfobox/UnusualFeatures') 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 origins = { ["alien"] = {"Aliens"}, ["deity"] = {"Deities"}, ["clone"] = {"Clones"}, ["cyborg"] = {"Cyborgs"}, ["cybernetic"] = {"Cyborgs"}, ["deity"] = {"Deities"}, ["mutant"] = {"Mutants"}, ["mutate"] = {"Mutates"}, ["zombie"] = {"Zombies"}, ["magician"] = {"Magicians"}, ["werewolf"] = {"Werewolves"}, ["metahuman"] = {"Metahumans"}, ["cosmic being"] = {"Cosmic Beings"}, ["doppelganger"] = {"Doppelgangers"}, ["gestalt"] = {"Gestalt Characters"}, ["gamma ray"] = {"Gamma Ray Exposure"}, ["time traveler"] = {"Time Travelers"}, ["cosmic ray"] = {"Cosmic Ray Exposure"}, ["psionic entity"] = {"Psionic Entities"}, ["vampire"] = {"Vampires", "Undead]"}, ["human/alien hybrid"] = {"Human/Alien Hybrid"}, ["hybrid"] = {"Hybrids"}, ["sorcer"] = {"Magicians"}, ["magician"] = {"Magicians"}, ["magic user"] = {"Magicians"}, ["witch"] = {"Magicians"}, ["neo "] = {"NeoMutants"}, ["undead"] = {"Undead"}, ["valkyr"] = {"Valkyries"}, ["warpie"] = {"WarpiesMutates"}, ["terrigen"] = {"Terrigenesis]"}, ["inhuman"] = {"Inhumans]"}, ["sentinel"] = {"Sentinels"}, ["kree sentr"] = {"Kree Sentries"}, ["wendigo"] = {"Wendigos"}, ["vi-lock "] = {"Vi-LocksTechno-Organic Virus"}, ["robot"] = {"Robots"}, ["robotic"] = {"Robots"}, ["ionic"] = {"Ionic Characters"}, ["psionic"] = {"Ionic Characters"}, ["cosmic being"] = {"Cosmic Beings"}, ["cosmic entity"] = {"Cosmic Beings"}, ["super-soldier"] = {"Super-Soldiers"}, ["super soldier"] = {"Super-Soldiers"}, }   for key, value in pairs(origins) 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 output end

function Infobox._Universe( field ) local o = {} local universes = HF.explode( ';', field.Value )

for i, universe in ipairs( universes ) do       local output = "" local UniverseNo   = string.match( universe, "%d+" ) local UniverseTRN  = string.match( string.lower( universe ), 'trn' ) local UniverseValid = universe if UniverseNo ~= nil then output = output .. HF.Link( UniverseValid ) output = output .. HF.CategoryLink(                UniverseValid .. ' Characters',                vars.Pagename,                '' ) else output = output .. HF.Link( universe ) output = output .. HF.CategoryLink(               universe .. ' Characters',                vars.Pagename,                '' ) end table.insert( o, output ) end output = table.concat( o, ' · ' ) 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._Sector( field, vars ) local output = HF.Link( 'Sector ' .. field.Value, 'Sector ' .. field.Value ) -- if string.find( vars.Theme, "greenlantern" ) ~= nil then --   output = output .. HF.Category( "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