197 lines
4.6 KiB
Lua
197 lines
4.6 KiB
Lua
local net = require "net"
|
|
local md = require "mdparse"
|
|
local event = require "event"
|
|
local fs = require "filesystem"
|
|
local computer = require "computer"
|
|
local home = "file:///usr/doc/mdbrowse.md"
|
|
local url = home
|
|
local cline = 1
|
|
local lines, links, listeners, history = {}, {}, {}, {}
|
|
local width, height = 80, 23
|
|
local run = true
|
|
|
|
local function pushhistory(url)
|
|
history[#history+1] = url
|
|
end
|
|
local function pophistory()
|
|
local rurl = history[#history] or home
|
|
history[#history] = nil
|
|
return rurl
|
|
end
|
|
|
|
local function parseurl(url)
|
|
local proto,addr = url:match("(.-)://(.+)")
|
|
addr = addr or url
|
|
local hp, path = addr:match("(.-)(/.*)")
|
|
hp, path = hp or addr, path or "/"
|
|
local host, port = hp:match("(.+):(.+)")
|
|
host = host or hp
|
|
path = fs.canonical(path)
|
|
return proto, host, port, path
|
|
end
|
|
|
|
function addButton(x,y,l,a)
|
|
local len = l:len() + 2
|
|
local function hf(_,_,tx,ty)
|
|
if y == ty and tx >= x and tx <= x+len then
|
|
io.write("\a")
|
|
computer.pushSignal("mdbrowsebutton",a)
|
|
end
|
|
end
|
|
event.listen("touch",hf)
|
|
listeners[#listeners+1] = hf
|
|
end
|
|
function dropButtons()
|
|
for k,v in pairs(listeners) do
|
|
event.ignore("touch",v)
|
|
end
|
|
end
|
|
|
|
function loadpage()
|
|
local protocol, host, port, path = parseurl(url)
|
|
protocol = protocol or "file"
|
|
if protocol == "file" then
|
|
local f = io.open(host..path,"rb")
|
|
if not f then
|
|
url = pophistory()
|
|
return false, "not found"
|
|
end
|
|
lines, links = md.reflow(f:read("*a"),width)
|
|
f:close()
|
|
return true
|
|
elseif protocol == "fget" then
|
|
port = tonumber(port) or 70
|
|
local socket = net.open(host,port)
|
|
if socket then
|
|
io.write("\27[u\27[2KConnection established.")
|
|
local buf = ""
|
|
socket:write("t"..path.."\n")
|
|
local c = socket:read(1)
|
|
repeat
|
|
c = socket:read(1)
|
|
os.sleep(0.5)
|
|
until c ~= ""
|
|
if c == "n" then
|
|
buf = path..": Not found.\n"
|
|
elseif c == "f" then
|
|
buf = "Failure: \n"
|
|
elseif c == "d" then
|
|
buf = "# Directory listing for "..path.."\n"
|
|
end
|
|
repeat
|
|
l = socket:read(1024)
|
|
buf = buf .. l
|
|
io.write("\27[u\27[2KRead "..tonumber(buf:len()).." bytes")
|
|
os.sleep(0.5)
|
|
until socket.state == "closed" and l == ""
|
|
if c == "d" then
|
|
local first, nbuf = false, ""
|
|
for line in buf:gmatch("[^\n]+") do
|
|
if first then
|
|
line = "- ["..line.."]("..line..")"
|
|
end
|
|
nbuf = nbuf .. line .. "\n"
|
|
first = true
|
|
end
|
|
buf = nbuf
|
|
end
|
|
lines, links = md.reflow(buf,width)
|
|
return true
|
|
else
|
|
url = pophistory()
|
|
return false, "unable to load"
|
|
end
|
|
end
|
|
end
|
|
|
|
function drawpage()
|
|
dropButtons()
|
|
if cline < 1 then
|
|
cline = 1
|
|
elseif cline > #lines then
|
|
cline = #lines
|
|
end
|
|
io.write("\27[2J\27[H")
|
|
for i = cline, cline+height do
|
|
print((lines[i] or ""):sub(1,width))
|
|
end
|
|
for k,v in pairs(links) do
|
|
if v[1] >= cline and v[1] <= height+cline then
|
|
addButton(v[2],(v[1])-cline+1,v[3],v[4])
|
|
end
|
|
end
|
|
local lstring = tostring(cline).."-"..tostring(cline+height).."/"..tostring(#lines)
|
|
io.write("\27[s"..lstring.." "..url)
|
|
end
|
|
|
|
function gourl(nurl)
|
|
pushhistory(url)
|
|
-- check for a protocol:// part
|
|
if nurl:match(".+://") then
|
|
url = nurl
|
|
-- check for a / -- root relative
|
|
elseif nurl:sub(1,1) == "/" then
|
|
url = (url:match(".+://.-/" or url:match(".+://.+/?").."/")) .. nurl
|
|
-- fail and assume relative
|
|
else
|
|
local host = (url:match(".+://.-/") or url:match(".+://.+/?").."/")
|
|
local path = url:sub(host:len()+1)
|
|
local tPath = fs.segments(path)
|
|
local ntPath = fs.segments(nurl)
|
|
if path:sub(path:len(),path:len()) ~= "/" then
|
|
tPath[#tPath] = nil
|
|
end
|
|
for k,v in ipairs(ntPath) do
|
|
tPath[#tPath+1] = v
|
|
end
|
|
url = host:sub(1,-2)
|
|
for k,v in ipairs(tPath) do
|
|
url = url .. "/" .. v
|
|
end
|
|
if nurl:sub(nurl:len(),nurl:len()) == "/" then
|
|
url = url .. "/"
|
|
end
|
|
end
|
|
end
|
|
|
|
loadpage()
|
|
drawpage()
|
|
while run do
|
|
local tev = {event.pull()}
|
|
if tev[1] == "key_down" then
|
|
if tev[3] == 0 and tev[4] == 200 then -- up
|
|
cline = cline - 1
|
|
drawpage()
|
|
elseif tev[3] == 0 and tev[4] == 208 then -- down
|
|
cline = cline + 1
|
|
drawpage()
|
|
elseif tev[3] == 0 and tev[4] == 203 then -- left
|
|
url = pophistory()
|
|
cline = 1
|
|
loadpage()
|
|
drawpage()
|
|
elseif tev[3] == 0 and tev[4] == 209 then -- page down
|
|
cline = cline + height
|
|
drawpage()
|
|
elseif tev[3] == 0 and tev[4] == 201 then -- page up
|
|
cline = cline - height
|
|
drawpage()
|
|
elseif tev[3] == 113 and tev[4] == 16 then -- q
|
|
run = false
|
|
elseif tev[3] == 111 then -- o
|
|
io.write("\27[u\27[2K\27[sURL: ")
|
|
gourl(io.read())
|
|
cline = 1
|
|
loadpage()
|
|
drawpage()
|
|
end
|
|
elseif tev[1] == "mdbrowsebutton" then
|
|
gourl(tev[2])
|
|
cline = 1
|
|
loadpage()
|
|
drawpage()
|
|
end
|
|
end
|
|
dropButtons()
|
|
io.write("\27[2J\27[H")
|