vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: AceLocale-2.0
3 Revision: $Rev: 7611 $
4 Author(s): ckknight (ckknight@gmail.com)
5 Website: http://www.wowace.com/
6 Documentation: http://wiki.wowace.com/index.php/AceLocale-2.0
7 SVN: http://svn.wowace.com/root/trunk/Ace2/AceLocale-2.0
8 Description: Localization library for addons to use to handle proper
9 localization and internationalization.
10 Dependencies: AceLibrary
11 ]]
12  
13 local MAJOR_VERSION = "AceLocale-2.0"
14 local MINOR_VERSION = "$Revision: 7611 $"
15  
16 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
17 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
18  
19 local AceLocale = {}
20  
21 local DEFAULT_LOCALE = "enUS"
22 local _G = getfenv(0)
23  
24 function AceLocale:new(name)
25 self:argCheck(name, 2, "string")
26  
27 if self.registry[name] and type(self.registry[name].GetLibraryVersion) ~= "function" then
28 return self.registry[name]
29 end
30  
31 local self = setmetatable({}, {
32 __index = self.prototype,
33 __call = self.prototype.GetTranslation,
34 __tostring = function(self)
35 if type(self.GetLibraryVersion) == "function" then
36 return self:GetLibraryVersion()
37 else
38 return "AceLocale(" .. name .. ")"
39 end
40 end
41 })
42  
43 AceLocale.registry[name] = self
44 return self
45 end
46  
47 setmetatable(AceLocale, { __call = AceLocale.new })
48  
49 AceLocale.prototype = {}
50 AceLocale.prototype.class = AceLocale
51  
52 function AceLocale.prototype:EnableDebugging()
53 if self.baseTranslations then
54 AceLocale.error(self, "Cannot enable debugging after a translation has been registered.")
55 end
56 self.debugging = true
57 end
58  
59 function AceLocale.prototype:RegisterTranslations(locale, func)
60 AceLocale.argCheck(self, locale, 2, "string")
61 AceLocale.argCheck(self, func, 3, "function")
62  
63 if locale == self.baseLocale then
64 AceLocale.error(self, "Cannot provide the same locale more than once. %q provided twice.", locale)
65 end
66  
67 if self.baseTranslations and GetLocale() ~= locale then
68 if self.debugging then
69 local t = func()
70 func = nil
71 if type(t) ~= "table" then
72 AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
73 end
74 self.translationTables[locale] = t
75 t = nil
76 end
77 func = nil
78 return
79 end
80 local t = func()
81 func = nil
82 if type(t) ~= "table" then
83 AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
84 end
85  
86 self.translations = t
87 if not self.baseTranslations then
88 self.baseTranslations = t
89 self.baseLocale = locale
90 for key,value in pairs(self.baseTranslations) do
91 if value == true then
92 self.baseTranslations[key] = key
93 end
94 end
95 else
96 for key, value in pairs(self.translations) do
97 if not self.baseTranslations[key] then
98 AceLocale.error(self, "Improper translation exists. %q is likely misspelled for locale %s.", key, locale)
99 elseif value == true then
100 AceLocale.error(self, "Can only accept true as a value on the base locale. %q is the base locale, %q is not.", self.baseLocale, locale)
101 end
102 end
103 end
104 if self.debugging then
105 if not self.translationTables then
106 self.translationTables = {}
107 end
108 self.translationTables[locale] = t
109 end
110 t = nil
111 end
112  
113 function AceLocale.prototype:SetStrictness(strict)
114 local mt = getmetatable(self)
115 if not mt then
116 AceLocale.error(self, "Cannot call `SetStrictness' without a metatable.")
117 end
118 if strict then
119 mt.__call = self.GetTranslationStrict
120 else
121 mt.__call = self.GetTranslation
122 end
123 end
124  
125 function AceLocale.prototype:GetTranslationStrict(text, sublevel)
126 AceLocale.argCheck(self, text, 1, "string")
127 AceLocale.assert(self, self.translations, "No translations registered")
128 if not self.translations then
129 AceLocale.error(self, "No translations registered")
130 end
131 if sublevel then
132 AceLocale.argCheck(self, sublevel, 2, "string")
133 local t = self.translations[text]
134 if type(t) ~= "table" then
135 if type(self.baseTranslations[text]) == "table" then
136 AceLocale.error(self, "%q::%q has not been translated into %q", text, sublevel, GetLocale())
137 return
138 else
139 AceLocale.error(self, "Translation for %q::%q does not exist", text, sublevel)
140 return
141 end
142 end
143 local translation = t[sublevel]
144 if type(translation) ~= "string" then
145 if type(self.baseTranslations[text]) == "table" then
146 if type(self.baseTranslations[text][sublevel]) == "string" then
147 AceLocale.error(self, "%q::%q has not been translated into %q", text, sublevel, GetLocale())
148 return
149 else
150 AceLocale.error(self, "Translation for %q::%q does not exist", text, sublevel)
151 return
152 end
153 else
154 AceLocale.error(self, "Translation for %q::%q does not exist", text, sublevel)
155 return
156 end
157 end
158 return translation
159 end
160 local translation = self.translations[text]
161 if type(translation) ~= "string" then
162 if type(self.baseTranslations[text]) == "string" then
163 AceLocale.error(self, "%q has not been translated into %q", text, GetLocale())
164 return
165 else
166 AceLocale.error(self, "Translation for %q does not exist", text)
167 return
168 end
169 end
170 return translation
171 end
172  
173 function AceLocale.prototype:GetTranslation(text, sublevel)
174 AceLocale:argCheck(text, 1, "string")
175 AceLocale.assert(self, self.translations, "No translations registered")
176 if sublevel then
177 AceLocale:argCheck(sublevel, 2, "string", "nil")
178 local t = self.translations[text]
179 if type(t) == "table" then
180 local translation = t[sublevel]
181 if type(translation) == "string" then
182 return translation
183 else
184 t = self.baseTranslations[text]
185 if type(t) ~= "table" then
186 AceLocale.error(self, "Translation table %q does not exist", text)
187 return
188 end
189 translation = t[sublevel]
190 if type(translation) ~= "string" then
191 AceLocale.error(self, "Translation for %q::%q does not exist", text, sublevel)
192 return
193 end
194 return translation
195 end
196 else
197 t = self.baseTranslations[text]
198 if type(t) ~= "table" then
199 AceLocale.error(self, "Translation table %q does not exist", text)
200 return
201 end
202 local translation = t[sublevel]
203 if type(translation) ~= "string" then
204 AceLocale.error(self, "Translation for %q::%q does not exist", text, sublevel)
205 return
206 end
207 return translation
208 end
209 end
210 local translation = self.translations[text]
211 if type(translation) == "string" then
212 return translation
213 else
214 translation = self.baseTranslations[text]
215 if type(translation) ~= "string" then
216 AceLocale.error(self, "Translation for %q does not exist", text)
217 return
218 end
219 return translation
220 end
221 end
222  
223 local function initReverse(self)
224 self.reverseTranslations = {}
225 local alpha = self.translations
226 local bravo = self.reverseTranslations
227 for base, localized in pairs(alpha) do
228 bravo[localized] = base
229 end
230 end
231  
232 function AceLocale.prototype:GetReverseTranslation(text)
233 AceLocale.argCheck(self, text, 1, "string")
234 AceLocale.assert(self, self.translations, "No translations registered")
235 if not self.reverseTranslations then
236 initReverse(self)
237 end
238 local translation = self.reverseTranslations[text]
239 if type(translation) ~= "string" then
240 AceLocale.error(self, "Reverse translation for %q does not exist", text)
241 return
242 end
243 return translation
244 end
245  
246 function AceLocale.prototype:GetIterator()
247 AceLocale.assert(self, self.translations, "No translations registered")
248 return pairs(self.translations)
249 end
250  
251 function AceLocale.prototype:GetReverseIterator()
252 AceLocale.assert(self, self.translations, "No translations registered")
253 if not self.reverseTranslations then
254 initReverse(self)
255 end
256 return pairs(self.reverseTranslations)
257 end
258  
259 function AceLocale.prototype:HasTranslation(text, sublevel)
260 AceLocale.argCheck(self, text, 1, "string")
261 AceLocale.assert(self, self.translations, "No translations registered")
262 if sublevel then
263 AceLocale.argCheck(self, sublevel, 2, "string", "nil")
264 return type(self.translations[text]) == "table" and self.translations[text][sublevel] and true
265 end
266 return self.translations[text] and true
267 end
268  
269 function AceLocale.prototype:HasReverseTranslation(text)
270 AceLocale.assert(self, self.translations, "No translations registered")
271 if not self.reverseTranslations then
272 initReverse(self)
273 end
274 return self.reverseTranslations[text] and true
275 end
276  
277 function AceLocale.prototype:GetTableStrict(key, key2)
278 AceLocale.argCheck(self, key, 1, "string")
279 AceLocale.assert(self, self.translations, "No translations registered")
280 if key2 then
281 AceLocale.argCheck(self, key2, 2, "string")
282 local t = self.translations[key]
283 if type(t) ~= "table" then
284 if type(self.baseTranslations[key]) == "table" then
285 AceLocale.error(self, "%q::%q has not been translated into %q", key, key2, GetLocale())
286 return
287 else
288 AceLocale.error(self, "Translation table %q::%q does not exist", key, key2)
289 return
290 end
291 end
292 local translation = t[key2]
293 if type(translation) ~= "table" then
294 if type(self.baseTranslations[key]) == "table" then
295 if type(self.baseTranslations[key][key2]) == "table" then
296 AceLocale.error(self, "%q::%q has not been translated into %q", key, key2, GetLocale())
297 return
298 else
299 AceLocale.error(self, "Translation table %q::%q does not exist", key, key2)
300 return
301 end
302 else
303 AceLocale.error(self, "Translation table %q::%q does not exist", key, key2)
304 return
305 end
306 end
307 return translation
308 end
309 local translation = self.translations[key]
310 if type(translation) ~= "table" then
311 if type(self.baseTranslations[key]) == "table" then
312 AceLocale.error(self, "%q has not been translated into %q", key, GetLocale())
313 return
314 else
315 AceLocale.error(self, "Translation table %q does not exist", key)
316 return
317 end
318 end
319 return translation
320 end
321  
322 function AceLocale.prototype:GetTable(key, key2)
323 AceLocale.argCheck(self, key, 1, "string")
324 AceLocale.assert(self, self.translations, "No translations registered")
325 if key2 then
326 AceLocale.argCheck(self, key2, 2, "string", "nil")
327 local t = self.translations[key]
328 if type(t) == "table" then
329 local translation = t[key2]
330 if type(translation) == "table" then
331 return translation
332 else
333 t = self.baseTranslations[key]
334 if type(t) ~= "table" then
335 AceLocale.error(self, "Translation table %q does not exist", key)
336 return
337 end
338 translation = t[key2]
339 if type(translation) ~= "table" then
340 AceLocale.error(self, "Translation table %q::%q does not exist", key, key2)
341 return
342 end
343 return translation
344 end
345 else
346 t = self.baseTranslations[key]
347 if type(t) ~= "table" then
348 AceLocale.error(self, "Translation table %q does not exist", key)
349 return
350 end
351 local translation = t[key2]
352 if type(translation) ~= "table" then
353 AceLocale.error(self, "Translation table %q::%q does not exist", key, key2)
354 return
355 end
356 return translation
357 end
358 end
359 local translation = self.translations[key]
360 if type(translation) == "table" then
361 return translation
362 else
363 translation = self.baseTranslations[key]
364 if type(translation) ~= "table" then
365 AceLocale.error(self, "Translation table %q does not exist", key)
366 return
367 end
368 return translation
369 end
370 end
371  
372 function AceLocale.prototype:Debug()
373 if not self.debugging then
374 return
375 end
376 local words = {}
377 local locales = {"enUS", "deDE", "frFR", "zhCN", "zhTW", "koKR"}
378 local localizations = {}
379 DEFAULT_CHAT_FRAME:AddMessage("--- AceLocale Debug ---")
380 for _,locale in ipairs(locales) do
381 if not self.translationTables[locale] then
382 DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q not found", locale))
383 else
384 localizations[locale] = self.translationTables[locale]
385 end
386 end
387 local localeDebug = {}
388 for locale, localization in pairs(localizations) do
389 localeDebug[locale] = {}
390 for word in pairs(localization) do
391 if type(localization[word]) == "table" then
392 if type(words[word]) ~= "table" then
393 words[word] = {}
394 end
395 for bit in pairs(localization[word]) do
396 if type(localization[word][bit]) == "string" then
397 words[word][bit] = true
398 end
399 end
400 elseif type(localization[word]) == "string" then
401 words[word] = true
402 end
403 end
404 end
405 for word in pairs(words) do
406 if type(words[word]) == "table" then
407 for bit in pairs(words[word]) do
408 for locale, localization in pairs(localizations) do
409 if not localization[word] or not localization[word][bit] then
410 localeDebug[locale][word .. "::" .. bit] = true
411 end
412 end
413 end
414 else
415 for locale, localization in pairs(localizations) do
416 if not localization[word] then
417 localeDebug[locale][word] = true
418 end
419 end
420 end
421 end
422 for locale, t in pairs(localeDebug) do
423 if not next(t) then
424 DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q complete", locale))
425 else
426 DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q missing:", locale))
427 for word in pairs(t) do
428 DEFAULT_CHAT_FRAME:AddMessage(string.format(" %q", word))
429 end
430 end
431 end
432 DEFAULT_CHAT_FRAME:AddMessage("--- End AceLocale Debug ---")
433 end
434  
435 local function activate(self, oldLib, oldDeactivate)
436 AceLocale = self
437  
438 if oldLib then
439 self.registry = oldLib.registry
440 end
441 if not self.registry then
442 self.registry = {}
443 end
444  
445 if oldDeactivate then
446 oldDeactivate(oldLib)
447 end
448 end
449  
450 AceLibrary:Register(AceLocale, MAJOR_VERSION, MINOR_VERSION, activate)
451 AceLocale = AceLibrary(MAJOR_VERSION)