Module:Type: Difference between revisions

From FiguraMC
PenguinEncounter (talk | contribs)
No edit summary
PenguinEncounter (talk | contribs)
mw.title.exists
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
local exports = {}
local exports = {}


local builtin_url = "https://www.lua.org/manual/5.2/manual.html#2.1"
local BUILTINS = {
local BUILTINS = {
["nil"] = true,
["nil"] = true,
Line 11: Line 12:
["function"] = true,
["function"] = true,
["table"] = true,
["table"] = true,
-- not really a builtin but close enough
["any"] = true
}
}
local NOT_PLURAL = {
local NOT_PLURAL = {
Line 16: Line 19:
}
}
local ALIASES = {
local ALIASES = {
["^bool$"] = "boolean",
["^[Mm]atrices$"] = "Matrix",
["^[Mm]atrix[234]?$"] = "Matrix",
["^[Vv]ector[234]?$"] = "Vector",
}
local LINKS = {
["^Vector$"] = "Vectors and Matrices",
["^Matrix$"] = "Vectors and Matrices"
}
}


local function exists(frame, page_name)
local function exists(page_name)
return frame:callParserFunction("PAGEID", page_name) ~= "0"
return mw.title.new(page_name).exists
end
end


local function create(frame, primary_text, link, css_name, extra_attr, secondary_text)
local function infer_name_link(frame, type_data)
local name = type_data.name
name = name:gsub("%s*$", ""):gsub("^%s*", "")
if not NOT_PLURAL[name] then name = name:gsub("s$", "") end
for pat, repl in pairs(ALIASES) do
local new_name, count = name:gsub(pat, repl)
if count > 0 then name = new_name break end
end
type_data.css_name = name
if type_data.link then
if type_data.link:find("^https?://") then type_data.link_external = true end
return
end
if BUILTINS[name] then
type_data.link = builtin_url
type_data.link_external = true
return
end
local link
for pat, target in pairs(LINKS) do
if name:find(pat) then link = target break end
end
if not link then
if exists(name .. " (type)") then
link = name .. " (type)"
else
link = name
if not exists(name) then
type_data.extra_attr = (type_data.extra_attr or "") .. " data-missing"
end
end
end
if link:find("^https?://") then type_data.link_external = true end
type_data.link = link
end
 
local function create(frame, options)
infer_name_link(frame, options)
if options.modifiers and options.modifiers:find("^%s*$") then options.modifiers = nil end
local secondary_text = options.modifiers
local link = options.link
local text = options.text or options.name
local link_text
if options.link_external then
link_text = string.format("[%s %s]", options.link, text)
else
link_text = string.format("[[%s|%s]]", options.link, text)
end
local secondary = string.format([[<span class="lua-type-mod">%s</span>]], secondary_text or "")
local secondary = string.format([[<span class="lua-type-mod">%s</span>]], secondary_text or "")
return string.format(
return string.format(
[=[<span class="lua-type" data-name="%s" %s>[[%s|%s]]%s</span>]=],
[=[<span class="lua-type" data-name="%s"%s>%s%s</span>]=],
css_name, extra_attr, link, primary_text,
options.css_name, options.extra_attr or "", link_text, secondary_text and secondary or ""
secondary_text ~= nil and secondary or ""
)
)
end
end
Line 40: Line 99:
if modifiers:find("?$") then
if modifiers:find("?$") then
modifiers = modifiers:sub(1, -2) -- cut off the ?
modifiers = modifiers:sub(1, -2) -- cut off the ?
table.insert(result, {{name="nil"}})
table.insert(result, {name="nil"})
end
end
table.insert(result, 1, {name=name, modifiers=modifiers})
table.insert(result, 1, {name=name, modifiers=modifiers})
Line 62: Line 121:
if input_args.link then type_structs[1].link = input_args.link end
if input_args.link then type_structs[1].link = input_args.link end
local strings = {}
local strings = {}
for _, part in ipairs(type_structs) do table.insert(strings, create(frame, part)) end
return table.concat(strings, " &vert; ")
end
end


return exports
return exports

Latest revision as of 21:02, 28 September 2024

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

local exports = {}

local builtin_url = "https://www.lua.org/manual/5.2/manual.html#2.1"
local BUILTINS = {
	["nil"] = true,
	["number"] = true,
	["integer"] = true,
	["boolean"] = true,
	["string"] = true,
	["true"] = true,
	["false"] = true,
	["function"] = true,
	["table"] = true,
	-- not really a builtin but close enough
	["any"] = true
}
local NOT_PLURAL = {
	["Matrixs"] = true,
}
local ALIASES = {
	["^bool$"] = "boolean",
	["^[Mm]atrices$"] = "Matrix",
	["^[Mm]atrix[234]?$"] = "Matrix",
	["^[Vv]ector[234]?$"] = "Vector",
}
local LINKS = {
	["^Vector$"] = "Vectors and Matrices",
	["^Matrix$"] = "Vectors and Matrices"
}

local function exists(page_name)
	return mw.title.new(page_name).exists
end

local function infer_name_link(frame, type_data)
	local name = type_data.name
	name = name:gsub("%s*$", ""):gsub("^%s*", "")
	if not NOT_PLURAL[name] then name = name:gsub("s$", "") end
	for pat, repl in pairs(ALIASES) do
		local new_name, count = name:gsub(pat, repl)
		if count > 0 then name = new_name break end
	end
	
	type_data.css_name = name
	if type_data.link then
		if type_data.link:find("^https?://") then type_data.link_external = true end
		return
	end
	if BUILTINS[name] then
		type_data.link = builtin_url
		type_data.link_external = true
		return
	end
	local link
	for pat, target in pairs(LINKS) do
		if name:find(pat) then link = target break end
	end
	if not link then
		if exists(name .. " (type)") then
			link = name .. " (type)"
		else
			link = name
			if not exists(name) then
				type_data.extra_attr = (type_data.extra_attr or "") .. " data-missing"
			end
		end
	end
	if link:find("^https?://") then type_data.link_external = true end
	type_data.link = link
end

local function create(frame, options)
	infer_name_link(frame, options)
	
	if options.modifiers and options.modifiers:find("^%s*$") then options.modifiers = nil end
	
	local secondary_text = options.modifiers
	local link = options.link
	local text = options.text or options.name
	local link_text
	if options.link_external then
		link_text = string.format("[%s %s]", options.link, text)
	else
		link_text = string.format("[[%s|%s]]", options.link, text)
	end
	local secondary = string.format([[<span class="lua-type-mod">%s</span>]], secondary_text or "")
	return string.format(
		[=[<span class="lua-type" data-name="%s"%s>%s%s</span>]=],
		options.css_name, options.extra_attr or "", link_text, secondary_text and secondary or ""
	)
end

-- local function resolve_type()

local function expand_types(type_name)
	local name, modifiers = type_name:match("^([^?[]-)([[%]?]*)$")
	if not name then error("Couldn't parse type name " .. type_name) end
	local result = {}
	if modifiers:find("?$") then
		modifiers = modifiers:sub(1, -2) -- cut off the ?
		table.insert(result, {name="nil"})
	end
	table.insert(result, 1, {name=name, modifiers=modifiers})
	return result
end

function exports.run(frame)
	local sb = ""
	local input_args = frame:getParent().args
	
	if not (input_args[1] or input_args.name) then error "need to specify at least one type name" end
	
	local name = input_args[1] or input_args.name
	local compatibility_mode = {["?"]=true,["[]"]=true, ["[]?"]=true}
	if input_args[2] and compatibility_mode[input_args[2]] then
		name = name .. input_args[2]
	end
	
	local type_structs = expand_types(name)
	if input_args.text then type_structs[1].text = input_args.text end
	if input_args.link then type_structs[1].link = input_args.link end
	local strings = {}
	for _, part in ipairs(type_structs) do table.insert(strings, create(frame, part)) end
	return table.concat(strings, " &vert; ")
end

return exports