Module:Character Template

-- module for Marvel Database:Character Template local p = {} local getArgs = require('Module:Arguments').getArgs local h = require("Module:HF") local design = require('Module:Design') local units = require('Module:Units') local list_of_power_grids = mw.loadData('Module:Power Grid/List')

function p.main(frame) local args = getArgs(frame) local pagename = mw.title.getCurrentTitle.text local page_type = 'Character' local value local categories = {} local output_categories = {} local output = {}

table.insert(output_categories, p.lua_get_outdated_fields(args) ) -- sections -- adds 'Quote', 'Overview' section, 'TOC' and 'History' section value, categories = design.add_quote_overview_toc_history(args, page_type) output_categories = h.join_tables(output_categories, categories) output = h.join_tables(output, value)

table.insert( output, design.add_section('Personality', args.Personality, 2) ) if not h.isempty(args.Powers) or not h.isempty(args.Abilities) or not h.isempty(args.Strength) or not h.isempty(args.Weaknesses) or list_of_power_grids[pagename] ~= nil then table.insert( output, design.add_header('Powers and Abilities', 2) ) if list_of_power_grids[pagename] ~= nil then value, categories = require('Module:Power Grid').main(pagename) output_categories = h.join_tables(output_categories, categories) table.insert(output, value) end table.insert( output, design.add_section('Powers', args.Powers, 3) ) table.insert( output, design.add_section('Abilities', args.Abilities, 3) ) table.insert( output, design.add_section('Physical Strength', args.Strength, 3) ) table.insert( output, design.add_section('Weaknesses', args.Weaknesses, 3) ) end if not h.isempty(args.Equipment) or not h.isempty(args.Weapons)or not h.isempty(args.Transportation) then table.insert( output, design.add_header('Paraphernalia', 2) ) table.insert( output, design.add_section('Equipment', args.Equipment, 3) ) table.insert( output, design.add_section('Weapons', args.Weapons, 3) ) table.insert( output, design.add_section('Transportation', args.Transportation, 3) ) end

-- adds 'Notes', 'Trivia', 'See Also', 'Recommended Reading' and 'Links and References' sections links to standard sub-pages/categories - "Appearances", "Minor Appearances", Mentions", "Images", "Quotes" and "Gallery" 	value, categories = design.add_notes_trivia_see_also_recommended_links_references(args, page_type, pagename)	output_categories = h.join_tables(output_categories, categories)	output = h.join_tables(output, value)

--	output_categories = h.add_categories(output_categories) output = table.concat(output) return frame:preprocess(output)..output_categories end

--

-- function p.get_current_alias(frame) local args = getArgs (frame) local value = args.CurrentAlias local ref = args.CurrentAliasRef or ''

return value..ref end

-- function p.get_aliases(frame) local args = getArgs (frame) local list = {args.Codenames, args.EditorialNames, args.Nicknames, args.Impersonations, args.Aliases} local labels = {'Codenames', 'Editorial Names', 'Nicknames', 'Impersonations', 'Other Aliases'} local i	local output = {}

for i = 1, 5 do		if not h.isempty(list[i]) then if labels[i] == 'Other Aliases' and table.concat(output) == '' then table.insert(output, list[i]) else table.insert(output, design.span(labels[i]..':').bold..' '..list[i]) end end end output = mw.text.listToText(output, ' ', ' ')

return output end

-- function p.get_relatives(frame) local args = getArgs (frame) local list = {args.Ancestors, args.Grandparents, args.Parents, args.Siblings, args.Spouses, args.Children, args.Descendants, args.Relatives} local labels = {'Ancestors', 'Grandparents', 'Parents', 'Siblings', 'Spouses', 'Children', 'Descendants', 'Other Relatives'} local i	local output = {} for i = 1, 8 do		if not h.isempty(list[i]) then if labels[i] == 'Other Relatives' and table.concat(output) == '' then table.insert(output, list[i]) else table.insert(output, design.span(labels[i]..':').bold..' '..list[i]) end end end output = mw.text.listToText(output, ' ', ' ') return design.add_infobox_row_collapsible({output}) end

-- function p.get_living_status(frame) local args = getArgs (frame) local living_status = args.Status local output_categories = {} local output = '' if not h.isempty(args.Death) then table.insert(output_categories, 'Deceased Characters') output = h.LinkToCategory('Deceased Characters', 'Deceased') else table.insert(output_categories, 'Living Characters') output = h.LinkToCategory('Living Characters', 'Alive') if not h.isempty( p.get_cause_of_death(frame) ) then output = output..'; '..h.LinkToCategory('Formerly Deceased', 'formerly deceased') table.insert(output_categories, 'Formerly Deceased') end end if not h.isempty(living_status) then output = output..' '..living_status end

return output..h.add_categories(output_categories) end

-- function p.get_cause_of_death(frame) local args = getArgs (frame) local killed = args.KilledBy local casualty = args.CasualtyOf local suicide = args.Suicide local sacrifice = args.Sacrifice local cause = args.CauseOfDeath local link = '' local i	local output_categories = {} local output = '' if not h.isempty(cause) then if #cause > 500 then output = ' \n'..cause else output = cause end end if not h.isempty(killed) then killed = h.explode(";", killed) for i = 1,#killed do				link = h.break_link(h.trim(killed[i]), 1) table.insert(output_categories, 'Killed by '..link) end end if not h.isempty(casualty) then casualty = h.explode(";", casualty) for i = 1,#casualty do				link = h.break_link(h.trim(casualty[i]), 1) table.insert(output_categories, link..' casualties') end end if not h.isempty(suicide) then table.insert(output_categories, 'Suicide') end if not h.isempty(sacrifice) then table.insert(output_categories, 'Self-sacrifice') end

return output..h.add_categories(output_categories) end

-- function p.get_marital_status(frame) local function get_value_and_remainder(value) local i		local remainder = ''

i = string.find(value, ' ') if i ~= nil then remainder = ' '..string.sub(value, i+1, #value) value = string.sub(value, 1, i-1) end

return value, remainder end local args = getArgs (frame) local value = args.MaritalStatus local value2 = args.MaritalStatus2 local list = {'Married', 'Divorced', 'Engaged', 'Separated', 'Single', 'Widowed'} local l = {} local output_categories = {} local output = {} if not h.isempty(value) then output = {} l = h.explode(';', value) for i = 1, #l do				value, remainder = get_value_and_remainder(h.trim(l[i])) if h.in_list(list, value) then table.insert(output, h.LinkToCategory(value..' Characters', value)..remainder ) table.insert(output_categories, value..' Characters') else table.insert(output, h.LinkToCategory('Marital Status Needing Correction', value) ) end end output = mw.text.listToText(output, ', ', ', ') end

--if not h.isempty(value2) --	then table.insert(output, ' '..value2) --end return output..h.add_categories(output_categories) end

-- function p.get_occupation(frame) local args = getArgs (frame) local value = args.Occupation local occupations = require('Module:CharacterInfoboxOccupation') local output_categories = {} local output = '' if not h.isempty(value) then for key, v in pairs(occupations) do				if string.find( string.lower(value), key ) ~= nil then for i, category in ipairs(v) do							table.insert(output_categories, category) end end end output = value end

return design.add_infobox_row_collapsible({value})..h.add_categories(output_categories) end

-- function p.get_citizenship(frame) local args = getArgs (frame) local citizenship = require('Module:Citizenship') local value1 = args.Citizenship local value2 = args.Citizenship2 local valueUpper local valueLower local value local substitute local list = {} local i	local output_categories = {} local output = {} if not h.isempty(value1) then list = h.explode(',', value1) end

for i = 1, #list do		value = h.trim(list[i]) valueUpper = h.firstToUpper(value) valueLower = string.lower(value) value = citizenship.valid[valueUpper] substitute = citizenship.substitutes[valueLower] if value == true then table.insert(output, h.LinkToCategory(valueUpper, valueUpper) ) table.insert(output_categories, valueUpper) elseif type(substitute) == "string" then table.insert(output, h.LinkToCategory(substitute, valueUpper) ) table.insert(output_categories, substitute) else table.insert(output, list[i]) end end output = mw.text.listToText(output, ', ', ', ') if not h.isempty(value2) then output = output..' '..value2 end

return output..h.add_categories(output_categories) end

-- function p.get_weight_value_and_unit(value) local list = {'lbs', 'ton', 'oz', 'kg'} local remainder = '' local unit = '' local output = value

if string.find(value, 'Variable') ~= nil then output = 'Variable' remainder = string.match(value, 'Variable(.*)') else for i = 1, 4 do				unit = list[i] output, remainder = string.match(value, '(%d+.*%d*)'..unit..'(.*)') if output ~= nil then break else output = value end end if output == value then unit = '' end end if h.isempty(remainder) then remainder = '' end

return output, unit, remainder end

-- function p.get_weight(frame) local function lbs_to_kg(weightLbs) return h.round(weightLbs * units['lbs'].kg, 2) end local function get_weight_category(weightLbs) local i		local output if weightLbs < 10 then output = 'Weight 0-9 lbs ('..lbs_to_kg(10)..' kg)' elseif weightLbs >= 10 and weightLbs < 20 then output = 'Weight 10-19 lbs ('..lbs_to_kg(10)..'-'..lbs_to_kg(20)..' kg)' elseif weightLbs >= 20 and weightLbs < 300 then i = 20 while i <= 280 do					if weightLbs >= i and weightLbs < i + 20 then output = 'Weight '..i..'-'..(i+19)..' lbs ('..lbs_to_kg(i)..'-'..lbs_to_kg(i+20)..' kg)' end i = i + 20 end elseif weightLbs >= 300 and weightLbs < 1000 then i = 300 while i <= 900 do					if weightLbs >= i and weightLbs < i + 100 then output = 'Weight '..i..'-'..(i+99)..' lbs ('..lbs_to_kg(i)..'-'..lbs_to_kg(i+100)..' kg)' end i = i + 100 end elseif weightLbs >= 1000 then output = 'Weight above 1000 lbs ('..lbs_to_kg(1000)..' kg)' end return output end local args = getArgs (frame) local value = args.Weight --local value2 = args.Weight2 local weight local weightLbs = 0 local weightKg = 0 local unit = "" local remainder local i	local category local list = {} local output_categories = {} local output = {}

if not h.isempty(value) then list = h.explode(';', value) for i = 1, #list do				weight, unit, remainder = p.get_weight_value_and_unit(list[i]) if unit ~= '' then weightLbs = h.round( weight * units[unit].lbs, 2 ) weightKg = weight * units[unit].kg						if weightKg < 1 then weightKg = h.round( weightKg * 1000, 2 ) .. " gram" elseif weightKg > 1000 then weightKg = h.round( weightKg / 1000, 2 ) .. " ton" else weightKg = h.round( weightKg, 2 ) .. " kg" end category = get_weight_category(weightLbs) table.insert(output_categories, category) table.insert(output, h.LinkToCategory(category, weightLbs .. " lbs (" .. weightKg .. ")")..remainder) elseif weight == 'Variable' then category = 'Variable Weight' table.insert(output_categories, category) table.insert(output, h.LinkToCategory(category, weight)..remainder) else table.insert(output, weight..remainder) end end output = mw.text.listToText(output, ', ', ', ') end

--if not h.isempty(value2) --	then output = output.." " ..value2 --end

return output..h.add_categories(output_categories) end

-- function p.get_height_value(value, value2) local function round(m) return tonumber( string.format("%.2f", m) ) end local feet = string.match(value, "(%d+)'") local inches = string.match(value, '(%d+)"')	local metres	local remainder = 	local output = 

if feet ~= nil then if inches == nil then inches = '0' metres = feet * units['ft'].m					remainder = string.match(value, "%d+'(.+)") else metres = (feet * units['ft'].m) + (inches * units['in'].m)					remainder = string.match(value, '%d+"(.+)')			end

if metres < 1 then output = round(metres * 100)..' cm' elseif metres >= 1000 then output = round(metres / 1000)..' km' else output = round(metres)..' m'			end if inches ~= '0' then output = feet..'′'..inches..'″'..' ('..output..')' else output = feet..'′'..' ('..output..')' end elseif string.find(value, 'Variable') ~= nil then output = 'Variable' remainder = string.match(value, 'Variable(.*)') else feet = string.match(value, "(%d+) mile") if feet ~= nil then output = string.match(value, "%d+ mile[s]?")..' ('..round(feet * 1.609) ..' km)' remainder = string.match(value, "%d+ mile[s]? (.+)") feet = 1000 -- value to sort height into correct category end

end if h.isempty(remainder) then remainder = '' end

return output, remainder, feet, inches end

-- function p.get_height(frame) local function ft_to_m(heightFt) return tonumber( string.format("%.2f", heightFt * units['ft'].m) ) end local function get_height_category(heightFt, heightIn) local output heightFt = tonumber(heightFt) if heightFt < 1 then output = 'Height 0-1 ft. ('..ft_to_m(1)..' m)' elseif heightFt >= 1 and heightFt < 2 then output = 'Height 1-2 ft. ('..ft_to_m(1)..'-'..ft_to_m(2)..' m)' elseif heightFt >= 2 and heightFt < 3 then output = 'Height 2-3 ft. ('..ft_to_m(2)..'-'..ft_to_m(3)..' m)' elseif heightFt >= 3 and heightFt < 4 then output = 'Height 3-4 ft. ('..ft_to_m(3)..'-'..ft_to_m(4)..' m)' elseif heightFt >= 4 and heightFt < 5 then output = 'Height 4-5 ft. ('..ft_to_m(4)..'-'..ft_to_m(5)..' m)' elseif heightFt >= 5 and heightFt < 6 then output = 'Height 5 ft. '..heightIn..' in. ('..ft_to_m(5 + heightIn/12)..' m)' elseif heightFt >= 6 and heightFt < 7 then output = 'Height 6 ft. '..heightIn..' in. ('..ft_to_m(6 + heightIn/12)..' m)' elseif heightFt >= 7 and heightFt < 8 then output = 'Height 7-8 ft. ('..ft_to_m(7)..'-'..ft_to_m(8)..' m)' elseif heightFt >= 8 then output = 'Height above 8 ft. ('..ft_to_m(8)..' m)' end return output end local args = getArgs (frame) local value = args.Height local value2 = args.Height2 local height local height_ft local height_in local remainder local i	local category local list = {} local output_categories = {} local output = {}

if not h.isempty(value) then list = h.explode(';', value) for i = 1, #list do				height, remainder, height_ft, height_in = p.get_height_value(list[i]) if height ~= '' then if height_ft ~= nil then category = get_height_category(height_ft, height_in) elseif height == 'Variable' then category = 'Variable Height' end table.insert(output_categories, category) table.insert(output, h.LinkToCategory(category, height)..remainder) else table.insert(output, height..remainder) end end output = mw.text.listToText(output, ', ', ', ') end

--if not h.isempty(value2) --	then output = output.." " ..value2 --end

return output..h.add_categories(output_categories) end

-- function p.get_eyes(frame) local function eyeballs_color(value) local category = '' local output = '' if not h.isempty(value) then category = value..' Eyeballs' output = h.LinkToCategory(category, value) end return output, category end local function iris_color(value) local category = '' local output = '' if not h.isempty(value) then value = string.gsub(value, 'Gray', 'Grey') category = value..' Eyes' if h.pages_in_category(category, 'pages') > 0 then output = h.LinkToCategory(category, value) elseif value == 'No Iris' then category = 'No visible Irises or Pupils' output = h.LinkToCategory(category, 'No Visible') elseif value == 'No Eyes' then category = 'No Eyes' output = h.LinkToCategory(category, 'No Eyes At All') else category = '' end end return output, category end local function get_value_and_remainder(value) local i		local j		local remainder = '' i, j = string.find(value, 'No Iris') if j ~= nil then i = string.find(value, ' ', j)			else value = string.gsub(value, '^n%/a', 'No') value = string.gsub(value, '^None', 'No') value = string.gsub(value, '^No Eyes', 'No') value = string.gsub(value, '^No', 'No Eyes') i, j = string.find(value, '^No Eyes') if j ~= nil then i = string.find(value, ' ', j)					else i = string.find(value, ' ') end end if i ~= nil then remainder = ' '..string.sub(value, i+1, #value) value = string.sub(value, 1, i-1) end return value, remainder end local args = getArgs (frame) local eyes = args.Eyes local eyes2 = args.Eyes2 local eyeballs = args.Eyeballs local list = {} local category = '' local value local remainder local i	local output_categories = {} local output = '' if not h.isempty(eyes) then list = h.explode(';', eyes) eyes = {} for i = 1, #list do				value, remainder = get_value_and_remainder(h.trim(list[i])) value, category = iris_color(value) table.insert(output_categories, category) table.insert(eyes, '\n* '..value..remainder) end eyes = mw.text.listToText(eyes, , ) --if not h.isempty(eyes2) --	then eyes = eyes..' '..eyes2 --end output = '\n'..design.span('Irises:').bold..eyes end

if not h.isempty(eyeballs) then list = h.explode(';', eyeballs) eyeballs = {} for i = 1, #list do				value, remainder = get_value_and_remainder(h.trim(list[i])) value, category = eyeballs_color(value) table.insert(output_categories, category) table.insert(eyeballs, '\n* '..value..remainder) end eyeballs = mw.text.listToText(eyeballs, , ) output = '\n'..design.span('Eyeballs:').bold..eyeballs..output end

return output..h.add_categories(output_categories) end

-- function p.get_hair(frame) local function get_value_and_remainder(value) local exceptions_list = {'light brown', 'platinum blond', 'strawberry blond', 'no hair'} local i		local j		local k		local dyed = false local remainder = ''

value = string.gsub(value, '^n%/a', 'No') value = string.gsub(value, '^None', 'No') value = string.gsub(value, '^No Hair', 'No') value = string.gsub(value, '^No', 'No Hair') i, j = string.find(value, 'Dyed ') if j ~= nil then dyed = true value = string.gsub(value, 'Dyed ', '') end for k = 1, #exceptions_list do			i, j = string.find(string.lower(value), exceptions_list[k]) if j ~= nil then i = string.find(value, ' ', j)					break else i = string.find(value, ' ') end end if i ~= nil then remainder = ' '..string.sub(value, i+1, #value) value = string.sub(value, 1, i-1) end

return value, remainder, dyed end local function hair_color(value, dyed) local category = '' local output_categories = {} local output = '' if not h.isempty(value) then value = string.gsub(value, 'Gray', 'Grey') value = string.gsub(value, 'Blonde', 'Blond') value = string.gsub(value, 'Fair', 'Blond') value = string.gsub(value, 'Reddish Brown', 'Auburn') if value == 'Bald' then category = 'Bald' else category = value..' Hair' end if h.pages_in_category(category, 'pages') > 0 then output = h.LinkToCategory(category, value) elseif value == 'No Hair' then category = 'No Hair' output = h.LinkToCategory(category, 'No Hair At All') else category = '' end table.insert(output_categories, category) if dyed == true then table.insert(output_categories, 'Dyed Hair') output = h.LinkToCategory('Dyed Hair', 'Dyed')..' '..output end end return output, output_categories end local args = getArgs (frame) local hair = args.Hair local hair2 = args.Hair2 local category = '' local value local remainder local dyed local i	local list = {} local output_categories = {} local output = '' if not h.isempty(hair) then output = {} list = h.explode(';', hair) for i = 1, #list do				value, remainder, dyed = get_value_and_remainder(h.trim(list[i])) value, category = hair_color(value, dyed) output_categories = h.join_tables(output_categories, category) table.insert(output, value..remainder) end output = mw.text.listToText(output, ', ', ', ') end --if not h.isempty(hair2) --	then output = output..' '..hair2 --end return output..h.add_categories(output_categories) end

-- function p.get_skin(frame) local function get_value_and_remainder(value) local exceptions_list = {'light green', 'green, yellow', 'no skin'} local i		local j		local k		local remainder = ''

value = string.gsub(value, '^n%/a', 'No') value = string.gsub(value, '^None', 'No') value = string.gsub(value, '^No Skin', 'No') value = string.gsub(value, '^No', 'No Skin')

for k = 1, #exceptions_list do			i, j = string.find(string.lower(value), exceptions_list[k]) if j ~= nil then i = string.find(value, ' ', j)					break else i = string.find(value, ' ') end end if i ~= nil then remainder = ' '..string.sub(value, i+1, #value) value = string.sub(value, 1, i-1) end

return value, remainder end local function skin_color(value) local category = '' local output_categories = {} local output = '' if not h.isempty(value) then value = string.gsub(value, 'Gray', 'Grey') category = value..' Skin' if h.pages_in_category(category, 'pages') > 0 then output = h.LinkToCategory(category, value) elseif value == 'No Skin' then category = 'No Skin' output = h.LinkToCategory(category, 'No Skin At All') else category = '' end table.insert(output_categories, category) end return output, output_categories end local args = getArgs (frame) local skin = args.UnusualSkinColor or args.UnusualSkinColour --local skin2 = args.UnusualSkinColour2 local category = '' local value local remainder local i	local list = {} local output_categories = {} local output = '' if not h.isempty(skin) then output = {} list = h.explode(';', skin) for i = 1, #list do				value, remainder = get_value_and_remainder(h.trim(list[i])) value, category = skin_color(value) output_categories = h.join_tables(output_categories, category) table.insert(output, value..remainder) end output = mw.text.listToText(output, ', ', ', ') end --if not h.isempty(skin2) --	then output = output..' '..skin2 --end return output..h.add_categories(output_categories) end

-- function p.get_gender(frame) local function get_value_and_remainder(value) local i		local remainder = ''

i = string.find(value, ' ') if i ~= nil then remainder = ' '..string.sub(value, i+1, #value) value = string.sub(value, 1, i-1) end

return value, remainder end local function gender_category(value) local category = '' local output_categories = {} local output = '' if not h.isempty(value) then category = value..' Characters' if h.pages_in_category(category, 'pages') > 0 then output = h.LinkToCategory(category, value) else category = '' end table.insert(output_categories, category) end return output, output_categories end local args = getArgs (frame) local gender = args.Gender --local gender2 = args.Gender2 local category = '' local value local remainder local i	local list = {} local output_categories = {} local output = '' if not h.isempty(gender) then output = {} list = h.explode(';', gender) for i = 1, #list do				value, remainder = get_value_and_remainder(h.trim(list[i])) value, category = gender_category(value) output_categories = h.join_tables(output_categories, category) table.insert(output, value..remainder) end output = mw.text.listToText(output, ', ', ', ') end --if not h.isempty(gender2) --	then output = output..' '..gender2 --end

return output..h.add_categories(output_categories) end

-- function p.get_unusual_features(frame) local args = getArgs (frame) local value = args.UnusualFeatures local list = require('Module:CharacterInfoboxUnusualFeatures') local output_categories = p.get_categories_from_keywords(value, list.valid, list.exceptions) return value..h.add_categories(output_categories) end

-- function p.get_ctry(frame) local substitutes = require('Module:CharacterInfoboxCtry') local args = getArgs (frame) local value = args[1] local output = '' if not h.isempty(value) then output = value if string.find(value, "%[%[.+%]%]") == nil then if type(substitutes[value]) == "string" then output = h.Link(substitutes[value]) end end end return output end

-- function p.get_origin(frame) local args = getArgs (frame) local list = require('Module:CharacterInfoboxOrigins') local value = args.Origin local output = '' if not h.isempty(value) then output = p.get_categories_from_keywords(value, list.valid, list.exceptions) output = value..h.add_categories(output) end return output end

-- function p.get_categories_from_keywords(value, valid, exceptions) local output = {}

if not h.isempty(value) -- Field isn't blank then -- Grab a valid pair and use it			for validKey, validValue in pairs(valid) do				-- If you find the validKey in the field, and there are no exceptions for this validKey, then categorize if string.find(string.lower(value), validKey) ~= nil and type(exceptions[validKey]) ~= "table" then for valueKey, valueCategoryName in ipairs( validValue ) do							table.insert(output, valueCategoryName) end end end end return output end

return p