Module:Elinks-api

From Warcraft Wiki
Jump to navigation Jump to search

This module is invoked by Template:Elinks-api to generate the external links on API pages. Links are tailored to each external site's unique folder structure and filename convention. Refer to the template page for further documentation and test suites.



-- See [[Template:Elinks-api]] and [[Module:Api]]

local api = require("Module:Api")	-- parses t= or auto-detects using common code for all api templates

local module = {}					-- see function module.GetLinks() below

-- private constants

local HTML_LIST_START = [=[<ul class="plainlinks elinks" style="list-style-position:outside">]=]
local HTML_LIST_ITEM = [=[<li style="padding-left: 0px"><span style="display:inline-block; width:25px; text-align:center">[[Image:%s.png|16px|link=]]</span>[%s %s], %s</li>]=]
local HTML_LIST_END = [=[</ul>]=]
local HTML_TYPE_NOT_FOUND = [=[<span style="color:red; font-weight:bold">Error: unknown or undetected type.</span>]=]

-- private functions

local function GetGetheQueryUrl(apiType, name)
	if (apiType == api.TYPE_WIDGETMETHOD and string.find(name, ":")) then
		-- Searches for only the method name to limit false positives in the search results
		return "https://github.com/Gethe/wow-ui-source/search?q="..string.sub(name, string.find(name, ":"),-1)
	else
		return "https://github.com/Gethe/wow-ui-source/search?q="..name
	end
end

local function GetTlyGlobeUrl(name)
	return "https://www.townlong-yak.com/globe/wut/#q:"..name
end

local function GetTlyBadUrl(fullName, patch)
	return string.format("https://www.townlong-yak.com/framexml/%s/Blizzard_APIDocumentation#%s",patch or "latest", fullName)
end

local function GetMrBudsUrl(apiType, member, system)
	if (apiType == api.TYPE_EVENT) then
		member = string.gsub(string.gsub("_"..string.lower(member),"%_%l",string.upper),"_","")  -- PLAYER_LOGIN to PlayerLogin
		return string.format("https://mrbuds.github.io/wow-api-web/?search=api:event:%s:%s", member, system)
	elseif (apiType == api.TYPE_FUNCTION) then
		return string.format("https://mrbuds.github.io/wow-api-web/?search=api:function:%s:%s", member, system)
	end
	return string.format("https://mrbuds.github.io/wow-api-web/")
end

local function GetWowProgrammingUrl(apiType, name)
	if (apiType == api.TYPE_FUNCTION) then
		return "http://wowprogramming.com/docs/api/"..name..".html"
	elseif (apiType == api.TYPE_CVAR) then
		return "http://wowprogramming.com/docs/cvars/"..name..".html"
	elseif (apiType == api.TYPE_EVENT) then
		return "http://wowprogramming.com/docs/events/"..name..".html"
	elseif (apiType == api.TYPE_SCRIPT) then
		return "http://wowprogramming.com/docs/scripts/"..name..".html"
	elseif (apiType == api.TYPE_WIDGET) then
		return "http://wowprogramming.com/docs/widgets/"..name..".html"
	elseif (apiType == api.TYPE_WIDGETMETHOD and string.find(name, ":")) then
		local widget = string.sub(name, 1, string.find(name, ":") - 1)
		local method = string.sub(name, string.find(name, ":") + 1)
		return "http://wowprogramming.com/docs/widgets/"..widget.."/"..method..".html"
	else
		return "http://wowprogramming.com/"
	end
end

-- public functions

function module.GetLinks(frame)
	local pagename = frame.args[1]		-- Pagename, or an override name=
	-- local t = frame.args[2]			-- The t= parameter is parsed by [[Module:Api]] below
	local namespace = frame.args[3]		-- C_Namespace or empty string
	local system = frame.args[4]		-- system or emtpy string
	local patch = frame.args[5]			-- legacy WoW patch for depreciated funcs, or empty string
	local flags = frame.args[6]			-- zero or more flags using the pattern:  [~~flag1[##param1][~~flag2[##param2]~~
	local str = {HTML_LIST_START}		-- pieces returned to the wiki using table.concat({firstLine, HTML_LIST_ITEM:format(...), ..., lastLine})

	-- Use [[Module:Api]] for common t= parsing and auto-detection.  If unrecognized, then STOP!
	local apiType, apiSubtype = api.GetType(frame)	-- pass the frame so it can pull args 1 and 2 as if it were a wiki {{#invoke}}
	if apiType == nil or apiType == api.TYPE_VARIABLE and apiSubtype == nil then
		return HTML_TYPE_NOT_FOUND
	end

	-- What is this called?
	local name = 
		apiType == api.TYPE_FUNCTION and string.gsub(string.sub(pagename, string.sub(pagename,1,4) == "API " and 5 or 1), " ", "_")
		or apiType == api.TYPE_CVAR and string.sub(pagename, string.sub(pagename,1,5) == "CVar " and 6 or 1)
		or apiType == api.TYPE_EVENT and string.gsub(pagename, " ", "_")
		or apiType == api.TYPE_WIDGET and string.sub(pagename, string.sub(pagename,1,9) == "UIOBJECT " and 10 or 1)
		or apiType == api.TYPE_WIDGETMETHOD and string.gsub(string.sub(pagename, string.sub(pagename,1,4) == "API " and 5 or 1), " ", ":")
		or apiType == api.TYPE_SCRIPT and string.sub(pagename, string.sub(pagename,1,9) == "UIHANDLER " and 11 or 1)
		or pagename

	-- What else do we know (manually set) or can infer from the name?
	local namespace = namespace ~= "" and namespace or string.find(name, "%.") and string.sub(1,string.find(name, "%.")-1)
	local system = system ~= "" and system or namespace and string.sub(namespace, 3)
	local member = string.find(name, "%.") and string.sub(name,string.find(name, "%.")+1)

	-- Build the output strings
	if (apiType == api.TYPE_FUNCTION or apiType == api.TYPE_EVENT) then
		-- Gethe
		if (string.find(flags, "~~nogit") == nil and patch == "") then
			table.insert(str, string.format(HTML_LIST_ITEM, "GitHub_Octocat", GetGetheQueryUrl(apiType, member or name), "GitHub FrameXML", "Gethe"))
		end
		
		-- TLY Globe
		if (patch == "") then
			table.insert(str, string.format(HTML_LIST_ITEM, "Townlong-Yak_Globe", GetTlyGlobeUrl(name), [[Globe "wut?" Tool]], "Townlong-Yak"))
		end
		
		-- Blizzard API Docs
		if (system and string.find(flags, "~~nodoc") == nil) then
			-- TLY BAD
			table.insert(str, string.format(HTML_LIST_ITEM, "Townlong-Yak_BAD", GetTlyBadUrl(name, patch ~= "" and patch), "Blizzard API Docs", "Townlong-Yak"))
			-- MrBuds
			if (patch == "") then
				table.insert(str, string.format(HTML_LIST_ITEM, "ProfIcons_engineering", GetMrBudsUrl(apiType, member or name, system), "Offline /api addon", "MrBuds"))
			end
		end
	elseif (apiType == api.TYPE_CVAR or apiType == api.TYPE_SCRIPT or apiType == api.TYPE_WIDGETMETHOD) then
		-- Gethe
		if (string.find(flags, "~~nogit") == nil and patch == "") then
			table.insert(str, string.format(HTML_LIST_ITEM, "GitHub_Octocat", GetGetheQueryUrl(apiType, member or name), "GitHub FrameXML", "Gethe"))
		end
	elseif (apiType == api.TYPE_VARIABLE) then
		if (apiSubtype == api.SUBTYPE_MIXIN) then
			-- TLY Globe
			if (patch == "") then
				table.insert(str, string.format(HTML_LIST_ITEM, "Townlong-Yak_Globe", GetTlyGlobeUrl(name), [[Globe "wut?" Tool]], "Townlong-Yak"))
			end	
			-- Gethe
			if (string.find(flags, "~~nogit") == nil and patch == "") then
				table.insert(str, string.format(HTML_LIST_ITEM, "GitHub_Octocat", GetGetheQueryUrl(apiType, member or name), "GitHub FrameXML", "Gethe"))
			end
		end
	end
	local wowprog = string.find(flags, "~~wowprog")
	if (wowprog) then
		table.insert(str, string.format(HTML_LIST_ITEM, "Wowprogramming", string.match(flags,"~~wowprog@@(.-)~~") or GetWowProgrammingUrl(apiType,name), "wowprogramming", "Jim Whitehead"))
	end
	table.insert(str, HTML_LIST_END)
	
	-- Return the list if it has at least one member; otherwise return an empty string.
	return #str > 2 and table.concat(str) or ""
end

return module