mirror of
https://github.com/lxsang/antd-web-apps
synced 2025-02-22 18:22:47 +01:00
commit
f684005fe4
@ -296,4 +296,10 @@ td.hljs-ln-numbers {
|
|||||||
/* for block of code */
|
/* for block of code */
|
||||||
.hljs-ln td.hljs-ln-code {
|
.hljs-ln td.hljs-ln-code {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
model-viewer{
|
||||||
|
/*border: 1px solid #333f67;*/
|
||||||
|
width: 100%;
|
||||||
|
height: 350px;
|
||||||
}
|
}
|
@ -1,12 +1,47 @@
|
|||||||
BaseController:subclass("DocController")
|
BaseController:subclass("DocController")
|
||||||
|
|
||||||
local getpath = function(vfspath, controller)
|
local getpath = function(vfspath, controller)
|
||||||
return vfspath:gsub(controller.path_map.vfs_path, controller.path_map.local_path)
|
return vfspath:gsub(controller.path_map.vfs_path,
|
||||||
|
controller.path_map.local_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local pre_process_md = function(str, obj)
|
||||||
|
local content = str
|
||||||
|
for capture in str:gmatch("(%[%[@book:image:[^\n%]]*%]%])") do
|
||||||
|
local apath = capture:match("%[%[@book:image:([^\n%]]*)%]%]")
|
||||||
|
local pattern = capture:gsub("%[", "%%["):gsub("%]", "%%]")
|
||||||
|
if apath then
|
||||||
|
apath = apath:gsub(" ", "%%%%20")
|
||||||
|
print(apath)
|
||||||
|
content = str:gsub(pattern,
|
||||||
|
"")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return content
|
||||||
|
end
|
||||||
|
|
||||||
|
local post_process_md = function(str, obj)
|
||||||
|
local content = str
|
||||||
|
local has_model = false
|
||||||
|
for capture in str:gmatch("(%[%[@book:3dmodel:[^\n%]]*%]%])") do
|
||||||
|
local apath = capture:match("%[%[@book:3dmodel:([^\n%]]*)%]%]")
|
||||||
|
local pattern = capture:gsub("%[", "%%["):gsub("%]", "%%]")
|
||||||
|
if apath then
|
||||||
|
--apath = utils.urlencode(apath):gsub("%%", "%%%%")
|
||||||
|
apath = apath:gsub(" ", "%%20")
|
||||||
|
content = str:gsub(pattern,
|
||||||
|
"<model-viewer src=\"" .. HTTP_ROOT .. "/" ..
|
||||||
|
obj.name .. "/asset/" .. apath ..
|
||||||
|
"\" auto-rotate camera-controls></model-viewer>")
|
||||||
|
has_model = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return content, has_model
|
||||||
|
end
|
||||||
function DocController:loadTOC()
|
function DocController:loadTOC()
|
||||||
local path = self.path_map.local_path.."/meta.json"
|
local path = self.path_map.local_path .. "/meta.json"
|
||||||
local result = { error = false}
|
local result = {error = false}
|
||||||
if ulib.exists(path) then
|
if ulib.exists(path) then
|
||||||
local bmeta = JSON.decodeFile(path)
|
local bmeta = JSON.decodeFile(path)
|
||||||
if bmeta == nil then
|
if bmeta == nil then
|
||||||
@ -15,39 +50,40 @@ function DocController:loadTOC()
|
|||||||
else
|
else
|
||||||
result.data = {
|
result.data = {
|
||||||
name = bmeta.name,
|
name = bmeta.name,
|
||||||
path = self.path_map.vfs_path.."/INTRO.md",
|
path = self.path_map.vfs_path .. "/INTRO.md",
|
||||||
entries = {},
|
entries = {},
|
||||||
parent = nil
|
parent = nil
|
||||||
}
|
}
|
||||||
-- read all the entries
|
-- read all the entries
|
||||||
for kc,vc in pairs(bmeta.entries) do
|
for kc, vc in pairs(bmeta.entries) do
|
||||||
local cpath = getpath(vc.path, self).."/meta.json"
|
local cpath = getpath(vc.path, self) .. "/meta.json"
|
||||||
if ulib.exists(cpath) then
|
if ulib.exists(cpath) then
|
||||||
local cmeta = JSON.decodeFile(cpath)
|
local cmeta = JSON.decodeFile(cpath)
|
||||||
if cmeta then
|
if cmeta then
|
||||||
local chapter = {
|
local chapter = {
|
||||||
name = cmeta.name,
|
name = cmeta.name,
|
||||||
path = vc.path.."/INTRO.md",
|
path = vc.path .. "/INTRO.md",
|
||||||
tpath = vc.path,
|
tpath = vc.path,
|
||||||
entries = {},
|
entries = {},
|
||||||
parent = result.data,
|
parent = result.data,
|
||||||
id = kc
|
id = kc
|
||||||
}
|
}
|
||||||
-- read all sections
|
-- read all sections
|
||||||
for ks,vs in pairs(cmeta.entries) do
|
for ks, vs in pairs(cmeta.entries) do
|
||||||
local spath = getpath(vs.path, self).."/meta.json"
|
local spath = getpath(vs.path, self) .. "/meta.json"
|
||||||
local smeta = JSON.decodeFile(spath)
|
local smeta = JSON.decodeFile(spath)
|
||||||
if smeta then
|
if smeta then
|
||||||
local section = {
|
local section =
|
||||||
name = smeta.name,
|
{
|
||||||
path = vs.path.."/INTRO.md",
|
name = smeta.name,
|
||||||
tpath = vs.path,
|
path = vs.path .. "/INTRO.md",
|
||||||
entries = {},
|
tpath = vs.path,
|
||||||
parent = chapter,
|
entries = {},
|
||||||
id = ks
|
parent = chapter,
|
||||||
}
|
id = ks
|
||||||
|
}
|
||||||
-- read all files
|
-- read all files
|
||||||
for kf,vf in pairs(smeta.entries) do
|
for kf, vf in pairs(smeta.entries) do
|
||||||
local fpath = getpath(vf.path, self)
|
local fpath = getpath(vf.path, self)
|
||||||
if ulib.exists(fpath) then
|
if ulib.exists(fpath) then
|
||||||
local file = io.open(fpath, "r")
|
local file = io.open(fpath, "r")
|
||||||
@ -55,21 +91,23 @@ function DocController:loadTOC()
|
|||||||
local line = io.read()
|
local line = io.read()
|
||||||
io.close()
|
io.close()
|
||||||
if line then
|
if line then
|
||||||
local file = {
|
local file =
|
||||||
name = std.trim(std.trim(line, "#"), " "),
|
{
|
||||||
path = vf.path,
|
name = std.trim(
|
||||||
tpath = vf.path,
|
std.trim(line, "#"), " "),
|
||||||
parent = section,
|
path = vf.path,
|
||||||
id = kf
|
tpath = vf.path,
|
||||||
}
|
parent = section,
|
||||||
table.insert( section.entries, file)
|
id = kf
|
||||||
|
}
|
||||||
|
table.insert(section.entries, file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert( chapter.entries, section)
|
table.insert(chapter.entries, section)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert( result.data.entries, chapter)
|
table.insert(result.data.entries, chapter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -101,19 +139,22 @@ function DocController:index(...)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
toc.cpath = self.path_map.vfs_path
|
toc.cpath = self.path_map.vfs_path
|
||||||
path = self.path_map.local_path.."/INTRO.md"
|
path = self.path_map.local_path .. "/INTRO.md"
|
||||||
end
|
end
|
||||||
if path and ulib.exists(path) then
|
if path and ulib.exists(path) then
|
||||||
|
local has_3d = false
|
||||||
local file = io.open(path, "r")
|
local file = io.open(path, "r")
|
||||||
local content = ""
|
local content = ""
|
||||||
local md = require("md")
|
local md = require("md")
|
||||||
local callback = function(s)
|
local callback = function(s) content = content .. s end
|
||||||
content = content..s
|
md.to_html(pre_process_md(file:read("*a"), self), callback)
|
||||||
end
|
|
||||||
md.to_html(file:read("*a"), callback)
|
|
||||||
file.close()
|
file.close()
|
||||||
|
content, has_3d = post_process_md(content, self)
|
||||||
|
-- replace some display plugins
|
||||||
|
|
||||||
self.template:setView("index", "index")
|
self.template:setView("index", "index")
|
||||||
self.template:set("data", content)
|
self.template:set("data", content)
|
||||||
|
self.template:set("has_3d", has_3d)
|
||||||
else
|
else
|
||||||
self.template:setView("notfound", "index")
|
self.template:setView("notfound", "index")
|
||||||
end
|
end
|
||||||
@ -127,11 +168,11 @@ function DocController:search(...)
|
|||||||
local cmd = "grep -ri --include=\\*.md "
|
local cmd = "grep -ri --include=\\*.md "
|
||||||
local arr = explode(query, " ")
|
local arr = explode(query, " ")
|
||||||
local patterns = {}
|
local patterns = {}
|
||||||
for k,v in ipairs(arr) do
|
for k, v in ipairs(arr) do
|
||||||
local world = std.trim(v, " ")
|
local world = std.trim(v, " ")
|
||||||
if v and v ~= "" then
|
if v and v ~= "" then
|
||||||
cmd = cmd.." -e '"..v.."' "
|
cmd = cmd .. " -e '" .. v .. "' "
|
||||||
table.insert( patterns,v:lower())
|
table.insert(patterns, v:lower())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #patterns > 0 then
|
if #patterns > 0 then
|
||||||
@ -139,7 +180,7 @@ function DocController:search(...)
|
|||||||
toc.controller = self.name
|
toc.controller = self.name
|
||||||
self.template:set("toc", toc)
|
self.template:set("toc", toc)
|
||||||
self.template:setView("search", "index")
|
self.template:setView("search", "index")
|
||||||
cmd = cmd..self.path_map.local_path
|
cmd = cmd .. self.path_map.local_path
|
||||||
local handle = io.popen(cmd)
|
local handle = io.popen(cmd)
|
||||||
local result = {}
|
local result = {}
|
||||||
for line in handle:lines() do
|
for line in handle:lines() do
|
||||||
@ -148,11 +189,13 @@ function DocController:search(...)
|
|||||||
if not result[file] then
|
if not result[file] then
|
||||||
result[file] = {}
|
result[file] = {}
|
||||||
end
|
end
|
||||||
local content = line:gsub("^[^:]*:",""):lower()
|
local content = line:gsub("^[^:]*:", ""):lower()
|
||||||
for k,p in ipairs(patterns) do
|
for k, p in ipairs(patterns) do
|
||||||
content = content:gsub(p, "<span class='pattern'>"..p.."</span>")
|
content = content:gsub(p,
|
||||||
|
"<span class='pattern'>" .. p ..
|
||||||
|
"</span>")
|
||||||
end
|
end
|
||||||
table.insert(result[file],content)
|
table.insert(result[file], content)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
handle:close()
|
handle:close()
|
||||||
@ -170,26 +213,43 @@ function DocController:search(...)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function DocController:asset(...)
|
||||||
|
local args = {...}
|
||||||
|
if #args == 0 then return self:actionnotfound(table.unpack(args)) end
|
||||||
|
|
||||||
|
local path = self.path_map.local_path .. "/" .. implode(args, DIR_SEP)
|
||||||
|
|
||||||
|
if self.registry.fileaccess and ulib.exists(path) then
|
||||||
|
local mime = std.mimeOf(path)
|
||||||
|
print(mime)
|
||||||
|
if POLICY.mimes[mime] then
|
||||||
|
std.sendFile(path)
|
||||||
|
else
|
||||||
|
self:error("Access forbidden: " .. path)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:error("Asset file not found or access forbidden: " .. path)
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
function DocController:api(...)
|
function DocController:api(...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
if not self.path_map.api_path then
|
if not self.path_map.api_path then
|
||||||
return self:actionnotfound(table.unpack(args))
|
return self:actionnotfound(table.unpack(args))
|
||||||
end
|
end
|
||||||
local rpath = "index.html"
|
local rpath = "index.html"
|
||||||
if #args ~= 0 then
|
if #args ~= 0 then rpath = implode(args, "/") end
|
||||||
rpath = implode(args,"/")
|
local path = self.path_map.api_path .. "/" .. rpath
|
||||||
end
|
|
||||||
local path = self.path_map.api_path.."/"..rpath
|
|
||||||
|
|
||||||
if ulib.exists(path) then
|
if ulib.exists(path) then
|
||||||
local mime = std.mimeOf(path)
|
local mime = std.mimeOf(path)
|
||||||
if POLICY.mimes[mime] then
|
if POLICY.mimes[mime] then
|
||||||
std.sendFile(path)
|
std.sendFile(path)
|
||||||
else
|
else
|
||||||
self:error("Access forbidden: "..path)
|
self:error("Access forbidden: " .. path)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:error("File not found or access forbidden: "..path)
|
self:error("File not found or access forbidden: " .. path)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -197,4 +257,4 @@ end
|
|||||||
function DocController:actionnotfound(...)
|
function DocController:actionnotfound(...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
return self:index(table.unpack(args))
|
return self:index(table.unpack(args))
|
||||||
end
|
end
|
||||||
|
@ -22,6 +22,8 @@ POST_LIMIT = 10
|
|||||||
-- require needed library
|
-- require needed library
|
||||||
require(BASE_FRW.."silk.api")
|
require(BASE_FRW.."silk.api")
|
||||||
|
|
||||||
|
POLICY.mimes["model/gltf-binary"] = true
|
||||||
|
|
||||||
if REQUEST.r then
|
if REQUEST.r then
|
||||||
REQUEST.r = REQUEST.r:gsub("%:", "/")
|
REQUEST.r = REQUEST.r:gsub("%:", "/")
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?lua
|
<?lua
|
||||||
local tocdata = __main__:get("toc")
|
local tocdata = __main__:get("toc")
|
||||||
local elinks = __main__:get("elinks")
|
local elinks = __main__:get("elinks")
|
||||||
|
local has_3d = __main__:get("has_3d")
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@ -13,10 +14,14 @@ local elinks = __main__:get("elinks")
|
|||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
type="text/css"
|
type="text/css"
|
||||||
href="<?=HTTP_ROOT?>/rst/katex/katex.min.css" />
|
href="<?=HTTP_ROOT?>/rst/katex/katex.min.css" />
|
||||||
<!--script
|
<?lua
|
||||||
type="text/javascript"
|
if has_3d then
|
||||||
src="<?=HTTP_ROOT?>/rst/gscripts/showdown.min.js"
|
?>
|
||||||
></script-->
|
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
|
||||||
|
<script nomodule src="https://unpkg.com/@google/model-viewer/dist/model-viewer-legacy.js"></script>
|
||||||
|
<?lua
|
||||||
|
end
|
||||||
|
?>
|
||||||
<script
|
<script
|
||||||
src="<?=HTTP_ROOT?>/rst/hljs/highlight.pack.js"
|
src="<?=HTTP_ROOT?>/rst/hljs/highlight.pack.js"
|
||||||
></script>
|
></script>
|
||||||
|
@ -19,5 +19,9 @@
|
|||||||
"wasm": {
|
"wasm": {
|
||||||
"mime": "application/wasm",
|
"mime": "application/wasm",
|
||||||
"binary": true
|
"binary": true
|
||||||
|
},
|
||||||
|
"glb": {
|
||||||
|
"mime": "model/gltf-binary",
|
||||||
|
"binary": true
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user