Created
July 4, 2011 17:08
-
-
Save daurnimator/1063631 to your computer and use it in GitHub Desktop.
Documentation Framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local dt = { } | |
local function doc ( ... ) | |
local args = {...} | |
return function ( v ) | |
if type(v) == "function" then | |
local t = dt [ v ] | |
if t then | |
local tn = #t | |
for i,doctbl in ipairs(args) do | |
t[tn+1]=doctbl | |
end | |
else | |
dt [ v ] = args | |
end | |
return func | |
else | |
error() | |
end | |
end | |
end | |
local value = {} | |
value.type = "table"; | |
value.elements = {} | |
value.elements.type = { | |
type = { "string", "table" }; | |
desc = [[Type of the value or list of types]]; | |
string = { "string", "table", "number", "cdata" }; | |
table = { | |
list = { type="string" , desc=[[type]] }; | |
}; | |
} | |
value.elements.string = { | |
desc = [[]]; | |
type = "table"; | |
table = { | |
elements = { | |
patterns = { | |
type = { "string", "table" }; | |
desc = [[Pattern or list of patterns the string must match]]; | |
table = { | |
list = { type="string" , desc=[[pattern]] }; | |
}; | |
}; | |
}; | |
list = { type="string", desc=[[If present, allowed values]] }; | |
}; | |
} | |
value.elements.number = { | |
desc = [[ | |
Condition or space seperated string of conditions for the number; or table of the former. | |
int: number is an integer (x%1 == 0) | |
>x: number is larger than x | |
<x: number is smaller than x | |
>=x: number is larger than or equal to x | |
<=x: number is smaller than or equal to x | |
==x: number is equal to x | |
eg. "int >=0" for a positive integer | |
]]; | |
type = { "string" , "table" }; | |
table = { | |
list = { type="string", desc=[[condition(s) for number]] }; | |
}; | |
} | |
value.elements.table = { | |
desc = [[]]; | |
type = "table"; | |
table = { | |
elements = { | |
elements = { type="table" , desc = [[Key/value in the table]] ; | |
table = { | |
elements = { | |
{ type="table" , table=value, desc=[[Value]] }; | |
}; | |
list = { type="table", table=value, desc=[[Allowed value types for elements not in element table]] }; | |
}; | |
}; | |
list = { type="table", table=value, desc=[[Contents of list part of table]] }; | |
}; | |
}; | |
} | |
value.elements.cdata = { | |
desc = [[cdata type or list of cdata types]]; | |
type = { "string", "table" }; | |
table = { | |
list= { type="string", desc=[[cdata type]] }; | |
}; | |
}; | |
local doctbl = { | |
elements = { | |
desc = { type={ "string", "nil" }, desc=[[Description]] }; | |
method = { desc=[[Specify the class this function is a method of; the class does not need to be specified in params.]] }; | |
params = { type="table", desc=[[Parameters]], table={ | |
elements = { vararg={ type="number", number={"int",">0"}, desc=[[From which element does a vararg start]] } }; | |
list = value; | |
} }; | |
returns = { type="table", desc=[[Return values]], table={list=value} }; | |
}; | |
} | |
doc{ | |
desc = [[Adds documentation for a function, call with any number of documentation tables]] ; | |
params = { | |
vararg = 1; | |
{ type="table", table=doctbl, desc=[[Documentation table(s) to be added]] }; | |
}; | |
returns = { | |
{ type="function", desc=[[Call this function with the object to document.]], | |
["function"]={ desc = [[Call with your object to document it.]]; | |
params = {{ [[object]] }}; | |
returns = {{ param=1 }}; | |
}; | |
}; | |
}; | |
}(doc) | |
local function adddef ( out , ... ) | |
local arg = { ... } | |
local n = out.n | |
local maxi = 0 | |
for i , v in ipairs(arg) do | |
out[n+i] = "<dd>" .. v .. "</dd>" | |
maxi = i | |
end | |
out.n = n+maxi | |
end | |
local function newdef ( out , item , ... ) | |
local n = out.n | |
out[n+1] = "<dt>" .. item .. "</dt>" | |
out.n = n+1 | |
if ... then | |
return adddef ( out , ... ) | |
end | |
end | |
local function newlist ( out ) | |
out.level = out.level+1 | |
local n = out.n | |
out[n+1] = "<dd><dl>" | |
out.n = n+1 | |
end | |
local function endlist ( out ) | |
local n = out.n | |
out[n+1] = "</dl></dd>" | |
out.n = n+1 | |
out.level = out.level-1 | |
end | |
local function concat ( out ) | |
local v = table.concat ( out , "" , 1 , out.n ) | |
out [ 1 ] = v | |
out.n = 1 | |
return v | |
end | |
local htmlmt = { | |
__index = { | |
newdef = newdef; | |
adddef = adddef; | |
newlist = newlist; | |
endlist = endlist; | |
concat = concat; | |
}; | |
__tostring = concat; | |
} | |
local function newhtml () | |
return setmetatable({n=0,level=0},htmlmt) | |
end | |
--[[ | |
<html> | |
<body> | |
</body> | |
</html]] | |
local function strpack ( o ) | |
local typ = type(o) | |
if typ == "string" then | |
return { o } | |
elseif typ == "table" then | |
for i , v in ipairs(o) do | |
assert(type(v) == "string","Not a string") | |
end | |
return o | |
else | |
error("Not a string or sequence of strings",2) | |
end | |
end | |
local function stringval ( val ) | |
local out = {"<ul>"} | |
local vt = strpack(val.type) | |
for i , typ in ipairs(vt) do | |
out [ #out + 1 ] = "<li><span class=type>" .. typ .. "</span>" | |
if typ == "nil" then | |
elseif typ == "number" then | |
elseif typ == "string" then | |
local dt = val[typ] or {} | |
local matches = {} | |
for i , value in ipairs(dt) do | |
matches [ #matches + 1 ] = "<span class=literal>" .. value .. "</span>" | |
end | |
for i , value in ipairs(strpack(dt.patterns or {})) do | |
matches [ #matches + 1 ] = "<span class=pattern>" .. value .. "</span>" | |
end | |
out [ #out + 1 ] = table.concat ( explicitvals , "|" ) | |
elseif typ == "table" then | |
elseif typ == "cdata" then | |
elseif typ == "function" then | |
else | |
error("Invalid type") | |
end | |
out [ #out + 1 ] = "</li>" | |
end | |
out [ #out + 1 ] = "</ul>" | |
return table.concat(out) | |
end | |
local function html ( tbl ) | |
local out = newhtml() | |
for name , v in pairs(tbl) do | |
local t = dt[v] | |
if t then | |
out:newdef(name) | |
out:newlist() | |
for i , doctbl in ipairs(t) do | |
out:newdef("Doctbl #"..i) | |
out:newlist() | |
if doctbl.desc then | |
out:newdef("Description",doctbl.desc) | |
end | |
out:newdef("Parameters") | |
for argi , argv in ipairs ( doctbl.params ) do | |
out:adddef( stringval(argv) ) | |
end | |
if doctbl.params.vararg then | |
out:adddef( "..." ) | |
end | |
out:newdef("Return Values") | |
for argi , argv in ipairs ( doctbl.returns ) do | |
out:adddef( stringval(argv) ) | |
end | |
out:endlist() | |
end | |
out:endlist() | |
end | |
end | |
print(out:concat()) | |
end | |
html({doc=doc}) | |
return { | |
doc = doc ; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment