Module:Card/models/Locale

From Yugipedia
< Module:Card
Revision as of 11:44, 19 August 2023 by Deltaneos (talk | contribs) (some fixes to `getHtmlLang`, add `getRomanizedHtmlLang`)
Jump to: navigation, search
-- Base object for the Locale
-- Represents a card's details in a particular language
--
-- Unless otherwise stated, string params are in the language in question
-- @field lang               string     Two-letter code for the language
-- @field name               string     The card's name
-- @field romanizedName      string     The card's name, romanized
-- @field translatedName     string     The card's name, translated into English
-- @field pendulumEffect     string     The card's Penudlum Effect
-- @field material           string     The material portion of the card's lore
-- @field lore               string     The card description/effect portion of the lore (Should not include italic markup)
-- @field archetypeCondition string     The archetype condition portion of the lore (Should not include parentheses)
local Locale = {
	lang = nil,
	name = nil,
	romanizedName = nil,
	translatedName = nil,
	pendulumEffect = nil,
	material = nil,
	lore = nil,
	archetypeCondition = nil,
}

local languages = {
	en = {
		name           = 'English',
		LangCode       = 'en',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
	},
	fr = {
		name           = 'French',
		langCode       = 'fr',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
	},
	de = {
		name           = 'German',
		langCode       = 'de',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
	},
	it = {
		name           = 'Italian',
		langCode       = 'it',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
	},
	pt = {
		name           = 'Portuguese',
		langCode       = 'pt',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
	},
	es = {
		name           = 'Spanish',
		langCode       = 'es',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
	},
	ja = {
		name           = 'Japanese',
		langCode       = 'ja',
		scriptCode     = 'Japn',
		romanizedNames = true,
		italicLores    = false,
	},
	zh = {
		name           = 'Chinese',
		langCode       = 'zh',
		scriptCode     = nil,
		romanizedNames = true,
		italicLores    = false,
	},
	tc = {
		name           = 'Traditional Chinese',
		langCode       = 'zh',
		scriptCode     = 'Hant',
		romanizedNames = false,
		italicLores    = true,
	},
	sc = {
		name           = 'Simplified Chinese',
		langCode       = 'zh',
		scriptCode     = 'Hans',
		romanizedNames = true,
		italicLores    = false,
	},
	ko = {
		name           = 'Korean',
		langCode       = 'ko',
		scriptCode     = nil,
		romanizedNames = true,
		italicLores    = false,
	},
}

-- Create a new instance of the Locale object
-- @param lang            string   The language code
-- @param params          table 
-- @return Locale
function Locale:new(lang, params)
	-- Create a new instance of the Locale class with all the default values
	local l = {}
	setmetatable(l, Locale)
	Locale.__index = Locale

	-- English parameters don't have a prefix e.g. `name`, `lore`
	-- Other languages use their code as their prefix e.g. `ja_name`, `ja_lore`
	local prefix = lang == 'en' and '' or lang .. '_'

	l.lang               = lang
	l.language           = languages[lang]
	l.name               = params[prefix .. 'name']                or nil
	l.romanizedName      = params[prefix .. 'romanized_name']      or nil
	l.translatedName     = params[prefix .. 'translated_name']     or nil
	l.pendulumEffect     = params[prefix .. 'pendulum_effect']     or nil
	l.material           = params[prefix .. 'material']            or nil
	l.lore               = params[prefix .. 'lore']                or nil
	l.archetypeCondition = params[prefix .. 'archetype_condition'] or nil

	return l
end

-- Create many instances of the Locale object
-- @param langs           array    List of language codes
-- @param params          table
-- @return table                   Mapping of language codes to Locale objects
function Locale:createMany(langs, params)
	params = Locale.normalizeParams(params)

	-- List of all Locale objects for the card
	local locales = {}

	for _, lang in pairs(langs) do
		-- Only add to the list if there is data for this language
		if (Locale.hasParams(lang, params)) then
			locales[lang] = self:new(lang, params)
		end
	end

	return locales
end

-- Normalize the input params
-- Relable params to use a consistent format across all languages.
-- e.g. "romaji_name", "ko_rr_name" → "ja_romanized_name", "ko_romanized_name"
-- @param params table
function Locale.normalizeParams(params)
	-- table mapping labels to standardized ones
	local mappings = {
		romaji_name = 'ja_romanized_name',
		trans_name  = 'ja_translated_name',
		ko_rr_name  = 'ko_romanized_name'
	}

	-- Loop through the mappings
	-- If the old label is used in params, also its value under the new label
	for inputParam, normalizedParam in pairs(mappings) do
		if params[inputParam] then
			params[normalizedParam] = params[inputParam]
		end
	end

	return params
end

-- Check if a supplied input has params in a specified language
-- @param lang string
-- @param params table - Input params (after normalization)
-- @return boolean
function Locale.hasParams(lang, params)
	-- There should always be an English
	if lang == 'en' then return true end

	-- Check if at least one param is supplied for the language
	return (
		params[lang .. '_name'] or
		params[lang .. '_lore'] or
		params[lang .. '_pendulum_effect'] or
		params[lang .. '_material'] or
		params[lang .. '_archetype_condition'] or
		params[lang .. '_romanized_name'] or
		params[lang .. '_translated_name']
	) and true or false
end

-- Get the name of the instance's language
-- @return string
function Locale:getLanguageName()
	return self.language.name
end

-- Get the code for the HTML lang attribute
-- i.e. text that appears inside `lang="..."` in HTML
-- @return string
function Locale:getHtmlLang()
	local output = self.language.langCode

	if (self.language.scriptCode ~= nil) then
		output = output .. '-' .. self.language.scriptCode
	end

	return output
end

-- Get the code for the HTML lang attribute for romanized text
-- @return string
function Locale:getRomanizedHtmlLang()
	return self.language.langCode .. '-Latn'
end

-- Put the material, lore and archetype condition together to form the full lore
-- @param boolean isNormalMonster - If the card is a Normal monster
-- @return string
function Locale:getFullLore(isNormalMonster)
	local output = ''
	local archetypeCondition = nil

	if (self.archetypeCondition) then
		archetypeCondition = '(' .. self.archetypeCondition .. ')'
	end

	-- Handle Normal Monsters
	-- Lore (with italics depending on language, followed by archetype condition)
	if (isNormalMonster) then
		local output = self.lore

		if (self.language.italicLores) then
			output = output .. '<i>' .. output .. '</i>' 
		end

		if (archetypeCondition) then
			output = output .. '<br /><br />' .. archetypeCondition
		end

		return output
	end

	-- Handle everything else
	-- Array of different lore comporenents
	local loreParts = {
		self.material or nil,
		archetypeCondition or nil,
		self.lore or nil
	}

	-- Remove empty values
	loreParts = TableTools.compressSparseArray(loreParts)

	-- Join the components, separating each with a line break
	return table.concat(loreParts, '<br />')
end

return Locale