Module:debug

local export = {}

local escape do local escapes = { ["\a"] = "a", ["\b"] = "b", ["\f"] = "f", ["\n"] = "n", ["\r"] = "r", ["\t"] = "t", ["\v"] = "v", ["\\"] = "\\", ["\""] = '"', ["'"] = "'", }	local function helper(char) return escapes[char] and "\\" .. escapes[char] or ("\\%03d"):format(char:byte) end -- Escape control characters, backslash, double quote, and bytes that aren't	-- used in UTF-8. -- Escape stuff that can't be saved in a MediaWiki page, like invalid UTF-8 -- and NFD character sequences? Hard. -- Similar to string.format("%q", str), which does not use C-like simple -- escapes and does not escape bytes that are not used in UTF-8. escape = function (str) return (str:gsub("[%c\\\"\192\193\245-\255]", helper))	end end

export.escape = escape

-- Convert a value to a string function export.dump(value, prefix, tsort) local t = type(value) prefix = prefix or "" if t == "string" then return '"' .. escape(value) .. '"' elseif t == "table" then local str_table = {} table.insert(str_table, " {") for key, val in require("Module:table").sortedPairs(value, tsort) do table.insert(str_table, " " .. prefix .. "\t[" .. export.dump(key, prefix .. "\t") .. "] = " .. export.dump(val, prefix .. "\t"):gsub("^ ", "") .. ",") end table.insert(str_table, " " .. prefix .. "}") return table.concat(str_table, "\n") else return tostring(value) end end

function export.highlight_dump(value, prefix, tsort, options) options = options or {} local func = options.modified and "modified_dump" or "dump" local dump = export[func](value, prefix, tsort) -- Remove spaces at beginnings of lines (which are simply to force a tag). dump = dump:gsub("%f[^%z\n] ", "") return export.highlight(dump) end

-- Returns true if table contains a table as one of its values local function containsTable(t) for key, value in pairs(t) do		if type(value) == "table" then return true end end return false end

local function containsTablesWithSize(t, size) for key, value in pairs(t) do		if type(value) == "table" and require("Module:table").size(value) ~= size then return false end end return true end

--[=[	Convert a value to a string. Like dump below, but if a table has consecutive numbered keys and does not have a table as one of its values, it will be placed on a single line. Used by Module:User:Erutuon/script recognition. ]=] function export.modified_dump(value, prefix, tsort) local t = type(value) prefix = prefix or "" if t == "string" then return '"' .. value .. '"' elseif t == "table" then local str_table = {} local containsTable = containsTable(value) local consecutive = require("Module:table").isArray(value) if consecutive and not containsTable or containsTable and containsTablesWithSize(value, 3) then table.insert(str_table, "{") for key, val in require("Module:table").sortedPairs(value, tsort) do				if containsTable then table.insert(str_table, "\n\t" .. prefix) else table.insert(str_table, " ") end if type(key) == "string" then table.insert(str_table, "[" .. export.modified_dump(key) .. "] = ") end table.insert(str_table, type(key) == "number" and type(val) == "number" and string.format("0x%05X", val) or export.modified_dump(val)) if not (consecutive and #value == 3) or type(key) == "number" and value[key + 1] then table.insert(str_table, ",") end end if containsTable then table.insert(str_table, "\n" .. prefix) else table.insert(str_table, " ") end table.insert(str_table, "}") return table.concat(str_table) end table.insert(str_table, " {") for key, val in require("Module:table").sortedPairs(value, tsort) do table.insert(str_table, " " .. prefix .. "\t[" .. export.modified_dump(key, prefix .. "\t") .. "] = " .. export.modified_dump(val, prefix .. "\t"):gsub("^ ", "") .. ",") end table.insert(str_table, " " .. prefix .. "}") return table.concat(str_table, "\n") elseif t == "number" and value > 46 then return string.format("0x%05X", value) else return tostring(value) end end

export.track = require("Module:debug/track")

-- Trigger a script error from a template function export.error(frame) error(frame.args[1] or "(no message specified)") end

--	Convenience function for generating syntaxhighlight tags.	Display defaults to block.	Options is a table. To display inline text with HTML highlighting:		{ inline = true, lang = "html" } function export.highlight(content, options) if type(content) == "table" then options = content options = { lang = options.lang or "lua", inline = options.inline and true }		return function(content) return mw.getCurrentFrame:extensionTag{ name = "syntaxhighlight", content = content, args = options }		end else return mw.getCurrentFrame:extensionTag{ name = "syntaxhighlight", content = content, args = { lang = options and options.lang or "lua", inline = options and options.inline and true or nil }		}	end end

function export.track_unrecognized_args(args, template_name) local function track(code) export.track(template_name .. "/" .. code) end track("unrecognized arg") local arg_list = {} for arg, value in pairs(args) do track("unrecognized arg/" .. arg) table.insert(arg_list, ("|%s=%s"):format(arg, value)) end mw.log(		("Unrecognized parameter%s in : %s."):format( arg_list[2] and "s" or "", template_name, table.concat(arg_list, ", "))) end

do local placeholder = "_message_" function export.placeholder_error(frame) -- A dummy function that throws an error with a placeholder message. error(placeholder, (frame.args.level or 1) + 6) end -- Throw an error via callParserFunction, which generates a real error with traceback, automatic categorization in CAT:E etc., but the error message is returned as a string. Then, replace the placeholder error message with `message`, which is preprocessed. This is necessary when preprocessing needs to be applied (e.g. when using tags), since otherwise strip markers and other half-processed text gets displayed instead. function export.formatted_error(message, level) local frame = mw.getCurrentFrame return (frame:callParserFunction("#invoke", {"debug", "placeholder_error", level = level})			:gsub(placeholder, frame:preprocess(message))) end end

return export