#!/usr/bin/env lua
-- docs
-- oUF documentation generator
--
-- This is really just a quick and dirty way of generating documentation for
-- oUF[1]. The syntax is inspired by TomDoc[2], but a lot of the non-oUF and
-- non-Lua things aren't implemented.
--
-- Why implement my own documentation generator?
-- It was mainly done because oUF is kind-of special, but also because the
-- available alternatives aren't good enough or have issues I can't workaround.
--
-- Things that need fixing:
-- - No highlighting of Lua code.
-- - Doesn't validate that comments are documentation strings.
-- - Doesn't parse its own documentation header.
-- - Close to zero error handling.
--
-- Usage
--
-- docs [docs path] [file...]
--
-- Links
--
-- [1] https://github.com/haste/oUF
-- [2] http://tomdoc.org/
local out
local lines
local tisf = function(fmt, ...)
table.insert(out, fmt:format(...))
end
local trim = function(str)
return str:match('^()%s*$') and '' or str:match('^%s*(.*%S)')
end
local findNextEmpty = function(start, stop)
for i=start, stop or #lines do
if(lines[i] == '') then
return i
end
end
end
local findNextHeader = function(offest)
for i=offest, #lines do
local pre, header, post = unpack(lines, i, i + 2)
-- Single lines without punctuation are headers.
if(pre == '' and post == '' and not header:match'%.') then
return i + 1
end
end
end
local findNextArguent = function(start, stop, padding, pattern)
for i=start, stop do
local match, pad = lines[i]:match(pattern)
if(match and pad == padding) then
return i
end
end
end
local replaceMarkup = function(str)
return str
-- `in-line code` to in-line code
:gsub('`([^`]+)`', '%1
')
-- [Link](http://example.com) to Link
:gsub('%[([^%]]+)%]%(([^)]+)%)', '%1')
end
local handleArguments = function(start, stop, pattern)
tisf('
%s', lines[start]:sub(3))
for i=start + 1, stop do
tisf(lines[i]:sub(3))
end
tisf('
')
end
local handleParagraph = function(start, stop)
tisf('') for i=start, stop do tisf(trim(lines[i])) end tisf('
') end local handleSection = function(start, stop) while(start) do -- Find the next empty line or continue until the end of the section. -- findNextEmpty() returns the position of the empty line, so we need to -- subtract one from it. local nextEmpty = findNextEmpty(start + 1, stop) if(nextEmpty) then nextEmpty = nextEmpty - 1 else nextEmpty = stop end local line = lines[start] if(not line) then return elseif(line:match('^%S+%s*%- ')) then handleArguments(start, nextEmpty, '(%S+)%s*()%- ()') elseif(line:sub(1, 2) == ' ') then handleExamples(start, nextEmpty) else handleParagraph(start, nextEmpty) end start = findNextEmpty(nextEmpty, stop) if(start) then start = start + 1 end end end local generateDocs = function(str, level) lines = {} out = {} for line in str:gmatch('([^\n]*)\n') do table.insert(lines, line:gsub('\t*', ''):sub(2)) end -- The first line is always the main header. tisf('