diff options
Diffstat (limited to 'MCServer/Plugins/APIDump/main.lua')
-rw-r--r-- | MCServer/Plugins/APIDump/main.lua | 231 |
1 files changed, 210 insertions, 21 deletions
diff --git a/MCServer/Plugins/APIDump/main.lua b/MCServer/Plugins/APIDump/main.lua index 73acd3e69..3827668e3 100644 --- a/MCServer/Plugins/APIDump/main.lua +++ b/MCServer/Plugins/APIDump/main.lua @@ -9,6 +9,7 @@ -- Global variables: g_Plugin = nil; +g_PluginFolder = ""; @@ -22,6 +23,8 @@ function Initialize(Plugin) Plugin:SetVersion(1); LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) + + g_PluginFolder = Plugin:GetLocalFolder(); -- dump all available API functions and objects: -- DumpAPITxt(); @@ -36,7 +39,6 @@ end - function DumpAPITxt() LOG("Dumping all available functions to API.txt..."); function dump (prefix, a, Output) @@ -162,6 +164,8 @@ function DumpAPIHtml() LOG("Dumping all available functions and constants to API subfolder..."); local API, Globals = CreateAPITables(); + local Hooks = {}; + local UndocumentedHooks = {}; -- Sort the classes by name: table.sort(API, @@ -174,26 +178,44 @@ function DumpAPIHtml() Globals.Name = "Globals"; table.insert(API, Globals); + -- Extract hook constants: + for name, obj in pairs(cPluginManager) do + if (type(obj) == "number") and (name:match("HOOK_.*")) then + table.insert(Hooks, { Name = name }); + end + end + table.sort(Hooks, + function(Hook1, Hook2) + return (Hook1.Name < Hook2.Name); + end + ); + -- Read in the descriptions: ReadDescriptions(API); + ReadHooks(Hooks); + -- Create the output folder + if not(cFile:IsFolder("API")) then + cFile:CreateFolder("API"); + end + -- Create a "class index" file, write each class as a link to that file, -- then dump class contents into class-specific file local f = io.open("API/index.html", "w"); if (f == nil) then - -- Create the output folder - os.execute("mkdir API"); - local err; - f, err = io.open("API/index.html", "w"); - if (f == nil) then - LOGINFO("Cannot output HTML API: " .. err); - return; - end + LOGINFO("Cannot output HTML API: " .. err); + return; end - f:write([[<html><head><title>MCServer API - class index</title> + f:write([[<html><head><title>MCServer API - index</title> <link rel="stylesheet" type="text/css" href="main.css" /> - </head><body><h1>MCServer API - class index</h1> + </head><body><h1>MCServer API - index</h1> + <p>The API reference is divided into the following sections:<ul> + <li><a href="#classes">Class index</a></li> + <li><a href="#hooks">Hooks</a></li> + <li><a href="#extra">Extra pages</a></li> + </ul></p> + <a name="classes"><h2>Class index</h2></a> <p>The following classes are available in the MCServer Lua scripting language: <ul> ]]); @@ -201,7 +223,48 @@ function DumpAPIHtml() f:write("<li><a href=\"" .. cls.Name .. ".html\">" .. cls.Name .. "</a></li>\n"); WriteHtmlClass(cls, API); end - f:write("</ul></p></body></html>"); + f:write([[</ul></p> + <a name="hooks"><h2>Hooks</h2></a> + <p>A plugin can register to be called whenever an “interesting event” occurs. It does so by calling + <a href="cPluginManager.html">cPluginManager</a>'s AddHook() function and implementing a callback + function to handle the event.</p> + <p>A plugin can decide whether it will let the event pass through to the rest of the plugins, or hide it + from them. This is determined by the return value from the hook callback function. If the function returns + false or no value, the event is propagated further. If the function returns true, the processing is + stopped, no other plugin receives the notification (and possibly MCServer disables the default behavior + for the event). See each hook's details to see the exact behavior.</p> + <table><tr><th>Hook name</th><th>Called when</th></tr> + ]]); + for i, hook in ipairs(Hooks) do + if (hook.DefaultFnName == nil) then + -- The hook is not documented yet + f:write("<tr><td>" .. hook.Name .. "</td><td><i>(No documentation yet)</i></td></tr>\n"); + table.insert(UndocumentedHooks, hook.Name); + else + f:write("<tr><td><a href=\"" .. hook.DefaultFnName .. ".html\">" .. hook.Name .. "</a></td><td>" .. LinkifyString(hook.CalledWhen) .. "</td></tr>\n"); + WriteHtmlHook(hook); + end + end + f:write([[</table> + <a name="extra"><h2>Extra pages</h2></a> + <p>The following pages provide various extra information</p> + <ul>]]); + for i, extra in ipairs(g_APIDesc.ExtraPages) do + local SrcFileName = g_PluginFolder .. "/" .. extra.FileName; + if (cFile:Exists(SrcFileName)) then + local DstFileName = "API/" .. extra.FileName; + if (cFile:Exists(DstFileName)) then + cFile:Delete(DstFileName); + end + cFile:Copy(SrcFileName, DstFileName); + f:write("<li><a href=\"" .. extra.FileName .. "\">" .. extra.Title .. "</a></li>\n"); + else + f:write("<li>" .. extra.Title .. " <i>(file is missing)</i></li>\n"); + end + end + f:write([[</ul> + </body></html> + ]]); f:close(); -- Copy the CSS file to the output folder (overwrite any existing): @@ -253,6 +316,24 @@ function DumpAPIHtml() f:write("\t\t},\n\n"); end end -- for i, cls - API[] + f:write("\t},\n"); + + if (#UndocumentedHooks > 0) then + f:write("\n\tHooks =\n\t{\n"); + for i, hook in ipairs(UndocumentedHooks) do + if (i > 1) then + f:write("\n"); + end + f:write("\t\t" .. hook .. " =\n\t\t{\n"); + f:write("\t\t\tCalledWhen = \"\",\n"); + f:write("\t\t\tDefaultFnName = \"On\", -- also used as pagename\n"); + f:write("\t\t\tDesc = [[]],\n"); + f:write("\t\t\tParams =\n\t\t\t{\n"); + f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n\t\t\t},\n"); + f:write("\t\t\tReturns = [[]],\n"); + f:write("\t\t}, -- " .. hook .. "\n"); + end + end f:close(); end @@ -291,6 +372,19 @@ end function ReadDescriptions(a_API) + -- Returns true if the class of the specified name is to be ignored + local function IsClassIgnored(a_ClsName) + if (g_APIDesc.IgnoreClasses == nil) then + return false; + end + for i, name in ipairs(g_APIDesc.IgnoreClasses) do + if (a_ClsName:match(name)) then + return true; + end + end + return false; + end + -- Returns true if the function (specified by its fully qualified name) is to be ignored local function IsFunctionIgnored(a_FnName) if (g_APIDesc.IgnoreFunctions == nil) then @@ -317,6 +411,18 @@ function ReadDescriptions(a_API) return false; end + -- Remove ignored classes from a_API: + local APICopy = {}; + for i, cls in ipairs(a_API) do + if not(IsClassIgnored(cls.Name)) then + table.insert(APICopy, cls); + end + end + for i = 1, #a_API do + a_API[i] = APICopy[i]; + end; + + -- Process the documentation for each class: for i, cls in ipairs(a_API) do -- Rename special functions: for j, fn in ipairs(cls.Functions) do @@ -335,6 +441,9 @@ function ReadDescriptions(a_API) elseif (fn.Name == ".sub") then fn.DocID = "operator_sub"; fn.Name = "<i>operator -</i>"; + elseif (fn.Name == ".eq") then + fn.DocID = "operator_eq"; + fn.Name = "<i>operator ==</i>"; end end @@ -470,19 +579,46 @@ end +function ReadHooks(a_Hooks) + --[[ + a_Hooks = { + { Name = "HOOK_1"}, + { Name = "HOOK_2"}, + ... + }; + We want to add hook descriptions to each hook in this array + --]] + for i, hook in ipairs(a_Hooks) do + local HookDesc = g_APIDesc.Hooks[hook.Name]; + if (HookDesc ~= nil) then + for key, val in pairs(HookDesc) do + hook[key] = val; + end + end + end -- for i, hook - a_Hooks[] +end + + + + + +-- Make a link out of anything with the special linkifying syntax {{link|title}} +function LinkifyString(a_String) + local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", "<a href=\"%1.html\">%2</a>") -- {{link|title}} + txt = txt:gsub("{{([^|}]*)}}", "<a href=\"%1.html\">%1</a>") -- {{LinkAndTitle}} + return txt; +end + + + + + function WriteHtmlClass(a_ClassAPI, a_AllAPI) local cf, err = io.open("API/" .. a_ClassAPI.Name .. ".html", "w"); if (cf == nil) then return; end - -- Make a link out of anything with the special linkifying syntax {{link|title}} - local function LinkifyString(a_String) - local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", "<a href=\"%1.html\">%2</a>") -- {{link|title}} - txt = txt:gsub("{{([^|}]*)}}", "<a href=\"%1.html\">%1</a>") -- {{LinkAndTitle}} - return txt; - end - -- Writes a table containing all functions in the specified list, with an optional "inherited from" header when a_InheritedName is valid local function WriteFunctions(a_Functions, a_InheritedName) if (#a_Functions == 0) then @@ -523,8 +659,10 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI) CurrInheritance = CurrInheritance.Inherits; end - cf:write([[<html><head><title>MCServer API - ]] .. a_ClassAPI.Name .. [[</title> + cf:write([[<html><head><title>MCServer API - ]] .. a_ClassAPI.Name .. [[ class</title> <link rel="stylesheet" type="text/css" href="main.css" /> + <script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script> + <script src="http://google-code-prettify.googlecode.com/svn/trunk/src/lang-lua.js"></script> </head><body> <h1>Contents</h1> <ul> @@ -591,7 +729,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI) if (a_ClassAPI.AdditionalInfo ~= nil) then for i, additional in ipairs(a_ClassAPI.AdditionalInfo) do cf:write("<a name=\"additionalinfo_" .. i .. "\"><h1>" .. additional.Header .. "</h1></a>\n"); - cf:write(additional.Contents); + cf:write(LinkifyString(additional.Contents)); end end @@ -603,3 +741,54 @@ end +function WriteHtmlHook(a_Hook) + local fnam = "API/" .. a_Hook.DefaultFnName .. ".html"; + local f, error = io.open(fnam, "w"); + if (f == nil) then + LOG("Cannot write \"" .. fnam .. "\": \"" .. error .. "\"."); + return; + end + f:write([[<html><head><title>MCServer API - ]] .. a_Hook.DefaultFnName .. [[ hook</title> + <link rel="stylesheet" type="text/css" href="main.css" /> + <script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script> + <script src="http://google-code-prettify.googlecode.com/svn/trunk/src/lang-lua.js"></script> + </head><body> + <h1>]] .. a_Hook.Name .. [[ hook</h1> + <p> + ]]); + f:write(LinkifyString(a_Hook.Desc)); + f:write("</p><h1>Callback function</h1><p>The default name for the callback function is "); + f:write(a_Hook.DefaultFnName .. ". It has the following signature:"); + f:write("<pre class=\"prettyprint lang-lua\">function " .. a_Hook.DefaultFnName .. "("); + if (a_Hook.Params == nil) then + a_Hook.Params = {}; + end + for i, param in ipairs(a_Hook.Params) do + if (i > 1) then + f:write(", "); + end + f:write(param.Name); + end + f:write(")</pre><p>Parameters:\n<table><tr><th>Name</th><th>Type</th><th>Notes</th></tr>\n"); + for i, param in ipairs(a_Hook.Params) do + f:write("<tr><td>" .. param.Name .. "</td><td>" .. LinkifyString(param.Type) .. "</td><td>" .. LinkifyString(param.Notes) .. "</td></tr>\n"); + end + f:write("</table></p>\n<p>" .. (a_Hook.Returns or "") .. "</p>\n"); + f:write([[<h1>Code examples</h1> + <h2>Registering the callback</h2> +<pre class=\"prettyprint lang-lua\"> +cPluginManager.AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[); +</pre> + ]]); + local Examples = a_Hook.CodeExamples or {}; + for i, example in ipairs(Examples) do + f:write("<h2>" .. example.Title .. "</h2>\n"); + f:write("<p>" .. example.Desc .. "</p>\n"); + f:write("<pre class=\"prettyprint lang-lua\">" .. example.Code .. "</pre>\n"); + end + f:close(); +end + + + + |