diff libs/AceLocale-2.0/AceLocale-2.0.lua @ 1:c11ca1d8ed91

Version 0.1
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:03:57 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libs/AceLocale-2.0/AceLocale-2.0.lua	Tue Mar 20 21:03:57 2007 +0000
@@ -0,0 +1,506 @@
+--[[
+Name: AceLocale-2.0
+Revision: $Rev: 18753 $
+Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
+Inspired By: Ace 1.x by Turan (turan@gryphon.com)
+Website: http://www.wowace.com/
+Documentation: http://www.wowace.com/index.php/AceLocale-2.0
+SVN: http://svn.wowace.com/root/trunk/Ace2/AceLocale-2.0
+Description: Localization library for addons to use to handle proper
+             localization and internationalization.
+Dependencies: AceLibrary
+]]
+
+local MAJOR_VERSION = "AceLocale-2.0"
+local MINOR_VERSION = "$Revision: 18753 $"
+
+if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
+if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
+
+local AceLocale = {}
+
+local DEFAULT_LOCALE = "enUS"
+local _G = getfenv(0)
+
+local __baseTranslations__, __debugging__, __translations__, __baseLocale__, __translationTables__, __reverseTranslations__, __strictness__
+
+local __call = function(self, key1, key2)
+	if key2 then
+		return self[key1][key2]
+	else
+		return self[key1]
+	end
+end
+
+local rawget = rawget
+local rawset = rawset
+local type = type
+
+local lastSelf
+
+local __index = function(self, key)
+	lastSelf = self
+	local value = (rawget(self, __translations__) or AceLocale.prototype)[key]
+	rawset(self, key, value)
+	return value
+end
+
+local __newindex = function(self, k, v)
+	if type(v) ~= "function" and type(k) ~= "table" then
+		AceLocale.error(self, "Cannot change the values of an AceLocale instance.")
+	end
+	rawset(self, k, v)
+end
+
+local __tostring = function(self)
+	if type(rawget(self, 'GetLibraryVersion')) == "function" then
+		return self:GetLibraryVersion()
+	else
+		return "AceLocale(" .. self[__name__] .. ")"
+	end
+end
+
+local refixInstance = function(instance)
+	if getmetatable(instance) then
+		setmetatable(instance, nil)
+	end
+	local translations = instance[__translations__]
+	if translations then
+		if getmetatable(translations) then
+			setmetatable(translations, nil)
+		end
+		local baseTranslations = instance[__baseTranslations__]
+		if getmetatable(baseTranslations) then
+			setmetatable(baseTranslations, nil)
+		end
+		if translations == baseTranslations or instance[__strictness__] then
+			setmetatable(instance, {
+				__index = __index,
+				__newindex = __newindex,
+				__call = __call,
+				__tostring = __tostring
+			})
+			
+			setmetatable(translations, {
+				__index = AceLocale.prototype
+			})
+		else
+			setmetatable(instance, {
+				__index = __index,
+				__newindex = __newindex,
+				__call = __call,
+				__tostring = __tostring
+			})
+			
+			setmetatable(translations, {
+				__index = baseTranslations,
+			})
+			
+			setmetatable(baseTranslations, {
+				__index = AceLocale.prototype,
+			})
+		end
+	else
+		setmetatable(instance, {
+			__index = __index,
+			__newindex = __newindex,
+			__call = __call,
+			__tostring = __tostring,
+		})
+	end
+end
+
+function AceLocale:new(name)
+	error(MAJOR_VERSION .. " is not supported in WoW 2.0", 2)
+	self:argCheck(name, 2, "string")
+	
+	if self.registry[name] and type(rawget(self.registry[name], 'GetLibraryVersion')) ~= "function" then
+		return self.registry[name]
+	end
+	
+	local self = {
+		[__strictness__] = false,
+		[__name__] = name,
+	}
+	refixInstance(self)
+	
+	AceLocale.registry[name] = self
+	return self
+end
+
+setmetatable(AceLocale, { __call = AceLocale.new })
+
+AceLocale.prototype = {}
+AceLocale.prototype.class = AceLocale
+
+function AceLocale.prototype:EnableDebugging()
+	if rawget(self, __baseTranslations__) then
+		AceLocale:error("Cannot enable debugging after a translation has been registered.")
+	end
+	rawset(self, __debugging__, true)
+end
+
+function AceLocale.prototype:RegisterTranslations(locale, func)
+	AceLocale.argCheck(self, locale, 2, "string")
+	AceLocale.argCheck(self, func, 3, "function")
+	
+	if locale == rawget(self, __baseLocale__) then
+		AceLocale.error(self, "Cannot provide the same locale more than once. %q provided twice.", locale)
+	end
+	
+	if rawget(self, __baseTranslations__) and GetLocale() ~= locale then
+		if rawget(self, __debugging__) then
+			local t = func()
+			func = nil
+			if type(t) ~= "table" then
+				AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
+			end
+			self[__translationTables__][locale] = t
+			t = nil
+		end
+		func = nil
+		return
+	end
+	local t = func()
+	func = nil
+	if type(t) ~= "table" then
+		AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
+	end
+	
+	rawset(self, __translations__, t)
+	if not rawget(self, __baseTranslations__) then
+		rawset(self, __baseTranslations__, t)
+		rawset(self, __baseLocale__, locale)
+		for key,value in pairs(t) do
+			if value == true then
+				t[key] = key
+			end
+		end
+	else
+		for key, value in pairs(self[__translations__]) do
+			if not rawget(self[__baseTranslations__], key) then
+				AceLocale.error(self, "Improper translation exists. %q is likely misspelled for locale %s.", key, locale)
+			end
+			if value == true then
+				AceLocale.error(self, "Can only accept true as a value on the base locale. %q is the base locale, %q is not.", rawget(self, __baseLocale__), locale)
+			end
+		end
+	end
+	refixInstance(self)
+	if rawget(self, __debugging__) then
+		if not rawget(self, __translationTables__) then
+			rawset(self, __translationTables__, {})
+		end
+		self[__translationTables__][locale] = t
+	end
+	t = nil
+end
+
+function AceLocale.prototype:SetStrictness(strict)
+	AceLocale.argCheck(self, strict, 2, "boolean")
+	local mt = getmetatable(self)
+	if not mt then
+		AceLocale.error(self, "Cannot call `SetStrictness' without a metatable.")
+	end
+	if not rawget(self, __translations__) then
+		AceLocale.error(self, "No translations registered.")
+	end
+	rawset(self, __strictness__, strict)
+	refixInstance(self)
+end
+
+function AceLocale.prototype:GetTranslationStrict(text, sublevel)
+	AceLocale.argCheck(self, text, 1, "string")
+	local translations = rawget(self, __translations__)
+	if not translations then
+		AceLocale.error(self, "No translations registered")
+	end
+	if sublevel then
+		local t = rawget(translations, text)
+		if type(t) ~= "table" then
+			AceLocale.error(self, "Strict translation %q::%q does not exist", text, sublevel)
+		end
+		local value = t[sublevel]
+		if not value then
+			AceLocale.error(self, "Strict translation %q::%q does not exist", text, sublevel)
+		end
+		return value
+	else
+		local value = rawget(translations, text)
+		if not value then
+			AceLocale.error(self, "Strict translation %q does not exist", text)
+		end
+		return value
+	end
+end
+
+function AceLocale.prototype:GetTranslation(text, sublevel)
+	AceLocale.argCheck(self, text, 1, "string")
+	local translations = rawget(self, __translations__)
+	if not translations then
+		AceLocale.error(self, "No translations registered")
+	end
+	if sublevel then
+		local base = self[__baseTranslations__]
+		local standard = rawget(translations, text)
+		local current
+		local baseStandard
+		if not standard then
+			baseStandard = rawget(base, text)
+			current = baseStandard
+		end
+		if not type(current) ~= "table" then
+			AceLocale.error(self, "Loose translation %q::%q does not exist", text, sublevel)
+		end
+		local value = current[sublevel]
+		if not value then
+			if current == baseStandard or type(baseStandard) ~= "table" then
+				AceLocale.error(self, "Loose translation %q::%q does not exist", text, sublevel)
+			end
+			value = baseStandard[sublevel]
+			if not value then
+				AceLocale.error(self, "Loose translation %q::%q does not exist", text, sublevel)
+			end
+		end
+		return value
+	else
+		local value = rawget(translations, text)
+		if not value then
+			AceLocale.error(self, "Loose translation %q does not exist", text)
+		end
+		return value
+	end
+end
+
+local function initReverse(self)
+	rawset(self, __reverseTranslations__, {})
+	local alpha = self[__translations__]
+	local bravo = self[__reverseTranslations__]
+	for base, localized in pairs(alpha) do
+		bravo[localized] = base
+	end
+end
+
+function AceLocale.prototype:GetReverseTranslation(text)
+	local x = rawget(self, __reverseTranslations__)
+	if not x then
+		if not rawget(self, __translations__) then
+			AceLocale.error(self, "No translations registered")
+		end
+		initReverse(self)
+		x = self[__reverseTranslations__]
+	end
+	local translation = x[text]
+	if not translation then
+		AceLocale.error(self, "Reverse translation for %q does not exist", text)
+	end
+	return translation
+end
+
+function AceLocale.prototype:GetIterator()
+	local x = rawget(self, __translations__)
+	if not x then
+		AceLocale.error(self, "No translations registered")
+	end
+	return next, x, nil
+end
+
+function AceLocale.prototype:GetReverseIterator()
+	local x = rawget(self, __reverseTranslations__)
+	if not x then
+		if not rawget(self, __translations__) then
+			AceLocale.error(self, "No translations registered")
+		end
+		initReverse(self)
+		x = self[__reverseTranslations__]
+	end
+	return next, x, nil
+end
+
+function AceLocale.prototype:HasTranslation(text, sublevel)
+	AceLocale.argCheck(self, text, 1, "string")
+	local x = rawget(self, __translations__)
+	if not x then
+		AceLocale.error(self, "No translations registered")
+	end
+	if sublevel then
+		AceLocale.argCheck(self, sublevel, 2, "string", "nil")
+		return type(rawget(x, text)) == "table" and x[text][sublevel] and true
+	end
+	return rawget(x, text) and true
+end
+
+function AceLocale.prototype:HasReverseTranslation(text)
+	local x = rawget(self, __reverseTranslations__)
+	if not x then
+		if not rawget(self, __translations__) then
+			AceLocale.error(self, "No translations registered")
+		end
+		initReverse(self)
+		x = self[__reverseTranslations__]
+	end
+	return x[text] and true
+end
+
+AceLocale.prototype.GetTableStrict = AceLocale.prototype.GetTranslationStrict
+AceLocale.prototype.GetTable = AceLocale.prototype.GetTranslation
+
+function AceLocale.prototype:Debug()
+	if not rawget(self, __debugging__) then
+		return
+	end
+	local words = {}
+	local locales = {"enUS", "deDE", "frFR", "koKR", "zhCN", "zhTW"}
+	local localizations = {}
+	DEFAULT_CHAT_FRAME:AddMessage("--- AceLocale Debug ---")
+	for _,locale in ipairs(locales) do
+		if not self[__translationTables__][locale] then
+			DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q not found", locale))
+		else
+			localizations[locale] = self[__translationTables__][locale]
+		end
+	end
+	local localeDebug = {}
+	for locale, localization in pairs(localizations) do
+		localeDebug[locale] = {}
+		for word in pairs(localization) do
+			if type(localization[word]) == "table" then
+				if type(words[word]) ~= "table" then
+					words[word] = {}
+				end
+				for bit in pairs(localization[word]) do
+					if type(localization[word][bit]) == "string" then
+						words[word][bit] = true
+					end
+				end
+			elseif type(localization[word]) == "string" then
+				words[word] = true
+			end
+		end
+	end
+	for word in pairs(words) do
+		if type(words[word]) == "table" then
+			for bit in pairs(words[word]) do
+				for locale, localization in pairs(localizations) do
+					if not rawget(localization, word) or not localization[word][bit] then
+						localeDebug[locale][word .. "::" .. bit] = true
+					end
+				end
+			end
+		else
+			for locale, localization in pairs(localizations) do
+				if not rawget(localization, word) then
+					localeDebug[locale][word] = true
+				end
+			end
+		end
+	end
+	for locale, t in pairs(localeDebug) do
+		if not next(t) then
+			DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q complete", locale))
+		else
+			DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q missing:", locale))
+			for word in pairs(t) do
+				DEFAULT_CHAT_FRAME:AddMessage(string.format("    %q", word))
+			end
+		end
+	end
+	DEFAULT_CHAT_FRAME:AddMessage("--- End AceLocale Debug ---")
+end
+
+setmetatable(AceLocale.prototype, {
+	__index = function(self, k)
+		if type(k) ~= "table" and k ~= 0 and k ~= "GetLibraryVersion"  and k ~= "error" and k ~= "assert" and k ~= "argCheck" and k ~= "pcall" then -- HACK: remove "GetLibraryVersion" and such later.
+			AceLocale.error(lastSelf or self, "Translation %q does not exist.", k)
+		end
+		return nil
+	end
+})
+
+local function activate(self, oldLib, oldDeactivate)
+	AceLocale = self
+	
+	if oldLib then
+		self.registry = oldLib.registry
+		self.__baseTranslations__ = oldLib.__baseTranslations__
+		self.__debugging__ = oldLib.__debugging__
+		self.__translations__ = oldLib.__translations__
+		self.__baseLocale__ = oldLib.__baseLocale__
+		self.__translationTables__ = oldLib.__translationTables__
+		self.__reverseTranslations__ = oldLib.__reverseTranslations__
+		self.__strictness__ = oldLib.__strictness__
+		self.__name__ = oldLib.__name__
+	end
+	if not self.__baseTranslations__ then
+		self.__baseTranslations__ = {}
+	end
+	if not self.__debugging__ then
+		self.__debugging__ = {}
+	end
+	if not self.__translations__ then
+		self.__translations__ = {}
+	end
+	if not self.__baseLocale__ then
+		self.__baseLocale__ = {}
+	end
+	if not self.__translationTables__ then
+		self.__translationTables__ = {}
+	end
+	if not self.__reverseTranslations__ then
+		self.__reverseTranslations__ = {}
+	end
+	if not self.__strictness__ then
+		self.__strictness__ = {}
+	end
+	if not self.__name__ then
+		self.__name__ = {}
+	end
+	
+	__baseTranslations__ = self.__baseTranslations__
+	__debugging__ = self.__debugging__
+	__translations__ = self.__translations__
+	__baseLocale__ = self.__baseLocale__
+	__translationTables__ = self.__translationTables__
+	__reverseTranslations__ = self.__reverseTranslations__
+	__strictness__ = self.__strictness__
+	__name__ = self.__name__
+	
+	if not self.registry then
+		self.registry = {}
+	else
+		for name, instance in pairs(self.registry) do
+			local name = name
+			local mt = getmetatable(instance)
+			setmetatable(instance, nil)
+			instance[__name__] = name
+			local strict
+			if instance.translations then
+				instance[__translations__], instance.translations = instance.translations
+				instance[__baseLocale__], instance.baseLocale = instance.baseLocale
+				instance[__baseTranslations__], instance.baseTranslations = instance.baseTranslations
+				instance[__debugging__], instance.debugging = instance.debugging
+				instance.reverseTranslations = nil
+				instance[__translationTables__], instance.translationTables = instance.translationTables
+				if mt and mt.__call == oldLib.prototype.GetTranslationStrict then
+					strict = true
+				end
+			else
+				if instance[__strictness__] ~= nil then
+					strict = instance[__strictness__]
+				elseif instance[__translations__] ~= instance[__baseTranslations__] then
+					if getmetatable(instance[__translations__]).__index == oldLib.prototype then
+						strict = true
+					end
+				end
+			end
+			instance[__strictness__] = strict and true or false
+			refixInstance(instance)
+		end
+	end
+	
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+AceLibrary:Register(AceLocale, MAJOR_VERSION, MINOR_VERSION, activate)