luau-unzip/.lune/docsgen/markdown.luau

177 lines
4.4 KiB
Text

local fs = require("@lune/fs")
local moonwave = require("./moonwave")
local logger = require("./log")
local function writeSectionHeader(buf: string, title: string)
buf ..= `## {title}\n`
return buf
end
local function writeRef(buf: string, name: string, fragment: string?)
buf ..= `\n[{name}]: #{fragment or name}\n`
return buf
end
local function writeClass(buf: string, name: string, desc: string)
buf ..= `# \`{name}\`\n`
buf ..= desc
buf ..= `\n\n`
return buf
end
local function writeDeclaration(buf: string, name: string, fields: { moonwave.Property })
buf ..= `\`\`\`luau\n`
buf ..= `export type {name} = \{\n`
for _, field in fields do
buf ..= `\t{field.name}: {field.lua_type},\n`
end
buf ..= "}\n"
buf ..= `\`\`\`\n`
return buf
end
local function writeProperty(buf: string, name: string, desc: string, type: string)
-- buf ..= `- **\`{name}: {type}\`** - {desc}\n`
buf ..= `- **{name}** - {desc}\n`
return buf
end
local function writeFunction(
buf: string,
class: string,
type: string,
name: string,
desc: string,
params: { moonwave.FunctionParam },
returns: { moonwave.FunctionReturn },
private: boolean
)
local sep = if type == "method" then ":" else "."
local declaredSignature = `{class}{sep}{name}`
buf ..= `### \`{name}\`\n`
if private then
buf ..= `> [!IMPORTANT]\n`
buf ..= `> This is a private API. It may be exported publically, but try to avoid\n`
buf ..= `> using this API, since it can have breaking changes at any time without\n`
buf ..= `> warning.\n\n`
end
buf ..= `{desc}\n`
buf ..= `\`\`\`luau\n`
buf ..= `{declaredSignature}(`
if #params > 0 then
buf ..= "\n"
for _, param in params do
buf ..= `\t{param.name}: {param.lua_type}, -- {param.desc}\n`
end
end
buf ..= `)`
if #returns > 0 then
if #returns == 1 then
buf ..= `: {returns[1].lua_type}\n`
else
for pos, ret in returns do
buf ..= `({ret.lua_type}`
if pos ~= #returns then
buf ..= `, `
end
end
buf ..= `)`
end
end
buf ..= `\n\`\`\`\n`
buf = writeRef(buf, declaredSignature, name)
return buf
end
local function writeType(buf: string, name: string, desc: string, type: string)
buf ..= `\`\`\`luau\n`
buf ..= `export type {name} = {type}\n`
buf ..= `\`\`\`\n`
return buf
end
local function writeMarkdown(path: string, items: { moonwave.Item })
local start = os.clock()
local buf = ""
for _, item in items do
logger.log("info", "Generating docs for", item.name)
buf = writeClass(buf, item.name, item.desc)
local props: { moonwave.Property } = {}
for pos, type in item.types do
if type.name == item.name then
table.remove(item.types, pos)
props = type.fields
end
end
buf = writeDeclaration(buf, item.name, props)
buf = writeSectionHeader(buf, "Properties")
for _, prop in props do
if prop.ignore then
continue
end
buf = writeProperty(buf, prop.name, prop.desc, prop.lua_type)
end
buf ..= "\n"
buf = writeSectionHeader(buf, "API")
for _, func in item.functions do
if func.ignore then
continue
end
buf = writeFunction(
buf,
item.name,
func.function_type,
func.name,
func.desc,
func.params,
func.returns,
func.private
)
end
buf ..= "\n"
buf = writeSectionHeader(buf, "Types")
for _, type in item.types do
if type.ignore then
continue
end
buf ..= `### \`{type.name}\`\n`
if type.private then
buf ..= `> [!IMPORTANT]\n`
buf ..= `> This is a private type. It may be exported publically, but try to avoid\n`
buf ..= `> using it, since its definition can have a breaking change at any time\n`
buf ..= `> without warning.\n\n`
end
buf ..= `{type.desc}\n`
if type.lua_type ~= nil then
buf = writeType(buf, type.name, type.desc, type.lua_type)
else
local fields: { moonwave.Property } = type.fields or {}
buf = writeDeclaration(buf, type.name, fields)
for _, field in fields do
buf = writeProperty(buf, field.name, field.desc, field.lua_type)
end
end
buf = writeRef(buf, type.name)
end
buf = writeRef(buf, item.name)
end
logger.log("info", string.format("Generated docs in %.2fms", (os.clock() - start) * 1000))
logger.log("info", "Writing to", path)
fs.writeFile(path, buf)
end
return writeMarkdown