-- vim: ft=terra
local page = lib.srv.convo.page
local pstr = lib.mem.ptr(int8)
local pref = lib.mem.ref(int8)
local P = lib.str.plit
local R = lib.str.lit
local topics = lib.util.keys(data.doc)
local topicidxt = {}
table.sort(topics) -- because deterministic builds are good
local branches = {}
for i,k in pairs(topics) do
topicidxt[k] = i
local par = data.doc[k].meta.parent
if par then
branches[par] = branches[par] or {}
local br = branches[par]
br[#br+1] = k
end
end
local struct pgpair {
content:page name:pref title:pref
priv:lib.store.powerset parent:intptr
}
local pages = symbol(pgpair[#topics])
local allpages = {}
for i,v in ipairs(topics) do
local t = data.doc[v]
local par = 0
if t.meta.parent then par = topicidxt[t.meta.parent] end
local restrict = symbol(lib.store.powerset)
local setbits = quote restrict:clear() end
if t.meta.priv then
if type(t.meta.priv) ~= 'table' then t.meta.priv = {t.meta.priv} end
for _,v in pairs(t.meta.priv) do
setbits = quote [setbits]; (restrict.[v] << true) end
end
end
allpages[i] = quote var [restrict]; [setbits] in pgpair {
name = R(v);
parent = par;
priv = restrict;
title = R(t.meta.title);
content = page {
title = ['documentation :: ' .. t.meta.title];
body = [ t.text ];
class = P'doc article';
cache = true;
};
} end
end
local terra
showpage(co: &lib.srv.convo, id: pref)
var [pages] = array([allpages])
for i=0,[pages.type.N] do
if pages[i].name:cmp(id) then
co:stdpage(pages[i].content)
return
end
end -- else
co:complain(404,'not found', 'no help article with that identifier is available')
end
local terra
pushbranches(list: &lib.str.acc, idx: intptr, ps: lib.store.powerset): {}
var [pages] = array([allpages])
var started = false
for i=0,[pages.type.N] do
if pages[i].parent == idx+1 and (pages[i].priv:sz() == 0 or
(ps and pages[i].priv):sz() ~= 0) then
if not started then
started = true
list:lpush('<ol>')
end
list:lpush('<li><a accesskey="'):ipush(i):lpush('" href="/doc/'):rpush(pages[i].name):lpush('">')
:rpush(pages[i].title):lpush('</a>')
pushbranches(list, i, ps)
list:lpush('</li>')
end
end
if started then list:lpush('</ol>') end
end
local terra
render_docpage(co: &lib.srv.convo, pg: pref)
var nullprivs: lib.store.powerset nullprivs:clear()
if not pg then -- display index
var list = co:stra(256)
list:lpush('<ul>')
var [pages] = array([allpages])
for i=0,[pages.type.N] do
if pages[i].parent == 0 and (pages[i].priv:sz() == 0 or
(co.aid ~= 0 and (co.who.rights.powers
and pages[i].priv):sz() > 0)) then
list:lpush('<li><a href="/doc/'):rpush(pages[i].name):lpush('">')
:rpush(pages[i].title):lpush('</a>')
if co.aid ~= 0 then
pushbranches(&list, i, co.who.rights.powers)
else
pushbranches(&list, i, nullprivs)
end
list:lpush('</li>')
end
end
list:lpush('</ul>')
co:stdpage(page {
title = 'documentation';
body = list:finalize();
class = P'doc listing';
cache = false;
})
else showpage(co, pg) end
end
return render_docpage