- Updated Table to support new Collection System (could break things, sorry) - Updated Tree to support new Collection System - Added experimental ScrollFrame - Updated Menu to support Collection System
321 lines
11 KiB
Lua
321 lines
11 KiB
Lua
local BasaltDoc = {}
|
|
|
|
local defaultPath = package.path
|
|
if fs then
|
|
local args = {...}
|
|
local docsPath = fs.getDir(args[2])
|
|
local format = "path/?.lua;path/?/init.lua;"
|
|
local main = format:gsub("path", docsPath)
|
|
package.path = main.."rom/?;"..defaultPath
|
|
else
|
|
local format = "path/?.lua;path/?/init.lua;"
|
|
local main = format:gsub("path", "tools/BasaltDoc")
|
|
package.path = main .. ";" .. defaultPath
|
|
end
|
|
|
|
local classParser = require("parsers.classParser")
|
|
|
|
local functionParser = require("parsers.functionParser")
|
|
|
|
local propertyParser = require("parsers.propertyParser")
|
|
|
|
local eventParser = require("parsers.eventParser")
|
|
|
|
local globalParser = require("parsers.globalParser")
|
|
|
|
local helper = require("utils.helper")
|
|
|
|
local markdownGenerator = require("utils.markdownGenerator")
|
|
|
|
BasaltDoc.annotationHandlers = {}
|
|
|
|
function BasaltDoc.registerAnnotation(tag, handler)
|
|
BasaltDoc.annotationHandlers[tag] = handler
|
|
end
|
|
|
|
----------------------------------------------------------------
|
|
-- Standard Annotation Handlers
|
|
----------------------------------------------------------------
|
|
BasaltDoc.registerAnnotation("@param", function(target, args)
|
|
if target.type == "function" then
|
|
local paramName, optional, paramType, paramDesc = args:match("([%w_]+)(%??)[%s]*([%w_|]+)[%s]*(.*)")
|
|
if paramName then
|
|
table.insert(target.params, {
|
|
name = paramName,
|
|
type = paramType or "any",
|
|
description = paramDesc or "",
|
|
optional = optional == "?"
|
|
})
|
|
end
|
|
end
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@return", function(target, args)
|
|
if target.type == "function" then
|
|
local returnType, returnName, returnDesc = args:match("([%w_|]+)[%s]+([%w_]+)[%s]+(.*)")
|
|
if returnType then
|
|
table.insert(target.returns, {
|
|
type = returnType,
|
|
name = returnName or "",
|
|
description = returnDesc or ""
|
|
})
|
|
else
|
|
table.insert(target.returns, {
|
|
type = args:match("([%w_|]+)") or "any",
|
|
name = "",
|
|
description = args:match("[%w_|]+[%s]+(.*)" ) or ""
|
|
})
|
|
end
|
|
end
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@returns", function(target, args)
|
|
BasaltDoc.annotationHandlers["@return"](target, args)
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@usage", function(target, args)
|
|
if not target.usage then target.usage = {} end
|
|
table.insert(target.usage, args)
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@example", function(target, args)
|
|
if not target.examples then target.examples = {} end
|
|
table.insert(target.examples, args)
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@see", function(target, args)
|
|
if not target.see then target.see = {} end
|
|
table.insert(target.see, args)
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@since", function(target, args)
|
|
target.since = args
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@deprecated", function(target, args)
|
|
target.deprecated = args ~= "" and args or true
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@private", function(target, args)
|
|
target.visibility = "private"
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@protected", function(target, args)
|
|
target.visibility = "protected"
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@configDescription", function(target, args)
|
|
if target.type == "class" then
|
|
target.configDescription = args
|
|
end
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@shortDescription", function(target, args)
|
|
if target.type == "function" then
|
|
target.shortDescription = args
|
|
end
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@run", function(target, args)
|
|
if not target.run then target.run = {} end
|
|
table.insert(target.run, args)
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@title", function(target, args)
|
|
target.title = args
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@skipFunctionList", function(target, args)
|
|
target.skipFunctionList = true
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@skipPropertyList", function(target, args)
|
|
target.skipPropertyList = true
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@skipDetailedFunctionList", function(target, args)
|
|
target.skipDetailedFunctionList = true
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@skip", function(target, args)
|
|
target.skip = true
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@globalDescription", function(target, args)
|
|
if args and args ~= "" then
|
|
target.description = args
|
|
end
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@tableType", function(target, args)
|
|
if not target.tableTypes then target.tableTypes = {} end
|
|
local tableName = args:match("^%s*(%S+)")
|
|
if tableName then
|
|
target._currentTableType = {
|
|
name = tableName,
|
|
fields = {}
|
|
}
|
|
table.insert(target.tableTypes, target._currentTableType)
|
|
end
|
|
end)
|
|
|
|
BasaltDoc.registerAnnotation("@tableField", function(target, args)
|
|
if target._currentTableType then
|
|
local fieldName, fieldType, fieldDesc = args:match("^%s*([%w_]+)%s+([%w_|]+)%s+(.*)")
|
|
if fieldName and fieldType then
|
|
table.insert(target._currentTableType.fields, {
|
|
name = fieldName,
|
|
type = fieldType,
|
|
description = fieldDesc or ""
|
|
})
|
|
end
|
|
end
|
|
end)
|
|
|
|
if classParser then classParser.setHandlers(BasaltDoc.annotationHandlers) end
|
|
if functionParser then functionParser.setHandlers(BasaltDoc.annotationHandlers) end
|
|
if propertyParser then propertyParser.setHandlers(BasaltDoc.annotationHandlers) end
|
|
if eventParser then eventParser.setHandlers(BasaltDoc.annotationHandlers) end
|
|
if globalParser then globalParser.setHandlers(BasaltDoc.annotationHandlers) end
|
|
|
|
----------------------------------------------------------------
|
|
-- Main Parser
|
|
----------------------------------------------------------------
|
|
function BasaltDoc.parse(content)
|
|
local ast = { classes = {}, global = nil }
|
|
|
|
local rawLines = {}
|
|
for line in content:gmatch("([^\r\n]*)\r?\n?") do
|
|
table.insert(rawLines, line)
|
|
end
|
|
|
|
local lines = {}
|
|
local i = 1
|
|
while i <= #rawLines do
|
|
local line = rawLines[i]
|
|
if line:match("@globalDescription") then
|
|
local globalAnnotations = {line}
|
|
i = i + 1
|
|
if i <= #rawLines and rawLines[i]:match("%-%-?%[%[") then
|
|
i = i + 1
|
|
while i <= #rawLines and not rawLines[i]:match("%]%]") do
|
|
table.insert(globalAnnotations, "--- " .. rawLines[i])
|
|
i = i + 1
|
|
end
|
|
if i <= #rawLines and rawLines[i]:match("%]%]") then
|
|
i = i + 1
|
|
end
|
|
if #globalAnnotations > 0 and globalParser then
|
|
local global = globalParser.parse(globalAnnotations, table.concat(globalAnnotations, "\n"))
|
|
ast.global = global
|
|
end
|
|
end
|
|
else
|
|
table.insert(lines, line)
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
local annotationBuffer = {}
|
|
local currentClass = nil
|
|
local firstTag = nil
|
|
local pendingTableTypes = {}
|
|
|
|
local blockStartTags = {
|
|
["@class"] = true,
|
|
["@property"] = true,
|
|
["@event"] = true,
|
|
["@skip"] = true,
|
|
["@tableType"] = true
|
|
}
|
|
|
|
local i = 1
|
|
while i <= #lines do
|
|
local line = lines[i]
|
|
if line:match("^%-%-%-?") then
|
|
table.insert(annotationBuffer, line)
|
|
if not firstTag then
|
|
local tag = line:match("@%S+")
|
|
if tag and blockStartTags[tag] then
|
|
firstTag = tag
|
|
end
|
|
end
|
|
i = i + 1
|
|
elseif #annotationBuffer > 0 then
|
|
local nextLine = lines[i]
|
|
local skip = false
|
|
if nextLine and nextLine:match("^function") and currentClass and functionParser then
|
|
local fn = functionParser.parse(annotationBuffer, nextLine)
|
|
if fn then
|
|
table.insert(currentClass.functions, fn)
|
|
end
|
|
skip = true
|
|
elseif firstTag then
|
|
if firstTag == "@class" and classParser then
|
|
local class = classParser.parse(annotationBuffer, table.concat(annotationBuffer, "\n"))
|
|
if class and not class.skip then
|
|
if #pendingTableTypes > 0 then
|
|
for _, tableType in ipairs(pendingTableTypes) do
|
|
table.insert(class.tableTypes, tableType)
|
|
end
|
|
pendingTableTypes = {}
|
|
end
|
|
table.insert(ast.classes, class)
|
|
currentClass = class
|
|
end
|
|
elseif firstTag == "@tableType" then
|
|
local tempTarget = {tableTypes = {}}
|
|
if classParser and classParser.handlers then
|
|
helper.applyAnnotations(annotationBuffer, tempTarget, classParser.handlers)
|
|
end
|
|
if tempTarget.tableTypes and #tempTarget.tableTypes > 0 then
|
|
for _, tt in ipairs(tempTarget.tableTypes) do
|
|
table.insert(pendingTableTypes, tt)
|
|
end
|
|
end
|
|
elseif firstTag == "@property" and currentClass and propertyParser then
|
|
local prop = propertyParser.parse(annotationBuffer, table.concat(annotationBuffer, "\n"))
|
|
if prop then
|
|
table.insert(currentClass.properties, prop)
|
|
end
|
|
elseif firstTag == "@event" and currentClass and eventParser then
|
|
local evt = eventParser.parse(annotationBuffer, table.concat(annotationBuffer, "\n"))
|
|
if evt then
|
|
table.insert(currentClass.events, evt)
|
|
end
|
|
end
|
|
end
|
|
if skip then i = i + 1 end
|
|
annotationBuffer = {}
|
|
firstTag = nil
|
|
i = i + 1
|
|
else
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
if #annotationBuffer > 0 and firstTag then
|
|
if firstTag == "@class" and classParser then
|
|
local class = classParser.parse(annotationBuffer, table.concat(annotationBuffer, "\n"))
|
|
if class and not class.skip then
|
|
table.insert(ast.classes, class)
|
|
currentClass = class
|
|
end
|
|
end
|
|
end
|
|
|
|
return ast
|
|
end
|
|
|
|
function BasaltDoc.generateMarkdown(ast)
|
|
if markdownGenerator then
|
|
local result = markdownGenerator.generate(ast)
|
|
return result
|
|
else
|
|
return {}
|
|
end
|
|
end
|
|
|
|
package.path = defaultPath
|
|
|
|
return BasaltDoc |