Module:CharacterInfobox

local CharacterInfobox={}

local HF = require("Module:HF")

-- PRIVATE METHODS --

local AddZeros = function( s, len ) local output = ""

local sLength = string.len( tostring( s ) ) local diff = tonumber( len ) - tonumber( sLength )

if diff > 0 then for i = 1, diff do     output = output .. "0"   end end

output = output .. s

return output end

local ExternalLink = function( link, text, plain ) local output = "[" .. link .. " " .. text .. "]"

if plain == true then output = "" .. output .. " " end

return output end

local CategoryLink = function( category, sort, text ) local output = "" if not HF.isempty( text ) then output = "" .. text .. "" else output = "" end return output end

local Link = function( link, text ) local output = "[[" .. link

if not HF.isempty( text ) then output = output .. "|" .. text end

output = output .. "]]" return output end

local CitizenshipCheck = function( values, table ) local output = "" local valueUpper = "" local valueLower = ""

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 .. CategoryLink( valueUpper, valueUpper, valueUpper ) .. ", "       elseif type( table.substitutes[valueLower] ) == "string" then output = output .. CategoryLink( table.substitutes[valueLower], table.substitutes[valueLower], table.substitutes[valueLower] ) .. ", "       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 eyes = "No Eyes" end if mw.site.stats.pagesInCategory( eyes .. " Eyes", "pages" ) > 0 then output = output .. 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 = CategoryLink( hair, vars.Pagename, hair ) elseif hairlc == "none" or hairlc == "no hair" then output = CategoryLink( "No Hair", vars.Pagename, "No Hair" ) else if mw.site.stats.pagesInCategory( hair .. " Hair", "pages" ) > 0 then output = CategoryLink( hair .. " Hair", vars.Pagename, hair ) else output = hair end end

return output end

local CategoriesFromKeywords = function( fieldValue, valid, exceptions, vars ) local output = ""

for key, value in pairs(valid) do

-- Continue only if a word is found if string.find( string.lower(fieldValue), key ) ~= nil then -- Get all of the matches local matches = string.gmatch( fieldValue, key ) -- Check if a keyword has exceptions if type( exceptions.keys ) == "table" then -- Check if any of the matches is not an exception for exception in pairs( exceptions.key ) do         for keyword in matches do            if string.find( keyword, exception ) == nil then -- If a word doesn't match exceptions - add a link for each element of a value array to the output for i, category in ipairs( value ) do                 output = output .. CategoryLink( category, vars.Pagename, "" ) end end end end else for i, category in ipairs( value ) do         output = output .. CategoryLink( category, vars.Pagename, "" ) end end

end end

return output end

-- PUBLIC METHODS -- function CharacterInfobox.InfoButton( field, vars ) if HF.isempty( field.buttonsize ) then field.buttonsize = "10px" end

local output = ' ' output = output .. '' output = output .. ' ' .. field.Label .. ' '

return output end

function CharacterInfobox.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 = ' ' local titleObj = mw.title.new( title )

if type(titleObj) ~= "nil" then if titleObj.exists then link = link .. Link( title, "" ) else link = link .. title end else link = link .. title end

if HF.isempty( field.Death ) then link = link .. CategoryLink( "Living Characters", vars.Pagename, "" ) else link = link .. CategoryLink( "Deceased Characters", vars.Pagename, "" ) end

return link end

function CharacterInfobox.MainImage( field, vars ) if HF.isempty( field.ImageText ) then field.ImageText = vars.Pagename end

local output = ''

return output end

function CharacterInfobox.MainImageLabel( field, vars ) if HF.isempty( field.Gallery ) then field.Gallery = vars.Pagename .. "/Gallery" end

return Link( field.Gallery, field.Label ) end

function CharacterInfobox.RealName( field, vars ) local output = "" if HF.isempty( field.ValueReal ) then output = field.Value else if string.find( field.ValueReal, "%[%[.+%]%]" ) == nil then link = 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 CharacterInfobox.CurrentAlias( field, vars ) local output = field.Value if not HF.isempty( field.ValueRef ) then output = output .. " " .. field.ValueRef end return output end

function CharacterInfobox.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" end output = CategoryLink( alignment .. " Characters", alignment .. " Characters", alignment ) else output = "" end

return output end

function CharacterInfobox.Identity( field, vars ) local output = "" if not HF.isempty( field.Value ) then local category = field.Value .. " Identity" output = CategoryLink( category, category, category ) end if not HF.isempty( field.Value2 ) then output = output .. " " .. field.Value2 end return output end

function CharacterInfobox.Citizenship( field, vars ) local ctznTable   = require('Module:CharacterInfoboxCitizenship')

local citizenships = HF.explode( ",", field.Value) local citizenships2 = HF.explode( ",", field.Value2)

local output = ""

if not HF.isempty( citizenships ) then output = output .. CitizenshipCheck( citizenships, ctznTable ) end

if not HF.isempty( citizenships2 ) then output = output .. CitizenshipCheck( citizenships2, ctznTable ) end

if string.sub( output, -2, -1 ) == ", " then output = string.sub( output, 1, -3 ) -- Remove last comma and space end

if string.sub( output, -1, -1 ) == "," then output = string.sub( output, 1, -2 ) -- Remove last comma end

return output end

function CharacterInfobox.MaritalStatus( field, vars ) local statuses = HF.explode( ";", field.Value )

local output = ""

for i, status in ipairs( statuses ) do   if string.lower(status) == "married" or string.lower(status) == "remarried" then output = output .. CategoryLink( "Married Characters", vars.Pagename, status ) else output = output .. CategoryLink( status .. " Characters", vars.Pagename, status ) end end

output = output .. " " .. field.Value2

return output end

function CharacterInfobox.Occupation( field, vars ) local occupations = require('Module:CharacterInfoboxOccupation') 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 .. CategoryLink( category, vars.Pagename, "" ) end end end

return output end

function CharacterInfobox.Characteristics( field, vars ) local output = field.Value if not HF.isempty( field.CharRef ) then output = output .. field.CharRefTag end return output end

function CharacterInfobox.Gender( field, vars ) local category = field.Value .. " Characters" return CategoryLink( category, vars.Pagename, field.Value ) .. field.Value2 end

function CharacterInfobox.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     = AddZeros( feet, 5 )      local inchesPadded   = 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 = ExternalLink( category, heightValid, true )

-- All into Height Category, sorted by Height and then Pagename output = output .. CategoryLink( "Height", heightPadded .. vars.Pagename, "" )

-- All of the same 'Feet' into appropriate Foot category, sorted by inches then pagename. output = output .. CategoryLink( footCategory, inchesPadded .. vars.Pagename, "" )

-- All of the same inches in the same feet category, sorted by pagename. output = output .. CategoryLink( inchesCategory, vars.Pagename, "" )

-- Concat Height2 output = output .. " " .. field.Value2

else output = field.Value .. " " .. field.Value2 end

return output end

function CharacterInfobox.Weight( field, vars ) local output = "" local Units = require('Module:Units') 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 .. AddZeros( subcategory, 5 ) ) )

output = ExternalLink( category, weightValid, true ) output = output .. CategoryLink( "Weight", "Weight " .. weightLbs, "" )

output = output .. " " .. field.Value2 else output = field.Value .. " " .. field.Value2 end

return output end

function CharacterInfobox.Eyes( field, vars ) local output = ""

output = output .. EyesCategory( field.Value, vars ) output = output .. " " .. EyesCategory( field.Value2, vars )

return output end

function CharacterInfobox.Hair( field, vars ) local output = "" output = output .. HairCategory( field.Value, vars ) if not HF.isempty( field.Value2 ) then output = output .. " " .. field.Value2 end

return output end

function CharacterInfobox.Skin( field, vars ) local output = "" local skin  = HF.firstToUpper( field.Value ) if string.lower( skin ) == "none" or string.lower( skin ) == "n/a" then output = output .. CategoryLink( "No Skin", vars.Pagename, "No Skin" ) else output = output .. CategoryLink( skin .. " Skin", vars.Pagename, skin ) end

output = output .. field.Value2 return output end

function CharacterInfobox.UnusualFeatures( field, vars ) local output = field.Value -- Add categorising links

local unusualFeatures = require('Module:CharacterInfoboxUnusualFeatures') local valid = unusualFeatures.valid local exceptions = unusualFeatures.exceptions

output = output .. CategoriesFromKeywords( field.Value, valid, exceptions, vars )

return output end

function CharacterInfobox.Origin( field, vars ) local output = field.Value local origins = require('Module:CharacterInfoboxOrigins')

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 .. CategoryLink( category, vars.Pagename, "" ) end end end

return output end

function CharacterInfobox.Universe( field, vars ) local output = "" local UniverseNo   = string.match( field.Value, "%d+" ) local UniverseTRN  = string.match( string.lower( field.Value ), "trn" ) local UniverseValid = ""

if UniverseNo ~= nil then if UniverseTRN ~= nil then UniverseValid = "Earth-TRN" .. UniverseNo else UniverseValid = "Earth-" .. UniverseNo end

output = output .. Link( UniverseValid ) output = output .. CategoryLink( UniverseValid .. " Characters", vars.Pagename, "" ) else output = output .. Link( field.Value ) output = output .. CategoryLink( field.Value .. " Characters", vars.Pagename, "" ) 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 CharacterInfobox.Sector( field, vars ) local output = Link( field.Value, "Sector " .. field.Value ) if string.find( vars.Theme, "greenlantern" ) ~= nil then output = output .. CategoryLink( "Green Lantern Corps member", vars.Pagename, "" ) end return output end

function CharacterInfobox.Ctry( field, vars ) local substitutes = require('Module:CharacterInfoboxCtry') local output = "" if string.find( field.Value, "%[%[.+%]%]" ) == nil then if type( substitutes[field.Value] ) == "string" then output = Link( substitutes[field.Value] ) else output = Link( field.Value ) end else output = field.Value end return output end

function CharacterInfobox.Creators( field, vars ) local output = "" local SC = require('Module:StaffCorrection')

local creators = HF.explode( ";", field.Value ) for i, creator in ipairs( creators ) do  if type( creator ) ~= nil then creator = SC.Correction( creator ) output = output .. CategoryLink( creator .. "/Creator", vars.Pagename, "" ) output = output .. Link( creator, creator ) .. ", "   else output = output .. CategoryLink ("Character Creators Needed", vars.Pagename, "" ) end end

if string.sub( output, -2, -1 ) == ", " then output = string.sub( output, 1, -3 ) -- Remove last comma and space end

if string.sub( output, -1, -1 ) == "," then output = string.sub( output, 1, -2 ) -- Remove last comma end

output = output .. " " .. field.Value2 return output end

function CharacterInfobox.OriginalPublisher( field, vars ) local output = field.Value if string.lower( field.Value ) ~= "dc" then output = output .. CategoryLink( field.Value .. "Characters", vars.Pagename, "" ) end

return output end

return CharacterInfobox