Module:Apitype

From Warcraft Watch Secrets
Revision as of 15:51, 6 October 2024 by imported>Ketho
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

-- https://warcraft.wiki.gg/wiki/Template:Apitype
local data = mw.loadData("Module:Apitype/data")
local m = {}

local suffices = {
	["%?"] = "nilable",
	["%[%]"] = "array",
}

-- cannot use table.concat
local function tconcat(t, del)
	local size = 0
	for _ in pairs(t) do
		size = size + 1
	end
	local s = ""
	for k, v in pairs(t) do
		s = s..v
		if k ~= size then
			s = s..del
		end
	end
	return s
end

-- todo: refactor
local function FormatString(args, text)
	-- need to match the dot in e.g. "Enum.AuctionHouseFilter"
	local name, symbols = text:match("([%w%._:]+)([%[%]%?]*)")
	local s
	if name:find("Mixin") or data.enum[name] or #args.link > 0 then -- specifically want a colored hyperlink
		s = string.format('[[%s|<font color="#ecbc2a">%s</font>]]%s<small>🔗</small>', name, name, symbols)
	elseif name:find("Callback$") then
		s = string.format('<font color="#ecbc2a">function</font>%s : <font color="#ecbc2a"><small>%s</small></font>', symbols, name)
	elseif name:find("^xs:") then
		s = string.format('<font color="#ecbc2a">%s</font>', name)
	elseif data.blizzardTypes[name] then
		if data.blizzardTypes[name].Type == "Mixin" then
			s = string.format('[[%s|<font color="#ecbc2a">%s</font>]]%s<small>🔗</small>', data.blizzardTypes[name].Mixin, data.blizzardTypes[name].Name, symbols)
		elseif data.blizzardTypes[name].Link then
			if data.blizzardTypes[name].Link:find("dbc:") then
				local link = string.format("https://wago.tools/db2/%s", data.blizzardTypes[name].Link:match("dbc:(.+)"))
				s = string.format('<font color="#ecbc2a">%s</font>%s <small>: <font color="#ecbc2a">[%s %s]</font></small>', data.blizzardTypes[name].Type, symbols, link, name)
			else
				s = string.format('<font color="#ecbc2a">%s</font>%s <small>: <font color="#ecbc2a">[[%s|%s]]</font></small>', data.blizzardTypes[name].Type, symbols, data.blizzardTypes[name].Link, name)
			end
		elseif data.blizzardTypes[name].Replace then
			s = string.format('[[UIOBJECT_%s|<font color="#ecbc2a">%s</font>]]%s<small>🔗</small>', data.blizzardTypes[name].Type, data.blizzardTypes[name].Type, symbols)
		elseif data.blizzardTypes[name].Values then
			s = string.format('<font color="#ecbc2a">%s</font>%s <small>: <span class="tttemplatelink"><font color="#ecbc2a">%s</font></span><span style="display:none"><small>%s</small></span></small>', data.blizzardTypes[name].Type, symbols, name, tconcat(data.blizzardTypes[name].Values, ", "))
		else
			s = string.format('<font color="#ecbc2a">%s</font>%s <small>: <font color="#ecbc2a">%s</font></small>', data.blizzardTypes[name].Type, symbols, name)
		end
		if data.blizzardTypes[name].Description then
			s = string.format('<font color="#ecbc2a"><span title="%s">%s</span></font>', data.blizzardTypes[name].Description, s)
		end
	elseif data.structure[name] then
		s = string.format('<font color="#4ec9b0"><span title="table">%s</span></font>%s', name, symbols)
	elseif data.widget[name] then
		s = string.format('<font color="#ecbc2a">[[UIOBJECT_%s|<font color="#ecbc2a">%s</font>]]%s<small>🔗</small></font>', name, name, symbols)
	elseif data.custom[name] then
		s = string.format('<font color="#ecbc2a"><span title="%s">%s</span></font>%s', data.custom[name], name, symbols)
	elseif data.link[name] then
		s = string.format('[[%s|<font color="#ecbc2a">%s</font>]]%s', data.link[name], name, symbols)
	else
		s = string.format('<font color="#ecbc2a">%s</font>%s', name, symbols)
	end
	if #symbols > 0 then
		for k, v in pairs(suffices) do
			s = s:gsub(k, string.format('<span title="%s">%s</span>', v, k))
		end
	end
	return s
end

local function GetTypes(args)
	local text = args[1]
	if data.multipleTypes[text] then
		text = data.multipleTypes[text].Type
	end
	local t = {}
	for s in text:gmatch("[^,]+") do
		table.insert(t, FormatString(args, s))
	end
	return table.concat(t, "|")
end

local remap = {
	fileID = "FileDataID",
	UnitToken = "UnitId",
	WOWGUID = "GUID",
	vector2 = "Vector2DMixin",
	TickerCallback = "API_types/FunctionContainer",
	TimerCallback = "API_types/FunctionContainer",
}

-- fuck this shit this is what happens when you dont give a fuck
function m.main(f)
	local s
	local text = f.args[1]
	if text:find("<") then
		return string.format('<font color="#ecbc2a">%s</font>', text)
	end
	local name, symbols = text:match("([%w%._]+)([%[%]%?]*)")
	if data.v2[name] then
		local r = {}
		for _, v in pairs(data.v2[name]) do
			if not (name == "TickerCallback" and f.args.info == "ret" and v == "function") then -- fugly hack
				local apitype = string.format([=[<font color="#ecbc2a">%s</font>]=], v)
				table.insert(r, apitype)
			end
		end
		local basictypes = table.concat(r, "|")
		local link
		if remap[name] then -- hack
			link = string.format("[[%s|<span style=\"color:#4ec9b0;\">%s</span>]]", remap[name], name)
		else
			link = string.format("[[API_types/%s|<span style=\"color:#4ec9b0;\">%s</span>]]", name, name)
		end
		if #symbols > 0 then
			basictypes = basictypes..symbols
		end
		return string.format([[%s <span style="font-size:smaller;">: %s</span>]], basictypes, link)
	else
		s = GetTypes(f.args)
		if #f.args.range > 0 then
			s = s..string.format(" <small><code>[%s]</code></small>", f.args.range)
		end
		if #f.args.default > 0 then
			s = s..string.format(' <span style="font-size:smaller; title="default"><code><font color="#dda0dd">= %s</font></code></span>', f.args.default)
		end
	end
	return s
end

return m