diff --git a/Makefile b/Makefile
index 558ee352bf..c90f11fc9d 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,10 @@ hostclean: clean
apidocs: hostenv
build/hostenv.sh $(realpath host) $(LUA_MODULEDIR) $(LUA_LIBRARYDIR) "build/makedocs.sh host/luci/ docs"
+uvldocs: hostenv
+ build/hostenv.sh $(realpath host) $(LUA_MODULEDIR) $(LUA_LIBRARYDIR) \
+ "build/uvldoc $(realpath host) $(UVL_SCHEMEDIR) uvldocs $(DOCS)"
+
run:
# make run is deprecated #
# Please use: #
diff --git a/build/config.mk b/build/config.mk
index 6f54ce591e..bac250d728 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -8,6 +8,9 @@ LUA_LIBRARYDIR = /usr/lib/lua
LUCI_MODULEDIR = $(LUA_MODULEDIR)/luci
LUCI_LIBRARYDIR = $(LUA_LIBRARYDIR)/luci
+UVL_SCHEMEDIR = host/lib/uci/schema
+
HTDOCS = /www
+LUA=$(shell which lua)
XSLTPROC=$(shell which xsltproc)
diff --git a/build/uvldoc b/build/uvldoc
new file mode 100755
index 0000000000..a6e9cc8e61
--- /dev/null
+++ b/build/uvldoc
@@ -0,0 +1,24 @@
+#!/usr/bin/env lua
+local fs = require "luci.fs"
+local util = require "luci.util"
+local uvldoc = require "luci.uvldoc.renderer"
+
+pcall(function()
+ require "uci"
+ require "luci.model.uci".cursor = function(config, save)
+ return uci.cursor(config or arg[1] .. "/etc/config", save or arg[1] .. "/tmp/.uci")
+ end
+end)
+
+local schemes = {}
+if not arg[4] or #arg[4] == 0 then
+ for i, name in ipairs(fs.dir(arg[2].."/default/")) do
+ if name ~= "." and name ~= ".." then
+ schemes[#schemes+1] = name
+ end
+ end
+else
+ schemes = util.split(arg[4], "[,;%s]+", nil, true)
+end
+
+uvldoc.Generator(schemes, arg[3], arg[2]):make()
diff --git a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/index.xml b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/index.xml
index 6fbfa374de..269c7989a0 100644
--- a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/index.xml
+++ b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/index.xml
@@ -1,6 +1,7 @@
<%+header.xml%>
-
UCI Documentation
-
+UCI Documentation
+Configurations
+
<% for k, v in luci.util.kspairs(self.schemes) do %>
<%=k%> |
diff --git a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/menu.xml b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/menu.xml
index 7a03002694..bfe8c45ca0 100644
--- a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/menu.xml
+++ b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/menu.xml
@@ -1,5 +1,5 @@
-LuCI UVLDoc
-
+
+
\ No newline at end of file
diff --git a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/scheme.xml b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/scheme.xml
index 985809e770..91043bfc83 100644
--- a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/scheme.xml
+++ b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/scheme.xml
@@ -1,2 +1,15 @@
<%+header.xml%>
+<%=scheme-%>
+<%-if package.title then%>: <%=package.title%><%end%>
+<%=package.description%>
+
+Sections:
+
+<% for k, v in luci.util.kspairs(package.sections) do %>
+
+ <%=k%> |
+ <%=v.title%> |
+
+<% end %>
+
<%+footer.xml%>
\ No newline at end of file
diff --git a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/section.xml b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/section.xml
index 985809e770..e5c4b3e667 100644
--- a/libs/uvldoc/luasrc/uvldoc/proto/xhtml/section.xml
+++ b/libs/uvldoc/luasrc/uvldoc/proto/xhtml/section.xml
@@ -1,2 +1,153 @@
<%+header.xml%>
+<%
+local table = require "table"
+
+function _parse_ref( r )
+ local k, v = r:match("([^.]+)%.([^.]+)")
+ return k and self:_section_filename(k, v)
+end
+
+function _parse_dep( r, c, s, o )
+ local ref = { }
+ local vars = {
+ config = c,
+ section = s,
+ option = o
+ }
+
+ for v in r:gmatch("[^.]+") do
+ ref[#ref+1] = (v:gsub( "%$(.+)", vars ))
+ end
+
+ if #ref < 2 then
+ table.insert(ref, 1, s or '$section')
+ end
+ if #ref < 3 then
+ table.insert(ref, 1, c or '$config')
+ end
+
+ return self:_variable_target(unpack(ref))
+end
+
+%>
+<%=scheme-%>
+<%-if package.title then%>: <%=package.title%><%end%>
+<%=type-%>
+<%-if section.title then%>: <%=section.title%><%end%>
+<%=section.description%>
+
+Attributes:
+
+<%-
+if section.required then %>
+ - required: A section of this type is required.
+<% end
+if section.unique then %>
+ - unique: There can be only one section of this type.
+<%- else -%>
+ - multiple: There can be more than one section of this type.
+<% end
+if section.dynamic then %>
+ - dynamic: Sections of this type may contain user-defined options.
+<% end
+if section.named then %>
+ - named: Sections of this type require a name.
+<% end -%>
+
+
+<% if section.depends then %>
+ Requirements (one of):
+
+ <% for i, d in ipairs(section.depends) do
+ local nf = false%>
+ -
+ <% for k2, v in luci.util.kspairs(d) do
+ local t = _parse_dep(k2, scheme, type)
+ %>
+ <% if nf then %>and<% end %>
+ <%if t then%><%end%><%=k2%><%if t then%><%end%><%if v~="" then%>=<%=v%><%end%>
+ <% nf = true
+ end %>
+
+ <% end %>
+
+<% end %>
+
+Options:
+
+<% for k, v in luci.util.kspairs(package.variables[type]) do
+if v.required then%>
+
+ <%=k%> |
+ <%=v.title%> |
+
+<% end end
+for k, v in luci.util.kspairs(package.variables[type]) do
+if not v.required then%>
+
+ <%=k%> |
+ <%=v.title%> |
+
+<% end end %>
+
+
+Options:
+<%-
+for i=0, 1 do
+for k, v in luci.util.kspairs(package.variables[type]) do
+if (i==0) == v.required then
+%>
+
+
+
+
<%=k-%>
+ <%-if v.title then%>: <%=v.title%><%end%>
+
<%=v.description%>
+
Attributes:
+
+ <% if v.required then %>
+ - required
+ <% end %>
+ - Type: <%=v.type%>
+ - Datatype: <%=v.datatype%>
+
+ <% if v.depends then %>
+
Dependencies (one of):
+
+ <% for i, d in ipairs(v.depends) do
+ local nf = false %>
+ -
+ <% for k2, v in luci.util.kspairs(d) do
+ local t = _parse_dep(k2, scheme, type, k)
+ %>
+ <% if nf then %>and<% end %>
+ <%if t then%><%end%><%=k2%><%if t then%><%end%><%if v~="" then%>=<%=v%><%end%>
+ <% nf = true
+ end %>
+
+ <% end %>
+
+ <% end %>
+ <% if v.type == "enum" then %>
+
Possible Values:
+
+ <% for k, d in pairs(v.values) do %>
+ - <%=k%><%if d then%> (<%=d%>)<%end%>
+ <% end %>
+
+ <% elseif v.type == "reference" then %>
+
Value references:
+
+ <% end %>
+
+<% end end end -%>
<%+footer.xml%>
\ No newline at end of file
diff --git a/libs/uvldoc/luasrc/uvldoc/renderer.lua b/libs/uvldoc/luasrc/uvldoc/renderer.lua
index f881032c20..27061d22d8 100644
--- a/libs/uvldoc/luasrc/uvldoc/renderer.lua
+++ b/libs/uvldoc/luasrc/uvldoc/renderer.lua
@@ -20,7 +20,7 @@ local util = require "luci.util"
local ltn12 = require "luci.ltn12"
local template = require "luci.template"
-local ipairs, getfenv, pairs, require = ipairs, getfenv, pairs, require
+local ipairs, getfenv, pairs, require, unpack = ipairs, getfenv, pairs, require, unpack
local luci = luci
module "luci.uvldoc.renderer"
@@ -28,7 +28,7 @@ module "luci.uvldoc.renderer"
Generator = util.class()
-function Generator.__init__(self, schemes, output)
+function Generator.__init__(self, schemes, output, uvlpath)
self.names = schemes
self.output = output or "doc"
self.schemes = {}
@@ -55,6 +55,9 @@ function Generator.make(self)
template.viewdir = self.sourcedir
template.context.viewns = {
include = function(name) template.Template(name):render(getfenv(2)) end,
+ pairs = pairs,
+ ipairs = ipairs,
+ unpack = unpack,
luci = luci,
require = require
}
@@ -108,5 +111,14 @@ function Generator._scheme_filename(self, scheme)
end
function Generator._section_filename(self, scheme, section)
- return "section.%s.%s%s" % {scheme, section, self.extension}
+ if self.schemes[scheme] and self.schemes[scheme].sections[section] then
+ return "section.%s.%s%s" % {scheme, section, self.extension}
+ end
end
+
+function Generator._variable_target(self, scheme, section, variable)
+ if self.schemes[scheme] and self.schemes[scheme].variables[section] and
+ self.schemes[scheme].variables[section][variable] then
+ return "section.%s.%s%s#variable.%s" % {scheme, section, self.extension, variable}
+ end
+end
\ No newline at end of file