From dac97826f7d0c9b9135c1a08c4d5f16b61494bd1 Mon Sep 17 00:00:00 2001
From: Mattes D
Date: Wed, 26 Aug 2015 10:58:51 +0200
Subject: Renamed output directory to Server
---
MCServer/Plugins/APIDump/main_APIDump.lua | 1685 -----------------------------
1 file changed, 1685 deletions(-)
delete mode 100644 MCServer/Plugins/APIDump/main_APIDump.lua
(limited to 'MCServer/Plugins/APIDump/main_APIDump.lua')
diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua
deleted file mode 100644
index 4892d477d..000000000
--- a/MCServer/Plugins/APIDump/main_APIDump.lua
+++ /dev/null
@@ -1,1685 +0,0 @@
--- main.lua
-
--- Implements the plugin entrypoint (in this case the entire plugin)
-
-
-
-
-
--- Global variables:
-local g_Plugin = nil
-local g_PluginFolder = ""
-local g_Stats = {}
-local g_TrackedPages = {}
-
-
-
-
-
-
-local function LoadAPIFiles(a_Folder, a_DstTable)
- assert(type(a_Folder) == "string")
- assert(type(a_DstTable) == "table")
-
- local Folder = g_PluginFolder .. a_Folder;
- for _, fnam in ipairs(cFile:GetFolderContents(Folder)) do
- local FileName = Folder .. fnam;
- -- We only want .lua files from the folder:
- if (cFile:IsFile(FileName) and fnam:match(".*%.lua$")) then
- local TablesFn, Err = loadfile(FileName);
- if (type(TablesFn) ~= "function") then
- LOGWARNING("Cannot load API descriptions from " .. FileName .. ", Lua error '" .. Err .. "'.");
- else
- local Tables = TablesFn();
- if (type(Tables) ~= "table") then
- LOGWARNING("Cannot load API descriptions from " .. FileName .. ", returned object is not a table (" .. type(Tables) .. ").");
- break
- end
- for k, cls in pairs(Tables) do
- a_DstTable[k] = cls;
- end
- end -- if (TablesFn)
- end -- if (is lua file)
- end -- for fnam - Folder[]
-end
-
-
-
-
-
-local function CreateAPITables()
- --[[
- We want an API table of the following shape:
- local API = {
- {
- Name = "cCuboid",
- Functions = {
- {Name = "Sort"},
- {Name = "IsInside"}
- },
- Constants = {
- },
- Variables = {
- },
- Descendants = {}, -- Will be filled by ReadDescriptions(), array of class APIs (references to other member in the tree)
- },
- {
- Name = "cBlockArea",
- Functions = {
- {Name = "Clear"},
- {Name = "CopyFrom"},
- ...
- },
- Constants = {
- {Name = "baTypes", Value = 0},
- {Name = "baMetas", Value = 1},
- ...
- },
- Variables = {
- },
- ...
- },
-
- cCuboid = {} -- Each array item also has the map item by its name
- };
- local Globals = {
- Functions = {
- ...
- },
- Constants = {
- ...
- }
- };
- --]]
-
- local Globals = {Functions = {}, Constants = {}, Variables = {}, Descendants = {}};
- local API = {};
-
- local function Add(a_APIContainer, a_ObjName, a_ObjValue)
- if (type(a_ObjValue) == "function") then
- table.insert(a_APIContainer.Functions, {Name = a_ObjName});
- elseif (
- (type(a_ObjValue) == "number") or
- (type(a_ObjValue) == "string")
- ) then
- table.insert(a_APIContainer.Constants, {Name = a_ObjName, Value = a_ObjValue});
- end
- end
-
- local function ParseClass(a_ClassName, a_ClassObj)
- local res = {Name = a_ClassName, Functions = {}, Constants = {}, Variables = {}, Descendants = {}};
- -- Add functions and constants:
- for i, v in pairs(a_ClassObj) do
- Add(res, i, v);
- end
-
- -- Member variables:
- local SetField = a_ClassObj[".set"] or {};
- if ((a_ClassObj[".get"] ~= nil) and (type(a_ClassObj[".get"]) == "table")) then
- for k in pairs(a_ClassObj[".get"]) do
- if (SetField[k] == nil) then
- -- It is a read-only variable, add it as a constant:
- table.insert(res.Constants, {Name = k, Value = ""});
- else
- -- It is a read-write variable, add it as a variable:
- table.insert(res.Variables, { Name = k });
- end
- end
- end
- return res;
- end
-
- for i, v in pairs(_G) do
- if (
- (v ~= _G) and -- don't want the global namespace
- (v ~= _G.packages) and -- don't want any packages
- (v ~= _G[".get"]) and
- (v ~= g_APIDesc)
- ) then
- if (type(v) == "table") then
- local cls = ParseClass(i, v)
- table.insert(API, cls);
- API[cls.Name] = cls
- else
- Add(Globals, i, v);
- end
- end
- end
-
- return API, Globals;
-end
-
-
-
-
-
---- Returns the timestamp in HTML format
--- The timestamp will be inserted to all generated HTML files
-local function GetHtmlTimestamp()
- return string.format("
The following articles provide various extra information on plugin development
-
- ]]);
- for _, 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("
");
-end
-
-
-
-
-
--- Make a link out of anything with the special linkifying syntax {{link|title}}
-local function LinkifyString(a_String, a_Referrer)
- assert(a_Referrer ~= nil);
- assert(a_Referrer ~= "");
-
- --- Adds a page to the list of tracked pages (to be checked for existence at the end)
- local function AddTrackedPage(a_PageName)
- local Pg = (g_TrackedPages[a_PageName] or {});
- table.insert(Pg, a_Referrer);
- g_TrackedPages[a_PageName] = Pg;
- end
-
- --- Creates the HTML for the specified link and title
- local function CreateLink(Link, Title)
- if (Link:sub(1, 7) == "http://") then
- -- The link is a full absolute URL, do not modify, do not track:
- return "" .. Title .. "";
- end
- local idxHash = Link:find("#");
- if (idxHash ~= nil) then
- -- The link contains an anchor:
- if (idxHash == 1) then
- -- Anchor in the current page, no need to track:
- return "" .. Title .. "";
- end
- -- Anchor in another page:
- local PageName = Link:sub(1, idxHash - 1);
- AddTrackedPage(PageName);
- return "" .. Title .. "";
- end
- -- Link without anchor:
- AddTrackedPage(Link);
- return "" .. Title .. "";
- end
-
- -- Linkify the strings using the CreateLink() function:
- local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", CreateLink) -- {{link|title}}
- txt = txt:gsub("{{([^|}]*)}}", -- {{LinkAndTitle}}
- function(LinkAndTitle)
- local idxHash = LinkAndTitle:find("#");
- if (idxHash ~= nil) then
- -- The LinkAndTitle contains a hash, remove the hashed part from the title:
- return CreateLink(LinkAndTitle, LinkAndTitle:sub(1, idxHash - 1));
- end
- return CreateLink(LinkAndTitle, LinkAndTitle);
- end
- );
- return txt;
-end
-
-
-
-
-
-local function WriteHtmlHook(a_Hook, a_HookNav)
- 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
- local HookName = a_Hook.DefaultFnName;
-
- f:write([[
-
- Cuberite API - ]], HookName, [[ Hook
-
-
-
-
-
-
-
The default name for the callback function is ");
- f:write(a_Hook.DefaultFnName, ". It has the following signature:\n");
- f:write("
function ", HookName, "(");
- 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(")
\n
Parameters:
\n
Name
Type
Notes
\n");
- for _, param in ipairs(a_Hook.Params) do
- f:write("
", param.Name, "
", LinkifyString(param.Type, HookName), "
", LinkifyString(param.Notes, HookName), "
\n");
- end
- f:write("
\n
" .. LinkifyString(a_Hook.Returns or "", HookName) .. "
- A plugin can register to be called whenever an "interesting event" occurs. It does so by calling
- cPluginManager's AddHook() function and implementing a callback
- function to handle the event.
-
- 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 Cuberite disables the default
- behavior for the event). See each hook's details to see the exact behavior.
-
-
-
Hook name
-
Called when
-
- ]]);
- for _, hook in ipairs(a_Hooks) do
- if (hook.DefaultFnName == nil) then
- -- The hook is not documented yet
- f:write("
\n");
- WriteHtmlHook(hook, a_HookNav);
- end
- end
- f:write([[
-
-
- ]]);
-end
-
-
-
-
-
-local 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 _, 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 is to be ignored
- local function IsFunctionIgnored(a_ClassName, a_FnName)
- if (g_APIDesc.IgnoreFunctions == nil) then
- return false;
- end
- if (((g_APIDesc.Classes[a_ClassName] or {}).Functions or {})[a_FnName] ~= nil) then
- -- The function is documented, don't ignore
- return false;
- end
- local FnName = a_ClassName .. "." .. a_FnName;
- for _, name in ipairs(g_APIDesc.IgnoreFunctions) do
- if (FnName:match(name)) then
- return true;
- end
- end
- return false;
- end
-
- -- Returns true if the constant (specified by its fully qualified name) is to be ignored
- local function IsConstantIgnored(a_CnName)
- if (g_APIDesc.IgnoreConstants == nil) then
- return false;
- end;
- for _, name in ipairs(g_APIDesc.IgnoreConstants) do
- if (a_CnName:match(name)) then
- return true;
- end
- end
- return false;
- end
-
- -- Returns true if the member variable (specified by its fully qualified name) is to be ignored
- local function IsVariableIgnored(a_VarName)
- if (g_APIDesc.IgnoreVariables == nil) then
- return false;
- end;
- for _, name in ipairs(g_APIDesc.IgnoreVariables) do
- if (a_VarName:match(name)) then
- return true;
- end
- end
- return false;
- end
-
- -- Remove ignored classes from a_API:
- local APICopy = {};
- for _, 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 _, cls in ipairs(a_API) do
- -- Initialize default values for each class:
- cls.ConstantGroups = {};
- cls.NumConstantsInGroups = 0;
- cls.NumConstantsInGroupsForDescendants = 0;
-
- -- Rename special functions:
- for _, fn in ipairs(cls.Functions) do
- if (fn.Name == ".call") then
- fn.DocID = "constructor";
- fn.Name = "() (constructor)";
- elseif (fn.Name == ".add") then
- fn.DocID = "operator_plus";
- fn.Name = "operator +";
- elseif (fn.Name == ".div") then
- fn.DocID = "operator_div";
- fn.Name = "operator /";
- elseif (fn.Name == ".mul") then
- fn.DocID = "operator_mul";
- fn.Name = "operator *";
- elseif (fn.Name == ".sub") then
- fn.DocID = "operator_sub";
- fn.Name = "operator -";
- elseif (fn.Name == ".eq") then
- fn.DocID = "operator_eq";
- fn.Name = "operator ==";
- end
- end
-
- local APIDesc = g_APIDesc.Classes[cls.Name];
- if (APIDesc ~= nil) then
- APIDesc.IsExported = true;
- cls.Desc = APIDesc.Desc;
- cls.AdditionalInfo = APIDesc.AdditionalInfo;
-
- -- Process inheritance:
- if (APIDesc.Inherits ~= nil) then
- for _, icls in ipairs(a_API) do
- if (icls.Name == APIDesc.Inherits) then
- table.insert(icls.Descendants, cls);
- cls.Inherits = icls;
- end
- end
- end
-
- cls.UndocumentedFunctions = {}; -- This will contain names of all the functions that are not documented
- cls.UndocumentedConstants = {}; -- This will contain names of all the constants that are not documented
- cls.UndocumentedVariables = {}; -- This will contain names of all the variables that are not documented
-
- local DoxyFunctions = {}; -- This will contain all the API functions together with their documentation
-
- local function AddFunction(a_Name, a_Params, a_Return, a_Notes)
- table.insert(DoxyFunctions, {Name = a_Name, Params = a_Params, Return = a_Return, Notes = a_Notes});
- end
-
- if (APIDesc.Functions ~= nil) then
- -- Assign function descriptions:
- for _, func in ipairs(cls.Functions) do
- local FnName = func.DocID or func.Name;
- local FnDesc = APIDesc.Functions[FnName];
- if (FnDesc == nil) then
- -- No description for this API function
- AddFunction(func.Name);
- if not(IsFunctionIgnored(cls.Name, FnName)) then
- table.insert(cls.UndocumentedFunctions, FnName);
- end
- else
- -- Description is available
- if (FnDesc[1] == nil) then
- -- Single function definition
- AddFunction(func.Name, FnDesc.Params, FnDesc.Return, FnDesc.Notes);
- else
- -- Multiple function overloads
- for _, desc in ipairs(FnDesc) do
- AddFunction(func.Name, desc.Params, desc.Return, desc.Notes);
- end -- for k, desc - FnDesc[]
- end
- FnDesc.IsExported = true;
- end
- end -- for j, func
-
- -- Replace functions with their described and overload-expanded versions:
- cls.Functions = DoxyFunctions;
- else -- if (APIDesc.Functions ~= nil)
- for _, func in ipairs(cls.Functions) do
- local FnName = func.DocID or func.Name;
- if not(IsFunctionIgnored(cls.Name, FnName)) then
- table.insert(cls.UndocumentedFunctions, FnName);
- end
- end
- end -- if (APIDesc.Functions ~= nil)
-
- if (APIDesc.Constants ~= nil) then
- -- Assign constant descriptions:
- for _, cons in ipairs(cls.Constants) do
- local CnDesc = APIDesc.Constants[cons.Name];
- if (CnDesc == nil) then
- -- Not documented
- if not(IsConstantIgnored(cls.Name .. "." .. cons.Name)) then
- table.insert(cls.UndocumentedConstants, cons.Name);
- end
- else
- cons.Notes = CnDesc.Notes;
- CnDesc.IsExported = true;
- end
- end -- for j, cons
- else -- if (APIDesc.Constants ~= nil)
- for _, cons in ipairs(cls.Constants) do
- if not(IsConstantIgnored(cls.Name .. "." .. cons.Name)) then
- table.insert(cls.UndocumentedConstants, cons.Name);
- end
- end
- end -- else if (APIDesc.Constants ~= nil)
-
- -- Assign member variables' descriptions:
- if (APIDesc.Variables ~= nil) then
- for _, var in ipairs(cls.Variables) do
- local VarDesc = APIDesc.Variables[var.Name];
- if (VarDesc == nil) then
- -- Not documented
- if not(IsVariableIgnored(cls.Name .. "." .. var.Name)) then
- table.insert(cls.UndocumentedVariables, var.Name);
- end
- else
- -- Copy all documentation:
- for k, v in pairs(VarDesc) do
- var[k] = v
- end
- end
- end -- for j, var
- else -- if (APIDesc.Variables ~= nil)
- for _, var in ipairs(cls.Variables) do
- if not(IsVariableIgnored(cls.Name .. "." .. var.Name)) then
- table.insert(cls.UndocumentedVariables, var.Name);
- end
- end
- end -- else if (APIDesc.Variables ~= nil)
-
- if (APIDesc.ConstantGroups ~= nil) then
- -- Create links between the constants and the groups:
- local NumInGroups = 0;
- local NumInDescendantGroups = 0;
- for j, group in pairs(APIDesc.ConstantGroups) do
- group.Name = j;
- group.Constants = {};
- if (type(group.Include) == "string") then
- group.Include = { group.Include };
- end
- local NumInGroup = 0;
- for _, incl in ipairs(group.Include or {}) do
- for _, cons in ipairs(cls.Constants) do
- if ((cons.Group == nil) and cons.Name:match(incl)) then
- cons.Group = group;
- table.insert(group.Constants, cons);
- NumInGroup = NumInGroup + 1;
- end
- end -- for cidx - cls.Constants[]
- end -- for idx - group.Include[]
- NumInGroups = NumInGroups + NumInGroup;
- if (group.ShowInDescendants) then
- NumInDescendantGroups = NumInDescendantGroups + NumInGroup;
- end
-
- -- Sort the constants:
- table.sort(group.Constants,
- function(c1, c2)
- return (c1.Name < c2.Name);
- end
- );
- end -- for j - APIDesc.ConstantGroups[]
- cls.ConstantGroups = APIDesc.ConstantGroups;
- cls.NumConstantsInGroups = NumInGroups;
- cls.NumConstantsInGroupsForDescendants = NumInDescendantGroups;
-
- -- Remove grouped constants from the normal list:
- local NewConstants = {};
- for _, cons in ipairs(cls.Constants) do
- if (cons.Group == nil) then
- table.insert(NewConstants, cons);
- end
- end
- cls.Constants = NewConstants;
- end -- if (ConstantGroups ~= nil)
-
- else -- if (APIDesc ~= nil)
-
- -- Class is not documented at all, add all its members to Undocumented lists:
- cls.UndocumentedFunctions = {};
- cls.UndocumentedConstants = {};
- cls.UndocumentedVariables = {};
- cls.Variables = cls.Variables or {};
- g_Stats.NumUndocumentedClasses = g_Stats.NumUndocumentedClasses + 1;
- for _, func in ipairs(cls.Functions) do
- local FnName = func.DocID or func.Name;
- if not(IsFunctionIgnored(cls.Name, FnName)) then
- table.insert(cls.UndocumentedFunctions, FnName);
- end
- end -- for j, func - cls.Functions[]
- for _, cons in ipairs(cls.Constants) do
- if not(IsConstantIgnored(cls.Name .. "." .. cons.Name)) then
- table.insert(cls.UndocumentedConstants, cons.Name);
- end
- end -- for j, cons - cls.Constants[]
- for _, var in ipairs(cls.Variables) do
- if not(IsConstantIgnored(cls.Name .. "." .. var.Name)) then
- table.insert(cls.UndocumentedVariables, var.Name);
- end
- end -- for j, var - cls.Variables[]
- end -- else if (APIDesc ~= nil)
-
- -- Remove ignored functions:
- local NewFunctions = {};
- for _, fn in ipairs(cls.Functions) do
- if (not(IsFunctionIgnored(cls.Name, fn.Name))) then
- table.insert(NewFunctions, fn);
- end
- end -- for j, fn
- cls.Functions = NewFunctions;
-
- -- Sort the functions (they may have been renamed):
- table.sort(cls.Functions,
- function(f1, f2)
- if (f1.Name == f2.Name) then
- -- Same name, either comparing the same function to itself, or two overloads, in which case compare the params
- if ((f1.Params == nil) or (f2.Params == nil)) then
- return 0;
- end
- return (f1.Params < f2.Params);
- end
- return (f1.Name < f2.Name);
- end
- );
-
- -- Remove ignored constants:
- local NewConstants = {};
- for _, cn in ipairs(cls.Constants) do
- if (not(IsFunctionIgnored(cls.Name, cn.Name))) then
- table.insert(NewConstants, cn);
- end
- end -- for j, cn
- cls.Constants = NewConstants;
-
- -- Sort the constants:
- table.sort(cls.Constants,
- function(c1, c2)
- return (c1.Name < c2.Name);
- end
- );
-
- -- Remove ignored member variables:
- local NewVariables = {};
- for _, var in ipairs(cls.Variables) do
- if (not(IsVariableIgnored(cls.Name .. "." .. var.Name))) then
- table.insert(NewVariables, var);
- end
- end -- for j, var
- cls.Variables = NewVariables;
-
- -- Sort the member variables:
- table.sort(cls.Variables,
- function(v1, v2)
- return (v1.Name < v2.Name);
- end
- );
- end -- for i, cls
-
- -- Sort the descendants lists:
- for _, cls in ipairs(a_API) do
- table.sort(cls.Descendants,
- function(c1, c2)
- return (c1.Name < c2.Name);
- end
- );
- end -- for i, cls
-end
-
-
-
-
-
-local 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 _, 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[]
- g_Stats.NumTotalHooks = #a_Hooks;
-end
-
-
-
-
-
-local function WriteHtmlClass(a_ClassAPI, a_ClassMenu)
- local cf, err = io.open("API/" .. a_ClassAPI.Name .. ".html", "w");
- if (cf == nil) then
- LOGINFO("Cannot write HTML API for class " .. a_ClassAPI.Name .. ": " .. err)
- return;
- 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
- return;
- end
-
- if (a_InheritedName ~= nil) then
- cf:write("
Functions inherited from ", a_InheritedName, "
\n");
- end
- cf:write("
\n
Name
Parameters
Return value
Notes
\n");
- for _, func in ipairs(a_Functions) do
- cf:write("
", func.Name, "
\n");
- cf:write("
", LinkifyString(func.Params or "", (a_InheritedName or a_ClassAPI.Name)), "
\n");
- cf:write("
", LinkifyString(func.Return or "", (a_InheritedName or a_ClassAPI.Name)), "
\n");
- cf:write("
", LinkifyString(func.Notes or "(undocumented)", (a_InheritedName or a_ClassAPI.Name)), "
\n");
- end
- cf:write("
\n");
- end
-
- local function WriteConstantTable(a_Constants, a_Source)
- cf:write("
\n
Name
Value
Notes
\n");
- for _, cons in ipairs(a_Constants) do
- cf:write("
", cons.Name, "
\n");
- cf:write("
", cons.Value, "
\n");
- cf:write("
", LinkifyString(cons.Notes or "", a_Source), "
\n");
- end
- cf:write("
\n\n");
- end
-
- local function WriteConstants(a_Constants, a_ConstantGroups, a_NumConstantGroups, a_InheritedName)
- if ((#a_Constants == 0) and (a_NumConstantGroups == 0)) then
- return;
- end
-
- local Source = a_ClassAPI.Name
- if (a_InheritedName ~= nil) then
- cf:write("
Constants inherited from ", a_InheritedName, "
\n");
- Source = a_InheritedName;
- end
-
- if (#a_Constants > 0) then
- WriteConstantTable(a_Constants, Source);
- end
-
- for _, group in pairs(a_ConstantGroups) do
- if ((a_InheritedName == nil) or group.ShowInDescendants) then
- cf:write("
");
- end
- end
- end
-
- local function WriteVariables(a_Variables, a_InheritedName)
- if (#a_Variables == 0) then
- return;
- end
-
- if (a_InheritedName ~= nil) then
- cf:write("
Member variables inherited from ", a_InheritedName, "
\n");
- end
-
- cf:write("
Name
Type
Notes
\n");
- for _, var in ipairs(a_Variables) do
- cf:write("
", var.Name, "
\n");
- cf:write("
", LinkifyString(var.Type or "(undocumented)", a_InheritedName or a_ClassAPI.Name), "
\n");
- cf:write("
", LinkifyString(var.Notes or "", a_InheritedName or a_ClassAPI.Name), "
\n
\n");
- end
- cf:write("
\n\n");
- end
-
- local function WriteDescendants(a_Descendants)
- if (#a_Descendants == 0) then
- return;
- end
- cf:write("
");
- for _, desc in ipairs(a_Descendants) do
- cf:write("
\n");
- WriteVariables(a_ClassAPI.Variables, nil);
- g_Stats.NumTotalVariables = g_Stats.NumTotalVariables + #a_ClassAPI.Variables;
- for _, cls in ipairs(InheritanceChain) do
- WriteVariables(cls.Variables, cls.Name);
- end;
- end
-
- -- Write the functions, including the inherited ones:
- if (HasFunctions) then
- cf:write("
\n");
- WriteFunctions(a_ClassAPI.Functions, nil);
- g_Stats.NumTotalFunctions = g_Stats.NumTotalFunctions + #a_ClassAPI.Functions;
- for _, cls in ipairs(InheritanceChain) do
- WriteFunctions(cls.Functions, cls.Name);
- end
- end
-
- -- Write the additional infos:
- if (a_ClassAPI.AdditionalInfo ~= nil) then
- for i, additional in ipairs(a_ClassAPI.AdditionalInfo) do
- cf:write("
\n");
- WriteHtmlClass(cls, a_ClassMenu);
- end
- f:write([[
-
-
- ]]);
-end
-
-
-
-
-
---- Writes a list of undocumented objects into a file
-local function ListUndocumentedObjects(API, UndocumentedHooks)
- local f = io.open("API/_undocumented.lua", "w");
- if (f ~= nil) then
- f:write("\n-- This is the list of undocumented API objects, automatically generated by APIDump\n\n");
- f:write("g_APIDesc =\n{\n\tClasses =\n\t{\n");
- for _, cls in ipairs(API) do
- local HasFunctions = ((cls.UndocumentedFunctions ~= nil) and (#cls.UndocumentedFunctions > 0));
- local HasConstants = ((cls.UndocumentedConstants ~= nil) and (#cls.UndocumentedConstants > 0));
- local HasVariables = ((cls.UndocumentedVariables ~= nil) and (#cls.UndocumentedVariables > 0));
- g_Stats.NumUndocumentedFunctions = g_Stats.NumUndocumentedFunctions + #cls.UndocumentedFunctions;
- g_Stats.NumUndocumentedConstants = g_Stats.NumUndocumentedConstants + #cls.UndocumentedConstants;
- g_Stats.NumUndocumentedVariables = g_Stats.NumUndocumentedVariables + #cls.UndocumentedVariables;
- if (HasFunctions or HasConstants or HasVariables) then
- f:write("\t\t" .. cls.Name .. " =\n\t\t{\n");
- if ((cls.Desc == nil) or (cls.Desc == "")) then
- f:write("\t\t\tDesc = \"\"\n");
- end
- end
-
- if (HasFunctions) then
- f:write("\t\t\tFunctions =\n\t\t\t{\n");
- table.sort(cls.UndocumentedFunctions);
- for _, fn in ipairs(cls.UndocumentedFunctions) do
- f:write("\t\t\t\t" .. fn .. " = { Params = \"\", Return = \"\", Notes = \"\" },\n");
- end -- for j, fn - cls.UndocumentedFunctions[]
- f:write("\t\t\t},\n\n");
- end
-
- if (HasConstants) then
- f:write("\t\t\tConstants =\n\t\t\t{\n");
- table.sort(cls.UndocumentedConstants);
- for _, cn in ipairs(cls.UndocumentedConstants) do
- f:write("\t\t\t\t" .. cn .. " = { Notes = \"\" },\n");
- end -- for j, fn - cls.UndocumentedConstants[]
- f:write("\t\t\t},\n\n");
- end
-
- if (HasVariables) then
- f:write("\t\t\tVariables =\n\t\t\t{\n");
- table.sort(cls.UndocumentedVariables);
- for _, vn in ipairs(cls.UndocumentedVariables) do
- f:write("\t\t\t\t" .. vn .. " = { Type = \"\", Notes = \"\" },\n");
- end -- for j, fn - cls.UndocumentedVariables[]
- f:write("\t\t\t},\n\n");
- end
-
- if (HasFunctions or HasConstants or HasVariables) then
- 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\t\t\t\t\n\t\t\t]],\n");
- f:write("\t\t\tParams =\n\t\t\t{\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n");
- f:write("\t\t\t},\n");
- f:write("\t\t\tReturns = [[\n\t\t\t\t\n\t\t\t]],\n");
- f:write("\t\t}, -- " .. hook .. "\n");
- end
- f:write("\t},\n");
- end
- f:write("}\n\n\n\n");
- f:close();
- end
- g_Stats.NumUndocumentedHooks = #UndocumentedHooks;
-end
-
-
-
-
-
---- Lists the API objects that are documented but not available in the API:
-local function ListUnexportedObjects()
- f = io.open("API/_unexported-documented.txt", "w");
- if (f ~= nil) then
- for clsname, cls in pairs(g_APIDesc.Classes) do
- if not(cls.IsExported) then
- -- The whole class is not exported
- f:write("class\t" .. clsname .. "\n");
- else
- if (cls.Functions ~= nil) then
- for fnname, fnapi in pairs(cls.Functions) do
- if not(fnapi.IsExported) then
- f:write("func\t" .. clsname .. "." .. fnname .. "\n");
- end
- end -- for j, fn - cls.Functions[]
- end
- if (cls.Constants ~= nil) then
- for cnname, cnapi in pairs(cls.Constants) do
- if not(cnapi.IsExported) then
- f:write("const\t" .. clsname .. "." .. cnname .. "\n");
- end
- end -- for j, fn - cls.Functions[]
- end
- end
- end -- for i, cls - g_APIDesc.Classes[]
- f:close();
- end
-end
-
-
-
-
-
-local function ListMissingPages()
- local MissingPages = {};
- local NumLinks = 0;
- for PageName, Referrers in pairs(g_TrackedPages) do
- NumLinks = NumLinks + 1;
- if not(cFile:Exists("API/" .. PageName .. ".html")) then
- table.insert(MissingPages, {Name = PageName, Refs = Referrers} );
- end
- end;
- g_Stats.NumTrackedLinks = NumLinks;
- g_TrackedPages = {};
-
- if (#MissingPages == 0) then
- -- No missing pages, congratulations!
- return;
- end
-
- -- Sort the pages by name:
- table.sort(MissingPages,
- function (Page1, Page2)
- return (Page1.Name < Page2.Name);
- end
- );
-
- -- Output the pages:
- local f, err = io.open("API/_missingPages.txt", "w");
- if (f == nil) then
- LOGWARNING("Cannot open _missingPages.txt for writing: '" .. err .. "'. There are " .. #MissingPages .. " pages missing.");
- return;
- end
- for _, pg in ipairs(MissingPages) do
- f:write(pg.Name .. ":\n");
- -- Sort and output the referrers:
- table.sort(pg.Refs);
- f:write("\t" .. table.concat(pg.Refs, "\n\t"));
- f:write("\n\n");
- end
- f:close();
- g_Stats.NumInvalidLinks = #MissingPages;
-end
-
-
-
-
-
---- Writes the documentation statistics (in g_Stats) into the given HTML file
-local function WriteStats(f)
- local function ExportMeter(a_Percent)
- local Color;
- if (a_Percent > 99) then
- Color = "green";
- elseif (a_Percent > 50) then
- Color = "orange";
- else
- Color = "red";
- end
-
- local meter = {
- "\n",
- "
There are ]], g_Stats.NumTrackedLinks, " internal links, ", g_Stats.NumInvalidLinks, " of them are invalid.
"
- );
-end
-
-
-
-
-
-local function DumpAPIHtml(a_API)
- LOG("Dumping all available functions and constants to API subfolder...");
-
- -- Create the output folder
- if not(cFile:IsFolder("API")) then
- cFile:CreateFolder("API");
- end
-
- LOG("Copying static files..");
- cFile:CreateFolder("API/Static");
- local localFolder = g_Plugin:GetLocalFolder();
- for _, fnam in ipairs(cFile:GetFolderContents(localFolder .. "/Static")) do
- cFile:Delete("API/Static/" .. fnam);
- cFile:Copy(localFolder .. "/Static/" .. fnam, "API/Static/" .. fnam);
- end
-
- -- Extract hook constants:
- local Hooks = {};
- local UndocumentedHooks = {};
- for name, obj in pairs(cPluginManager) do
- if (
- (type(obj) == "number") and
- name:match("HOOK_.*") and
- (name ~= "HOOK_MAX") and
- (name ~= "HOOK_NUM_HOOKS")
- ) then
- table.insert(Hooks, { Name = name });
- end
- end
- table.sort(Hooks,
- function(Hook1, Hook2)
- return (Hook1.Name < Hook2.Name);
- end
- );
- ReadHooks(Hooks);
-
- -- Create a "class index" file, write each class as a link to that file,
- -- then dump class contents into class-specific file
- LOG("Writing HTML files...");
- local f, err = io.open("API/index.html", "w");
- if (f == nil) then
- LOGINFO("Cannot output HTML API: " .. err);
- return;
- end
-
- -- Create a class navigation menu that will be inserted into each class file for faster navigation (#403)
- local ClassMenuTab = {};
- for _, cls in ipairs(a_API) do
- table.insert(ClassMenuTab, "");
- table.insert(ClassMenuTab, cls.Name);
- table.insert(ClassMenuTab, " ");
- end
- local ClassMenu = table.concat(ClassMenuTab, "");
-
- -- Create a hook navigation menu that will be inserted into each hook file for faster navigation(#403)
- local HookNavTab = {};
- for _, hook in ipairs(Hooks) do
- table.insert(HookNavTab, "");
- table.insert(HookNavTab, (hook.Name:gsub("^HOOK_", ""))); -- remove the "HOOK_" part of the name
- table.insert(HookNavTab, " ");
- end
- local HookNav = table.concat(HookNavTab, "");
-
- -- Write the HTML file:
- f:write([[
-
-
- Cuberite API - Index
-
-
-
-
-
-
Cuberite API - Index
-
-
-
The API reference is divided into the following sections:
-
- ]]);
-
- WriteArticles(f);
- WriteClasses(f, a_API, ClassMenu);
- WriteHooks(f, Hooks, UndocumentedHooks, HookNav);
-
- -- Copy the static files to the output folder:
- local StaticFiles =
- {
- "main.css",
- "prettify.js",
- "prettify.css",
- "lang-lua.js",
- };
- for _, fnam in ipairs(StaticFiles) do
- cFile:Delete("API/" .. fnam);
- cFile:Copy(g_Plugin:GetLocalFolder() .. "/" .. fnam, "API/" .. fnam);
- end
-
- -- List the documentation problems:
- LOG("Listing leftovers...");
- ListUndocumentedObjects(a_API, UndocumentedHooks);
- ListUnexportedObjects();
- ListMissingPages();
-
- WriteStats(f);
-
- f:write([[
]])
- f:write(GetHtmlTimestamp())
- f:write([[]])
- f:close()
-
- LOG("API subfolder written");
-end
-
-
-
-
-
---- Returns the string with extra tabs and CR/LFs removed
-local function CleanUpDescription(a_Desc)
- -- Get rid of indent and newlines, normalize whitespace:
- local res = a_Desc:gsub("[\n\t]", "")
- res = a_Desc:gsub("%s%s+", " ")
-
- -- Replace paragraph marks with newlines:
- res = res:gsub("
", "\n")
- res = res:gsub("
", "")
-
- -- Replace list items with dashes:
- res = res:gsub("?ul>", "")
- res = res:gsub("
", "\n - ")
- res = res:gsub("
", "")
-
- return res
-end
-
-
-
-
-
---- Writes a list of methods into the specified file in ZBS format
-local function WriteZBSMethods(f, a_Methods)
- for _, func in ipairs(a_Methods or {}) do
- f:write("\t\t\t[\"", func.Name, "\"] =\n")
- f:write("\t\t\t{\n")
- f:write("\t\t\t\ttype = \"method\",\n")
- if ((func.Notes ~= nil) and (func.Notes ~= "")) then
- f:write("\t\t\t\tdescription = [[", CleanUpDescription(func.Notes or ""), " ]],\n")
- end
- f:write("\t\t\t},\n")
- end
-end
-
-
-
-
-
---- Writes a list of constants into the specified file in ZBS format
-local function WriteZBSConstants(f, a_Constants)
- for _, cons in ipairs(a_Constants or {}) do
- f:write("\t\t\t[\"", cons.Name, "\"] =\n")
- f:write("\t\t\t{\n")
- f:write("\t\t\t\ttype = \"value\",\n")
- if ((cons.Desc ~= nil) and (cons.Desc ~= "")) then
- f:write("\t\t\t\tdescription = [[", CleanUpDescription(cons.Desc or ""), " ]],\n")
- end
- f:write("\t\t\t},\n")
- end
-end
-
-
-
-
-
---- Writes one Cuberite class definition into the specified file in ZBS format
-local function WriteZBSClass(f, a_Class)
- assert(type(a_Class) == "table")
-
- -- Write class header:
- f:write("\t", a_Class.Name, " =\n\t{\n")
- f:write("\t\ttype = \"class\",\n")
- f:write("\t\tdescription = [[", CleanUpDescription(a_Class.Desc or ""), " ]],\n")
- f:write("\t\tchilds =\n")
- f:write("\t\t{\n")
-
- -- Export methods and constants:
- WriteZBSMethods(f, a_Class.Functions)
- WriteZBSConstants(f, a_Class.Constants)
-
- -- Finish the class definition:
- f:write("\t\t},\n")
- f:write("\t},\n\n")
-end
-
-
-
-
-
---- Dumps the entire API table into a file in the ZBS format
-local function DumpAPIZBS(a_API)
- LOG("Dumping ZBS API description...")
- local f, err = io.open("mcserver_api.lua", "w")
- if (f == nil) then
- LOG("Cannot open mcserver_lua.lua for writing, ZBS API will not be dumped. " .. err)
- return
- end
-
- -- Write the file header:
- f:write("-- This is a Cuberite API file automatically generated by the APIDump plugin\n")
- f:write("-- Note that any manual changes will be overwritten by the next dump\n\n")
- f:write("return {\n")
-
- -- Export each class except Globals, store those aside:
- local Globals
- for _, cls in ipairs(a_API) do
- if (cls.Name ~= "Globals") then
- WriteZBSClass(f, cls)
- else
- Globals = cls
- end
- end
-
- -- Export the globals:
- if (Globals) then
- WriteZBSMethods(f, Globals.Functions)
- WriteZBSConstants(f, Globals.Constants)
- end
-
- -- Finish the file:
- f:write("}\n")
- f:close()
- LOG("ZBS API dumped...")
-end
-
-
-
-
-
---- Returns true if a_Descendant is declared to be a (possibly indirect) descendant of a_Base
-local function IsDeclaredDescendant(a_DescendantName, a_BaseName, a_API)
- -- Check params:
- assert(type(a_DescendantName) == "string")
- assert(type(a_BaseName) == "string")
- assert(type(a_API) == "table")
- if not(a_API[a_BaseName]) then
- return false
- end
- assert(type(a_API[a_BaseName]) == "table", "Not a class name: " .. a_BaseName)
- assert(type(a_API[a_BaseName].Descendants) == "table")
-
- -- Check direct inheritance:
- for _, desc in ipairs(a_API[a_BaseName].Descendants) do
- if (desc.Name == a_DescendantName) then
- return true
- end
- end -- for desc - a_BaseName's descendants
-
- -- Check indirect inheritance:
- for _, desc in ipairs(a_API[a_BaseName].Descendants) do
- if (IsDeclaredDescendant(a_DescendantName, desc.Name, a_API)) then
- return true
- end
- end -- for desc - a_BaseName's descendants
-
- return false
-end
-
-
-
-
-
---- Checks the specified class' inheritance
--- Reports any problems as new items in the a_Report table
-local function CheckClassInheritance(a_Class, a_API, a_Report)
- -- Check params:
- assert(type(a_Class) == "table")
- assert(type(a_API) == "table")
- assert(type(a_Report) == "table")
-
- -- Check that the declared descendants are really descendants:
- local registry = debug.getregistry()
- for _, desc in ipairs(a_Class.Descendants or {}) do
- local isParent = false
- local parents = registry["tolua_super"][_G[desc.Name]]
- if not(parents[a_Class.Name]) then
- table.insert(a_Report, desc.Name .. " is not a descendant of " .. a_Class.Name)
- end
- end -- for desc - a_Class.Descendants[]
-
- -- Check that all inheritance is listed for the class:
- local parents = registry["tolua_super"][_G[a_Class.Name]] -- map of "classname" -> true for each class that a_Class inherits
- for clsName, isParent in pairs(parents or {}) do
- if ((clsName ~= "") and not(clsName:match("const .*"))) then
- if not(IsDeclaredDescendant(a_Class.Name, clsName, a_API)) then
- table.insert(a_Report, a_Class.Name .. " inherits from " .. clsName .. " but this isn't documented")
- end
- end
- end
-end
-
-
-
-
-
---- Checks each class's declared inheritance versus the actual inheritance
-local function CheckAPIDescendants(a_API)
- -- Check each class:
- local report = {}
- for _, cls in ipairs(a_API) do
- if (cls.Name ~= "Globals") then
- CheckClassInheritance(cls, a_API, report)
- end
- end
-
- -- If there's anything to report, output it to a file:
- if (report[1] ~= nil) then
- LOG("There are inheritance errors in the API description:")
- for _, msg in ipairs(report) do
- LOG(" " .. msg)
- end
-
- local f, err = io.open("API/_inheritance_errors.txt", "w")
- if (f == nil) then
- LOG("Cannot report inheritance problems to a file: " .. tostring(err))
- return
- end
- f:write(table.concat(report, "\n"))
- f:close()
- end
-end
-
-
-
-
-
-local function DumpApi()
- LOG("Dumping the API...")
-
- -- Load the API descriptions from the Classes and Hooks subfolders:
- -- This needs to be done each time the command is invoked because the export modifies the tables' contents
- dofile(g_PluginFolder .. "/APIDesc.lua")
- if (g_APIDesc.Classes == nil) then
- g_APIDesc.Classes = {};
- end
- if (g_APIDesc.Hooks == nil) then
- g_APIDesc.Hooks = {};
- end
- LoadAPIFiles("/Classes/", g_APIDesc.Classes);
- LoadAPIFiles("/Hooks/", g_APIDesc.Hooks);
-
- -- Reset the stats:
- g_TrackedPages = {}; -- List of tracked pages, to be checked later whether they exist. Each item is an array of referring pagenames.
- g_Stats = -- Statistics about the documentation
- {
- NumTotalClasses = 0,
- NumUndocumentedClasses = 0,
- NumTotalFunctions = 0,
- NumUndocumentedFunctions = 0,
- NumTotalConstants = 0,
- NumUndocumentedConstants = 0,
- NumTotalVariables = 0,
- NumUndocumentedVariables = 0,
- NumTotalHooks = 0,
- NumUndocumentedHooks = 0,
- NumTrackedLinks = 0,
- NumInvalidLinks = 0,
- }
-
- -- Create the API tables:
- local API, Globals = CreateAPITables();
-
- -- Sort the classes by name:
- table.sort(API,
- function (c1, c2)
- return (string.lower(c1.Name) < string.lower(c2.Name));
- end
- );
- g_Stats.NumTotalClasses = #API;
-
- -- Add Globals into the API:
- Globals.Name = "Globals";
- table.insert(API, Globals);
-
- -- Read in the descriptions:
- LOG("Reading descriptions...");
- ReadDescriptions(API);
-
- -- Check that the API lists the inheritance properly, report any problems to a file:
- CheckAPIDescendants(API)
-
- -- Dump all available API objects in HTML format into a subfolder:
- DumpAPIHtml(API);
-
- -- Dump all available API objects in format used by ZeroBraneStudio API descriptions:
- DumpAPIZBS(API)
-
- LOG("APIDump finished");
- return true
-end
-
-
-
-
-
-local function HandleWebAdminDump(a_Request)
- if (a_Request.PostParams["Dump"] ~= nil) then
- DumpApi()
- end
- return
- [[
-
Pressing the button will generate the API dump on the server. Note that this can take some time.
-
- ]]
-end
-
-
-
-
-
-local function HandleCmdApi(a_Split)
- DumpApi()
- return true
-end
-
-
-
-
-
-local function HandleCmdApiShow(a_Split, a_EntireCmd)
- os.execute("API" .. cFile:GetPathSeparator() .. "index.html")
- return true, "Launching the browser to show the API docs..."
-end
-
-
-
-
-
-function Initialize(Plugin)
- g_Plugin = Plugin;
- g_PluginFolder = Plugin:GetLocalFolder();
-
- LOG("Initialising " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
-
- -- Bind a console command to dump the API:
- cPluginManager:BindConsoleCommand("api", HandleCmdApi, "Dumps the Lua API docs into the API/ subfolder")
- cPluginManager:BindConsoleCommand("apishow", HandleCmdApiShow, "Runs the default browser to show the API docs")
-
- -- Add a WebAdmin tab that has a Dump button
- g_Plugin:AddWebTab("APIDump", HandleWebAdminDump)
-
- return true
-end
--
cgit v1.2.3