Module:GameText

local cache = mw.ext.LuaCache local trim = mw.text.trim

local args_table -- cache

local lastRevisions = mw.loadData('Module:GameText/LastRevs')

-- helper function local getArg = function(key) local value = trim(args_table[key] or '') return (value ~= '') and value or nil end

local concatTable = function(tbl, sep) local arr = {} for _, v in pairs(tbl) do		arr[#arr+1] = v	end return table.concat(arr, sep) end

local db = {} local loadDatabase = function(lang) if not db[lang] then local status, result = xpcall(			function return mw.loadData("Module:GameText/loaddata-"..lang) end, -- try to load database for that language			function return mw.loadData("Module:GameText/loaddata-en") end -- if it doesn't exist, load en database as fallback		) db[lang] = result or {} end return db[lang] end

-- key: e.g. "BuffName.ManaRegeneration". -- return string or table, nil when key or data is invalid. local get -- for recursion get = function(key, lang) local data = db[lang] or loadDatabase(lang or 'en') data = data.info local key = trim(key) local pos = 1 for st,sp in function return string.find(key, '.', pos, true) end do		index = string.sub(key, pos, st-1) data = data[tonumber(index) or index] -- convert to number for pure number index. if not data then return nil end pos = sp + 1 end if pos ~= 0 then key = string.sub(key, pos) end local result = data[tonumber(key) or key] if result and type(result) == 'string' then -- for ref marks such as {$CommonItemTooltip.RightClickToOpen} result = string.gsub(result, "({%$(.-)})", function(_, ref) return get(ref, lang) end) end return result end

-- get internal name by text -- e.g getInternal("ItemName", "Iron Pickaxe", "en") => "IronPickaxe" getInternalName = function(section, text, lang) local data = db[lang] or loadDatabase(lang or 'en') data = data.flipped if not data[section] then return nil end return data[section][text] end

-- args: replacement table, e.g.: { ["{0}"] = "Party Girl", [" "] = "Right click" } local getText = function(key, lang, args) if not key then return end local str = get(key, lang) or get(key, 'en') if not str then return end str = string.gsub(str, "{%?.-}", "") -- strip condition marks, e.g.: "{?Homeless}"" -> ""	if args then		str = string.gsub(str, "%b{}", args)		str = string.gsub(str, "%b<>", args)	end	return str end

-- bulid replacement table from template arguments. -- e.g.: |x_0=Party Girl|y_right=Right click -> { ["{0}"] = "Party Girl", [" "] = "Right click" } local replacementArgs = function(argsTable) local args for k, v in pairs(argsTable) do		string.gsub(k, '^x_(.+)', function(n)			if not args then args = {} end			args['{'..n..'}'] = v		end) string.gsub(k, '^y_(.+)', function(n)			if not args then args = {} end			args['<'..n..'>'] = v		end) end return args end

local getSectionList = function local data = db['en'] or loadDatabase('en') local arr = {} for k, v in pairs(data.info) do		arr[#arr + 1] = k	end return arr end

-- sorted pairs function local function spairs(t, order) -- collect the keys local keys = {} for k in pairs(t) do keys[#keys+1] = tostring(k) end

-- if order function given, sort by it by passing the table and keys a, b,   -- otherwise just sort the keys if order then table.sort(keys, function(a,b) return order(t, a, b) end) else table.sort(keys) end

-- return the iterator function local i = 0 return function i = i + 1 if keys[i] then return keys[i], t[keys[i]] end end end

local function getCacheKey(args, lang, raw) local last_rev = lastRevisions[lang] or lastRevisions['en'] or '' local result = 'gameText:cache:' .. last_rev .. ':' .. lang .. ':'	if raw then result = result .. 'raw:' end for k, v in spairs(args or {}) do result = result .. k .. '=' .. v .. ';'	end return result end

return { -- for template get = function(frame) args_table = frame:getParent.args -- cache local lang = getArg('lang') or frame.args['lang'] local cache_key = getCacheKey(args_table, lang) local str = cache.get(cache_key) if str then return str end str = getText(getArg(1), lang, replacementArgs(args_table)) if str then local result = ' ' .. string.gsub(str, '\n', ' ') .. ' '			cache.set(cache_key, result, 24 * 60 * 60) return result end end,

getRaw = function(frame) local lang = frame.args['lang'] or frame:expandTemplate{title = 'lang'} local cache_key = getCacheKey(frame.args, lang, true) local str = cache.get(cache_key) if str then return str end str = (frame.args['prefix'] or '') ..(getText(frame.args[1], lang, replacementArgs(frame.args)) or '') ..(frame.args['postfix'] or '') cache.set(cache_key, str, 24 * 60 * 60) return str end,

-- for getInternalName = function(frame) args_table = frame.args -- cache return getInternalName(getArg(1), getArg(2), getArg('lang')) end,

listAll = function(frame) local lang = frame.args['lang'] or 'en' loadDatabase(lang) local arr = {} if frame.args[1] then if not db[lang]['info'][frame.args[1]] then return end for k, v in pairs(db[lang]['info'][frame.args[1]]) do arr[#arr + 1] = k .. '₪' .. v			end

else for k, v in pairs(db[lang]['info']) do				arr[#arr + 1] = k			end end return table.concat(arr, '¦') end,

listKeys = function(frame) local lang = frame.args['lang'] or 'en' loadDatabase(lang) local arr = {} for k, v in pairs(frame.args[1] and (db[lang]['info'][frame.args[1]] or {}) or db[lang]['info']) do			arr[#arr + 1] = k		end return table.concat(arr, '¦') end,

printTable = function(frame) local lang = frame.args['lang'] or 'en' local data = loadDatabase(lang).info local output = {' ' .. str .. ' '			end end output[#output + 1] = ' ' return table.concat(output, '\n') end,

-- purge database cache -- from template: -- from module: require('Module:gameText').purge purge = function(frame) local lang if frame == mw.getCurrentFrame then lang = frame.args['lang'] else lang = frame end lang = lang or 'en' require('Module:GameText/loaddata').purge(lang) end, -- purge output purgeGet = function(frame) args_table = frame:getParent.args -- cache local lang = getArg('lang') or frame.args['lang'] local cache_key = getCacheKey(args_table, lang) cache.delete(cache_key) end, -- purge output purgeRaw = function(frame) local lang = frame.args['lang'] or mw.getCurrentFrame:expandTemplate{title = 'lang'} local cache_key = getCacheKey(frame.args, lang, true) cache.delete(cache_key) end,

-- for module getText = getText, getData = get, getKey = getInternalName, getSections = getSectionList, }