293 lines
7.8 KiB
Lua
293 lines
7.8 KiB
Lua
-- LibBabble-3.0 is hereby placed in the Public Domain
|
|
-- Credits: ckknight
|
|
local LIBBABBLE_MAJOR, LIBBABBLE_MINOR = "LibBabble-3.0", 2
|
|
|
|
local LibBabble = LibStub:NewLibrary(LIBBABBLE_MAJOR, LIBBABBLE_MINOR)
|
|
if not LibBabble then
|
|
return
|
|
end
|
|
|
|
local data = LibBabble.data or {}
|
|
for k,v in pairs(LibBabble) do
|
|
LibBabble[k] = nil
|
|
end
|
|
LibBabble.data = data
|
|
|
|
local tablesToDB = {}
|
|
for namespace, db in pairs(data) do
|
|
for k,v in pairs(db) do
|
|
tablesToDB[v] = db
|
|
end
|
|
end
|
|
|
|
local function warn(message)
|
|
local _, ret = pcall(error, message, 3)
|
|
geterrorhandler()(ret)
|
|
end
|
|
|
|
local lookup_mt = { __index = function(self, key)
|
|
local db = tablesToDB[self]
|
|
local current_key = db.current[key]
|
|
if current_key then
|
|
self[key] = current_key
|
|
return current_key
|
|
end
|
|
local base_key = db.base[key]
|
|
local real_MAJOR_VERSION
|
|
for k,v in pairs(data) do
|
|
if v == db then
|
|
real_MAJOR_VERSION = k
|
|
break
|
|
end
|
|
end
|
|
if not real_MAJOR_VERSION then
|
|
real_MAJOR_VERSION = LIBBABBLE_MAJOR
|
|
end
|
|
if base_key then
|
|
warn(("%s: Translation %q not found for locale %q"):format(real_MAJOR_VERSION, key, GetLocale()))
|
|
rawset(self, key, base_key)
|
|
return base_key
|
|
end
|
|
warn(("%s: Translation %q not found."):format(real_MAJOR_VERSION, key))
|
|
rawset(self, key, key)
|
|
return key
|
|
end }
|
|
|
|
local function initLookup(module, lookup)
|
|
local db = tablesToDB[module]
|
|
for k in pairs(lookup) do
|
|
lookup[k] = nil
|
|
end
|
|
setmetatable(lookup, lookup_mt)
|
|
tablesToDB[lookup] = db
|
|
db.lookup = lookup
|
|
return lookup
|
|
end
|
|
|
|
local function initReverse(module, reverse)
|
|
local db = tablesToDB[module]
|
|
for k in pairs(reverse) do
|
|
reverse[k] = nil
|
|
end
|
|
for k,v in pairs(db.current) do
|
|
reverse[v] = k
|
|
end
|
|
tablesToDB[reverse] = db
|
|
db.reverse = reverse
|
|
db.reverseIterators = nil
|
|
return reverse
|
|
end
|
|
|
|
local prototype = {}
|
|
local prototype_mt = {__index = prototype}
|
|
|
|
--[[---------------------------------------------------------------------------
|
|
Notes:
|
|
* If you try to access a nonexistent key, it will warn but allow the code to pass through.
|
|
Returns:
|
|
A lookup table for english to localized words.
|
|
Example:
|
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
|
local BL = B:GetLookupTable()
|
|
assert(BL["Some english word"] == "Some localized word")
|
|
DoSomething(BL["Some english word that doesn't exist"]) -- warning!
|
|
-----------------------------------------------------------------------------]]
|
|
function prototype:GetLookupTable()
|
|
local db = tablesToDB[self]
|
|
|
|
local lookup = db.lookup
|
|
if lookup then
|
|
return lookup
|
|
end
|
|
return initLookup(self, {})
|
|
end
|
|
--[[---------------------------------------------------------------------------
|
|
Notes:
|
|
* If you try to access a nonexistent key, it will return nil.
|
|
Returns:
|
|
A lookup table for english to localized words.
|
|
Example:
|
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
|
local B_has = B:GetUnstrictLookupTable()
|
|
assert(B_has["Some english word"] == "Some localized word")
|
|
assert(B_has["Some english word that doesn't exist"] == nil)
|
|
-----------------------------------------------------------------------------]]
|
|
function prototype:GetUnstrictLookupTable()
|
|
local db = tablesToDB[self]
|
|
|
|
return db.current
|
|
end
|
|
--[[---------------------------------------------------------------------------
|
|
Notes:
|
|
* If you try to access a nonexistent key, it will return nil.
|
|
* This is useful for checking if the base (English) table has a key, even if the localized one does not have it registered.
|
|
Returns:
|
|
A lookup table for english to localized words.
|
|
Example:
|
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
|
local B_hasBase = B:GetBaseLookupTable()
|
|
assert(B_hasBase["Some english word"] == "Some english word")
|
|
assert(B_hasBase["Some english word that doesn't exist"] == nil)
|
|
-----------------------------------------------------------------------------]]
|
|
function prototype:GetBaseLookupTable()
|
|
local db = tablesToDB[self]
|
|
|
|
return db.base
|
|
end
|
|
--[[---------------------------------------------------------------------------
|
|
Notes:
|
|
* If you try to access a nonexistent key, it will return nil.
|
|
* This will return only one English word that it maps to, if there are more than one to check, see :GetReverseIterator("word")
|
|
Returns:
|
|
A lookup table for localized to english words.
|
|
Example:
|
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
|
local BR = B:GetReverseLookupTable()
|
|
assert(BR["Some localized word"] == "Some english word")
|
|
assert(BR["Some localized word that doesn't exist"] == nil)
|
|
-----------------------------------------------------------------------------]]
|
|
function prototype:GetReverseLookupTable()
|
|
local db = tablesToDB[self]
|
|
|
|
local reverse = db.reverse
|
|
if reverse then
|
|
return reverse
|
|
end
|
|
return initReverse(self, {})
|
|
end
|
|
local blank = {}
|
|
local weakVal = {__mode='v'}
|
|
--[[---------------------------------------------------------------------------
|
|
Arguments:
|
|
string - the localized word to chek for.
|
|
Returns:
|
|
An iterator to traverse all English words that map to the given key
|
|
Example:
|
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
|
for word in B:GetReverseIterator("Some localized word") do
|
|
DoSomething(word)
|
|
end
|
|
-----------------------------------------------------------------------------]]
|
|
function prototype:GetReverseIterator(key)
|
|
local db = tablesToDB[self]
|
|
local reverseIterators = db.reverseIterators
|
|
if not reverseIterators then
|
|
reverseIterators = setmetatable({}, weakVal)
|
|
db.reverseIterators = reverseIterators
|
|
elseif reverseIterators[key] then
|
|
return pairs(reverseIterators[key])
|
|
end
|
|
local t
|
|
for k,v in pairs(db.current) do
|
|
if v == key then
|
|
if not t then
|
|
t = {}
|
|
end
|
|
t[k] = true
|
|
end
|
|
end
|
|
reverseIterators[key] = t or blank
|
|
return pairs(reverseIterators[key])
|
|
end
|
|
--[[---------------------------------------------------------------------------
|
|
Returns:
|
|
An iterator to traverse all translations English to localized.
|
|
Example:
|
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
|
for english, localized in B:Iterate() do
|
|
DoSomething(english, localized)
|
|
end
|
|
-----------------------------------------------------------------------------]]
|
|
function prototype:Iterate()
|
|
local db = tablesToDB[self]
|
|
|
|
return pairs(db.current)
|
|
end
|
|
|
|
-- #NODOC
|
|
-- modules need to call this to set the base table
|
|
function prototype:SetBaseTranslations(base)
|
|
local db = tablesToDB[self]
|
|
local oldBase = db.base
|
|
if oldBase then
|
|
for k in pairs(oldBase) do
|
|
oldBase[k] = nil
|
|
end
|
|
for k, v in pairs(base) do
|
|
oldBase[k] = v
|
|
end
|
|
base = oldBase
|
|
else
|
|
db.base = base
|
|
end
|
|
for k,v in pairs(base) do
|
|
if v == true then
|
|
base[k] = k
|
|
end
|
|
end
|
|
end
|
|
|
|
local function init(module)
|
|
local db = tablesToDB[module]
|
|
if db.lookup then
|
|
initLookup(module, db.lookup)
|
|
end
|
|
if db.reverse then
|
|
initReverse(module, db.reverse)
|
|
end
|
|
db.reverseIterators = nil
|
|
end
|
|
|
|
-- #NODOC
|
|
-- modules need to call this to set the current table. if current is true, use the base table.
|
|
function prototype:SetCurrentTranslations(current)
|
|
local db = tablesToDB[self]
|
|
if current == true then
|
|
db.current = db.base
|
|
else
|
|
local oldCurrent = db.current
|
|
if oldCurrent then
|
|
for k in pairs(oldCurrent) do
|
|
oldCurrent[k] = nil
|
|
end
|
|
for k, v in pairs(current) do
|
|
oldCurrent[k] = v
|
|
end
|
|
current = oldCurrent
|
|
else
|
|
db.current = current
|
|
end
|
|
end
|
|
init(self)
|
|
end
|
|
|
|
for namespace, db in pairs(data) do
|
|
setmetatable(db.module, prototype_mt)
|
|
init(db.module)
|
|
end
|
|
|
|
-- #NODOC
|
|
-- modules need to call this to create a new namespace.
|
|
function LibBabble:New(namespace, minor)
|
|
local module, oldminor = LibStub:NewLibrary(namespace, minor)
|
|
if not module then
|
|
return
|
|
end
|
|
|
|
if not oldminor then
|
|
local db = {
|
|
module = module,
|
|
}
|
|
data[namespace] = db
|
|
tablesToDB[module] = db
|
|
else
|
|
for k,v in pairs(module) do
|
|
module[k] = nil
|
|
end
|
|
end
|
|
|
|
setmetatable(module, prototype_mt)
|
|
|
|
return module
|
|
end
|