Difference between revisions of "Module:Card/models/Locale"

From Yugipedia
Jump to: navigation, search
(some fixes to `getHtmlLang`, add `getRomanizedHtmlLang`)
(It should still be okay to make this local.)
 
(20 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
local Ruby = require('Module:Ruby')
 +
 +
-- Generic functions
 +
 +
-- Check if a value is filled (i.e. not `nil` or an empty string)
 +
-- @param value mixed
 +
-- @return boolean
 +
local function isFilled(value)
 +
return (value ~= nil and value ~= '')
 +
end
 +
 +
 
-- Base object for the Locale
 
-- Base object for the Locale
 
-- Represents a card's details in a particular language
 
-- Represents a card's details in a particular language
Line 9: Line 21:
 
-- @field pendulumEffect    string    The card's Penudlum Effect
 
-- @field pendulumEffect    string    The card's Penudlum Effect
 
-- @field material          string    The material portion of the card's lore
 
-- @field material          string    The material portion of the card's lore
 +
-- @field summoningCondition string    The Summoning condition portion of the card's lore
 +
-- @field requirement        string    The requirement portion of the card's lore (Should not include the '[REQUIREMENT]' prefix)
 
-- @field lore              string    The card description/effect portion of the lore (Should not include italic markup)
 
-- @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)
+
-- @field condition          string    The condition portion of the lore (Should not include parentheses)
 
local Locale = {
 
local Locale = {
 
lang = nil,
 
lang = nil,
 
name = nil,
 
name = nil,
 
romanizedName = nil,
 
romanizedName = nil,
 +
baseRomanizedName = nil,
 
translatedName = nil,
 
translatedName = nil,
 +
baseTranslatedName = nil,
 
pendulumEffect = nil,
 
pendulumEffect = nil,
 
material = nil,
 
material = nil,
 +
requirement = nil,
 
lore = nil,
 
lore = nil,
archetypeCondition = nil,
+
condition = nil,
 
}
 
}
  
Line 29: Line 46:
 
romanizedNames = false,
 
romanizedNames = false,
 
italicLores    = true,
 
italicLores    = true,
 +
text          = {
 +
['Requirement']        = '[REQUIREMENT]',
 +
['Effect']              = '[EFFECT]',
 +
['Continuous Effect']  = '[CONTINUOUS EFFECT]',
 +
['Multi-Choice Effect'] = '[MULTI-CHOICE EFFECT]'
 +
}
 
},
 
},
 
fr = {
 
fr = {
Line 36: Line 59:
 
romanizedNames = false,
 
romanizedNames = false,
 
italicLores    = true,
 
italicLores    = true,
 +
text          = {}
 
},
 
},
 
de = {
 
de = {
Line 43: Line 67:
 
romanizedNames = false,
 
romanizedNames = false,
 
italicLores    = true,
 
italicLores    = true,
 +
text          = {}
 
},
 
},
 
it = {
 
it = {
Line 50: Line 75:
 
romanizedNames = false,
 
romanizedNames = false,
 
italicLores    = true,
 
italicLores    = true,
 +
text          = {}
 
},
 
},
 
pt = {
 
pt = {
Line 57: Line 83:
 
romanizedNames = false,
 
romanizedNames = false,
 
italicLores    = true,
 
italicLores    = true,
 +
text          = {}
 
},
 
},
 
es = {
 
es = {
Line 64: Line 91:
 
romanizedNames = false,
 
romanizedNames = false,
 
italicLores    = true,
 
italicLores    = true,
 +
text          = {}
 
},
 
},
 
ja = {
 
ja = {
Line 71: Line 99:
 
romanizedNames = true,
 
romanizedNames = true,
 
italicLores    = false,
 
italicLores    = false,
 +
text          = {
 +
['Requirement']        = '【<ruby><rb>条</rb><rt>じょう</rt><rb>件</rb><rt>けん</rt>】',
 +
['Effect']              = '【<ruby><rb>効</rb><rt>こう</rt><rb>果</rb><rt>か</rt>】',
 +
['Continuous Effect']  = '【<ruby><rb>永</rb><rt>えい</rt><rb>続</rb><rt>ぞく</rt><rb>効</rb><rt>こう</rt><rb>果</rb><rt>か</rt></ruby>】',
 +
['Multi-Choice Effect'] = '【<ruby><rb>選</rb><rt>せん</rt><rb>択</rb><rt>たく</rt><rb>効</rb><rt>こう</rt><rb>果</rb><rt>か</rt></ruby>】'
 +
}
 
},
 
},
 
zh = {
 
zh = {
Line 78: Line 112:
 
romanizedNames = true,
 
romanizedNames = true,
 
italicLores    = false,
 
italicLores    = false,
 +
text          = {}
 
},
 
},
 
tc = {
 
tc = {
Line 83: Line 118:
 
langCode      = 'zh',
 
langCode      = 'zh',
 
scriptCode    = 'Hant',
 
scriptCode    = 'Hant',
romanizedNames = false,
+
romanizedNames = true,
italicLores    = true,
+
italicLores    = false,
 +
text          = {}
 
},
 
},
 
sc = {
 
sc = {
Line 92: Line 128:
 
romanizedNames = true,
 
romanizedNames = true,
 
italicLores    = false,
 
italicLores    = false,
 +
text          = {}
 
},
 
},
 
ko = {
 
ko = {
Line 99: Line 136:
 
romanizedNames = true,
 
romanizedNames = true,
 
italicLores    = false,
 
italicLores    = false,
 +
text          = {
 +
['Requirement']        = '【조건】',
 +
['Effect']              = '【효과】',
 +
['Continuous Effect']  = '【지속 효과】',
 +
['Multi-Choice Effect'] = '【선택 효과】'
 +
}
 
},
 
},
 +
ru = {
 +
name          = 'Russian',
 +
langCode      = 'ru',
 +
scriptCode    = nil,
 +
romanizedNames = true,
 +
italicLores    = false,
 +
text          = {}
 +
}
 
}
 
}
  
Line 108: Line 159:
 
function Locale:new(lang, params)
 
function Locale:new(lang, params)
 
-- Create a new instance of the Locale class with all the default values
 
-- Create a new instance of the Locale class with all the default values
local l = {}
+
local l = mw.clone(Locale)
setmetatable(l, Locale)
 
Locale.__index = Locale
 
  
 
-- English parameters don't have a prefix e.g. `name`, `lore`
 
-- English parameters don't have a prefix e.g. `name`, `lore`
Line 118: Line 167:
 
l.lang              = lang
 
l.lang              = lang
 
l.language          = languages[lang]
 
l.language          = languages[lang]
l.name              = params[prefix .. 'name']               or nil
+
l.name              = params[prefix .. 'name']                 or nil
l.romanizedName      = params[prefix .. 'romanized_name']     or nil
+
l.romanizedName      = params[prefix .. 'romanized_name']       or nil
l.translatedName    = params[prefix .. 'translated_name']     or nil
+
l.baseRomanizedName  = params[prefix .. 'base_romanized_name']  or nil
l.pendulumEffect    = params[prefix .. 'pendulum_effect']     or nil
+
l.translatedName    = params[prefix .. 'translated_name']     or nil
l.material          = params[prefix .. 'material']           or nil
+
l.baseTranslatedName = params[prefix .. 'base_translated_name'] or nil
l.lore              = params[prefix .. 'lore']               or nil
+
l.pendulumEffect    = params[prefix .. 'pendulum_effect']     or nil
l.archetypeCondition = params[prefix .. 'archetype_condition'] or nil
+
l.material          = params[prefix .. 'material']             or nil
 +
l.summoningCondition = params[prefix .. 'summoning_condition']  or nil
 +
l.requirement        = params[prefix .. 'requirement']          or nil
 +
l.lore              = params[prefix .. 'lore']                 or nil
 +
l.condition          = params[prefix .. 'condition'] or nil
  
 
return l
 
return l
Line 156: Line 209:
 
-- table mapping labels to standardized ones
 
-- table mapping labels to standardized ones
 
local mappings = {
 
local mappings = {
romaji_name = 'ja_romanized_name',
+
romaji_name     = 'ja_romanized_name',
trans_name  = 'ja_translated_name',
+
base_romaji_name = 'ja_base_romanized_name',
ko_rr_name = 'ko_romanized_name'
+
trans_name       = 'ja_translated_name',
 +
base_trans_name = 'ja_base_translated_name',
 +
zh_pinyin_name  = 'zh_romanized_name',
 +
tc_pinyin_name  = 'tc_romanized_name',
 +
sc_pinyin_name  = 'sc_romanized_name',
 +
ko_rr_name       = 'ko_romanized_name'
 
}
 
}
  
Line 182: Line 240:
 
-- Check if at least one param is supplied for the language
 
-- Check if at least one param is supplied for the language
 
return (
 
return (
params[lang .. '_name'] or
+
isFilled(params[lang .. '_name']) or
params[lang .. '_lore'] or
+
isFilled(params[lang .. '_lore']) or
params[lang .. '_pendulum_effect'] or
+
isFilled(params[lang .. '_pendulum_effect']) or
params[lang .. '_material'] or
+
isFilled(params[lang .. '_material']) or
params[lang .. '_archetype_condition'] or
+
isFilled(params[lang .. '_archetype_condition']) or
params[lang .. '_romanized_name'] or
+
isFilled(params[lang .. '_summoning_condition']) or
params[lang .. '_translated_name']
+
isFilled(params[lang .. '_romanized_name']) or
) and true or false
+
isFilled(params[lang .. '_translated_name'])
 +
)
 +
end
 +
 
 +
-- Get the name without any ruby annotations
 +
-- e.g. デーモンの{{Ruby|召|しょう}}{{Ruby|喚|かん}} → デーモンの召喚
 +
-- @return string
 +
function Locale:getBaseName()
 +
return Ruby.split(self.name)
 
end
 
end
  
-- Get the name of the instance's language
+
-- Get the name favoring "top" text over base text for ruby annotations
 +
-- e.g. デーモンの{{Ruby|召|しょう}}{{Ruby|喚|かん}} → デーモンのしょうかん
 
-- @return string
 
-- @return string
function Locale:getLanguageName()
+
function Locale:getTopName()
return self.language.name
+
return Ruby.split(self.name, 'top')
 
end
 
end
  
Line 215: Line 282:
 
function Locale:getRomanizedHtmlLang()
 
function Locale:getRomanizedHtmlLang()
 
return self.language.langCode .. '-Latn'
 
return self.language.langCode .. '-Latn'
 +
end
 +
 +
-- Get a piece of text in the current language
 +
-- @param message string
 +
-- @return string
 +
function Locale:getText(message)
 +
-- If the language has a translation for the message use that
 +
return self.language.text[message]
 +
-- Otherwise use the English one if it exists
 +
or languages.en[message]
 +
-- Otherwise just return the supplied text
 +
or message
 
end
 
end
  
 
-- Put the material, lore and archetype condition together to form the full lore
 
-- Put the material, lore and archetype condition together to form the full lore
-- @param boolean isNormalMonster - If the card is a Normal monster
+
-- @param card   Card    The full card object
 
-- @return string
 
-- @return string
function Locale:getFullLore(isNormalMonster)
+
function Locale:getFullLore(card)
 
local output = ''
 
local output = ''
local archetypeCondition = nil
+
local condition = nil
  
if (self.archetypeCondition) then
+
if (self.condition) then
archetypeCondition = '(' .. self.archetypeCondition .. ')'
+
condition = '(' .. self.condition .. ')'
 
end
 
end
  
 
-- Handle Normal Monsters
 
-- Handle Normal Monsters
 
-- Lore (with italics depending on language, followed by archetype condition)
 
-- Lore (with italics depending on language, followed by archetype condition)
if (isNormalMonster) then
+
if (card.isNormalMonster) then
local output = self.lore
+
local output = isFilled(self.lore) and self.lore or ''
 
+
if (self.language.italicLores) then
+
if (self.language.italicLores and isFilled(self.lore)) then
output = output .. '<i>' .. output .. '</i>'  
+
output = '<i>' .. self.lore .. '</i>'
 
end
 
end
  
if (archetypeCondition) then
+
if (condition) then
output = output .. '<br /><br />' .. archetypeCondition
+
output = output .. '<br /><br />' .. condition
 
end
 
end
  
Line 245: Line 324:
  
 
-- Handle everything else
 
-- Handle everything else
-- Array of different lore comporenents
+
lore = self.lore
 +
requirement = self.requirement
 +
 
 +
-- If there is a requirement, prefix the lore and requirement with their labels
 +
if (isFilled(self.requirement)) then
 +
requirement = '<b>' .. self:getText('Requirement') .. '</b> ' .. requirement
 +
lore = '<b>' .. self:getText(card.mainEffectType or 'Effect') .. '</b> ' .. lore
 +
end
 +
 
 +
-- Array of different lore components
 
local loreParts = {
 
local loreParts = {
 
self.material or nil,
 
self.material or nil,
archetypeCondition or nil,
+
condition or nil,
self.lore or nil
+
self.summoningCondition or nil,
 +
requirement,
 +
lore or nil,
 
}
 
}
 
+
 
-- Remove empty values
 
-- Remove empty values
 
loreParts = TableTools.compressSparseArray(loreParts)
 
loreParts = TableTools.compressSparseArray(loreParts)

Latest revision as of 02:48, 27 December 2023

local Ruby = require('Module:Ruby')

-- Generic functions

-- Check if a value is filled (i.e. not `nil` or an empty string)
-- @param value mixed
-- @return boolean
local function isFilled(value)
	return (value ~= nil and value ~= '')
end


-- 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 summoningCondition string     The Summoning condition portion of the card's lore
-- @field requirement        string     The requirement portion of the card's lore (Should not include the '[REQUIREMENT]' prefix)
-- @field lore               string     The card description/effect portion of the lore (Should not include italic markup)
-- @field condition          string     The condition portion of the lore (Should not include parentheses)
local Locale = {
	lang = nil,
	name = nil,
	romanizedName = nil,
	baseRomanizedName = nil,
	translatedName = nil,
	baseTranslatedName = nil,
	pendulumEffect = nil,
	material = nil,
	requirement = nil,
	lore = nil,
	condition = nil,
}

local languages = {
	en = {
		name           = 'English',
		LangCode       = 'en',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
		text           = {
			['Requirement']         = '[REQUIREMENT]',
			['Effect']              = '[EFFECT]',
			['Continuous Effect']   = '[CONTINUOUS EFFECT]',
			['Multi-Choice Effect'] = '[MULTI-CHOICE EFFECT]'
		}
	},
	fr = {
		name           = 'French',
		langCode       = 'fr',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
		text           = {}
	},
	de = {
		name           = 'German',
		langCode       = 'de',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
		text           = {}
	},
	it = {
		name           = 'Italian',
		langCode       = 'it',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
		text           = {}
	},
	pt = {
		name           = 'Portuguese',
		langCode       = 'pt',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
		text           = {}
	},
	es = {
		name           = 'Spanish',
		langCode       = 'es',
		scriptCode     = nil,
		romanizedNames = false,
		italicLores    = true,
		text           = {}
	},
	ja = {
		name           = 'Japanese',
		langCode       = 'ja',
		scriptCode     = 'Japn',
		romanizedNames = true,
		italicLores    = false,
		text           = {
			['Requirement']         = '【<ruby><rb>条</rb><rt>じょう</rt><rb>件</rb><rt>けん</rt>】',
			['Effect']              = '【<ruby><rb>効</rb><rt>こう</rt><rb>果</rb><rt>か</rt>】',
			['Continuous Effect']   = '【<ruby><rb>永</rb><rt>えい</rt><rb>続</rb><rt>ぞく</rt><rb>効</rb><rt>こう</rt><rb>果</rb><rt>か</rt></ruby>】',
			['Multi-Choice Effect'] = '【<ruby><rb>選</rb><rt>せん</rt><rb>択</rb><rt>たく</rt><rb>効</rb><rt>こう</rt><rb>果</rb><rt>か</rt></ruby>】'
		}
	},
	zh = {
		name           = 'Chinese',
		langCode       = 'zh',
		scriptCode     = nil,
		romanizedNames = true,
		italicLores    = false,
		text           = {}
	},
	tc = {
		name           = 'Traditional Chinese',
		langCode       = 'zh',
		scriptCode     = 'Hant',
		romanizedNames = true,
		italicLores    = false,
		text           = {}
	},
	sc = {
		name           = 'Simplified Chinese',
		langCode       = 'zh',
		scriptCode     = 'Hans',
		romanizedNames = true,
		italicLores    = false,
		text           = {}
	},
	ko = {
		name           = 'Korean',
		langCode       = 'ko',
		scriptCode     = nil,
		romanizedNames = true,
		italicLores    = false,
		text           = {
			['Requirement']         = '【조건】',
			['Effect']              = '【효과】',
			['Continuous Effect']   = '【지속 효과】',
			['Multi-Choice Effect'] = '【선택 효과】'
		}
	},
	ru = {
		name           = 'Russian',
		langCode       = 'ru',
		scriptCode     = nil,
		romanizedNames = true,
		italicLores    = false,
		text           = {}
	}
}

-- 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 = mw.clone(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.baseRomanizedName  = params[prefix .. 'base_romanized_name']  or nil
	l.translatedName     = params[prefix .. 'translated_name']      or nil
	l.baseTranslatedName = params[prefix .. 'base_translated_name'] or nil
	l.pendulumEffect     = params[prefix .. 'pendulum_effect']      or nil
	l.material           = params[prefix .. 'material']             or nil
	l.summoningCondition = params[prefix .. 'summoning_condition']  or nil
	l.requirement        = params[prefix .. 'requirement']          or nil
	l.lore               = params[prefix .. 'lore']                 or nil
	l.condition           = params[prefix .. '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',
		base_romaji_name = 'ja_base_romanized_name',
		trans_name       = 'ja_translated_name',
		base_trans_name  = 'ja_base_translated_name',
		zh_pinyin_name   = 'zh_romanized_name',
		tc_pinyin_name   = 'tc_romanized_name',
		sc_pinyin_name   = 'sc_romanized_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 (
		isFilled(params[lang .. '_name']) or
		isFilled(params[lang .. '_lore']) or
		isFilled(params[lang .. '_pendulum_effect']) or
		isFilled(params[lang .. '_material']) or
		isFilled(params[lang .. '_archetype_condition']) or
		isFilled(params[lang .. '_summoning_condition']) or
		isFilled(params[lang .. '_romanized_name']) or
		isFilled(params[lang .. '_translated_name'])
	)
end

-- Get the name without any ruby annotations
-- e.g. デーモンの{{Ruby|召|しょう}}{{Ruby|喚|かん}} → デーモンの召喚
-- @return string
function Locale:getBaseName()
	return Ruby.split(self.name)
end

-- Get the name favoring "top" text over base text for ruby annotations
-- e.g. デーモンの{{Ruby|召|しょう}}{{Ruby|喚|かん}} → デーモンのしょうかん
-- @return string
function Locale:getTopName()
	return Ruby.split(self.name, 'top')
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

-- Get a piece of text in the current language
-- @param message string
-- @return string
function Locale:getText(message)
	-- If the language has a translation for the message use that
	return self.language.text[message]
		-- Otherwise use the English one if it exists
		or languages.en[message]
		-- Otherwise just return the supplied text
		or message
end

-- Put the material, lore and archetype condition together to form the full lore
-- @param card    Card    The full card object
-- @return string
function Locale:getFullLore(card)
	local output = ''
	local condition = nil

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

	-- Handle Normal Monsters
	-- Lore (with italics depending on language, followed by archetype condition)
	if (card.isNormalMonster) then
		local output = isFilled(self.lore) and self.lore or ''
	
		if (self.language.italicLores and isFilled(self.lore)) then
			output = '<i>' .. self.lore .. '</i>'
		end

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

		return output
	end

	-- Handle everything else
	lore = self.lore
	requirement = self.requirement

	-- If there is a requirement, prefix the lore and requirement with their labels
	if (isFilled(self.requirement)) then
		requirement = '<b>' .. self:getText('Requirement') .. '</b> ' .. requirement
		lore = '<b>' .. self:getText(card.mainEffectType or 'Effect') .. '</b> ' .. lore
	end

	-- Array of different lore components
	local loreParts = {
		self.material or nil,
		condition or nil,
		self.summoningCondition or nil,
		requirement,
		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