Marvel Database
Advertisement

Documentation for this module may be created at Module:Character Template/Sandbox/doc

-- module for Marvel Database:Character Template
local p = {}
local getArgs = require('Module:Arguments').getArgs 
local h = require("Module:HF")
local design = require('Module:Design/Sandbox')
local standard = require("Module:StandardizedName")
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().subpageText
	local page_type = 'Character'
	local value
	local categories = {}
	local output_categories = {}
	local output = {}

	table.insert(output, '{{DEFAULTSORT:'..standard.name_for_sorting({pagename})..'|noerror}}')
	table.insert(output_categories, 'Characters')
	table.insert(output_categories, p.lua_get_outdated_fields(args) )

-- sections
	value, categories = design.add_quote(args)
	output_categories = h.join_tables(output_categories, categories)
	table.insert(output, value)

	table.insert( output, design.add_overview_and_toc(args.Overview) )
	
	value = args.HistoryText
	if h.isempty(value)
		then table.insert(output_categories, 'Character History Needed')
		else table.insert( output, design.add_section('History', value, 2) )
	end
	
	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
	or h.exists(pagename..'/Power Grid')
		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').lua_main(pagename)
					output_categories = h.join_tables(output_categories, categories)
					table.insert(output, value)
				elseif h.exists(pagename..'/Power Grid')
					then table.insert(output, '{{:'..pagename..'/Power Grid}}')
			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

	table.insert( output, design.add_section('Notes', args.Notes, 2) )
	table.insert( output, design.add_section('Trivia', args.Trivia, 2) )

	table.insert( output, design.add_header('See Also', 2) )
	--add links to standard sub-pages/categories - "Appearances", "Minor Appearances", Mentions", "Images", "Quotes" and "Gallery" 
	value, categories = design.add_links_to_standard_subpages(pagename, page_type)
	output_categories = h.join_tables(output_categories, categories)
	output = h.join_tables(output, value)
	
	table.insert( output, design.add_section('Recommended Reading', args.Recommended, 2) )
	
	table.insert( output, design.add_links_and_references(args, pagename) )
--
	output_categories = h.add_categories(output_categories)
	output = table.concat(output)
	
	return frame:preprocess(output)..output_categories
end

--------------------------------------------------------------------------------------------------
function p.lua_get_outdated_fields(args)
	local output = ''
	
	if  not h.isempty(args.Custom)
		or not h.isempty(args.CustomLabel)
		or not h.isempty(args.CustomSection1)
		or not h.isempty(args.CustomText1)
		or not h.isempty(args.CustomSection2)
		or not h.isempty(args.CustomText2)
		or not h.isempty(args.NotesHeader)
		or not h.isempty(args.TriviaHeader)
		or not h.isempty(args.LinksHeader)
		or not h.isempty(args.HistoryHeader)
		or not h.isempty(args.RecommendedHeader)
		or not h.isempty(args.PersonalityHeader)
		or not h.isempty(args.Height2)
		or not h.isempty(args.Weight2)
		or not h.isempty(args.Eyes2)
		or not h.isempty(args.Hair2)
		or not h.isempty(args.Gender2)
		or not h.isempty(args.Citizenship2) -- temporarily, to correctly put all citizenships into "Citizenship" field
		or not h.isempty(args.UnusualSkinColour2)
		or not h.isempty(args.MaritalStatus2) 
		or not h.isempty(args.PowersAbilitiesHeader)
		or not h.isempty(args.ParaphernaliaHeader)
		or not h.isempty(args.DiscoverAndDiscussHeader)
		or not h.isempty(args.OtherMedia)
		or not h.isempty(args.UniverseRef)
			then output = 'Outdated Fields/Character'
	end

	return output	
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, #list 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..'<br>'..list[i])
				end
		end
	end
	output = mw.text.listToText(output, '<br>', '<br>') 
	
	return design.add_infobox_row_collapsible({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, #list 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..'<br>'..list[i])
				end
		end
	end
	output = mw.text.listToText(output, '<br>', '<br>') 
	
	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
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 = '<br>\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 mw.text.listToText(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, ',<br>', ',<br>')
	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, ',<br>', ',<br>')
	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(.*)')
	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, ',<br>', ',<br>')
	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, ',<br>', ',<br>')
	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.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, ',<br>', ',<br>')
	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, ',<br>', ',<br>')
	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
Advertisement