1
0
mirror of https://github.com/lxsang/antd-web-apps synced 2024-11-19 18:08:21 +01:00

Add Booklet front end

This commit is contained in:
lxsang 2020-06-22 22:14:52 +02:00
parent 16801d947d
commit 44f50f3a52
15 changed files with 486 additions and 4 deletions

View File

@ -1,5 +1,5 @@
BUILDDIR?=./build
PROJS?=grs info blog apps os
PROJS?=grs info blog apps os doc
copyfiles = index.ls mimes.json
main: copy
for f in $(PROJS); do BUILDDIR=$(BUILDDIR)/"$${f}" make -C "$${f}" ; done

View File

@ -125,7 +125,7 @@
</div>
</div>
<div id = "bottom">
Powered by antd server, (c) 2017 - 2018 Xuan Sang LE
Powered by antd server, (c) 2017 - <?=os.date("*t").year?> Xuan Sang LE
</div>
</body>
</html>

6
doc/Makefile Normal file
View File

@ -0,0 +1,6 @@
copyfiles = views controllers router.lua assets
main:
- mkdir $(BUILDDIR)
cp -rvf $(copyfiles) $(BUILDDIR)
- cd $(BUILDDIR) && ln -s ../grs ./rst

164
doc/assets/style.css Normal file
View File

@ -0,0 +1,164 @@
html,body{
margin: 0;
padding: 0;
font-family: "Ubuntu";
font-size: 15px;
line-height: 1.5;
width: 100%;
height: 100%;
overflow: hidden;
}
#top{
background-color: #2c2c2c;
color: white;
font-weight: bold;
display: block;
text-align: center;
height: 30px;
}
#bottom{
position: fixed;
bottom: 0;
height: 20px;
text-align: center;
color:#878887;
background-color: white;
font-size: 12px;
width: 100%;
padding:5px;
border-top: 1px solid #878887;
}
#cover{
height: calc(100% - 80px);
overflow-y: auto;
}
#navbar{
margin:0 auto;
max-width: 85%;
display: flex;
justify-content:flex-end;
flex-direction: row;
}
#book{
margin:0 auto;
max-width: 85%;
max-height: 100%;
display: block;
justify-content:flex-end;
flex-direction: row;
text-align: justify;
height: 100%;
}
div.doc-name {
width: 300px;
text-align: left;
padding-top:3px;
}
div.doc-name a {
text-decoration: none;
color: #c9c9c9;
}
div.doc-name a:before{
/* padding-top:13px; */
content: "\f015";
color:#c9c9c9;
width:20px;
height: 25px;
font-family: "FontAwesome";
font-size: 18px;
}
input.search-box{
outline: none;
border: 0;
flex:1;
padding:0;
margin:0;
/* padding-top:13px; */
height: 25px;
background-color: transparent;
border-bottom: 1px solid #878887;
font-size: 15px;
font-family: "Ubuntu";
line-height: 0.5;
color: #878887;
}
div.search-icon:before{
/* padding-top:13px; */
content: "\f002";
color:#878887;
display: block;
width:20px;
height: 25px;
font-family: "FontAwesome";
font-size: 18px;
border-bottom: 1px solid #878887;
}
div.search-icon {
width: 35px;
}
div.doc-toc {
width: 300px;
/* font-size: 11px; */
background-color: #e3e3e3;
color: #2c2c2c;
overflow: auto;
position: fixed;
top: 30px;
bottom: 30px;
border-right: 1px solid #c9c9c9;
padding-top: 10px;
}
div.doc-toc a {
text-decoration: none;
color: #2c2c2c;
}
#toc {
margin: 0;
list-style-type: none;
padding: 0;
padding-left: 10px;
}
div.doc-toc ul.nested {
list-style-type: none;
}
div.doc-toc .caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
}
div.doc-toc .caret::before {
content: "\f147";
color: #2c2c2c;
display: inline-block;
font-family: "FontAwesome";
margin-right: 5px;
}
div.doc-toc .nested {
display: none;
}
div.doc-toc .caret-down::before {
content: "\f196";
color: #2c2c2c;
display: inline-block;
font-family: "FontAwesome";
margin-right: 5px;
}
div.doc-toc .active {
display: block;
padding-left: 20px;
}
div.doc-content {
display: block;
width: calc(100% - 320px);
float: right;
}
/* for block of code */
/* #container .blogentry .hljs-ln td.hljs-ln-code {
padding-left: 10px;
} */
img {max-width:100%}

View File

@ -0,0 +1,8 @@
require(CONTROLLER_ROOT..".doccontroller")
DocController:subclass("AntosController", {
path_map = {
vfs_path = "home://testws/antos",
local_path = "/home/mrsang/testws/antos"
},
name = "antos"
})

View File

@ -0,0 +1,10 @@
BaseController:subclass("IndexController")
function IndexController:index(...)
return true
end
function IndexController:actionnotfound(...)
self.template:setView("index")
return self:index(table.unpack({...}))
end

View File

@ -0,0 +1,5 @@
BaseController:subclass("TocController")
function TocController:index(...)
return true
end

View File

@ -0,0 +1,107 @@
BaseController:subclass("DocController")
local getpath = function(vfspath, controller)
return vfspath:gsub(controller.path_map.vfs_path, controller.path_map.local_path)
end
function DocController:loadTOC()
local path = self.path_map.local_path.."/meta.json"
local result = { error = false}
if ulib.exists(path) then
local bmeta = JSON.decodeFile(path)
if bmeta == nil then
result.error = true
result.data = "Unable to read book meta.json"
else
result.data = {
name = bmeta.name,
path = self.path_map.vfs_path.."/INTRO.md",
entries = {}
}
-- read all the entries
for kc,vc in pairs(bmeta.entries) do
local cpath = getpath(vc.path, self).."/meta.json"
if ulib.exists(cpath) then
local cmeta = JSON.decodeFile(cpath)
if cmeta then
local chapter = {
name = cmeta.name,
path = vc.path.."/INTRO.md",
entries = {}
}
-- read all sections
for ks,vs in pairs(cmeta.entries) do
local spath = getpath(vs.path, self).."/meta.json"
local smeta = JSON.decodeFile(spath)
if smeta then
local section = {
name = smeta.name,
path = vs.path.."/INTRO.md",
entries = {}
}
-- read all files
for kf,vf in pairs(smeta.entries) do
local fpath = getpath(vf.path, self)
if ulib.exists(fpath) then
local file = io.open(fpath, "r")
io.input(file)
local line = io.read()
io.close()
if line then
local file = {
name = std.trim(std.trim(line, "#"), " "),
path = vf.path
}
table.insert( section.entries, file)
end
end
end
table.insert( chapter.entries, section)
end
end
table.insert( result.data.entries, chapter)
end
end
end
end
else
result.error = true
result.data = "No meta-data found"
end
return result
end
function DocController:index(...)
local args = {...}
local toc = self:loadTOC()
toc.controller = self.name
self.template:set("toc", toc)
-- read data from the parameter
local path = nil
if args[1] then
local b64text = args[1]
if b64text then
local p = bytes.__tostring(std.b64decode(b64text .. "=="))
if p then
path = getpath(p, self)
end
end
else
path = self.path_map.local_path.."/INTRO.md"
end
if path and ulib.exists(path) then
local file = io.open(path, "r")
local content = file:read("*a")
file.close()
self.template:setView("index", "index")
self.template:set("data", content)
else
self.template:setView("notfound", "index")
end
return true
end
function DocController:actionnotfound(...)
local args = {...}
return self:index(table.unpack(args))
end

52
doc/router.lua Normal file
View File

@ -0,0 +1,52 @@
-- the rewrite rule for the framework
-- should be something like this
-- ^\/apps\/+(.*)$ = /apps/router.lua?r=<1>&<query>
-- some global variables
DIR_SEP = "/"
WWW_ROOT = __ROOT__.."/doc"
if HEADER.Host then
HTTP_ROOT= "https://"..HEADER.Host
else
HTTP_ROOT = "https://doc.iohub.dev"
end
-- class path: path.to.class
BASE_FRW = ""
-- class path: path.to.class
CONTROLLER_ROOT = BASE_FRW.."doc.controllers"
MODEL_ROOT = BASE_FRW.."doc.models"
-- file path: path/to/file
VIEW_ROOT = WWW_ROOT..DIR_SEP.."views"
LOG_ROOT = WWW_ROOT..DIR_SEP.."logs"
POST_LIMIT = 10
-- require needed library
require(BASE_FRW.."silk.api")
if REQUEST.r then
REQUEST.r = REQUEST.r:gsub("%:", "/")
end
-- registry object store global variables
local REGISTRY = {}
-- set logging level
REGISTRY.logger = Logger:new{ levels = {INFO = false, ERROR = true, DEBUG = false}}
REGISTRY.layout = 'default'
REGISTRY.fileaccess = true
local router = Router:new{registry = REGISTRY}
REGISTRY.router = router
router:setPath(CONTROLLER_ROOT)
--router:route('edit', 'post/edit', "ALL" )
-- example of depedencies to the current main route
-- each layout may have different dependencies
local default_routes_dependencies = {
toc = {
url = "toc/index",
visibility = "ALL"
}
}
router:route('default', default_routes_dependencies )
--router:remap("r", "post")
router:delegate()

View File

@ -0,0 +1,4 @@
<?lua
echo(data)
?>

View File

@ -0,0 +1 @@
404 not found

View File

@ -0,0 +1,93 @@
<?lua
local tocdata = __main__:get("toc")
?>
<!DOCTYPE html>
<html>
<head>
<script
type="text/javascript"
src="<?=HTTP_ROOT?>/rst/gscripts/showdown.min.js"
></script>
<link
rel="stylesheet"
type="text/css"
href="<?=HTTP_ROOT?>/assets/style.css" />
<link
rel="stylesheet"
type="text/css"
href="<?=HTTP_ROOT?>/rst/font-awesome.css" />
<link
rel="stylesheet"
type="text/css"
href="<?=HTTP_ROOT?>/rst/ubuntu-regular.css" />
<title>
<?lua
if tocdata then
echo(tocdata.data.name)
else
echo("Untitled")
end
?>
</title>
</head>
<body>
<div id = "top">
<div id = "navbar">
<div class = "doc-name">
<?lua if tocdata then ?>
<a href ="<?=HTTP_ROOT..'/'..tocdata.controller..'/'?>">
<?=tocdata.data.name?>
</a>
<?lua end ?>
</div>
<input type = "text" class = "search-box"></input>
<div class= "search-icon"></div>
</div>
</div>
<div id = "cover">
<div id = "book">
<div class = "doc-toc">
<?lua
if toc then
toc:set("data", tocdata)
toc:render()
end
?>
</div>
<div class="doc-content">
<?lua
if __main__ then
__main__:render()
end
?>
</div>
</div>
</div>
<div id = "bottom">
Powered by antd server, (c) 2019 - <?=os.date("*t").year?> Xuan Sang LE
</div>
<script>
window.onload = function () {
var els = document.getElementsByClassName("doc-content");
var converter = new showdown.Converter();
for (var i in els) {
var text = els[i].innerHTML;
var html = converter.makeHtml(text);
els[i].innerHTML = html;
}
// tree view events
var toggler = document.getElementsByClassName("caret");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("caret-down");
});
}
// TODO math display
};
</script>
</body>
</html>

View File

@ -0,0 +1,31 @@
<?lua
gentree = function(data, controller)
if not data then
return ""
end
local caret = ''
if data.entries then
caret = '<span class = "caret"></span>'
end
local markup = '<li>'..caret..'<a href="'..HTTP_ROOT..'/'..controller..'/'..std.b64encode(data.path):gsub("=","")..'/'..data.name:gsub(" ", "_")..'.md">'..data.name.."</a>"
if data.entries then
markup = markup.."<ul class='nested'>"
for k,v in pairs(data.entries) do
markup = markup..gentree(v, controller)
end
markup = markup.."</ul>"
end
markup = markup.."</li>"
return markup
end
?>
<ul id = "toc">
<?lua
if data.error then
return echo("Unable to read toc")
end
for k,v in pairs(data.data.entries) do
echo(gentree(v, data.controller))
end
?>
</ul>

View File

@ -49,7 +49,7 @@
?>
<div class = "container_footer">
<h1 style="margin:0;"></h1>
<p style="text-align:right; padding:0; margin:0;color:#878887;">Powered by antd server, (C) 2017-2018 Xuan Sang LE</p>
<p style="text-align:right; padding:0; margin:0;color:#878887;">Powered by antd server, (C) 2017-<?=os.date("*t").year?> Xuan Sang LE</p>
</div>
</div>
<?lua

View File

@ -73,7 +73,8 @@ function Router:infer(url)
-- create the coresponding controller
data.controller = _G[controller_name]:new {registry = self.registry}
if not data.controller[data.action] then
data.args = {data.action}
--data.args = {data.action}
table.insert(data.args, 1, data.action)
data.action = "actionnotfound"
end
end