Модуль:GameText

Материал из Terraria Wiki
Перейти к навигации Перейти к поиску
Lua.svg Документация Документация, указанная ниже, находится на странице «Модуль:GameText/док». (править | история)
См. также этот модуль на английском языке: Module:GameText. В нём может содержаться более полная или подробная информация.

Этот модуль предназначен для корректной работы шаблона {{gameText}}.


local trim = mw.text.trim

local args_table -- cache
-- 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')
	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

-- args: replacement table, e.g.: { ["{0}"] = "Party Girl", ["<right>"] = "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>"] = "Right click" }
local replacementArgs = function(argsTable)
	local args = {}
	local flag = false
	for k, v in pairs(argsTable) do
		string.gsub(k, '^x_(.+)', function(n)
			args['{'..n..'}'] = v
			flag = true
		end)
		string.gsub(k, '^y_(.+)', function(n)
			args['<'..n..'>'] = v
			flag = true
		end)
	end
	return flag and args or nil
end

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

return {
	---------- for template ----------------
	get = function(frame)
		args_table = frame:getParent().args -- cache
		local str = getText(getArg(1), getArg('lang') or frame.args['lang'], replacementArgs(args_table))
		if str then
			return '<span class="gameText">' .. string.gsub(str, '\n', '<br/>') .. '</span>'
		end
	end,

	getRaw = function(frame)
		return (frame.args['prefix'] or '')
		     ..(getText(frame.args[1], frame.args['lang'] or frame:expandTemplate{title = 'lang'}, replacementArgs(frame.args)) or '')
		     ..(frame.args['postfix'] or '')
	end,

	-- export a section as an Array of Extension:ArrayFunctions
	getSection = function(frame)
		args_table = frame.args -- cache
		return mw.af.export(get(getArg(1), getArg('lang')))
	end,
	
	getSectionList = function(frame)
		args_table = frame.args -- cache
		return mw.af.export(getSectionList())
	end,

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

		else
			for k, v in pairs(db[lang]) 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][frame.args[1]] or {}) or db[lang]) 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)

		local all_keys = {}
		local all_values = {}
		function recurse(datatable, previous_key)
			for this_subkey, data in pairs(datatable) do
				local next_key
				if previous_key ~= '' then
					next_key = previous_key .. '.' .. this_subkey
				else
					next_key = this_subkey
				end
				if type(data) ~= 'table' then
					table.insert(all_keys, next_key)
					all_values[next_key] = data
				else
					recurse(data, next_key)
				end
			end
		end
		recurse(data, '')
		table.sort(all_keys)

		local output = {'<table class="wikitable"><tr><th>Key</th><th>String</th></tr>'}
		for i = 1, #all_keys do
			local key = all_keys[i]
			local keyCell = '<td><code>' .. key .. '</code></td>'
			local valueCell = '<td><span class="gameText">' .. string.gsub(all_values[key], '\n', '<br/>') .. '</span></td>'
			table.insert(output, '<tr>' .. keyCell .. valueCell .. '</tr>')
		end
		table.insert(output, '</table>')
		return table.concat(output)
	end,
	

	-- purge database cache
	-- from template: {{#invoke:gameText|purge|lang=<lang>}}
	-- from module: require('Module:gameText').purge(<lang>)
	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,
	

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