-- main.lua -- Implements the plugin entrypoint (in this case the entire plugin) -- Global variables: g_Plugin = nil; function Initialize(Plugin) g_Plugin = Plugin; Plugin:SetName("APIDump") Plugin:SetVersion(1) PluginManager = cRoot:Get():GetPluginManager() LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) -- dump all available API functions and objects: -- DumpAPITxt(); -- DEBUG: Convert the wiki dump into APIDesc ConvertWikiToDesc(); -- Dump all available API object in HTML format into a subfolder: DumpAPIHtml(); return true end function DumpAPITxt() LOG("Dumping all available functions to API.txt..."); function dump (prefix, a, Output) for i, v in pairs (a) do if (type(v) == "table") then if (GetChar(i, 1) ~= ".") then if (v == _G) then -- LOG(prefix .. i .. " == _G, CYCLE, ignoring"); elseif (v == _G.package) then -- LOG(prefix .. i .. " == _G.package, ignoring"); else dump(prefix .. i .. ".", v, Output) end end elseif (type(v) == "function") then if (string.sub(i, 1, 2) ~= "__") then table.insert(Output, prefix .. i .. "()"); end end end end local Output = {}; dump("", _G, Output); table.sort(Output); local f = io.open("API.txt", "w"); for i, n in ipairs(Output) do f:write(n, "\n"); end f:close(); LOG("API.txt written."); end function CreateAPITables() --[[ We want an API table of the following shape: local API = { { Name = "cCuboid", Functions = { {Name = "Sort"}, {Name = "IsInside"} }, Constants = { } }}, { Name = "cBlockArea", Functions = { {Name = "Clear"}, {Name = "CopyFrom"}, ... } Constants = { {Name = "baTypes", Value = 0}, {Name = "baMetas", Value = 1}, ... } ... }} }; local Globals = { Functions = { ... }, Constants = { ... } }; --]] local Globals = {Functions = {}, Constants = {}}; local API = {}; local function Add(a_APIContainer, a_ClassName, a_ClassObj) if (type(a_ClassObj) == "function") then table.insert(a_APIContainer.Functions, {Name = a_ClassName}); elseif (type(a_ClassObj) == "number") then table.insert(a_APIContainer.Constants, {Name = a_ClassName, Value = a_ClassObj}); end end local function SortClass(a_ClassAPI) -- Sort the function list and constant lists: table.sort(a_ClassAPI.Functions, function(f1, f2) return (f1.Name < f2.Name); end ); table.sort(a_ClassAPI.Constants, function(c1, c2) return (c1.Name < c2.Name); end ); end; 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 SortClass(res); return res; end for i, v in pairs(_G) do if (type(v) == "table") then -- It is a table - probably a class local StartLetter = GetChar(i, 0); if (StartLetter == "c") then -- Starts with a "c", handle it as a MCS API class table.insert(API, ParseClass(i, v)); end else Add(Globals, i, v); end end SortClass(Globals); table.sort(API, function(c1, c2) return (c1.Name < c2.Name); end ); return API, Globals; end 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 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 end f:write([[
"); cf:write(a_ClassAPI.Desc); cf:write("
\n"); end; -- Write the constants: if (#a_ClassAPI.Constants > 0) then cf:write("Name | Value | Notes |
---|---|---|
" .. cons.Name .. " | "); cf:write("" .. cons.Value .. " | "); cf:write("" .. LinkifyString(cons.Notes or "") .. " |
Name | Parameters | Return value | Notes |
---|---|---|---|
" .. func.Name .. " | "); cf:write("" .. LinkifyString(func.Params or "").. " | "); cf:write("" .. LinkifyString(func.Return or "").. " | "); cf:write("" .. LinkifyString(func.Notes or "") .. " |
"; -- Replace empty lines with paragraph delimiters end Desc = Desc .. line .. "\n"; elseif (state == 2) then -- Constants: local Split = StringSplitAndTrim(line, "|"); if (#Split >= 3) then -- Split[1] is always "", because the line starts with a "|" table.insert(Constants, {Name = Split[2], Notes = Split[3]}); end elseif (state == 3) then -- Functions: local Split = StringSplitAndTrim(line, "|"); if (#Split >= 5) then -- Split[1] is always "", because the line starts with a "|" table.insert(Functions, {Name = Split[2], Params = Split[3], Return = Split[4], Notes = Split[5]}); end end end -- for line fin:close(); -- Write the info into the output file: fout:write(filename:match("[^\.]*") .. " =\n{\tFunctions =\n\t{\n"); for i, func in ipairs(Functions) do fout:write("\t\t{ " .. func.Name .. " = { Params = \"" .. func.Params .. "\", Return =\"" .. func.Return .. "\", Desc = \"" .. func.Notes .. "\" },\n" ); end fout:write("\t},\n\tConstants =\n\t{\n"); for i, cons in ipairs(Constants) do fout:write("\t\t{ " .. cons.Name .. " = { Notes = \"" .. cons.Notes .. "\" },\n"); end fout:write("\t},\n},\n\n\n"); end -- if fin ~= nil end -- for file fout:close(); end