summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-04-19 17:28:27 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-04-19 17:28:27 +0200
commit0bc04866afcb280678aec47daed0716a2a4d17c7 (patch)
tree41892fb3437ba1512fcf8b3a8f0badb3caa9bc78 /scripts
parentd4edb7402ca3c02612ab4d74aab47c17e384d512 (diff)
downloadcontext-0bc04866afcb280678aec47daed0716a2a4d17c7.tar.gz
2016-04-19 17:20:00
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/lua/mtx-server-ctx-help.lua130
-rw-r--r--scripts/context/lua/mtx-server.lua109
2 files changed, 155 insertions, 84 deletions
diff --git a/scripts/context/lua/mtx-server-ctx-help.lua b/scripts/context/lua/mtx-server-ctx-help.lua
index a67d69ffd..a7181e8e1 100644
--- a/scripts/context/lua/mtx-server-ctx-help.lua
+++ b/scripts/context/lua/mtx-server-ctx-help.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['mtx-server-ctx-help'] = {
license = "see context related readme files"
}
-local gsub, find, lower = string.gsub, string.find, string.lower
+local gsub, find, lower, match = string.gsub, string.find, string.lower, string.match
local concat, sort = table.concat, table.sort
dofile(resolvers.findfile("trac-lmx.lua","tex"))
@@ -42,29 +42,41 @@ local f_spans_t = {
}
local f_href_in_list_t = {
- tex = formatters[ [[<a class="setupmenuurl" href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>]] ],
- lua = formatters[ [[<a class="setupmenuurl" href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>]] ],
+ tex = formatters["<a class='setupmenuurl' href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>"],
+ lua = formatters["<a class='setupmenuurl' href='mtx-server-ctx-help.lua?command=%s&mode=%s'>%s</a>"],
+}
+
+local f_href_in_list_i = {
+ tex = formatters["<a class='setupmenucmd' href='mtx-server-ctx-help.lua?command=%s&mode=%s' id='#current'>%s</a>"],
+ lua = formatters["<a class='setupmenucmd' href='mtx-server-ctx-help.lua?command=%s&mode=%s' id='#current'>%s</a>"],
}
local f_href_as_command_t = {
- tex = formatters[ [[<a class="setuplisturl" href='mtx-server-ctx-help.lua?command=%s&mode=%s'>\%s</a>]] ],
- lua = formatters[ [[<a class="setuplisturl" href='mtx-server-ctx-help.lua?command=%s&mode=%s'>context.%s</a>]] ],
+ tex = formatters["<a class='setuplisturl' href='mtx-server-ctx-help.lua?command=%s&mode=%s'>\\%s</a>"],
+ lua = formatters["<a class='setuplisturl' href='mtx-server-ctx-help.lua?command=%s&mode=%s'>context.%s</a>"],
}
local s_modes_t = {
- tex = [[<a class="setupmodeurl" href='mtx-server-ctx-help.lua?mode=lua'>lua mode</a>]],
- lua = [[<a class="setupmodeurl" href='mtx-server-ctx-help.lua?mode=tex'>tex mode</a>]],
+ tex = "<a class='setupmodeurl' href='mtx-server-ctx-help.lua?mode=lua'>lua mode</a>",
+ lua = "<a class='setupmodeurl' href='mtx-server-ctx-help.lua?mode=tex'>tex mode</a>",
+}
+
+local s_views_t = {
+ groups = "<a class='setupviewurl' href='mtx-server-ctx-help.lua?view=names'>names</a>",
+ names = "<a class='setupviewurl' href='mtx-server-ctx-help.lua?view=groups'>groups</a>",
}
-local f_interface = formatters[ [[<a href='mtx-server-ctx-help.lua?interface=%s&mode=%s'>%s</a>]] ]
-local f_source = formatters[ [[<a href='mtx-server-ctx-help.lua?source=%s&mode=%s'>%s</a>]] ]
-local f_keyword = formatters[ [[<tr><td width='15%%'>%s</td><td width='85%%' colspan='2'>%s</td></tr>]] ]
-local f_parameter = formatters[ [[<tr><td width='15%%'>%s</td><td width='15%%'>%s</td><td width='70%%'>%s</td></tr>]] ]
-local f_parameters = formatters[ [[<table width='100%%'>%s</table>]] ]
-local f_listing = formatters[ [[<pre><t>%s</t></listing>]] ]
-local f_special = formatters[ [[<i>%s</i>]] ]
-local f_url = formatters[ [[<tr><td width='15%%'>%s</td><td width='85%%' colspan='2'><i>%s</i>: %s</td></tr>]] ]
-local f_default = formatters[ [[<u>%s</u>]] ]
+local f_interface = formatters["<a href='mtx-server-ctx-help.lua?interface=%s&mode=%s'>%s</a>"]
+local f_source = formatters["<a href='mtx-server-ctx-help.lua?source=%s&mode=%s'>%s</a>"]
+local f_keyword = formatters[" <tr>\n <td width='15%%'>%s</td>\n <td width='85%%' colspan='2'>%s</td>\n </tr>\n"]
+local f_parameter = formatters[" <tr>\n <td width='15%%'>%s</td>\n <td width='15%%'>%s</td>\n <td width='70%%'>%s</td>\n </tr>\n"]
+local f_url = formatters[" <tr>\n <td width='15%%'>%s</td>\n <td width='85%%' colspan='2'><i>%s</i>: %s</td>\n </tr>\n"]
+local f_parameters = formatters["\n<table width='100%%'>\n%s</table>\n"]
+local f_listing = formatters["<pre><t>%s</t></pre>"]
+local f_special = formatters["<i>%s</i>"]
+local f_default = formatters["<u>%s</u>"]
+
+local f_group = formatters["<div class='setupmenugroup'>\n<div class='setupmenucategory'>%s</div>%s</div>"]
local function translate(tag,int,noformat) -- to be checked
local translation = setupstrings[tag]
@@ -135,20 +147,33 @@ local function csname(e,int) -- to be checked
end
local function getnames(root)
- local found = { }
- local names = { }
- for e in xmlcollected(root,'cd:command') do
- local name = e.at.name
- local csname = csname(e,int)
- if not found[csname] then
- names[#names+1] = { name, csname }
- found[csname] = name
- else
- -- variant
+ local found = { }
+ local names = { }
+ local groups = { }
+ for e in xmlcollected(root,'cd:interface/cd:interface') do
+ local category = match(e.at.file or "","^i%-(.*)%.xml$")
+ local list = { }
+ for e in xmlcollected(e,'cd:command') do
+ local name = e.at.name
+ local csname = csname(e,int)
+ if not found[csname] then
+ local t = { name, csname }
+ names[#names+1] = t
+ list[#list+1] = t
+ found[csname] = true
+ else
+ -- variant
+ end
end
+ if #list > 0 then
+ sort(list, function(a,b) return lower(a[2]) < lower(b[2]) end)
+ groups[#groups+1] = { category, list }
+ end
+
end
- sort(names, function(a,b) return lower(a[2]) < lower(b[2]) end)
- return names
+ sort(names, function(a,b) return lower(a[2]) < lower(b[2]) end)
+ sort(groups, function(a,b) return lower(a[1]) < lower(b[1]) end)
+ return names, groups
end
local function getdefinitions(root)
@@ -167,12 +192,14 @@ local loaded = setmetatableindex(function(loaded,interface)
if fullname ~= "" then
local root = xmlload(fullname)
if root then
+ local names, groups = getnames(root)
current = {
- intercace = interface,
+ interface = interface,
filename = filename,
fullname = fullname,
root = root,
- names = getnames(root),
+ names = names,
+ groups = groups,
definitions = getdefinitions(root),
}
end
@@ -461,6 +488,8 @@ local function collect(current,name,int,lastmode)
data.mode = s_modes_t[lastmode or "tex"]
list[#list+1] = data
+ data.view = s_views_t[lastview or "groups"]
+ list[#list+1] = data
end
return list
end
@@ -486,7 +515,7 @@ local variables = {
['title'] = 'ConTeXt Help Information',
}
-local what = { "environment", "category", "source", "mode" }
+local what = { "environment", "category", "source", "mode", "view" }
local function generate(configuration,filename,hashed)
@@ -497,6 +526,7 @@ local function generate(configuration,filename,hashed)
local lastinterface = detail.interface or "en"
local lastcommand = detail.command or ""
+ local lastview = detail.view or "groups"
local lastsource = detail.source or ""
local lastmode = detail.mode or "tex"
@@ -507,13 +537,35 @@ local function generate(configuration,filename,hashed)
local f_div = f_divs_t[lastinterface]
----- f_span = f_spans[lastinterface]
- local names = current.names
- local refs = { }
- local ints = { }
+ local names = current.names
+ local groups = current.groups
+ local refs = { }
+ local ints = { }
+
+ local function addnames(names)
+ local target = { }
+ for k=1,#names do
+ local namedata = names[k]
+ local command = namedata[1]
+ local text = namedata[2]
+ if command == lastcommand then
+ target[#target+1] = f_href_in_list_i[lastmode](command,lastmode,text)
+ else
+ target[#target+1] = f_href_in_list_t[lastmode](command,lastmode,text)
+ end
+ end
+ return concat(target,"<br/>\n")
+ end
- for k=1,#names do
- local v = names[k]
- refs[k] = f_href_in_list_t[lastmode](v[1],lastmode,v[2])
+ if lastview == "groups" then
+ local target = { }
+ for i=1,#groups do
+ local group = groups[i]
+ target[#target+1] = f_group(group[1],addnames(group[2]))
+ end
+ refs = concat(target,"<br/>\n")
+ else
+ refs = addnames(names)
end
if lastmode ~= "lua" then
@@ -524,8 +576,8 @@ local function generate(configuration,filename,hashed)
end
end
- local n = concat(refs,"<br/>")
- local i = concat(ints,"<br/><br/>")
+ local n = refs
+ local i = concat(ints,"<br/><br/>\n")
if f_div then
variables.names = f_div(n)
diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua
index 3fb50829a..448b20ac5 100644
--- a/scripts/context/lua/mtx-server.lua
+++ b/scripts/context/lua/mtx-server.lua
@@ -35,7 +35,15 @@ local application = logs.application {
helpinfo = helpinfo,
}
+local tonumber, tostring, loadfile, type = tonumber, tostring, loadfile, type
+local find, gsub = string.find, string.gsub
+local joinpath, filesuffix, dirname, is_qualified_path = file.join, file.suffix, file.dirname, file.is_qualified_path
+local loaddata = io.loaddata
+local P, C, patterns, lpegmatch = lpeg.P, lpeg.C, lpeg.patterns, lpeg.match
+local formatters = string.formatters
+local urlhashed, urlquery = url.hashed, url.query
local report = application.report
+local gettime = os.gettimeofday or os.clock
scripts = scripts or { }
scripts.webserver = scripts.webserver or { }
@@ -44,7 +52,6 @@ dofile(resolvers.findfile("luat-soc.lua","tex"))
local socket = socket or require("socket")
----- http = http or require("socket.http") -- not needed
-local format = string.format
-- The following two lists are taken from webrick (ruby) and
-- extended with a few extra suffixes.
@@ -154,10 +161,14 @@ local messages = {
[505] = 'HTTP Version Not Supported',
}
+local f_content_length = formatters["Content-Length: %s\r\n"]
+local f_content_type = formatters["Content-Type: %s\r\n"]
+local f_error_title = formatters["<head><title>%s %s</title></head><html><h2>%s %s</h2></html>"]
+
local handlers = { }
local function errormessage(client,configuration,n)
- local data = format("<head><title>%s %s</title></head><html><h2>%s %s</h2></html>",n,messages[n],n,messages[n])
+ local data = f_error_title(n,messages[n],n,messages[n])
report("handling error %s: %s",n,messages[n])
handlers.generic(client,configuration,data,nil,true)
end
@@ -166,42 +177,43 @@ local validpaths, registered = { }, { }
function scripts.webserver.registerpath(name)
if not registered[name] then
- local cleanname = string.gsub(name,"%.%.","deleted-parent")
- report("registering path '%s'",cleanname)
+ local cleanname = gsub(name,"%.%.","deleted-parent")
+ report("registering path: %s",cleanname)
validpaths[#validpaths+1] = cleanname
registered[name] = true
end
end
function handlers.generic(client,configuration,data,suffix,iscontent)
+ local name = data
if not iscontent then
- local name = data
- report("requested file '%s'",name)
- local fullname = file.join(configuration.root,name)
- data = io.loaddata(fullname) or ""
+ report("requested file: %s",name)
+ local fullname = joinpath(configuration.root,name)
+ data = loaddata(fullname) or ""
if data == "" then
for n=1,#validpaths do
- local fullname = file.join(validpaths[n],name)
- data = io.loaddata(fullname) or ""
+ local fullname = joinpath(validpaths[n],name)
+ data = loaddata(fullname) or ""
if data ~= "" then
- report("sending generic file '%s'",fullname)
+ report("sending generic file: %s",fullname)
break
end
end
else
- report("sending generic file '%s'",fullname)
+ report("sending generic file: %s",fullname)
end
end
if data and data ~= "" then
client:send("HTTP/1.1 200 OK\r\n")
client:send("Connection: close\r\n")
- client:send(format("Content-Length: %s\r\n",#data))
- client:send(format("Content-Type: %s\r\n",(suffix and mimetypes[suffix]) or "text/html"))
+ client:send(f_content_length(#data))
+ client:send(f_content_type(suffix and mimetypes[suffix] or "text/html"))
client:send("Cache-Control: no-cache, no-store, must-revalidate, max-age=0\r\n")
client:send("\r\n")
client:send(data)
client:send("\r\n")
else
+ report("unknown file: %s",tostring(name))
errormessage(client,configuration,404)
end
end
@@ -217,9 +229,9 @@ end
local loaded = { }
function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) -- filename will disappear, and become hashed.filename
- local filename = file.join(configuration.scripts,filename)
- if not file.is_qualified_path(filename) then
- filename = file.join(configuration.root,filename)
+ local filename = joinpath(configuration.scripts,filename)
+ if not is_qualified_path(filename) then
+ filename = joinpath(configuration.root,filename)
end
-- todo: split url in components, see l-url; rather trivial
local result, keep = loaded[filename], false
@@ -258,16 +270,19 @@ function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) --
local action = handlers[suffix] or handlers.generic
action(client,configuration,result.content,suffix,true) -- content
elseif result.filename then
- local suffix = file.suffix(result.filename) or "text/html"
+ local suffix = filesuffix(result.filename) or "text/html"
local action = handlers[suffix] or handlers.generic
action(client,configuration,result.filename,suffix,false) -- filename
else
+ report("no content of filename in result")
errormessage(client,configuration,404)
end
else
+ report("no valid result")
errormessage(client,configuration,500)
end
else
+ report("no result")
errormessage(client,configuration,404)
end
end
@@ -278,19 +293,19 @@ handlers.html = handlers.htm
local indices = { "index.htm", "index.html" }
local portnumber = 8088
-local newline = lpeg.patterns.newline
-local spacer = lpeg.patterns.spacer
-local whitespace = lpeg.patterns.whitespace
-local method = lpeg.P("GET")
- + lpeg.P("POST")
+local newline = patterns.newline
+local spacer = patterns.spacer
+local whitespace = patterns.whitespace
+local method = P("GET")
+ + P("POST")
local identify = (1-method)^0
- * lpeg.C(method)
+ * C(method)
* spacer^1
- * lpeg.C((1-spacer)^1)
+ * C((1-spacer)^1)
* spacer^1
- * lpeg.P("HTTP/")
+ * P("HTTP/")
* (1-whitespace)^0
- * lpeg.C(lpeg.P(1)^0)
+ * C(P(1)^0)
function scripts.webserver.run(configuration)
-- check configuration
@@ -314,7 +329,7 @@ function scripts.webserver.run(configuration)
if not configuration.index then
for i=1,#indices do
local name = indices[i]
- if lfs.isfile(file.join(configuration.root,name)) then
+ if lfs.isfile(joinpath(configuration.root,name)) then
configuration.index = name -- we will prepend the rootpath later
break
end
@@ -322,7 +337,7 @@ function scripts.webserver.run(configuration)
configuration.index = configuration.index or "unknown"
end
if not configuration.scripts or configuration.scripts == "" then
- configuration.scripts = dir.expandname(file.join(configuration.root or ".",configuration.scripts or "."))
+ configuration.scripts = dir.expandname(joinpath(configuration.root or ".",configuration.scripts or "."))
end
-- so far for checks
report("running at port: %s",configuration.port)
@@ -333,20 +348,20 @@ function scripts.webserver.run(configuration)
local server = assert(socket.bind("*", configuration.port))
local script = configuration.script
while true do -- blocking
- local start = os.clock()
+ -- local start = gettime()
local client = server:accept()
client:settimeout(configuration.timeout or 60)
local request, e = client:receive()
if e then
- errormessage(client,configuration,404)
+ -- probably a time out
+ -- errormessage(client,configuration,404)
else
local from = client:getpeername()
report("request from: %s",tostring(from))
report("request data: %s",tostring(request))
- -- local fullurl = string.match(request,"(GET) (.+) HTTP/.*$") or "" -- todo: more clever / post
+ -- local fullurl = match(request,"(GET) (.+) HTTP/.*$") or "" -- todo: more clever / post
-- if fullurl == "" then
--- print("!!!!",request)
- local method, fullurl, body = lpeg.match(identify,request)
+ local method, fullurl, body = lpegmatch(identify,request)
if method == "" or fullurl == "" then
report("no url")
errormessage(client,configuration,404)
@@ -357,46 +372,50 @@ function scripts.webserver.run(configuration)
fullurl = url.unescapeget(fullurl)
report("requested url: %s",fullurl)
-- fullurl = socket.url.unescape(fullurl) -- happens later
- local hashed = url.hashed(fullurl)
- local query = url.query(hashed.query)
+ local hashed = urlhashed(fullurl)
+ local query = urlquery(hashed.query)
local filename = hashed.path -- hm, not query?
hashed.body = body
if script then
filename = script
report("forced script: %s",filename)
- local suffix = file.suffix(filename)
+ local suffix = filesuffix(filename)
local action = handlers[suffix] or handlers.generic
if action then
report("performing action: %s",filename)
action(client,configuration,filename,suffix,false,hashed) -- filename and no content
else
+ report("invalid action: %s",filename)
errormessage(client,configuration,404)
end
elseif filename then
- filename = socket.url.unescape(filename)
- report("requested action: %s",filename)
- if string.find(filename,"%.%.") then
+ local rawname = socket.url.unescape(filename)
+ filename = rawname
+ report("requested action: %s",filename or "?")
+ if find(filename,"%.%.") then
filename = nil -- invalid path
end
if filename == nil or filename == "" or filename == "/" then
filename = configuration.index
report("invalid filename, forcing: %s",filename)
end
- local suffix = file.suffix(filename)
+ local suffix = filesuffix(filename)
local action = handlers[suffix] or handlers.generic
if action then
- report("performing action: %s",filename)
+ report("performing action: %s",filename or "?")
action(client,configuration,filename,suffix,false,hashed) -- filename and no content
else
+ report("invalid action: %s",filename or "?")
errormessage(client,configuration,404)
end
else
+ report("invalid request")
errormessage(client,configuration,404)
end
end
end
client:close()
- report("time spent with client: %0.03f seconds",os.clock()-start)
+ -- report("time spent with client: %0.03f seconds",gettime()-start)
end
end
@@ -404,8 +423,8 @@ if environment.argument("auto") then
local path = resolvers.findfile("mtx-server.lua") or "."
scripts.webserver.run {
port = environment.argument("port"),
- root = environment.argument("root") or file.dirname(path) or ".",
- scripts = environment.argument("scripts") or file.dirname(path) or ".",
+ root = environment.argument("root") or dirname(path) or ".",
+ scripts = environment.argument("scripts") or dirname(path) or ".",
script = environment.argument("script"),
}
elseif environment.argument("start") then