From 8012b8be6eb667ed018470e08d2b657b62afcd59 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 11 Sep 2013 16:57:57 +0200 Subject: APIDump: First attempt at outputting annotations in the HTML format --- MCServer/Plugins/APIDump/APIDesc.lua | 68 +++++++++++ MCServer/Plugins/APIDump/APIDump.deproj | 3 + MCServer/Plugins/APIDump/main.lua | 193 ++++++++++++++++++-------------- 3 files changed, 179 insertions(+), 85 deletions(-) create mode 100644 MCServer/Plugins/APIDump/APIDesc.lua (limited to 'MCServer/Plugins/APIDump') diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua new file mode 100644 index 000000000..44981fdd7 --- /dev/null +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -0,0 +1,68 @@ + +-- APIDesc.lua + +-- Contains the API objects' descriptions + + + + +g_APIDesc = +{ + Classes = + { + cBlockArea = + { + Desc = [[ + This class is used when multiple adjacent blocks are to be manipulated. Because of chunking + and multithreading, manipulating single blocks using {{api:cWorld|cWorld:SetBlock}}() is a rather + time-consuming operation (locks for exclusive access need to be obtained, chunk lookup is done + for each block), so whenever you need to manipulate multiple adjacent blocks, it's better to wrap + the operation into a cBlockArea access. cBlockArea is capable of reading / writing across chunk + boundaries, has no chunk lookups for get and set operations and is not subject to multithreading + locking (because it is not shared among threads).

+

+ cBlockArea remembers its origin (MinX, MinY, MinZ coords in the Read() call) and therefore supports + absolute as well as relative get / set operations. Despite that, the contents of a cBlockArea can + be written back into the world at any coords.

+

+ cBlockArea can hold any combination of the following datatypes:

+ Read() and Write() functions have parameters that tell the class which datatypes to read / write. + Note that a datatype that has not been read cannot be written (FIXME).

+

+ Typical usage:

+ ]], + Functions = + { + Clear = { Notes = "Clears the object, resets it to zero size" }, + CopyFrom = { Params = "{{cBlockArea|BlockAreaSrc}}", Notes = "Copies contents from BlockAreaSrc into self"}, + CopyTo = { Params = "{{cBlockArea|BlockAreaDst}}", Notes = "Copies contents from self into BlockAreaDst"}, + GetBlockLight = { Params = "BlockX, BlockY, BlockZ", Return = "NIBBLETYPE", Notes = "Returns the blocklight at the specified absolute coords"}, + }, + }, + + cBlockEntity = + { + } + }, + + IgnoreFunctions = + { + "globals.assert", + "globals.collectgarbage", + "globals.xpcall", + } +} ; + + + + diff --git a/MCServer/Plugins/APIDump/APIDump.deproj b/MCServer/Plugins/APIDump/APIDump.deproj index 0d6ad82fa..9ee9170f2 100644 --- a/MCServer/Plugins/APIDump/APIDump.deproj +++ b/MCServer/Plugins/APIDump/APIDump.deproj @@ -1,5 +1,8 @@ + + APIDesc.lua + main.lua diff --git a/MCServer/Plugins/APIDump/main.lua b/MCServer/Plugins/APIDump/main.lua index 0f63f9ab5..c13611d2e 100644 --- a/MCServer/Plugins/APIDump/main.lua +++ b/MCServer/Plugins/APIDump/main.lua @@ -7,8 +7,17 @@ +-- Global variables: +g_Plugin = nil; + + + + + function Initialize(Plugin) + g_Plugin = Plugin; + Plugin:SetName("APIDump") Plugin:SetVersion(1) @@ -18,12 +27,9 @@ function Initialize(Plugin) -- dump all available API functions and objects: -- DumpAPITxt(); - -- Dump all available API objects in wiki-style tables: - -- DumpAPIWiki(); - -- Dump all available API object in HTML format into a subfolder: DumpAPIHtml(); - + return true end @@ -69,69 +75,30 @@ end -function DumpAPIWiki() - LOG("Dumping all available functions and constants to API_wiki.txt..."); - - local API, Globals = CreateAPITables(); - - -- Now dump the whole thing into a file, formatted as a wiki table: - local function WriteClass(a_File, a_ClassAPI) - if (#a_ClassAPI.Functions > 0) then - a_File:write("Functions:\n"); - a_File:write("^ Function name ^ Parameters ^ Return value ^ Note ^\n"); - for i, n in ipairs(a_ClassAPI.Functions) do - a_File:write("| " .. n[1] .. " | | | |\n"); - end - a_File:write("\n\n"); - end - - if (#a_ClassAPI.Constants > 0) then - a_File:write("Constants:\n"); - a_File:write("^ Constant ^ Value ^ Note ^\n"); - for i, n in ipairs(a_ClassAPI.Constants) do - a_File:write("| " .. n[1] .. " | " .. n[2] .. " | |\n"); - end - a_File:write("\n\n"); - end - end - - local f = io.open("API_wiki.txt", "w"); - for i, n in ipairs(API) do - f:write("Class " .. n[1] .. "\n"); - WriteClass(f, n[2]); - f:write("\n\n\n----------------\n"); - end - f:write("globals:\n"); - WriteClass(f, Globals); - f:close(); - - LOG("API_wiki.txt file written"); -end - - - function CreateAPITables() --[[ We want an API table of the following shape: local API = { - {"cCuboid", { + { + Name = "cCuboid", Functions = { - {"Sort"}, -- The extra table will be used to later add params, return values and notes - {"IsInside"} + {Name = "Sort"}, + {Name = "IsInside"} }, Constants = { } }}, - {"cBlockArea", { + { + Name = "cBlockArea", Functions = { - "Clear", - "CopyFrom", + {Name = "Clear"}, + {Name = "CopyFrom"}, ... } Constants = { - {"baTypes", 0}, - {"baMetas", 1}, + {Name = "baTypes", Value = 0}, + {Name = "baMetas", Value = 1}, ... } ... @@ -152,9 +119,9 @@ function CreateAPITables() local function Add(a_APIContainer, a_ClassName, a_ClassObj) if (type(a_ClassObj) == "function") then - table.insert(a_APIContainer.Functions, {a_ClassName}); + table.insert(a_APIContainer.Functions, {Name = a_ClassName}); elseif (type(a_ClassObj) == "number") then - table.insert(a_APIContainer.Constants, {a_ClassName, a_ClassObj}); + table.insert(a_APIContainer.Constants, {Name = a_ClassName, Value = a_ClassObj}); end end @@ -162,18 +129,18 @@ function CreateAPITables() -- Sort the function list and constant lists: table.sort(a_ClassAPI.Functions, function(f1, f2) - return (f1[1] < f2[1]); + return (f1.Name < f2.Name); end ); table.sort(a_ClassAPI.Constants, function(c1, c2) - return (c1[1] < c2[1]); + return (c1.Name < c2.Name); end ); end; - local function ParseClass(a_ClassObj) - local res = {Functions = {}, Constants = {}}; + local function ParseClass(a_ClassName, a_ClassObj) + local res = {Name = a_ClassName, Functions = {}, Constants = {}}; for i, v in pairs(a_ClassObj) do Add(res, i, v); end @@ -188,7 +155,7 @@ function CreateAPITables() local StartLetter = GetChar(i, 0); if (StartLetter == "c") then -- Starts with a "c", handle it as a MCS API class - table.insert(API, {i, ParseClass(v)}); + table.insert(API, ParseClass(i, v)); end else Add(Globals, i, v); @@ -197,7 +164,7 @@ function CreateAPITables() SortClass(Globals); table.sort(API, function(c1, c2) - return (c1[1] < c2[1]); + return (c1.Name < c2.Name); end ); @@ -212,8 +179,13 @@ function DumpAPIHtml() LOG("Dumping all available functions and constants to API subfolder..."); local API, Globals = CreateAPITables(); + Globals.Name = "Globals"; + table.insert(API, Globals); + + -- Read in the descriptions: + ReadDescriptions(API); - -- Create the folder: + -- Create the output folder: os.execute("mkdir API"); -- Create a "class index" file, write each class as a link to that file, @@ -224,9 +196,9 @@ function DumpAPIHtml() "); f:close(); @@ -235,19 +207,70 @@ end + +function ReadDescriptions(a_API) + local UnexportedDocumented = {}; -- List of API objects that are documented but not exported, simply a list of names + for i, cls in ipairs(a_API) do + local APIDesc = g_APIDesc.Classes[cls.Name]; + if (APIDesc ~= nil) then + cls.Desc = APIDesc.Desc; + + if (APIDesc.Functions ~= nil) then + -- Assign function descriptions: + for j, func in ipairs(cls.Functions) do + -- func is {"FuncName"}, add Parameters, Return and Notes from g_APIDesc + local FnDesc = APIDesc.Functions[func.Name]; + if (FnDesc ~= nil) then + func.Params = FnDesc.Params; + func.Return = FnDesc.Return; + func.Notes = FnDesc.Notes; + FnDesc.IsExported = true; + end + end -- for j, func + + -- Add all non-exported function descriptions to UnexportedDocumented: + for j, func in pairs(APIDesc.Functions) do + -- TODO + end + end -- if (APIDesc.Functions ~= nil) + + if (APIDesc.Constants ~= nil) then + -- Assign constant descriptions: + for j, cons in ipairs(cls.Constants) do + local CnDesc = APIDesc.Constants[cons.Name]; + if (CnDesc ~= nil) then + cons.Notes = CnDesc.Notes; + CnDesc.IsExported = true; + end + end -- for j, cons + + -- Add all non-exported constant descriptions to UnexportedDocumented: + for j, cons in pairs(APIDesc.Constants) do + -- TODO + end + end -- if (APIDesc.Constants ~= nil) + + end + end -- for i, class +end + + + + + function WriteHtmlClass(a_ClassAPI) - local cf, err = io.open("API/" .. a_ClassAPI[1] .. ".html", "w"); + local cf, err = io.open("API/" .. a_ClassAPI.Name .. ".html", "w"); if (cf == nil) then return; end local function LinkifyString(a_String) - -- TODO: Make a link out of anything with the special linkifying syntax [[link|title]] - -- a_String:gsub("\[\[" .. "[ + -- TODO: Make a link out of anything with the special linkifying syntax {{link|title}} + -- a_String:gsub("{{([^|]*)|[^}]*}}", "%2"); return a_String; end - cf:write([[MCServer API - ]] .. a_ClassAPI[1] .. [[ + cf:write([[MCServer API - ]] .. a_ClassAPI.Name .. [[

Contents

@@ -255,43 +278,43 @@ function WriteHtmlClass(a_ClassAPI) ]]); -- Write the table of contents: - if (#a_ClassAPI[2].Constants > 0) then + if (#a_ClassAPI.Constants > 0) then cf:write("
  • Constants
  • \n"); end - if (#a_ClassAPI[2].Functions > 0) then + if (#a_ClassAPI.Functions > 0) then cf:write("
  • Functions
  • \n"); end cf:write(""); -- Write the class description: - cf:write("

    " .. a_ClassAPI[1] .. "

    \n"); - if (a_ClassAPI.Description ~= nil) then + cf:write("

    " .. a_ClassAPI.Name .. "

    \n"); + if (a_ClassAPI.Desc ~= nil) then cf:write("

    "); - cf:write(n.Description); + cf:write(a_ClassAPI.Desc); cf:write("

    \n"); end; -- Write the constants: - if (#a_ClassAPI[2].Constants > 0) then + if (#a_ClassAPI.Constants > 0) then cf:write("

    Constants

    \n"); cf:write("\n"); - for i, n in ipairs(a_ClassAPI[2].Constants) do - cf:write(""); - cf:write(""); - cf:write("\n"); + for i, cons in ipairs(a_ClassAPI.Constants) do + cf:write(""); + cf:write(""); + cf:write("\n"); end cf:write("
    NameValueNotes
    " .. n[1] .. "" .. n[2] .. "" .. LinkifyString(n.Notes or "") .. "
    " .. cons.Name .. "" .. cons.Value .. "" .. LinkifyString(cons.Notes or "") .. "
    \n"); end -- Write the functions: - if (#a_ClassAPI[2].Functions > 0) then + if (#a_ClassAPI.Functions > 0) then cf:write("

    Functions

    \n"); cf:write("\n"); - for i, f in ipairs(a_ClassAPI[2].Functions) do - cf:write(""); - cf:write(""); - cf:write(""); - cf:write("\n"); + for i, func in ipairs(a_ClassAPI.Functions) do + cf:write(""); + cf:write(""); + cf:write(""); + cf:write("\n"); end cf:write("
    NameParametersReturn valueNotes
    " .. f[1] .. "" .. LinkifyString(f.Params or "").. "" .. LinkifyString(f.Return or "").. "" .. LinkifyString(f.Notes or "") .. "
    " .. func.Name .. "" .. LinkifyString(func.Params or "").. "" .. LinkifyString(func.Return or "").. "" .. LinkifyString(func.Notes or "") .. "
    \n"); end -- cgit v1.2.3