Module:GameText

From The Stars Above Mod Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:GameText/doc

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(mod)
	if not db[mod] then
		db[mod] = mw.loadData('Module:GameText/loaddata-' .. mod)
	end
	return db[mod]
end

-- key: e.g.  "BuffName.ManaRegeneration".
-- return string or table, nil when key or data is invalid.
local get -- for recursion
get = function(key, mod)
	local modkey = trim(mod) == '' and 'en' or mod
	local data = db[modkey] or loadDatabase(modkey)
	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 replaceArg
	if string.find(key, '@', 1, true) then
		key, replaceArg = string.match(key, '(.+)@(.+)')
	end
	local result = data[tonumber(key) or key]
	if result then
		-- for ref marks such as {$CommonItemTooltip.RightClickToOpen}
		result = string.gsub(result, "({%$(.-)})", function(_, ref) 
			return get(ref, mod)
		end)
		
		if replaceArg then
			result = string.gsub(result, "%{0%}", replaceArg)
		end
	else
		result = get(ref, 'en') -- use vanilla l10n as a fallback
	end
	return result
end

-- args: replacement table, e.g.: { ["{0}"] = "Party Girl", ["<right>"] = "Right click" }
local getText = function(key, mod, args, raw)
	if not key then
		return
	end
	local str = get(key, mod)
	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
	str = replaceColorCodes(str, raw)
	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

function replaceColorCodes(inputText, raw)
    return mw.ustring.gsub(inputText, '%[c/([0-9A-Fa-f]+):(.-)%]', (raw and '%2' or '<span style="color:#%1; font-weight:bold;">%2</span>'))
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

return {
	---------- for template ----------------
	get = function(frame)
		args_table = frame:getParent().args -- cache
		local str = getText(getArg(1), getArg('mod') or frame.args['mod'], replacementArgs(args_table), false)
		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['mod'] or frame:expandTemplate{title = 'modname', args = { 'get' }},
		     	replacementArgs(frame.args),
		    	not frame.args['colors']) or '')
		     ..(frame.args['postfix'] or '')
	end,

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